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 |
|
BLAKE2-256 | 01768496680d9b1c69918df482a67e1af3156e9588a6c115fe60fdb098e8cd60 |