Skip to main content

nene2-python

A Python reference framework implementing the NENE2 design philosophy — clean architecture, security-first, and AI-readable code.

CI Python License: MIT

Current release: v1.8.97 · 466 tests · CI on Python 3.12 and 3.14


Features

  • FastAPI + Pydantic v2 — modern Python API stack with automatic OpenAPI docs
  • Clean Architecture — UseCase / Domain layer fully decoupled from HTTP and DB
  • mypy --strict — equivalent to PHPStan level 8 type safety
  • ruff — lint and format in one tool (replaces flake8, isort, black, bandit)
  • RFC 9457 Problem Details — uniform error responses across all endpoints
  • Bearer Token / API Key auth — LocalTokenVerifier, CompositeAuthMiddleware, dev JWT helpers
  • MCP support — expose UseCases as AI agent tools via LocalMcpServer
  • SQLAlchemy Core — parameterised SQL without ORM overhead
  • Security middleware — CSP, rate limiting, request size limit, CORS via setup_middlewares()
  • ETag / conditional requests — generate_etag(), check_not_modified(), check_precondition()
  • TTL cache & webhooks — TtlCache[V], verify_hmac_signature()
  • structlog — structured JSON logging with request ID correlation
  • 219 field trials — stdlib and framework patterns validated in sandbox apps (INDEX)

Installation

pip install nene2-python
# or
uv add nene2-python

Requires Python 3.12+ (CI also tests 3.14).


Quick Start

Use APIRouter + create_app() at the end of the file (see CLAUDE.md). Register middlewares with setup_middlewares() so 500 responses still get X-Request-Id and security headers.

from fastapi import APIRouter, FastAPI
from nene2.config import AppSettings
from nene2.middleware import setup_middlewares

router = APIRouter()

@router.get("/health")
def health() -> dict[str, str]:
    return {"status": "ok"}

def create_app() -> FastAPI:
    cfg = AppSettings()
    app = FastAPI(title=cfg.app_name)
    setup_middlewares(
        app,
        debug=cfg.app_debug,
        throttle_limit=cfg.throttle_limit if cfg.throttle_enabled else None,
        cors_allowed_origins=cfg.cors_origins if cfg.cors_enabled else None,
    )
    app.include_router(router)
    return app

app = create_app()

See the full reference app in src/example/ (Note / Tag / Comment CRUD, auth, MCP).


Define a domain

from dataclasses import dataclass
from abc import ABC, abstractmethod

@dataclass(frozen=True, slots=True)
class Note:
    id: int
    title: str
    body: str

class NoteRepositoryInterface(ABC):
    @abstractmethod
    def find_by_id(self, note_id: int) -> Note | None: ...

@dataclass(frozen=True, slots=True)
class GetNoteInput:
    note_id: int

class GetNoteUseCase:
    def __init__(self, repository: NoteRepositoryInterface) -> None:
        self._repository = repository

    def execute(self, input_: GetNoteInput) -> Note:
        note = self._repository.find_by_id(input_.note_id)
        if note is None:
            raise NoteNotFoundException(input_.note_id)
        return note

Wire to HTTP

from fastapi import APIRouter
from fastapi.responses import JSONResponse

router = APIRouter(prefix="/notes", tags=["notes"])

@router.get("/{note_id}")
async def get_note(note_id: int) -> JSONResponse:
    note = get_use_case.execute(GetNoteInput(note_id))
    return JSONResponse({"id": note.id, "title": note.title, "body": note.body})

Development Commands

uv sync                         # install dependencies
uv run pytest                   # 466 tests, coverage ≥ 80%
uv run mypy src/                # type check (strict)
uv run ruff check src/ tests/   # lint
uv run ruff format src/ tests/  # format
uv run uvicorn src.example.app:app --reload --port 8080  # dev server

Full CI check (equivalent to GitHub Actions):

uv run pytest && \
uv run mypy src/ && \
uv run ruff check src/ tests/ && \
uv run ruff format --check src/ tests/ && \
uv run pip-audit --ignore-vuln PYSEC-2025-183

