Skip to content

Introduction

Pait is a lightweight Python Api development tool, with parameter type checking, type conversion, providing document output and gRPC GateWay and other functions, very suitable for back-end interface development, it is designed to be used for multiple Pythons Web application development framework (currently adapted to Flask, Starlette, Sanic, Tornado).

Note

type hint check 100%

test coverage 95%+ (no include api_doc)

python version >= 3.7 (support postponed annotations)

The following code does not specify, all default to use the starlette framework.

The current document is generated by Google Translate, if there are any errors, please contact us and we will fix them as soon as possible.

Vision

  • 1.Code is Documentation。

  • 2.Enables developers to achieve the most complete functionality with the least amount of code。

Feature

  • Enables developers to achieve the most complete functionality with the least amount of code
  • Parameter dependency verification
  • Automatically generate openapi files
  • Swagger, Redoc route
  • gRPC Gateway route
  • TestClient support, support response result verification
  • Support for plugin extensions, such as the Mock plugin

Require

Python3.7+

Use Type Hints in your project

Install

pip3 install pait

Example

Parameter verification and API document generation

The usage of Pait is very simple, taking the starlette framework as an example

from typing import Type
import uvicorn  # type: ignore
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

from pait.app.starlette import pait, add_doc_route
from pait.field import Body
from pait.model.response import PaitResponseModel
from pydantic import BaseModel, Field


class DemoResponseModel(PaitResponseModel):
    """Responsive struct model that can be used by Pait"""
    class ResponseModel(BaseModel):
        uid: int = Field()
        user_name: str = Field()

    description: str = "demo response"
    response_data: Type[BaseModel] = ResponseModel


# Decorate a function with the pait decorator
@pait(response_model_list=[DemoResponseModel])
async def demo_post(
    uid: int = Body.i(description="user id", gt=10, lt=1000),
    user_name: str = Body.i(description="user name", min_length=2, max_length=4)
) -> JSONResponse:
    # Get the corresponding value and return it
    return JSONResponse({'uid': uid, 'user_name': user_name})


app = Starlette(routes=[Route('/api', demo_post, methods=['POST'])])
# Register Open API interface
add_doc_route(app)
uvicorn.run(app)
This code adds the highlighted part of the code to complete the use of a simple Pait, of which line 24 uses the pait decorator, so that Pait can manage the input and output of the route, At the same time, declare what the output format of this routing function is through response model list. Lines 26 and 27 declare the parameters required by this route, where to get their parameters, and what are the restriction rules for the parameters. Line 35 registers a Swagger route, then runs the code, and in the Browser access: http:127.0.0.1:8000swagger, you can see a SwaggerUI page, which currently has two sets of interfaces:

One group is the 3 interfaces that come with Pait doc, and the other group is default, which contains the /api interface we just created, click on the /api interface, and the details of the interface will pop up:

The data in the details is generated by Pait by reading the function signature and the incoming DemoResponseModel, then you can click try it out, enter the parameters and click Execute, you can see the result generated by the Curl command And the server response result:

As can be seen from the results, the routing function works normally, and the parameters of the routing function are Pait automatically extract the values of uid and user_name from the Json Body and pass in.

Plugin

In addition to parameter verification and API document generation, Pait also has a plugin system, through which other feature can be extended, such as the Mock response, which can automatically return data according to the Response Model, even if the route has no data to return, such as the following the code:

from typing import Type
import uvicorn  # type: ignore
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

from pait.app.starlette import pait, add_doc_route
from pait.app.starlette.plugin.mock_response import MockPlugin
from pait.field import Body
from pait.model.response import PaitResponseModel
from pydantic import BaseModel, Field


class DemoResponseModel(PaitResponseModel):
    """Responsive struct model that can be used by Pait"""
    class ResponseModel(BaseModel):
        uid: int = Field(example=999)
        user_name: str = Field()

    description: str = "demo response"
    response_data: Type[BaseModel] = ResponseModel


# Decorate a function with the pait decorator
@pait(
    post_plugin_list=[MockPlugin.build()],
    response_model_list=[DemoResponseModel]
)
async def demo_post(
    uid: int = Body.i(description="user id", gt=10, lt=1000),
    user_name: str = Body.i(description="user name", min_length=2, max_length=4)
) -> JSONResponse:
    pass


app = Starlette(routes=[Route('/api', demo_post, methods=['POST'])])
# Register Open API interface
add_doc_route(app)
uvicorn.run(app)
The code is modified from the above code, it removes the return response, and introduces the highlighted part of the code, where uid: int = Field(example=999) in line 17 specifies that the example value is 999, then run the code and run the Curl command returned by Swagger above:
➜  ~ curl -X 'POST' \
  'http://127.0.0.1:8000/api' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "uid": 666,
  "user_name": "so1n"
}'
{"uid":999,"user_name":""}
As you can see, the interface can still return a response, which is automatically generated by the Mock plugin. The value of uid in the response is 999, which is the same as the uid: int = Field(example=999) set in our code, and the value of user_name is the default empty string.

In addition, Pait has other plugins and other feature, which will be described in detail in subsequent documents.

Performance

Pait implements function signature extraction based on inspect that comes with Python, implements parameter verification and type conversion based on Pydantic, and also uses a lot of preloading designs, so the runtime performance of Pait is so good。 However, the current Pait is still growing, and there are still many areas that need to be optimized. Welcome to optimize together through issues

Example of use

Pait has complete code samples for each supported web framework, you can learn best practices by visiting the sample code:

Back to top