Documentació d'APIs amb Swagger / OpenAPI¶
Swagger és un conjunt d'eines per dissenyar, construir i documentar APIs REST. Utilitza l'especificació OpenAPI (anteriorment Swagger Specification) per descriure l'API en format YAML o JSON.
Conceptes clau¶
| Terme | Descripció |
|---|---|
| OpenAPI Specification | Estàndard per descriure APIs REST (format YAML/JSON) |
| Swagger UI | Interfície web interactiva generada automàticament |
| Swagger Editor | Editor en línia per escriure especificacions OpenAPI |
| flasgger | Extensió de Flask que integra Swagger UI automàticament |
Instal·lació de flasgger¶
Exemple bàsic amb flasgger¶
from flask import Flask, jsonify
from flasgger import Swagger
app = Flask(__name__)
swagger = Swagger(app)
@app.route('/api/pelicules', methods=['GET'])
def get_pelicules():
"""
Retorna la llista de pel·lícules.
---
tags:
- Pel·lícules
responses:
200:
description: Llista de pel·lícules
schema:
type: array
items:
type: object
properties:
id:
type: integer
titol:
type: string
any:
type: integer
"""
pelicules = [
{"id": 1, "titol": "El Padrí", "any": 1972},
{"id": 2, "titol": "Pulp Fiction", "any": 1994},
]
return jsonify(pelicules)
@app.route('/api/pelicules/<int:id>', methods=['GET'])
def get_pelicula(id):
"""
Retorna una pel·lícula per ID.
---
tags:
- Pel·lícules
parameters:
- name: id
in: path
type: integer
required: true
description: Identificador de la pel·lícula
responses:
200:
description: Dades de la pel·lícula
404:
description: Pel·lícula no trobada
"""
return jsonify({"id": id, "titol": "El Padrí", "any": 1972})
if __name__ == '__main__':
app.run(debug=True)
Un cop en marxa el servidor, visita http://127.0.0.1:5000/apidocs/ per veure la interfície Swagger UI.
Estructura d'una especificació OpenAPI (YAML)¶
openapi: 3.0.0
info:
title: API de Pel·lícules
version: 1.0.0
description: API per gestionar una col·lecció de pel·lícules
servers:
- url: http://127.0.0.1:5000/api
paths:
/pelicules:
get:
summary: Llista totes les pel·lícules
tags:
- Pel·lícules
responses:
'200':
description: Llista de pel·lícules
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pelicula'
post:
summary: Crea una nova pel·lícula
tags:
- Pel·lícules
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PeliculaInput'
responses:
'201':
description: Pel·lícula creada
/pelicules/{id}:
get:
summary: Obté una pel·lícula per ID
tags:
- Pel·lícules
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Dades de la pel·lícula
'404':
description: No trobada
delete:
summary: Elimina una pel·lícula
tags:
- Pel·lícules
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'204':
description: Eliminada correctament
components:
schemas:
Pelicula:
type: object
properties:
id:
type: integer
titol:
type: string
any:
type: integer
puntuacio:
type: number
PeliculaInput:
type: object
required:
- titol
- any
properties:
titol:
type: string
any:
type: integer
puntuacio:
type: number
Carregar l'especificació des d'un fitxer YAML¶
from flask import Flask
from flasgger import Swagger
app = Flask(__name__)
# Carrega la spec des d'un fitxer extern
swagger = Swagger(app, template_file='swagger.yml')
if __name__ == '__main__':
app.run(debug=True)
Swagger UI — funcionalitats¶
La interfície http://127.0.0.1:5000/apidocs/ permet:
- Veure tots els endpoints documentats agrupats per
tags - Executar peticions directament des del navegador (botó Try it out)
- Veure els paràmetres d'entrada i el format de resposta esperat
- Descarregar l'especificació en format JSON
Alternativa: flask-smorest¶
Per a projectes més grans, flask-smorest integra OpenAPI 3.0 amb validació automàtica via marshmallow:
from flask import Flask
from flask_smorest import Api, Blueprint
import marshmallow as ma
app = Flask(__name__)
app.config['API_TITLE'] = 'API de Pel·lícules'
app.config['API_VERSION'] = 'v1'
app.config['OPENAPI_VERSION'] = '3.0.2'
app.config['OPENAPI_URL_PREFIX'] = '/'
app.config['OPENAPI_SWAGGER_UI_PATH'] = '/swagger-ui'
app.config['OPENAPI_SWAGGER_UI_URL'] = 'https://cdn.jsdelivr.net/npm/swagger-ui-dist/'
api = Api(app)
class PeliculaSchema(ma.Schema):
id = ma.fields.Int(dump_only=True)
titol = ma.fields.Str(required=True)
any = ma.fields.Int(required=True)
blp = Blueprint('pelicules', __name__, url_prefix='/api/pelicules')
@blp.route('/')
class PeliculaList(MethodView):
@blp.response(200, PeliculaSchema(many=True))
def get(self):
return pelicules
api.register_blueprint(blp)