PyMacaron uses the OpenAPI format to define microservice APIs, formerly known as the swagger format.
PyMacaron relies on pymacaron-core to generate the Flask app running your microservice API.
pymacaron-core extends the OpenAPI standard with the following custom attributes when implementing the OpenAPI specification (ie on the server):
And when using the specification to generate an API client:
For every API endpoint in your microservice, you need to tell PyMacaron which python method to execute. You do that with the ‘x-bind-server’ attribute. Below an example of a fictional login endpoint:
/login: post: summary: Login a user. produces: - application/json x-bind-server: myserver.handlers.do_login parameters: - in: body name: body description: User login credentials. required: true schema: $ref: "#/definitions/Credentials" responses: 200: description: API version schema: $ref: '#/definitions/TokenAndProfile' default: description: Error schema: $ref: '#/definitions/Error'
Your login method could look like:
from pymacaron import get_model from pymacaron.exceptions import PyMacaronException def do_login(credentials): if not authenticate_user(credentials): raise PyMacaronException("Login failed") # Get the class representing bravado-core Welcome objects return get_model('LoginResponse')( token=generate_user_token(), profile=get_user_profile(), )
To require JWT authentication on some of your API endpoints, you need to set the ‘x-decorate-request’ and ‘x-decorate-server’ attributes for those endpoints, as described here.
All PyMacaron services implement a few default endpoints defined in this OpenAPI specification. Those are:
‘/ping’: Returns a json dictionary showing the status of the server. Convenient as a health-check endpoint. Does not require authentication.
‘/version’: Returns the version of the running server when deployed in a Docker container. Does not require authentication.
‘/auth/version’: Same as ‘/version’ but requiring a valid JWT token in the HTTP Authorization header.
PyMacaron requires that you define an Error object in your microservice API. It should look as follows:
Error: type: object description: An api error properties: status: type: integer format: int32 description: HTTP error code. error: type: string description: A unique identifier for this error. error_description: type: string description: A humanly readable error message in the user''s selected language. required: - status - error - error_description example: status: 500 error: SERVER_ERROR error_description: Expected data to send in reply but got none