> ## Documentation Index
> Fetch the complete documentation index at: https://docs.expectedparrot.com/llms.txt
> Use this file to discover all available pages before exploring further.

# FileStore

> Represent files as EDSL inputs and distinguish file attachments from tabular rows.

`FileStore` represents a file and its contents for use in EDSL or storage on Expected Parrot. A scenario can contain a FileStore attachment, or rows extracted from a file can become separate scenarios. For complete examples of asking questions about PDFs, images, video, and audio, see [Files and media as scenarios](https://docs.expectedparrot.com/en/latest/scenarios.md#data-and-files).

## Rows from a CSV and a whole-file attachment

This self-contained example writes a two-row CSV using Python's CSV writer, constructs a FileStore, and loads the rows as scenarios. It makes no model calls or uploads.

```python theme={null}
import csv
from pathlib import Path
from edsl import FileStore, Scenario, ScenarioList, QuestionMultipleChoice

path = Path("feedback.csv")
with path.open("w", newline="", encoding="utf-8") as handle:
    writer = csv.DictWriter(handle, fieldnames=["record_id", "feedback"])
    writer.writeheader()
    writer.writerows([
        {"record_id": "f1", "feedback": "The setup was easy."},
        {"record_id": "f2", "feedback": "The export button is missing."},
    ])
file = FileStore(str(path))
# A CSV row becomes one scenario, retaining its record_id.
rows = ScenarioList.from_source("csv", str(path))
question = QuestionMultipleChoice(
    question_name="sentiment",
    question_text="Classify this feedback: {{ scenario.feedback }}",
    question_options=["Positive", "Neutral", "Negative"],
)
job = question.by(rows)
# A whole file can instead be attached under a scenario key for a compatible model.
attachment = Scenario({"document": file})
```

`rows` has two scenarios, each with `record_id` and `feedback`. The `attachment` scenario instead holds the complete file under `document`. Loading a CSV into rows is useful for one classification per record; attaching a whole document is useful when the model needs the document itself.

## Images, PDFs, and other media

Use a FileStore value in a scenario and reference its field in the question. For example, `Scenario({"image": FileStore("image.png")})` attaches an image that the question can reference with `{{ scenario.image }}`. A plain path string carries only the filename.

The [Scenarios page](https://docs.expectedparrot.com/en/latest/scenarios.md#data-and-files) contains worked examples for:

* [Images](https://docs.expectedparrot.com/en/latest/scenarios.md#images), including [several attachments in one question](https://docs.expectedparrot.com/en/latest/scenarios.md#multiple-attachments-in-one-scenario).
* [Whole PDFs](https://docs.expectedparrot.com/en/latest/scenarios.md#pdf-attachments), [PDF text by page](https://docs.expectedparrot.com/en/latest/scenarios.md#pdf-text), and [PDF pages rendered as images](https://docs.expectedparrot.com/en/latest/scenarios.md#pdf-page-images).
* [Video](https://docs.expectedparrot.com/en/latest/scenarios.md#video) and [audio](https://docs.expectedparrot.com/en/latest/scenarios.md#audio).
* [A directory of files](https://docs.expectedparrot.com/en/latest/scenarios.md#a-collection-of-files), with one scenario per file.

## Storage and sharing

Creating a FileStore reads local data. Calling `push()` uploads it to Expected Parrot and requires authentication. Set visibility explicitly and retain the returned identifier. See [Saving and sharing objects](https://docs.expectedparrot.com/en/latest/guides/saving_objects.md) for posting and retrieving research materials.

For example, save a PDF on Expected Parrot and retrieve it as a scenario attachment:

```python theme={null}
from edsl import FileStore

report = FileStore("report.pdf")
info = report.push(description="Study report", visibility="private")
retrieved_report = FileStore.pull(info["uuid"])
document = retrieved_report.to_scenario(key_name="document")
```

Reference `{{ scenario.document }}` in your question, then pass `document` to `question.by(document)`. You can also pass a shared file URL to `FileStore.pull()`. Access follows the object's sharing permissions. To extract PDF text after retrieval, use `ScenarioList.from_source("pdf", retrieved_report.to_tempfile())` after importing `ScenarioList`.

## Common methods

| Call | Arguments and result |
| - | - |
| `FileStore("document.pdf")` | Read a local file and create an object containing its data. |
| `file.to_scenario(key_name="document")` | Return a Scenario with the file under the named key. |
| `file.to_scenario_list()` | Parse supported file formats into rows; available conversions depend on the file type. |
| `file.write("copy.pdf")` | Write the stored content to disk and return the filename. |
| `file.push(description="...", visibility="private")` | Upload the file object and return remote metadata. Requires an account. |
| `FileStore.pull(url_or_uuid)` | Retrieve a stored file object from Expected Parrot. |

Using the CSV created in the example above:

```python theme={null}
from edsl import FileStore

file = FileStore("feedback.csv")
attachment = file.to_scenario(key_name="document")
rows = file.to_scenario_list()
rows
# In a script: rows.print()
```

`attachment` contains one complete file, while `rows` contains the CSV records. Choose the input that matches what each respondent should evaluate.

## Read, preview, and convert files

| Task | Method and result |
| - | - |
| Download a file | `FileStore.from_url(url, download_path=absolute_path)` downloads content to the supplied path and returns a FileStore. |
| Extract text | `file.extract_text()` returns extracted text when the file handler supports it. Inspect the text for extraction errors. |
| Read through a file object | `file.open()` returns a Python file-like object; close it when finished. |
| Create a temporary copy | `file.to_tempfile()` writes the stored content to a temporary file. |
| Preview | `file.view()` displays supported content. `file.download_link()` creates a notebook download link. |
| Read a table | `file.to_pandas()` uses the file's supported tabular reader. |
| Convert Markdown | `file.to_docx(output_path="report.docx")` or `file.to_pdf(output_path="report.pdf")` converts a Markdown FileStore. Conversion dependencies must be installed. |
| Inspect media | `file.is_image()`, `is_video()`, `get_image_dimensions()`, and `get_video_metadata()` identify supported media and inspect dimensions or video metadata. |

`FileStore.from_file_upload_answer(file_info)` retrieves one uploaded file from a human survey answer; see [file upload responses](https://docs.expectedparrot.com/en/latest/humanize.md#working-with-file-upload-responses).

## Generate image inputs

`ImageGeneration` produces FileStore objects that can be attached to scenarios. This example uses a local test service that returns a tiny placeholder image, without a provider request:

```python theme={null}
from edsl import ImageGeneration

generator = ImageGeneration(model="test", service_name="test")
image = generator.generate("A product concept illustration")
image.write("test-image.png")
```

For actual generation, choose a model supported by the image service, for example `ImageGeneration(model="MODEL_NAME", service_name="google")`, with the provider credential configured. Image generation can incur costs. Pass `input_images=[file]` when the chosen service supports editing or image-conditioned generation. Provider-specific parameters can be supplied at construction or to `generate()`.

In a notebook with an active event loop or an asynchronous function, use `await generator.async_generate(prompt)` instead of `generate()`. A single generated image returns one FileStore; multiple images return a list. With `return_type="generated_image"`, the return value instead contains `GeneratedImage` metadata. Use its `to_filestore()` to access the file, `token_usage()` for usage information, and `cost()` for the model-price-based cost calculation; missing usage can be estimated rather than measured.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.