Flask-RESTX’s OpenAPI integration automatically generates an interactive API documentation page from your Flask application, often called "Swagger UI" or "ReDoc," based on your API definitions.
Here’s an example of a simple Flask app using Flask-RESTX with OpenAPI enabled:
from flask import Flask
from flask_restx import Api, Resource, fields
app = Flask(__name__)
api = Api(app, version='1.0', title='My Awesome API',
description='A sample API demonstrating Flask-RESTX OpenAPI integration',
doc='/swagger/') # This sets the path for Swagger UI
# Define a model for request/response data
user_model = api.model('User', {
'username': fields.String(required=True, description='The user\'s username'),
'email': fields.String(required=True, description='The user\'s email address')
})
# Define a namespace for our API
ns = api.namespace('users', description='User operations')
@ns.route('/')
class UserList(Resource):
@api.doc(summary='List all users')
@api.marshal_list_with(user_model)
def get(self):
"""Returns a list of all users."""
return [{'username': 'alice', 'email': 'alice@example.com'},
{'username': 'bob', 'email': 'bob@example.com'}]
@ns.route('/<string:username>')
@api.response(404, 'User not found')
class User(Resource):
@api.doc(summary='Get a user by username',
params={'username': 'The username of the user to retrieve'})
@api.marshal_with(user_model)
def get(self, username):
"""Returns a single user by username."""
users = {
'alice': {'username': 'alice', 'email': 'alice@example.com'},
'bob': {'username': 'bob', 'email': 'bob@example.com'}
}
user = users.get(username)
if user:
return user
api.abort(404, f"User {username} doesn't exist")
@api.doc(summary='Create a new user')
@api.expect(user_model)
@api.marshal_with(user_model, code=201)
def post(self, username):
"""Creates a new user."""
# In a real app, you'd save this to a database
data = api.payload
new_user = {'username': username, 'email': data['email']}
return new_user, 201
if __name__ == '__main__':
app.run(debug=True)
When you run this Flask application and navigate to /swagger/ (or whatever you set doc= to), you’ll see an interactive UI. You can browse your API endpoints, see their request and response schemas, and even try them out directly from the browser.
Flask-RESTX builds this documentation by inspecting the decorators and arguments you use in your Resource classes. The @api.model, @api.expect, @api.marshal_with, @api.doc, and @api.param decorators are all crucial for defining your API’s structure and behavior, which Flask-RESTX then translates into the OpenAPI specification. The version, title, and description parameters passed to the Api constructor form the basic metadata for your API documentation.
The magic lies in how Flask-RESTX interprets these Python constructs. For instance, @api.expect(user_model) tells Flask-RESTX that a POST request to this endpoint expects data conforming to the user_model schema. Similarly, @api.marshal_with(user_model) indicates that the response will be structured according to user_model. The api.namespace helps group related endpoints logically in the documentation.
The api.doc() decorator is your primary tool for annotating endpoints. It takes summary for a brief description, description for more detail, and params to describe query parameters, path parameters, or even request body fields (though @api.expect is more common for request bodies). The api.response() decorator is used to document possible HTTP status codes and their meanings, like the 404 case shown.
The most surprising thing about Flask-RESTX’s OpenAPI integration is how little you actually write about the OpenAPI spec itself. You write Python code that describes your API’s logic and data structures, and Flask-RESTX infers the vast majority of the OpenAPI specification from that code. This means your API code and its documentation are always in sync, reducing the chance of documentation drift.
If you need to define more complex or custom OpenAPI properties that aren’t directly supported by Flask-RESTX decorators, you can often inject them into the generated OpenAPI schema using the extensions parameter within decorators like @api.doc or by directly manipulating the schema object if you’re comfortable doing so.
The next step is often exploring how to customize the appearance of the Swagger UI or integrate with other OpenAPI tooling.