pip install pactum
With Pactum
you can specify HTTP-APIs using pure python.
Pactum is easy to use, easy to extend and easy to contribute:
The only requirements to start writing an API specification with pactum
is pactum
package itself and some knowledge of python.
import pactum
class MyAPI(pactum.API):
name = 'My API'
versions = [...]
Using the visitor pattern you can create exporters and extensions for any format or service you want.
Take a look at pactum/exporters/openapi.py.
Always keep this diagram in mind when defining your APIs.
Create a file called specs.py and start defining your API.
You can define a Resource
object for your API.
from pactum import Action, API, Resource, Response, Version
from pactum import fields, verbs
class Order(Resource):
fields = [
fields.IntegerField(name='code', required=True),
fields.TimestampField(name='created_at'),
fields.StringField(name='item')
]
resource = Order()
error_resource = Resource(
name = 'ErrorResource'
fields = [fields.StringField(name='error', required=False)]
)
You can define any element of your specification by calling it directly as in
error_resource
or by class definition as in MyResource
and then calling it.
List resources are definitions of lists of the same resource.
list_order_resource = ListResource(resource=resource)
You can define Response
objects with status
, description
(optional) a
header
(optional) and a Resource
/ListResource
object as body
(optionally)...
list_response = Response(
status=200, description='Here is your orders list.', body=list_resource
)
detail_response = Response(
status=200, description='Here is your order.', body=resource
)
error_response = Response(status=404, resource=error_resource, headers=[('Content-type': 'application-json')])
... and Request
objects with verb
, description
, header
(optional) and a Resource
/ListResource
object as payload
.
get_request = Request(verb=verbs.GET)
An Action
groups your request and a list of responses for a specified action passed in the description parameter.
list_action = Action(
description='Returns a list of resources.',
request=get_request,
responses=[error_response, list_response]
)
detail_action = Action(
description='Returns a resource based on its code.',
request=get_request,
responses=[error_response, detail_response]
)
The Action object, as all other elements in Pactum, receive a description string
that sets the .__doc__
attribute and can be the docstring of the class
if the object is defined by class definition.
A route can have a list of actions in an HTTP path.
class OrderListRoute(Route):
path = '/orders'
actions = [list_action]
list_route = OrderListRoute()
detail_route = OrderRoute(path='/orders/{code}', actions=detail_action)
Your routes can be grouped in API versions.
class V1(Version):
name = 'V1'
routes = [list_route, detail_route]
v1 = V1()
Then you can define your API. ;)
class OrdersAPI(API):
name = 'Orders API'
versions = [v1]
api = OrdersAPI()
Be happy and ready to export your specification to any format you want.
Pactum has a command that exports your specification to OpenAPI. You can call it by using:
pactum-openapi <spec_file.py> <output_file> [--format=<json or yaml>]