Decorator-driven OpenAPI 3 spec generation for Pecan applications
Project description
Decorator-driven OpenAPI 3 spec generation for Pecan applications.
pecan-apispec follows the same shape as pecan-swagger – lightweight decorators record metadata into a global registry, and a build step walks that registry to assemble the document – with two differences:
it emits OpenAPI 3 (not Swagger 2.0), and
operations are filled in (summaries, parameters, request bodies, responses, and optional marshmallow schemas) instead of being empty stubs.
Install
uv pip install pecan-apispec
# optional extras
uv pip install "pecan-apispec[marshmallow,yaml]"
Quick start
import pecan
from pecan_apispec import path, operation, schema, security_scheme
security_scheme('bearerAuth', type='http', scheme='bearer', bearerFormat='JWT')
@path('profile', name='Profile', parent='Root', tags=['profile'])
class ProfileController:
@pecan.expose(generic=True, template='json')
@operation(summary='Get profile',
responses={'200': {'description': 'The profile'}})
def index(self):
...
@index.when(method='POST', template='json')
@operation(summary='Update profile', security=[{'bearerAuth': []}])
def index_post(self):
...
@path('/', name='Root')
class RootController:
profile = ProfileController()
Then build the document:
from pecan_apispec import build_dict, build_yaml
doc = build_dict('myapp', '1.0') # -> dict (OpenAPI 3.0.3)
text = build_yaml('myapp', '1.0') # -> YAML string (needs 'yaml' extra)
How it works
- registry
Module-level dicts plus ControllerNode / OperationInfo dataclasses. No Pecan or apispec imports, so it is testable in isolation.
- decorators
@path(segment, name, parent, tags) registers a controller node; @operation(methods, path_suffix, **openapi_fields) attaches per-method OpenAPI metadata; schema() / security_scheme() register reusable components.
- introspect
Reads Pecan conventions purely by attribute access (never import pecan): the _pecan dict for exposed methods, generic_handlers for verbs on @expose(generic=True), and RestController conventions by MRO class name. index maps to the controller path, other methods to /<name>, and REST member actions to /{id}. @operation overrides anything inferred.
- tree
Pure functions that walk the parent chain to the root and normalize slashes; guards against cycles and unknown parents.
- builder
build_spec / build_dict / build_yaml: constructs an APISpec (adding MarshmallowPlugin automatically when marshmallow is installed), registers components, then emits one path per controller.
- ext.ui
SpecController mounts in your controller tree and serves GET /<mount>/openapi.json plus a Swagger UI page at GET /<mount>/. Pecan is imported lazily so the package imports without Pecan present.
Design decisions
Lazy apispec/Pecan imports via __getattr__ – the decorator layer is usable without apispec or Pecan installed.
``@operation`` always wins over introspection, so bad inference is never a dead end.
OpenAPI 3.0.3 by default; marshmallow schemas resolve to $ref components.
Serving the spec
from pecan_apispec import SpecController
@path('/', name='Root')
class RootController:
docs = SpecController('myapp', '1.0') # GET /docs/ and /docs/openapi.json
License
Apache-2.0.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pecan_apispec-0.1.0.tar.gz.
File metadata
- Download URL: pecan_apispec-0.1.0.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b27f2f359aba612a7413f80d4465c28a234b1e7cc76d90f23780e26c305b247f
|
|
| MD5 |
cc886e155459f4d0b4c022f31302e69c
|
|
| BLAKE2b-256 |
e9462f097e437e93058f3c1d1018c20582df2aed45ad88f6b35e5cafc1ea1ee2
|
File details
Details for the file pecan_apispec-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pecan_apispec-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.7 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a68a7ebb6695324c9b21a13b7d3bfa01af0450695dbb6f3537e9990b17b07db
|
|
| MD5 |
2104d38b8177d9678ef941175738fe31
|
|
| BLAKE2b-256 |
de90fe2b852cb353baa2f6afbd8b0cf0adada9b275cc605dbf3c22344792a8c7
|