Skip to main content

OpenFrame Microservice Suite — core SDK. Ports, tracing, telemetry, exceptions, config.

Project description

openframe-core

OpenFrame Microservice Suite — core SDK.

openframe-core is the foundation package of the OpenFrame Microservice Development Suite. It defines the structural contracts, telemetry primitives, and shared utilities that every other package in the ecosystem depends on.

Every package in the OpenFrame ecosystem pins openframe-core>=1.0,<2. The major version is the stability contract for the entire ecosystem.


What's in this package

Module Contents
openframe.core.exceptions AdapterError hierarchy — structured exceptions all adapters raise
openframe.core.config BaseAdapterSettings — Pydantic base config all adapters inherit
openframe.core.ports BaseRepository[T], BaseProducer[T], BaseConsumer[T] Protocols
openframe.core.health HealthCheck Protocol — ping() and is_ready()
openframe.core.telemetry OTel SDK bootstrap — setup_telemetry(), get_tracer(), get_meter()
openframe.core.tracing TracingProxy — zero-code async telemetry sidecar
openframe.core.middleware TelemetryMiddleware — pure ASGI telemetry middleware
openframe.core.middleware.types ASGI type aliases — ASGIScope, ASGIMessage, Receive, Send, ASGIApp

Installation

pip install openframe-core

For development (includes pytest, pytest-asyncio, httpx):

pip install "openframe-core[dev]"

Quick start

Exceptions

from openframe.core.exceptions import AdapterConnectionError, AdapterNotFoundError

# In an adapter:
try:
    result = await conn.fetchrow(query)
except SomeDriverError as exc:
    raise AdapterQueryError(
        "Query failed",
        adapter="postgres",
        operation="get",
        cause=exc,
    ) from exc

# In a service (single catch point):
try:
    entity = await repo.get(entity_id)
except AdapterNotFoundError:
    return None
except AdapterError as exc:
    logger.error("Adapter failure: %s", exc)
    raise

Settings

from openframe.core.config import BaseAdapterSettings

class PostgresSettings(BaseAdapterSettings):
    database_url: str     # reads DATABASE_URL — required
    pool_size: int = 10   # reads POOL_SIZE — optional

# Raises ValidationError at startup if DATABASE_URL is not set:
settings = PostgresSettings()

Ports

from openframe.core.ports import BaseRepository

class PostgresItemRepository:
    async def get(self, entity_id: str) -> Item | None: ...
    async def list(self, limit: int, offset: int) -> tuple[list[Item], int]: ...
    async def create(self, entity: Item) -> Item: ...
    async def update(self, entity: Item) -> Item | None: ...
    async def delete(self, entity_id: str) -> bool: ...

# Structural conformance check at startup:
assert isinstance(PostgresItemRepository(), BaseRepository)

Telemetry

from openframe.core.telemetry import setup_telemetry, record_lifecycle_event

# In your lifespan handler — call once at startup:
@asynccontextmanager
async def lifespan(app):
    setup_telemetry()
    record_lifecycle_event("cold_start")
    yield

Authentication: Set OTEL_EXPORTER_OTLP_HEADERS — the OTel SDK handles it natively:

export OTEL_EXPORTER_OTLP_ENDPOINT="https://otlp.example.com"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic <base64_token>"
export OTEL_SERVICE_NAME="my-service"
export OPENFRAME_ENV="prod"

TracingProxy

from openframe.core.tracing import TracingProxy

raw_repo = PostgresItemRepository(settings)
traced_repo = TracingProxy(raw_repo, prefix="repository.item")

# Now traced_repo.get(...)    creates span "repository.item.get"
# And traced_repo.create(...) creates span "repository.item.create"
# The service layer is unaware telemetry exists.

Middleware

from openframe.core.middleware import TelemetryMiddleware

# Works with FastAPI:
from fastapi import FastAPI
app = FastAPI()
app.add_middleware(TelemetryMiddleware)  # or: app = TelemetryMiddleware(app)

# Works with bare ASGI:
app = TelemetryMiddleware(my_asgi_app)

Note: Do not call setup_telemetry() inside the middleware. Call it once in your lifespan handler. The middleware uses get_tracer() and get_meter() directly against whatever providers are currently set.


Environment variables

Variable Default Description
OTEL_EXPORTER_OTLP_ENDPOINT (none) OTLP base URL. When absent, no-op providers are used.
OTEL_EXPORTER_OTLP_HEADERS (none) Auth headers, e.g. Authorization=Basic xxx
OTEL_SERVICE_NAME openframe Service name tag
OTEL_SERVICE_VERSION 1.0.0 Service version tag
OTEL_METRIC_EXPORT_INTERVAL_MS 15000 Metric export interval in ms
OPENFRAME_ENV dev Deployment environment: dev / feat / prod

Modal users: Map MODAL_ENVOPENFRAME_ENV in your configure_env_vars() helper.


Running tests

pip install -e ".[dev]"
pytest tests/ -v

Smoke test:

python -c "from openframe.core.ports import BaseRepository; print('openframe-core OK')"

Ecosystem packages

Package Description
openframe-adapters Database and queue adapters (Postgres, Redis, Kafka, SQS, …)
openframe-protocol Protocol adapters (WebSocket, SSE, gRPC, MCP, webhooks)
openframe-infra Storage, auth, secrets, observability, feature flags
openframe-ai LangChain, LlamaIndex, CrewAI, model serving and training
openframe-suite Top-level meta-package — installs the full suite

All packages pin openframe-core>=1.0,<2.


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

openframe_core-1.0.0.tar.gz (34.1 kB view details)

Uploaded Source

Built Distribution

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

openframe_core-1.0.0-py3-none-any.whl (27.9 kB view details)

Uploaded Python 3

File details

Details for the file openframe_core-1.0.0.tar.gz.

File metadata

  • Download URL: openframe_core-1.0.0.tar.gz
  • Upload date:
  • Size: 34.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openframe_core-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f48ac4a2a5fca8a66012ce45e6c3eacdd1fd2b0df2d04c582b45e167a6a49dcc
MD5 2b06177fb11087e5e2e8348ddb225c24
BLAKE2b-256 8545b656dd4b1be871db3a41214a62c22e15665cce20f58e04acde18e6eff3f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for openframe_core-1.0.0.tar.gz:

Publisher: python-build.yml on Furious-Meteors/openframe-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openframe_core-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: openframe_core-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 27.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openframe_core-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 af31ad3e8a2d36f61f8817fcde69e615a72098946ae6cc7c052bbece1911bbfa
MD5 e757409ae7ef5128d4ba043b41c43a1d
BLAKE2b-256 272b58f9193aa757254b931f7da31534e92fc142b73941120f885eaaef2dcc07

See more details on using hashes here.

Provenance

The following attestation bundles were made for openframe_core-1.0.0-py3-none-any.whl:

Publisher: python-build.yml on Furious-Meteors/openframe-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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