An ASGI middleware to populate OpenAPI Specification examples from pytest functions
Project description
PyTest-API: Populate OpenAPI Examples from Python Tests
PyTest-API is an ASGI middleware that populates OpenAPI-Specification examples from pytest functions.
Installation
poetry add --dev pytest-api
How to use it:
Starting with test_main.py
file:
from .main import spec
@spec.describe(route="/behavior-example/")
def test_example_body(client):
"""
GIVEN behavior in body
WHEN example behavior endpoint is called with POST method
THEN response with status 200 and body OK is returned
"""
assert client.post(
"/behavior-example/", json={"name": "behavior"},
headers={"spec-example": test_example_body.id}
).json() == {"message": "OK"}
Impliment solution in /main.py
file:
from fastapi import FastAPI
from pydantic import BaseModel
from pytest_api import ASGIMiddleware
app = FastAPI()
spec = ASGIMiddleware
app.add_middleware(spec)
app.openapi = spec.openapi_behaviors(app)
class Behavior(BaseModel):
name: str
@app.post("/behavior-example/")
async def example_body(behavior: Behavior):
return {"message": "OK"}
Run FastAPI app:
poetry run uvicorn test_app.main:app --reload
Open your browser to http://localhost:8000/docs#/ too find the doc string is populated into the description.
Implimentation Details
Under the hood the ASGIMiddleware
uses the describe
decorator to store the pytest
function by its id
:
def wrap_behavior(*args, **kwargs):
try:
BEHAVIORS[route]
except KeyError as e:
if route in e.args:
BEHAVIORS[route] = {str(id(func)): func}
BEHAVIORS[route][str(id(func))] = func
When pytest
calls your API the SpecificationResponder
is looking for the coresponding id
in the headers
of the request:
def handle_spec(self, headers):
behaviors = BEHAVIORS[self.path]
self.should_update_example = headers.get("spec-example", "") in behaviors
self.should_update_description = (
headers.get("spec-description", "") in behaviors
)
if self.should_update_example:
self.func = behaviors[headers.get("spec-example")]
elif self.should_update_description:
self.func = behaviors[headers.get("spec-description")]
This is possible thanks to python's first-class functions
i.e. Closure_(computer_programming).
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
Hashes for pytest_api-0.1.4-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 44357859f0fa021f10aef7865379dbc244cf99ccdd648ab5be47a9c496eeec84 |
|
MD5 | d18512a4e068df34d2e3f51988bef34a |
|
BLAKE2b-256 | 01768496680d9b1c69918df482a67e1af3156e9588a6c115fe60fdb098e8cd60 |