Skip to main content
The storage module handles uploading generated llms.txt files to Cloudflare R2 (S3-compatible object storage). It uses boto3 for S3 API compatibility and generates deterministic filenames based on URL hashing.

Overview

The storage module provides a single async function for saving llms.txt content to R2:
  • MD5-based filename generation for consistent paths
  • S3-compatible upload using boto3
  • Public URL generation with custom domain support
  • Graceful handling when storage is not configured

Configuration

Storage requires the following environment variables (from config.settings):
  • r2_endpoint - R2 endpoint URL
  • r2_access_key - R2 access key ID
  • r2_secret_key - R2 secret access key
  • r2_bucket - Target bucket name
  • r2_public_domain - Optional custom domain for public URLs

Functions

save_llms_txt()

Saves llms.txt content to R2 storage and returns the public URL.
str
required
The base URL of the crawled site (used for filename generation)
str
required
The formatted llms.txt content to upload
Callable
required
Logging function (sync or async) that accepts string messages
str | None
Public URL of the uploaded file, or None if upload failed or storage not configured
Behavior:
  1. Checks if all required R2 settings are configured
  2. If not configured, logs message and returns None
  3. Creates boto3 S3 client with R2 credentials
  4. Generates MD5 hash of base URL for deterministic filename
  5. Uploads content with text/markdown content type
  6. Constructs public URL using custom domain or endpoint
  7. Logs upload success with URL
  8. Returns public URL on success, None on error
Object Key Format:
Where <md5_hash> is the MD5 hash of the base URL.

Usage Examples

Basic Upload

Integration with Crawler and Formatter

Without Storage Configured

Error Handling

Public URL Generation

The function generates public URLs in two ways:

With Custom Domain

If settings.r2_public_domain is set:

Without Custom Domain

Falls back to R2 endpoint:

Filename Determinism

The MD5 hash ensures consistent filenames for the same base URL:
Benefits:
  • No need to track or delete old files
  • Recrawls automatically update the same file
  • Predictable URLs for integration

Content Type

Files are uploaded with Content-Type: text/markdown:
This ensures browsers and LLM tools recognize the content as markdown.

Error Handling

The function handles errors gracefully:
Common Errors:
  • Invalid credentials → ClientError
  • Network timeout → ClientError
  • Bucket not found → ClientError
  • Permission denied → ClientError
All errors are logged and return None.

Dependencies

  • boto3 - AWS SDK for S3-compatible operations
  • botocore - Error handling for boto3
  • config - Settings management
  • formatter - Generates the content to upload
  • database - Stores the public URL in Supabase
  • config - Provides R2 configuration settings

Notes

  • Function is async for consistency with other backend modules
  • Boto3 operations are synchronous (no async boto3 used)
  • Graceful degradation when storage not configured
  • Public URLs are immediately accessible after upload
  • No explicit public ACL needed (bucket configured for public reads)