Skip to main content

A Python framework where the application code is the infrastructure declaration.

Project description

Skaal

CI Python License Targets Status

Your Python app is your architecture.

Write classes and functions. Skaal infers the infrastructure, generates the Pulumi, and your primitive classes are the typed clients. Pylance follows every call site straight down to the underlying SDK. One codebase. One mental model. skaal deploy knows what to build.

What Skaal looks like

from skaal import App, BlobStore, Cron, Store, Topic
from pydantic import BaseModel

class User(BaseModel):
    id: str
    email: str

class Users(Store[User]):
    """One table. The class is the table."""
    by_email = "email"  # declarative secondary index

class Avatars(BlobStore):
    """One bucket. The class is the bucket."""

class SignupEvents(Topic[User]):
    """One topic. The class is the topic."""

app = App("acme")

@app.expose
async def signup(user: User) -> User:
    await Users.put(user.id, user)
    await SignupEvents.publish(user)
    return user

@app.schedule(Cron("0 * * * *"))
async def hourly_compact() -> None:
    ...

The class is the typed client, importable from anywhere with no codegen step:

from acme.users import Users
user: User | None = await Users.get("u1")   # Pylance: user is User | None

When you need a backend-specific feature, you pin the type and get the real SDK client back, typed:

from skaal import Store
from skaal.backends.redis import Redis

class Sessions(Store[SessionRecord, Redis]):
    """Session rows backed by Redis in every environment."""

r = await Sessions.native()    # redis.asyncio.Redis, in every environment

The CLI is symmetric:

skaal run                      # local: SQLite + filesystem + in-memory topic
skaal plan --env prod          # diff: Users -> DynamoDB, Avatars -> S3, ...
skaal deploy --env prod        # Pulumi up against AWS

There is no constraint DSL. There is no catalog you maintain. There is no solver. The shape of the code is the deployment plan; an environment picks the backend by a fixed table the framework owns.

How it works

  1. Declare classes (Store[T], BlobStore, Topic[T], Table) and functions (@app.expose, @app.schedule, @app.job).
  2. Infer an environment-independent Blueprint by walking the App graph.
  3. Bind the blueprint against an environment (local, aws, gcp) using a fixed defaults table.
  4. Generate Pulumi programs, Dockerfiles, and handler entrypoints from the bound plan.
  5. Deploy via Pulumi. The skaal.lock file pins each binding so the next plan is empty unless code changed.

For full HTTP routing, mount any ASGI app (FastAPI, Starlette, Litestar) — Skaal deploys it; the framework you already know owns the routes:

from fastapi import FastAPI
api = FastAPI()
app.mount("/api", api)

What Skaal targets

  • Local — SQLite, filesystem, in-process topics, async functions, APScheduler.
  • AWS — DynamoDB, S3, SQS, Lambda, EventBridge, RDS Postgres, Secrets Manager.
  • GCP — Firestore, GCS, Pub/Sub, Cloud Run, Cloud Scheduler, Cloud SQL, Secret Manager.

The 0.4.0 cut ships AWS first; GCP follows in a 0.4.x point release.

Installation

pip install skaal                       # base
pip install "skaal[serve,runtime]"      # local development
pip install "skaal[deploy,aws,runtime]" # AWS
pip install "skaal[deploy,gcp,runtime]" # GCP

Status

Alpha (0.4.0a0). The framework is functional end-to-end on the local target and against AWS via Pulumi. The public surface (App, Module, Store[T, B], BlobStore[B], Topic[T, B], Table[B], @app.expose, @app.schedule, @app.job) is the supported surface going forward — see notes/redesign-status.md for the live progress tracker against ADR 028.

Roadmap and design decisions: ADR index.

License

GPL-3.0-or-later. See LICENSE.

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

skaal-0.4.0.tar.gz (505.0 kB view details)

Uploaded Source

Built Distribution

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

skaal-0.4.0-py3-none-any.whl (317.0 kB view details)

Uploaded Python 3

File details

Details for the file skaal-0.4.0.tar.gz.

File metadata

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

File hashes

Hashes for skaal-0.4.0.tar.gz
Algorithm Hash digest
SHA256 e66e632b15fb4116bf9353cdb886011da002410264cd815a651e94f3efb917fd
MD5 431216f0bd7ca3c6b23ab3120995bfba
BLAKE2b-256 56f7aab0707bec78e1556115ec903e1c4692e0f4801fe4f5a2df60871eba8693

See more details on using hashes here.

Provenance

The following attestation bundles were made for skaal-0.4.0.tar.gz:

Publisher: release.yml on Elouen-ginat/Skaal

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

File details

Details for the file skaal-0.4.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for skaal-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 daceb6968efc73c9b3c1d3f7445e240af61aced1b829de6896285b81df27be2e
MD5 cb70a7e04cc3d6a51c1c4b0dbe4b54be
BLAKE2b-256 12a341182f094f266f7a95a215ac5b828f7994097d2e3e3927a1c58c29e76eab

See more details on using hashes here.

Provenance

The following attestation bundles were made for skaal-0.4.0-py3-none-any.whl:

Publisher: release.yml on Elouen-ginat/Skaal

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