Skip to main content

Async-first Python web framework with Flask ergonomics and Django-inspired security defaults.

Project description

Flasgo

Flasgo is an async-first Python web framework designed as a hybrid of:

  • Flask ergonomics: decorator-based routing, minimal ceremony, quick iteration.
  • Django security defaults: CSRF protection, host validation, secure headers, signed sessions.

Project goals

  • Fast request handling with an ASGI core.
  • First-class async support.
  • Type-safe APIs with strict tooling.
  • Minimal moving parts and sensible defaults.

Requirements

  • Python >=3.14
  • Tooling: uv, ruff, ty, pytest

Quick start

uv venv
uv sync --group dev

Create app.py:

from flasgo import Flasgo

app = Flasgo()


@app.get("/")
async def home():
    return {"framework": "flasgo", "status": "ok"}


@app.post("/notes/<int:note_id>")
async def update_note(note_id: int):
    return {"updated": note_id}


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8000)

Run:

uv run python app.py

Development run (recommended)

Uses uvicorn with reload while building locally:

uv run uvicorn app:app --reload --host 127.0.0.1 --port 8000

app.run(...) uses the built-in dev server and should only be used for local development.

Production deployment

Use a production ASGI server process and configure secrets with environment variables:

import os
from flasgo import Flasgo

app = Flasgo(
    settings={
        "DEBUG": False,
        "SECRET_KEY": os.environ["FLASGO_SECRET_KEY"],
        "ALLOWED_HOSTS": {"api.example.com"},
        "CSRF_ENABLED": True,
        "SESSION_COOKIE_SECURE": True,
        "CSRF_COOKIE_SECURE": True,
    }
)

Run with workers:

export FLASGO_SECRET_KEY="$(openssl rand -hex 32)"
uv run uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4

Put a reverse proxy/load balancer in front (Caddy, Cloudflare, etc.) for TLS termination and network controls.

Security defaults

  • Host header allowlist (localhost, 127.0.0.1 by default).
  • CSRF double-submit cookie defense for unsafe methods.
  • Signed session cookies (HMAC-SHA256).
  • No-store cache headers by default to reduce sensitive data caching (CWE-524 mitigation).
  • Request body/head limits and read timeouts in the built-in dev server.
  • Optional per-client throttling for repeated security failures (429).
  • Security event logging for host/CSRF/authz denials.
  • Hardened headers (CSP, HSTS, X-Frame-Options, Referrer-Policy, etc.).

Developer commands

uv run ruff check .
uv run ty check
uv run pytest

API surface (initial)

  • Flasgo.route, Flasgo.get, Flasgo.post, Flasgo.put, Flasgo.patch, Flasgo.delete
  • Flasgo.before_request, Flasgo.after_request, Flasgo.errorhandler
  • Flasgo.register_auth_backend, Flasgo.authorize
  • Auth helpers: bearer_token_backend, extract_bearer_token
  • Flask-style path params: <name>, <int:name>, <float:name>, <path:name>
  • Optional OpenAPI spec + Swagger UI docs (disabled by default)
  • Response coercion:
    • str / bytes
    • dict / list (JSON)
    • (body, status) / (body, status, headers)
    • Response

Flask-style globals

from flasgo import Flasgo, jsonify, request

app = Flasgo()


@app.get("/inspect")
def inspect():
    return jsonify({"method": request.method, "path": request.path})

Django-like settings

app = Flasgo(
    settings={
        "SECRET_KEY": "replace-in-production",
        "ALLOWED_HOSTS": {"api.example.com"},
        "CSRF_ENABLED": True,
    }
)

You can also pass a Python module path string ("myproject.settings"), and Flasgo will load uppercase settings attributes.

Auth and permissions

from flasgo import Flasgo, HasScope, IsAuthenticated, User, bearer_token_backend

app = Flasgo()


def validate_token(token: str):
    if token == "token-123":
        return User(id="alice", is_authenticated=True, scopes=frozenset({"admin"}))
    return None


app.register_auth_backend("bearer", bearer_token_backend(validate_token))


@app.get("/admin")
@app.authorize(IsAuthenticated(), HasScope("admin"), backend="bearer")
def admin():
    return "ok"

Auth behavior:

  • Unauthenticated requests are denied with 401 Unauthorized.
  • Authenticated requests without permission are denied with 403 Forbidden.

SSRF protection helpers (CWE-918)

For outbound URLs from user input, validate before fetching:

from flasgo import Flasgo

app = Flasgo(
    settings={
        "SSRF_ALLOWED_SCHEMES": {"https"},
        "SSRF_ALLOWED_HOSTS": {"api.example.com"},
    }
)

safe_url = app.validate_outbound_url("https://api.example.com/data")

By default, Flasgo blocks unsafe schemes, embedded credentials, localhost/private network targets, and unresolved hosts.

Automatic API docs

Flasgo can expose:

  • OpenAPI JSON (default path: /openapi.json)
  • Swagger UI (default path: /docs)

Docs are disabled by default for safer production posture. Enable and customize with settings:

app = Flasgo(
    settings={
        "ENABLE_DOCS": True,
        "DOCS_PATH": "/api-docs",
        "OPENAPI_PATH": "/api/openapi.json",
        "API_TITLE": "My API",
        "API_VERSION": "1.2.3",
        "API_DESCRIPTION": "Internal service API",
    }
)

This is the initial framework baseline; it is intentionally small so the core can evolve quickly.

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

flasgo-0.1.0.tar.gz (46.7 kB view details)

Uploaded Source

Built Distribution

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

flasgo-0.1.0-py3-none-any.whl (28.7 kB view details)

Uploaded Python 3

File details

Details for the file flasgo-0.1.0.tar.gz.

File metadata

  • Download URL: flasgo-0.1.0.tar.gz
  • Upload date:
  • Size: 46.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for flasgo-0.1.0.tar.gz
Algorithm Hash digest
SHA256 41eb8c7d543c300e3e4cf435eb4a7b4620c80e1c9bef3f5ef9d5a2349e12e16c
MD5 663812dac68035457f102fc1a572525f
BLAKE2b-256 60b8686d90f883827c574cbb910b23daf12962c0c49dc965c812f0631c847213

See more details on using hashes here.

File details

Details for the file flasgo-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: flasgo-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 28.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for flasgo-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 22f9be36855710a9ed2645d2425da65b3b98259c599a44de7481bcfd08892c32
MD5 c848b144fe4685f1b2e364bbdb3ed98f
BLAKE2b-256 e73cc3eac175235c8ba85a7473c4f0aaee9a383083aa524e36cf15a0d091e20b

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