CI also runs a 90% coverage gate on example/*/use_case.py, entity.py, and async_use_case.py.


Framework Modules

Module Purpose
nene2.http Pagination, Problem Details, health checks, ETag, query helpers, RequestScopedContext
nene2.middleware Full pipeline + setup_middlewares(), rate-limit storage protocol
nene2.auth Bearer / API Key / composite auth, LocalTokenIssuer, make_require_auth()
nene2.database SqlAlchemyQueryExecutor, SqlAlchemyTransactionManager, DatabaseHealthCheck
nene2.config AppSettings (pydantic-settings, reads from env / .env)
nene2.validation ValidationException, ValidationError
nene2.cache TtlCache[V] — thread-safe in-memory TTL cache
nene2.security verify_hmac_signature() for webhook verification
nene2.mcp LocalMcpServer, HttpxMcpClient
nene2.log setup_logging() (structlog, JSON in production)
nene2.use_case UseCaseProtocol[I, O], AsyncUseCaseProtocol[I, O]

Details: Framework modules reference · How-to guides


Versioning

  • pyproject.toml version — bumped with each merged FT or feature PR (currently 1.8.97).
  • Git tags (v1.8.N) — created on selected releases; may lag behind pyproject.toml during rapid FT loops.
  • See docs/todo/current.md for the latest milestone table.

PHP NENE2 Correspondence

PHP Python
readonly class dataclass(frozen=True, slots=True)
PHPStan level 8 mypy --strict
PHP-CS-Fixer ruff format
composer check uv run pytest && mypy && ruff check && ruff format --check && pip-audit --ignore-vuln PYSEC-2025-183
ValidationException nene2.validation.ValidationException
PaginationQueryParser nene2.http.PaginationQueryParser
ErrorHandlerMiddleware nene2.middleware.ErrorHandlerMiddleware
LocalMcpServer nene2.mcp.LocalMcpServer

Related

Metadata

Release files for nene2-python 1.8.164

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nene2-python 1.8.164
File Size Uploaded
nene2_python-1.8.164.tar.gz 908.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nene2-python 1.8.164
File Interpreter ABI Platform
nene2_python-1.8.164-py3-none-any.whl Python 3 none any Details

Total release size: 961.4 kB

Release files / nene2_python-1.8.164.tar.gz

Download URL nene2_python-1.8.164.tar.gz
Size 908.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0db3053006acaf4ddcef35dfb29f42c6383da077e3e11e473caae3ac88d93770
BLAKE2b-256 checksum
How to use checksums
0ec959884d4e13003b86c346551ab9e5af6416ccc1035f096dfef952cf8764fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","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}

Release files / nene2_python-1.8.164-py3-none-any.whl

Download URL nene2_python-1.8.164-py3-none-any.whl
Size 53.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bf62a00bed09f01526a717e4e78b8627c07394258d8e428dda3acf80de00c230
BLAKE2b-256 checksum
How to use checksums
ebb64428827ecc7d0a0f4329c8c53a127dc84c2c357f8f274e1a1aace5f33a26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","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}

Release history Release notifications | RSS feed

This release

1.8.164 This release

2 release files

1.8.66

2 release files

1.8.65

2 release files

1.8.64

2 release files

1.8.63

2 release files

1.8.62

2 release files

1.8.60

2 release files

1.8.59

2 release files

1.8.58

2 release files

1.8.57

2 release files

1.8.56

2 release files

1.8.55

2 release files

1.8.54

2 release files

1.8.53

2 release files

1.8.52

2 release files

1.8.51

2 release files

1.8.50

2 release files

1.8.49

2 release files

1.8.48

2 release files

1.8.47

2 release files

1.8.46

2 release files

1.8.45

2 release files

1.8.44

2 release files

1.8.43

2 release files

1.8.42

2 release files

1.8.41

2 release files

1.8.40

2 release files

1.8.39

2 release files

1.8.38

2 release files

1.8.37

2 release files

1.8.36

2 release files

1.8.35

2 release files

1.8.34

2 release files

1.8.33

2 release files

1.8.32

2 release files

1.8.31

2 release files

1.8.30

2 release files

1.8.29

2 release files

1.8.28

2 release files

1.8.27

2 release files

1.8.26

2 release files

1.8.25

2 release files

1.8.24

2 release files

1.8.23

2 release files

1.8.22

2 release files

1.8.21

2 release files

1.8.20

2 release files

1.8.19

2 release files

1.8.18

2 release files

1.8.17

2 release files

1.8.16

2 release files

1.8.15

2 release files

1.8.14

2 release files

1.8.13

2 release files

1.8.12

2 release files

1.8.11

2 release files

1.8.10

2 release files

1.8.9

2 release files

1.8.8

2 release files

1.8.7

2 release files

1.8.6

2 release files

1.8.5

2 release files

1.8.4

2 release files

1.8.3

2 release files

1.8.2

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page