Skip to main content

Context Files and URLs

Prompts can have attached context items - files and URLs that provide additional information when using the prompt.

Understanding Context

Context items are attachments that supplement a prompt:
  • Files - Documents, images, data files uploaded to Claro
  • URLs - Web pages or external resources
from baytos.claro import BaytClient

client = BaytClient(api_key="your_api_key")
prompt = client.get_prompt("@workspace/research-assistant:v1")

# Check if prompt has context
if prompt.has_context():
    print(f"This prompt has {len(prompt.context)} context items")

Checking for Context

Before working with context, check if it exists:
prompt = client.get_prompt("@workspace/my-prompt:v1")

# Check if any context exists
if prompt.has_context():
    print("Prompt has attachments")

# Get all context items
context_items = prompt.context
for item in context_items:
    print(f"- {item.type}: {item}")

File Contexts

Getting File Contexts

prompt = client.get_prompt("@workspace/prompt-with-files:v1")

# Get only file-type contexts
files = prompt.get_file_contexts()

for file in files:
    print(f"File: {file.file_name}")
    print(f"Size: {file.file_size:,} bytes")
    print(f"Type: {file.mime_type}")
    print()

File Metadata

Each file context provides:
file = files[0]

# Basic info
print(f"ID: {file.id}")
print(f"Type: {file.type}")  # Always "file"
print(f"Label: {file.label}")  # Optional custom label

# File-specific info
print(f"Filename: {file.file_name}")
print(f"Size: {file.file_size} bytes")
print(f"MIME type: {file.mime_type}")
print(f"Created: {file.created_at}")  # Unix timestamp

Downloading Files

Download file content to memory:
prompt = client.get_prompt("@workspace/data-analysis:v1")
files = prompt.get_file_contexts()

if files:
    file = files[0]

    # Download file content
    content = client.download_context_file(file.id)

    # Content is returned as bytes
    print(f"Downloaded {len(content):,} bytes")

    # Save to disk
    with open(file.file_name, 'wb') as f:
        f.write(content)

    print(f"Saved to: {file.file_name}")

Getting Download URLs

For large files or delegating downloads, get a signed URL:
file = files[0]

# Get signed download URL
url_info = client.get_context_download_url(file.id)

download_url = url_info['url']
expires_in = url_info['expiresIn']  # Seconds until expiry

print(f"Download URL: {download_url}")
print(f"Expires in: {expires_in} seconds")

# URL is pre-signed, no authentication needed
# Can be passed to browser, other services, etc.
Download URLs expire after 1 hour by default. Generate a new URL if needed.

Example: Download All Files

import os
from baytos.claro import BaytClient

client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
prompt = client.get_prompt("@workspace/research:v1")

# Create directory for downloads
os.makedirs("downloads", exist_ok=True)

# Download all files
files = prompt.get_file_contexts()
for file in files:
    print(f"Downloading {file.file_name}...")

    content = client.download_context_file(file.id)

    # Save with original filename
    filepath = os.path.join("downloads", file.file_name)
    with open(filepath, 'wb') as f:
        f.write(content)

    print(f"  Saved: {filepath} ({file.file_size:,} bytes)")

print(f"\nDownloaded {len(files)} file(s)")

URL Contexts

Getting URL Contexts

prompt = client.get_prompt("@workspace/web-research:v1")

# Get only URL-type contexts
urls = prompt.get_url_contexts()

for url_item in urls:
    print(f"URL: {url_item.url}")
    if url_item.label:
        print(f"Label: {url_item.label}")
    if url_item.url_fetched_at:
        print(f"Fetched: {url_item.url_fetched_at}")
    print()

URL Metadata

Each URL context provides:
url_item = urls[0]

# Basic info
print(f"ID: {url_item.id}")
print(f"Type: {url_item.type}")  # Always "url"
print(f"Label: {url_item.label}")  # Optional custom label

# URL-specific info
print(f"URL: {url_item.url}")
print(f"Fetched at: {url_item.url_fetched_at}")  # Unix timestamp

Working with Mixed Context

Handle both files and URLs:
prompt = client.get_prompt("@workspace/comprehensive:v1")

# Get all context items
for item in prompt.context:
    if item.is_file():
        print(f"📄 File: {item.file_name} ({item.file_size:,} bytes)")
    elif item.is_url():
        print(f"🔗 URL: {item.url}")

