Skip to main content

Analytics event ingestion server for Spectra

Project description

spectra-server

The Spectra event ingestion server. Receives analytics events from the Spectra tracker script and writes them to Google BigQuery.

Built with FastAPI and Pydantic.

Installation

pip install spectra-server

Requires Python 3.11+.

Running the server

Option A — CLI (quickest)

Set the required environment variables (see Configuration), then:

spectra-server

Available flags:

Flag Default Description
--host 0.0.0.0 Bind host (overrides HOST env var)
--port 8000 Bind port (overrides PORT env var)
--reload off Enable auto-reload (development only)
--workers 1 Number of worker processes

Option B — uvicorn directly

uvicorn spectra:app --host 0.0.0.0 --port 8000

Configuration

Copy .env.example to .env and fill in the values. The server reads configuration from environment variables (loaded via python-dotenv):

Variable Required Description
BIGQUERY_PROJECT_ID Yes (for storage) GCP project ID
BIGQUERY_DATASET Yes (for storage) BigQuery dataset name
GOOGLE_APPLICATION_CREDENTIALS One of the two Path to a service account JSON file
GOOGLE_APPLICATION_CREDENTIALS_JSON One of the two Base64-encoded service account JSON
HOST No Bind host (default: 0.0.0.0)
PORT No Bind port (default: 8000)
CORS_ORIGINS No Comma-separated allowed origins, or * (default: *)

If neither BigQuery variable is set the server starts successfully and discards events — useful for local development without a GCP project.

API

POST /track

Ingest one or more events.

Headers

Header Description
X-Account-ID Tenant / BigQuery table name. Can also be passed in the request body.
Content-Type application/json or text/plain (plain text avoids CORS preflight for navigator.sendBeacon)

Body

{
  "account_id": "optional_if_provided_in_header",
  "events": [
    { "name": "page_view", "timestamp": "2024-01-01T00:00:00Z", "properties": {} }
  ]
}

Response

{ "status": "ok", "count": 2 }

GET /health

Returns server status and whether BigQuery is configured.

{ "status": "ok", "bigquery": "configured" }

Extending the server

The create_app() factory lets you mount your own middleware — API key validation, rate limiting, authentication, request logging, etc. — without forking the codebase.

Adding middleware

# myapp.py
from spectra import create_app
from my_auth import APIKeyMiddleware

app = create_app(
    middleware=[
        (APIKeyMiddleware, {"header": "X-API-Key", "keys": ["sk-live-..."]}),
    ]
)

Then run it:

uvicorn myapp:app --host 0.0.0.0 --port 8000

Middleware entries are (MiddlewareClass, kwargs_dict) tuples. The first entry in the list is the outermost layer (runs first on incoming requests).

API key validation example

Here is a minimal Starlette middleware that validates a bearer token:

# auth.py
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse

class APIKeyMiddleware(BaseHTTPMiddleware):
    def __init__(self, app, *, keys: list[str], header: str = "Authorization"):
        super().__init__(app)
        self.keys = set(keys)
        self.header = header

    async def dispatch(self, request: Request, call_next):
        if request.url.path == "/health":
            return await call_next(request)
        token = request.headers.get(self.header, "").removeprefix("Bearer ").strip()
        if token not in self.keys:
            return JSONResponse({"detail": "Unauthorized"}, status_code=401)
        return await call_next(request)
# myapp.py
from spectra import create_app
from auth import APIKeyMiddleware

app = create_app(
    middleware=[
        (APIKeyMiddleware, {"keys": ["sk-live-abc123"], "header": "Authorization"}),
    ]
)

Overriding FastAPI settings

Any keyword argument not recognised by create_app is forwarded to FastAPI():

app = create_app(
    cors_origins=["https://myapp.com"],
    docs_url=None,      # disable Swagger UI in production
    redoc_url=None,
)

Local development

git clone https://github.com/mvallejo3/spectra.git
cd spectra/server

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

cp .env.example .env  # fill in your values

make start            # uvicorn app:app --reload

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spectra_server-1.0.1.tar.gz (8.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spectra_server-1.0.1-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file spectra_server-1.0.1.tar.gz.

File metadata

  • Download URL: spectra_server-1.0.1.tar.gz
  • Upload date:
  • Size: 8.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for spectra_server-1.0.1.tar.gz
Algorithm Hash digest
SHA256 2827ce03a6d87f4d3d4e172a6896573fe3d24e5442017312ae167e539331243a
MD5 1a657f59d74417efc3bef1df71097d29
BLAKE2b-256 698cb018ae0dcf991824653e39c04495a99884e458d5e8dff9fba77492177bba

See more details on using hashes here.

File details

Details for the file spectra_server-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: spectra_server-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for spectra_server-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ff10a7f0f0e8a4a7746c482ba1ad8d8a4102552e7a8aa28ed9f8a9b65d2ed833
MD5 d3870fdf191256a17b7ebab6f2317568
BLAKE2b-256 ae6d501f08b78737466c67ab0e926e24cc01106de815a1b55ac2d1f48e36528d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page