> ## Documentation Index
> Fetch the complete documentation index at: https://agno-v2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Reading and Deleting Session Media

> Read session media through AgentOS, then delete the session and request a best-effort object sweep.

Attach and read session media through AgentOS, then request object cleanup when deleting the session.

<Warning>
  Session deletion and object cleanup are not atomic. AgentOS records the storage keys, deletes the session rows, then attempts a best-effort object sweep. A storage failure still returns a successful deletion and can leave orphaned objects.
</Warning>

```python media_storage_delete.py theme={null}
"""
Reading and Deleting Session Media
==================================

Demonstrates the AgentOS media routes: attach a file to a run, read it back through the
session, then delete the session and its stored objects together.

Media outlives a session by default. The reference on the run is the only record of which
object belongs to which session, so delete_media=true reads the keys off the rows before
they go, then sweeps the objects.

Set AGNO_FILE_OUTPUT_S3_BUCKET to the destination bucket.

Prerequisites: OPENAI_API_KEY, AWS credentials, and pip install 'agno[s3]'
Run: .venvs/demo/bin/python cookbook/05_agent_os/02_databases/media_storage_delete.py
Try: Attach a file to a run, then GET /sessions/{session_id} to see the MediaReference,
     GET /sessions/{session_id}/media/{storage_key} to stream it back, and
     DELETE /sessions/{session_id}?delete_media=true to remove the rows and the objects
"""

import os

from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.media.storage.s3 import AsyncS3MediaStorage
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from dotenv import load_dotenv

load_dotenv()

# ---------------------------------------------------------------------------
# Create Database and Media Storage
# ---------------------------------------------------------------------------

bucket = os.getenv("AGNO_FILE_OUTPUT_S3_BUCKET")
if not bucket:
    raise ValueError(
        "AGNO_FILE_OUTPUT_S3_BUCKET must be set to the destination S3 bucket"
    )

db = SqliteDb(db_file="tmp/agentos_media_delete.db")
storage = AsyncS3MediaStorage(
    bucket=bucket,
    region=os.getenv(
        "AWS_REGION"
    ),  # unset falls back to AWS_DEFAULT_REGION or ~/.aws/config
    prefix="agno/agentos/files/",
    presigned_url_expiry=3600,
)

# ---------------------------------------------------------------------------
# Create Agent
# ---------------------------------------------------------------------------

file_agent = Agent(
    id="media-delete-agent",
    name="Media Delete Agent",
    model=OpenAIResponses(id="gpt-5.5"),
    db=db,
    media_storage=storage,
    store_media=True,
    description="Answer questions about attached files.",
    markdown=True,
)

# ---------------------------------------------------------------------------
# Create AgentOS
# ---------------------------------------------------------------------------

agent_os = AgentOS(
    id="agentos-media-delete",
    name="AgentOS Media Delete",
    agents=[file_agent],
    db=db,
    media_storage=storage,  # the read and delete routes resolve keys through this
)
app = agent_os.get_app()

# ---------------------------------------------------------------------------
# Run AgentOS
# ---------------------------------------------------------------------------

if __name__ == "__main__":
    agent_os.serve(app="media_storage_delete:app", reload=True)
```

## Run the Example

<Steps>
  <Snippet file="create-venv-step.mdx" />

  <Step title="Install dependencies">
    ```bash theme={null}
    uv pip install -U "agno[os,s3]" botocore openai python-dotenv
    ```
  </Step>

  <Step title="Export environment variables">
    <CodeGroup>
      ```bash Mac/Linux theme={null}
      export AGNO_FILE_OUTPUT_S3_BUCKET="your_agno_file_output_s3_bucket_here"
      export AWS_REGION="your_aws_region_here"
      export OPENAI_API_KEY="your_openai_api_key_here"
      ```

      ```bash Windows theme={null}
      $Env:AGNO_FILE_OUTPUT_S3_BUCKET="your_agno_file_output_s3_bucket_here"
      $Env:AWS_REGION="your_aws_region_here"
      $Env:OPENAI_API_KEY="your_openai_api_key_here"
      ```
    </CodeGroup>
  </Step>

  <Step title="Configure AWS credentials">
    Configure the AWS SDK default credential chain with environment variables, a shared credentials file, or an IAM role.
  </Step>

  <Step title="Run the example">
    Save the code above as `media_storage_delete.py`, then run:

    ```bash theme={null}
    python media_storage_delete.py
    ```
  </Step>

  <Step title="Attach and read a file">
    In another terminal with `curl` and `jq`, attach a repository file, resolve its storage key from the session, and read it through AgentOS:

    ```bash theme={null}
    curl -sS -X POST http://127.0.0.1:7777/agents/media-delete-agent/runs \
      -F 'message=Summarize the attached file.' \
      -F 'session_id=media-delete-demo' \
      -F 'stream=false' \
      -F 'files=@README.md' > /tmp/agentos-media-run.json
    curl -sS http://127.0.0.1:7777/sessions/media-delete-demo > /tmp/agentos-media-session.json
    STORAGE_KEY="$(jq -r '.. | objects | .storage_key? // empty' /tmp/agentos-media-session.json | head -n 1)"
    test -n "$STORAGE_KEY"
    curl -sS -o /tmp/agentos-media-download "http://127.0.0.1:7777/sessions/media-delete-demo/media/${STORAGE_KEY}"
    ```
  </Step>

  <Step title="Delete the session and request cleanup">
    Delete the rows and request the best-effort storage sweep. Verify the object separately in S3 when cleanup assurance matters:

    ```bash theme={null}
    curl -i -X DELETE 'http://127.0.0.1:7777/sessions/media-delete-demo?delete_media=true'
    ```
  </Step>
</Steps>

Full source: [cookbook/05\_agent\_os/02\_databases/media\_storage\_delete.py](https://github.com/agno-agi/agno/blob/v3.0.4/cookbook/05_agent_os/02_databases/media_storage_delete.py)