Type Checking

Check context item types:
for item in prompt.context:
    # Method 1: Use helper methods
    if item.is_file():
        print(f"This is a file: {item.file_name}")

    if item.is_url():
        print(f"This is a URL: {item.url}")

    # Method 2: Check type property
    if item.type == "file":
        print("File type")
    elif item.type == "url":
        print("URL type")

Complete Example

#!/usr/bin/env python3
"""
Example: Download all context files from a prompt
"""

import os
from pathlib import Path
from baytos.claro import BaytClient

def download_prompt_context(package_name: str, output_dir: str = "downloads"):
    """Download all files attached to a prompt"""

    client = BaytClient(api_key=os.getenv("BAYT_API_KEY"))
    prompt = client.get_prompt(package_name)

    print(f"Prompt: {prompt.title}")
    print(f"Package: {prompt.package_name}\n")

    if not prompt.has_context():
        print("No context items attached to this prompt")
        return

    # Create output directory
    Path(output_dir).mkdir(parents=True, exist_ok=True)

    # Process all context items
    files = prompt.get_file_contexts()
    urls = prompt.get_url_contexts()

    # Download files
    if files:
        print(f"Downloading {len(files)} file(s)...\n")
        for i, file in enumerate(files, 1):
            print(f"{i}. {file.file_name}")
            print(f"   Size: {file.file_size:,} bytes")
            print(f"   Type: {file.mime_type}")

            # Download
            content = client.download_context_file(file.id)

            # Save
            filepath = Path(output_dir) / file.file_name
            filepath.write_bytes(content)

            print(f"   Saved: {filepath}")
            print()

    # List URLs
    if urls:
        print(f"\n{len(urls)} URL(s):")
        for i, url_item in enumerate(urls, 1):
            label = url_item.label or "Untitled"
            print(f"{i}. {label}: {url_item.url}")

    print("\nDone!")

if __name__ == "__main__":
    download_prompt_context("@workspace/research-assistant:v1")

Error Handling

Handle common errors when working with context:
from baytos.claro import (
    BaytClient,
    BaytNotFoundError,
    BaytAuthError,
    BaytValidationError
)

client = BaytClient(api_key="...")

try:
    prompt = client.get_prompt("@workspace/my-prompt:v1")
    files = prompt.get_file_contexts()

    if files:
        content = client.download_context_file(files[0].id)

except BaytNotFoundError:
    print("Prompt or file not found")
except BaytAuthError:
    print("Authentication failed - check your API key")
except BaytValidationError as e:
    print(f"Invalid request: {e}")
except Exception as e:
    print(f"Error: {e}")

Best Practices

Always check if context exists before accessing:
# ✅ Good: Check first
if prompt.has_context():
    files = prompt.get_file_contexts()
    if files:
        content = client.download_context_file(files[0].id)

# ❌ Bad: Assume context exists
files = prompt.get_file_contexts()
content = client.download_context_file(files[0].id)  # May fail!
For large files, consider using download URLs instead of downloading to memory:
MAX_MEMORY_SIZE = 50 * 1024 * 1024  # 50 MB

for file in files:
    if file.file_size > MAX_MEMORY_SIZE:
        # Get URL instead of downloading
        url_info = client.get_context_download_url(file.id)
        print(f"Large file - use URL: {url_info['url']}")
    else:
        # Safe to download to memory
        content = client.download_context_file(file.id)
Sanitize filenames before saving to disk:
import re
from pathlib import Path

def safe_filename(filename: str) -> str:
    """Remove unsafe characters from filename"""
    # Remove path traversal attempts
    filename = Path(filename).name
    # Remove unsafe characters
    filename = re.sub(r'[^\w\s.-]', '', filename)
    return filename

for file in files:
    safe_name = safe_filename(file.file_name)
    content = client.download_context_file(file.id)

    with open(safe_name, 'wb') as f:
        f.write(content)
Filter and process files based on MIME type:
files = prompt.get_file_contexts()

# Process only images
image_files = [f for f in files if f.mime_type.startswith('image/')]

# Process only PDFs
pdf_files = [f for f in files if f.mime_type == 'application/pdf']

# Process text files
text_files = [f for f in files if f.mime_type.startswith('text/')]

for pdf in pdf_files:
    content = client.download_context_file(pdf.id)
    # Process PDF...

Next Steps