> ## 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.

# Expected Parrot objects

> Store, retrieve, update, and share EDSL objects through the Expected Parrot platform.

Expected Parrot is a platform for model access, remote execution, caching, human research, and sharing study materials. The `Coop` client exposes its services in Python. This page covers storing and retrieving EDSL objects; see [Remote Inference](https://docs.expectedparrot.com/en/latest/remote_inference.md), [Remote Caching](https://docs.expectedparrot.com/en/latest/remote_caching.md), and [Human studies](https://docs.expectedparrot.com/en/latest/guides/human_studies.md) for execution and collection workflows.

Use these methods to reopen a study from another computer, reuse a collaborator's questionnaire, or share completed results. `push()` uploads an object and `pull()` retrieves it as a usable EDSL object. The returned **UUID** is its unique identifier, which you can keep instead of searching for the object each time.

## Authentication

Create an Expected Parrot account and configure your key using [Managing Keys](https://docs.expectedparrot.com/en/latest/api_keys.md). Remote operations below require authentication. Saving a local [`.ep` package](https://docs.expectedparrot.com/en/latest/guides/saving_objects) does not upload it.

## Upload and retrieve a survey

This example creates a local survey, then uploads a private copy. The upload stores the definition; it does not run the survey or generate responses.

```python theme={null}
from edsl import QuestionFreeText, Survey

survey = Survey([
    QuestionFreeText(question_name="feedback", question_text="What should improve?")
])
info = survey.push(description="Feature feedback survey", visibility="private")
survey_uuid = info["uuid"]
restored = Survey.pull(survey_uuid)
```

Keep the returned UUID with the study. Choose visibility explicitly. Sharing a survey definition is separate from publishing a respondent link; use `survey.humanize()` when collecting human responses.

## Use the client directly

The equivalent client operations let you work with multiple object types. Continuing with the UUID returned above:

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

coop = Coop()
restored = coop.get(survey_uuid, expected_object_type="survey")
```

Use `coop.push(object, description=..., visibility=...)` to upload another object. Objects such as surveys, agents, scenarios, and results preserve different parts of a study; saving one does not automatically preserve every related artifact.

## Find objects with filters and pagination

`coop.list()` returns a `CoopRegularObjects` collection of object metadata. For example, find private surveys and results whose descriptions match a study label:

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

coop = Coop()
objects = coop.list(
    object_type=["survey", "results"],
    visibility="private",
    search_query="Customer feedback",
    page=1,
    page_size=20,
    sort_ascending=False,
)
objects.select("uuid", "object_type", "description", "visibility")
# In a script, append .print() to display the selected metadata.
```

| Argument | Meaning |
| - | - |
| `object_type` | One type or a list, such as `"survey"`, `"results"`, `"agent_list"`, or `"scenario_list"`. Omit to include all types. |
| `visibility` | One value or a list drawn from `private`, `unlisted`, and `public`. |
| `search_query` | Search descriptions; this does not search the contents of questions or answers. |
| `page` | Page number, starting at **1**. |
| `page_size` | Objects per page, from 1 to 100. |
| `sort_ascending` | `False` returns the most recently created objects first. |
| `community` | `False` searches objects you own or that are shared with you. `True` searches public objects owned by other users. |

The returned collection exposes `current_page`, `total_pages`, `page_size`, and `total_count`. To retrieve another page, call `coop.list()` again with the same filters and a different `page` value. Fetching one page does not fetch all matches.

You can also filter the metadata you have already downloaded:

```python theme={null}
surveys_on_page = objects.filter("object_type == 'survey'")
surveys_on_page.select("uuid", "description")
```

This local filter returns a ScenarioList and only examines the current page. Use `object_type="survey"` in `coop.list()` to filter the search across all matching objects.

## Retrieve the listed objects

Listing metadata does not download each object's contents. Call `fetch()` on the original collection to download all objects on that page:

```python theme={null}
downloaded = objects.fetch()  # A Python list of EDSL objects.
```

To download only the surveys selected above, retrieve each by its object UUID:

```python theme={null}
surveys = [
    coop.pull(item["uuid"], expected_object_type="survey")
    for item in surveys_on_page
]
```

For a known object UUID or URL, `coop.pull(identifier, expected_object_type="results")` retrieves the Results object directly; `Results.pull(identifier)` is the class-specific alternative. `coop.get()` also retrieves and deserializes objects. These identifiers refer to stored objects. Use the [background jobs guide](https://docs.expectedparrot.com/en/latest/guides/background_jobs.md#find-jobs-with-filters-and-pagination) to find execution records and obtain their results UUIDs.

## Update and share

`coop.patch(survey_uuid, description="Revised description")` updates metadata. Supply `value=updated_survey` to replace object content deliberately. Preserve a local version before updating a shared definition that collaborators may rely on.

Read metadata without downloading the object with `coop.get_metadata(survey_uuid)`. `coop.patch_metadata(survey_uuid, description="Revised description", visibility="private")` changes metadata without replacing the object contents.

Use Python methods for access management:

```python theme={null}
coop.get_object_shared_users(survey_uuid)
# To grant access to a particular person:
# coop.share_object(survey_uuid, username_or_email="collaborator@example.com")
# To remove their access later:
# coop.unshare_object(survey_uuid, username_or_email="collaborator@example.com")
```

Sharing and unsharing change who can access the remote object. Private, unlisted, and public visibility have different access implications; choose the appropriate setting before sharing a link. The [CLI alternatives](https://docs.expectedparrot.com/en/latest/cli.md) are `ep shared`, `ep share`, and `ep unshare`.

## Delete a remote object

`coop.delete(survey_uuid)` deletes the remote object. Use it only when that deletion is intended. It is separate from removing a local file. The CLI equivalent is `ep delete`, which requires explicit confirmation in automated use.

## Research materials and provenance

Keep questions, logic, source data, model settings, prompts, results, and the EDSL version needed to interpret a run. Use [Notebooks](https://docs.expectedparrot.com/en/latest/notebooks.md) to share supporting notebooks or scripts and [Saving objects](https://docs.expectedparrot.com/en/latest/guides/saving_objects.md) for local versioning.

## Common methods

These client methods contact Expected Parrot and require configured access. `url_or_uuid` can be a stored object's URL or UUID.

| Call | Arguments and result |
| - | - |
| `coop.push(object, description=..., visibility="private")` | Upload an EDSL object and return its remote metadata, including its UUID. |
| `coop.pull(url_or_uuid, expected_object_type="results")` | Download and deserialize a stored object; optionally require a particular type. |
| `coop.get(url_or_uuid, expected_object_type="survey")` | Retrieve and deserialize an object; optionally require a particular type. |
| `coop.list(object_type="survey", page=1, page_size=10)` | Retrieve a page of accessible objects, optionally filtered by type. |
| `coop.patch(url_or_uuid, description=...)` | Update supplied metadata fields. Use `value=updated_object` to replace the stored content. |
| `coop.delete(url_or_uuid)` | Delete the remote object when you intend to remove it. |


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