Skip to content

Uploads ​

Single-file upload + text extraction for inline RAG injection. The chat handler embeds the returned ExtractedFile into the next chat completion's user message via packages.gateway.uploads.render_for_prompt, so an operator UI can drag-and-drop a PDF or DOCX into the chat box without separately ingesting it into the knowledge base.

This is the inline / one-shot path — for persistent RAG ingest, use the knowledge-base routes covered in 09 — Knowledge bases.

The router lives at packages/gateway/upload_routes.py.

Endpoints ​

MethodPathAuthSummary
POST/v1/uploadsBearerAccept one file; return its extracted text + metadata.

POST /v1/uploads ​

Multipart multipart/form-data body with a single file field.

Returns ExtractedFile (packages/gateway/uploads.py:76):

json
{
  "filename": "spec.pdf",
  "mime_type": "application/pdf",
  "byte_size": 124533,
  "content": "Title page\n\nSection 1 …"
}

The content field is plain UTF-8 text with the file's extracted prose — page breaks are flattened to blank lines.

bash
curl -X POST -H "Authorization: Bearer $BIGWAVE_ADMIN_TOKEN" \
  -F "file=@spec.pdf" \
  http://localhost:8000/v1/uploads

Supported formats ​

The default install handles plain text, JSON, YAML, XML, TOML, Markdown, JavaScript, and shell scripts via the built-in MIME allowlist (packages/gateway/uploads.py). Operators who want PDF or DOCX support install one of the optional extras groups:

ExtraWhat it adds
bigwave[uploads-pdf]pypdf — extracts text from application/pdf.
bigwave[uploads-docx]python-docx — extracts text from .docx.

PDF / DOCX uploads return 400 Bad Request with "unsupported MIME" until the extra is installed; the route does not lazy-fail at extraction time.

Operator notes ​

  • Size limit. Defaults to DEFAULT_MAX_BYTES (packages/gateway/uploads.py). Override per-process by setting app.state.uploads_max_bytes before the lifespan completes; the route reads it on every call. Oversize uploads return 400 with "upload <name> is N bytes; max is M bytes".
  • Image / audio / video. Returns 400 with UnsupportedMimeError — multimodal handling is not part of this surface. Use a chat completion with an image part instead.
  • Workspace scoping. Auth is required (AuthPrincipal) but the route does not persist anything per-workspace — extraction is stateless. The chat handler that embeds the result is the workspace boundary.
  • Errors. 400 for missing filename, oversize, unsupported MIME, or extraction-library failure. extract_text raises subclasses of UploadError; the route maps the message verbatim.
  • Streaming. Not supported. The whole file is read into memory, extracted, and returned. Stream large corpora through the knowledge-base ingest path instead.

Dual-licensed: MIT OR Apache-2.0