Skip to main content
The S3-compatible connector (AWS S3, Cloudflare R2, MinIO) is fully wired into the REST API: create a connection once, then test, validate, and forecast against it. Connection-management calls require a tenant identity (an API key with an organization, or an EOMER_API_KEY_TENANT_MAP_JSON mapping for local keys).

What a connector gives you

A data connection is a tenant-owned, reusable pointer to your data system, with credentials handled securely on eomer’s side. Once configured, eomer can:
  • Test connectivity and authentication (test_connection)
  • Discover objects under a prefix (list_objects) and estimate volume (estimate_size)
  • Infer schema from a bounded sample (infer_schema)
  • Validate the data as a forecasting dataset (validate_source)
  • Read the data for a forecast job (read_data)
  • Write forecast results back to a destination (write_output)

Credential model (IAM-first)

When a secret is stored, it is encrypted with a Fernet key from EOMER_CONNECTOR_ENCRYPTION_KEY before persistence. API responses never return secrets — only a redacted summary (auth_method, a masked hint, key version). See the package README.md for rotation and the KMS path.

REST quickstart

Responses never contain credentials — only a redacted credential summary (auth method, masked key hint, key version).

Configure an S3-compatible source (Python library)

AWS S3 (keyless)

Cloudflare R2

R2 is S3-compatible, so it reuses the same connector — only the endpoint, region, and (sealed) access key differ:

Validate before you forecast

validate_source reuses eomer’s core validator (required columns, null checks, numeric target, duplicate entity-time rows, parseable timestamps, minimum history) and adds frequency inference, schema-drift detection, and a volume guardrail.

Deliver results back to your system

Add an output block to the forecast request and eomer writes the completed forecast straight back to your bucket — closing the loop with no polling or manual download:
  • output.connection_id may point at a different connection (it must belong to your tenant); omitted = write back to the source connection.
  • key_template supports {job_id} and {date} placeholders; the default is eomer-forecasts/{date}/{job_id}.csv. Formats: csv, json, jsonl, parquet.
  • Delivery never overwrites existing objects unless allow_overwrite: true.
  • Track it on the job: GET /jobs/{job_id} returns delivery_status (pending → delivering → delivered | failed | skipped), delivery_uri, and a sanitized delivery_error. A failed delivery never fails the forecast — the result stays downloadable and the attempt is recorded in the audit trail (action: "deliver").

Partitioned data, globs, and compression

  • A trailing-slash prefix reads and concatenates all objects under it; add key_pattern (e.g. "part-*.csv", "2026-*/part-*.parquet") to filter.
  • Set compression: "gzip" on the connection for gzip’d CSV/JSON objects (zstd supported with the optional zstandard package); Parquet’s internal codec needs no configuration.
  • Forecast submission returns 202 immediately — the connector read happens inside the job worker, and a failed read marks the job failed with the sanitized connector error (visible on GET /jobs/{job_id} and in the audit trail).

Safety guarantees

  • Reads are byte- and row-bounded (max_bytes / max_rows) — oversized sources raise DATASET_TOO_LARGE instead of OOMing.
  • Object keys are sanitised against path traversal and control characters.
  • Format magic bytes are checked (a Parquet file declared as CSV fails fast).
  • Writes refuse to overwrite existing objects unless explicitly allowed, and can apply server-side encryption.
  • Every failure maps to a stable ConnectorErrorCode (AUTHENTICATION_FAILED, AUTHORIZATION_FAILED, SOURCE_NOT_FOUND, RATE_LIMITED, …); provider error text is never echoed back.