OpenAPI Dokumentation erstellen mit Python & PySwagger: Eine Schritt-für-Schritt Anleitung

Rebecca Kovács

Rebecca Kovács

12 June 2025

OpenAPI Dokumentation erstellen mit Python & PySwagger: Eine Schritt-für-Schritt Anleitung

Die Generierung umfassender und präziser API-Dokumentation ist ein kritischer, aber oft mühsamer Teil der Softwareentwicklung. Die OpenAPI Specification (früher bekannt als Swagger) hat sich als Industriestandard für die Definition von RESTful APIs etabliert. Sie bietet ein maschinenlesbares Format, das es sowohl Menschen als auch Computern ermöglicht, die Fähigkeiten eines Dienstes zu entdecken und zu verstehen, ohne Zugriff auf Quellcode, Dokumentation oder durch Inspektion des Netzwerkverkehrs zu haben.1

Während viele Frameworks Plugins zur Generierung von OpenAPI-Spezifikationen aus Code-Annotationen (wie Docstrings) anbieten, gibt es Szenarien, in denen Sie eine direktere, programmatische Kontrolle über die Erstellung der Spezifikation benötigen. Dies könnte der Fall sein, wenn Sie mit einem Altsystem, einem nicht standardmäßigen Framework arbeiten oder eine Spezifikation für eine API generieren müssen, die aus mehreren Microservices besteht.

Hier kommt pyswagger ins Spiel. Es ist eine leistungsstarke Python-Bibliothek, die als Toolkit für OpenAPI fungiert. Obwohl es oft als API-Client zur Nutzung von Diensten verwendet wird, die durch eine OpenAPI-Spezifikation definiert sind, liegt seine wahre Stärke in seinem Objektmodell, das es Ihnen ermöglicht, eine Spezifikation programmatisch zu konstruieren, zu manipulieren und zu validieren.

In diesem umfassenden Tutorial werden wir den Prozess der Verwendung von pyswagger durchgehen, um manuell, aber dennoch automatisch, eine vollständige OpenAPI 3.0-Spezifikation für eine einfache Python-Webanwendung zu generieren, die mit Flask erstellt wurde. Wir werden die Spezifikation von Grund auf Stück für Stück aufbauen und dabei zeigen, wie die Objekte von pyswagger direkt den Komponenten des OpenAPI-Standards zugeordnet sind. Am Ende werden Sie nicht nur eine generierte openapi.json-Datei haben, sondern auch eine live, interaktive Dokumentations-UI, die direkt von Ihrer Anwendung bereitgestellt wird.

💡
Möchten Sie ein großartiges API-Testwerkzeug, das schöne API-Dokumentation generiert?

Möchten Sie eine integrierte All-in-One-Plattform, auf der Ihr Entwicklerteam mit maximaler Produktivität zusammenarbeiten kann?

Apidog erfüllt all Ihre Anforderungen und ersetzt Postman zu einem viel günstigeren Preis!
button

Teil 1: Einrichten der Projektumgebung

Bevor wir mit der Generierung unserer Spezifikation beginnen können, müssen wir eine geeignete Entwicklungsumgebung einrichten. Dazu gehört die Erstellung einer isolierten Python-Umgebung zur Verwaltung unserer Abhängigkeiten und die Installation der notwendigen Bibliotheken.

Erstellen Ihres Arbeitsbereichs ⚙️

Zuerst erstellen wir ein Verzeichnis für unser Projekt. Öffnen Sie Ihr Terminal oder Ihre Eingabeaufforderung und führen Sie die folgenden Befehle aus:Bash

# Create a new directory for our project
mkdir pyswagger-tutorial
cd pyswagger-tutorial

# Create a Python virtual environment
# On macOS/Linux
python3 -m venv venv
# On Windows
python -m venv venv

Eine virtuelle Umgebung ist ein in sich geschlossener Verzeichnisbaum, der eine Python-Installation und eine Reihe unterstützender Dateien enthält. Die Verwendung einer virtuellen Umgebung stellt sicher, dass die Pakete, die wir für dieses Projekt installieren, nicht mit Paketen kollidieren, die für andere Projekte installiert wurden.

Aktivieren Sie nun die virtuelle Umgebung:Bash

# On macOS/Linux
source venv/bin/activate

# On Windows
.\venv\Scripts\activate

Nach der Aktivierung sollte sich Ihre Terminaleingabeaufforderung ändern und den Namen der virtuellen Umgebung anzeigen (z. B. (venv)), was darauf hinweist, dass Sie nun darin arbeiten.

Installieren notwendiger Bibliotheken

Nachdem unsere Umgebung aktiv ist, können wir die Python-Bibliotheken installieren, die wir für dieses Tutorial benötigen. Wir benötigen pyswagger selbst, um die Spezifikation zu erstellen, Flask, um unsere einfache Web-API zu erstellen, und PyYAML, da pyswagger es für YAML-Operationen verwendet.Bash

pip install "pyswagger[utils]" Flask PyYAML

Der Teil [utils] bei der Installation von pyswagger ist eine gute Praxis, da er hilfreiche Dienstprogramme enthält, wie z. B. einen Validator, den wir später verwenden werden, um unsere generierte Spezifikation auf Korrektheit zu überprüfen.

Für ein gutes Projektmanagement ist es ratsam, Ihre Abhängigkeiten in einer requirements.txt-Datei festzuhalten.Bash

pip freeze > requirements.txt

Ihre requirements.txt enthält nun die Bibliotheken und ihre spezifischen Versionen, wodurch Ihr Projekt von anderen leicht reproduzierbar wird.

Erstellen der grundlegenden Flask-Anwendung

Nun erstellen wir eine minimale Flask-Anwendung. Diese dient als Grundlage der API, die wir dokumentieren werden.

Erstellen Sie in Ihrem Projektverzeichnis eine neue Datei namens app.py und fügen Sie den folgenden Code hinzu:Python

# app.py

from flask import Flask, jsonify

# Initialize the Flask application
app = Flask(__name__)

@app.route("/")
def index():
    """ A simple endpoint to check if the app is running. """
    return jsonify({"message": "API is up and running!"})

if __name__ == "__main__":
    # Runs the Flask app on http://127.0.0.1:5000
    app.run(debug=True)

Dieser Code richtet einen sehr einfachen Webserver mit einem einzigen Endpunkt ein. Um ihn auszuführen, stellen Sie sicher, dass Ihre virtuelle Umgebung noch aktiv ist, und führen Sie den folgenden Befehl in Ihrem Terminal aus:Bash

python app.py

Sie sollten eine Ausgabe sehen, die anzeigt, dass der Server läuft, etwa so:

 * Serving Flask app 'app'
 * Debug mode: on
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)

Sie können nun Ihren Webbrowser öffnen oder ein Werkzeug wie curl verwenden, um http://127.0.0.1:5000 zu besuchen. Sie sollten die JSON-Antwort sehen: {"message": "API is up and running!"}.

Mit unserer grundlegenden Umgebung und dem Anwendungsskelett können wir nun in die Kernkonzepte von pyswagger eintauchen.


Teil 2: Verstehen des pyswagger-Objektmodells

Um pyswagger effektiv zur Generierung einer Spezifikation nutzen zu können, müssen Sie zunächst verstehen, wie sein Objektmodell der Struktur eines OpenAPI-Dokuments entspricht. Eine OpenAPI-Spezifikation ist im Wesentlichen ein großes JSON- oder YAML-Objekt mit einem spezifischen Schema. pyswagger bietet Python-Klassen und -Objekte, die dieses Schema widerspiegeln und Ihnen ermöglichen, die Spezifikation auf intuitivere, objektorientierte Weise zu erstellen.

Kernkonzepte der OpenAPI 3.0 Spezifikation 📜

Ein OpenAPI 3.0 Dokument hat einige wichtige Top-Level-Felder:

Mapping von OpenAPI auf pyswagger-Objekte

pyswagger bietet eine saubere Zuordnung dieser OpenAPI-Konzepte zu Python-Objekten. Betrachten wir die wichtigsten, die wir verwenden werden.

Das zentrale Objekt in pyswagger ist die App. Sie können sich eine App-Instanz als Wurzel Ihres OpenAPI-Dokuments vorstellen.Python

from pyswagger import App

# The root of the specification document
# We initialize it with a version, but it can also load from a URL or file
root_app = App(version='3.0.0')

Sobald Sie Ihr App-Objekt haben, können Sie beginnen, seine Attribute zu füllen, die direkt den OpenAPI-Feldern entsprechen. pyswagger verwendet ein Builder-Muster, das eine flüssige und lesbare Syntax ermöglicht.

Info und Server

Die Abschnitte info und servers sind einfach zu füllen.Python

# Populating the 'info' object
root_app.info.title = "User API"
root_app.info.version = "1.0.0"
root_app.info.description = "A simple API to manage users, used for the pyswagger tutorial."

# Populating the 'servers' array
# You create a Server object and append it
server = root_app.prepare_obj('Server', {'url': 'http://127.0.0.1:5000', 'description': 'Local development server'})
root_app.servers.append(server)

Pfade und Operationen

Pfade werden auf dem App-Objekt definiert. Sie fügen neue Pfade hinzu und definieren dann die Operationen (HTTP-Methoden) darin. Jede Operation wird mit Details wie summary, description, parameters, einem requestBody und responses konfiguriert.Python

# Defining a path and an operation
# This doesn't execute anything; it just builds the object structure.
path_item = root_app.define_path('/users')
get_op = path_item.define_op('get')
get_op.summary = "Retrieve a list of all users"

Komponenten: Schemata, Parameter und Antworten

Die wahre Stärke einer gut strukturierten OpenAPI-Spezifikation kommt von wiederverwendbaren Komponenten. Anstatt die Struktur eines "User"-Objekts jedes Mal neu zu definieren, wenn es in einer Antwort erscheint, definieren Sie es einmal in components/schemas und verweisen dann mit einem $ref-Pointer darauf. pyswagger handhabt dies elegant.

Schema: Ein Schema-Objekt definiert ein Datenmodell. Sie können seinen Typ (object, string, integer) und seine Eigenschaften angeben.Python

# Preparing a Schema object for a User
user_schema = root_app.prepare_obj('Schema', {
    'type': 'object',
    'properties': {
        'id': {'type': 'integer', 'format': 'int64'},
        'username': {'type': 'string'},
        'email': {'type': 'string', 'format': 'email'}
    },
    'required': ['id', 'username', 'email']
})

# Add it to the reusable components
root_app.components.schemas['User'] = user_schema

Parameter: Ein Parameter-Objekt definiert einen einzelnen Operationsparameter. Sie geben seinen Namen an, wo er sich befindet (in: 'path', 'query', 'header' oder 'cookie'), und sein Schema.Python

# Preparing a Parameter object for a user ID in the path
user_id_param = root_app.prepare_obj('Parameter', {
    'name': 'user_id',
    'in': 'path',
    'description': 'ID of the user to retrieve',
    'required': True,
    'schema': {'type': 'integer'}
})

Response: Ein Response-Objekt definiert die Struktur einer Antwort für einen bestimmten HTTP-Statuscode. Es enthält eine description und den content, der den Medientyp (z. B. application/json) und sein Schema angibt.Python

# Preparing a Response object for a 200 OK response returning a single user
# Note the use of '$ref' to point to our reusable User schema
ok_user_response = root_app.prepare_obj('Response', {
    'description': 'Successful retrieval of a user',
    'content': {
        'application/json': {
            'schema': {'$ref': '#/components/schemas/User'}
        }
    }
})

Das Verständnis dieser Zuordnung ist der Schlüssel zum Aufbau Ihrer Spezifikation. Sie konstruieren im Wesentlichen einen Python-Objektgraphen, den pyswagger später in eine gültige OpenAPI JSON- oder YAML-Datei serialisieren wird.


Teil 3: Erstellen einer einfachen API mit Flask

Um unsere Dokumentationsübung praktisch zu gestalten, benötigen wir eine tatsächliche API zum Dokumentieren. Wir werden unsere einfache Flask-App aus Teil 1 zu einer minimalen REST-API zur Verwaltung einer Liste von Benutzern erweitern. Diese API dient als "Quelle der Wahrheit", die wir mit pyswagger beschreiben werden.

Entwerfen einer einfachen "User"-API 📝

Wir werden vier grundlegende Endpunkte implementieren, die gängige CRUD-Operationen (Create, Read, Update, Delete) darstellen:

  1. GET /users: Abrufen einer Liste aller Benutzer.
  2. POST /users: Erstellen eines neuen Benutzers.
  3. GET /users/{user_id}: Abrufen eines einzelnen Benutzers anhand seiner ID.
  4. DELETE /users/{user_id}: Löschen eines Benutzers anhand seiner ID.

Der Einfachheit halber verwenden wir ein einfaches Python-Wörterbuch als unsere In-Memory-"Datenbank". In einer realen Anwendung wäre dies eine Verbindung zu einer Datenbank wie PostgreSQL oder MongoDB.

Implementieren der Flask-Endpunkte

Aktualisieren wir unsere Datei app.py, um die Logik für diese Endpunkte aufzunehmen. Ersetzen Sie den Inhalt von app.py durch Folgendes:Python

# app.py

from flask import Flask, jsonify, request, abort

app = Flask(__name__)

# --- In-Memory Database ---
# A simple dictionary to store our users.
# The key is the user_id (integer), and the value is the user data (dict).
USERS_DB = {
    1: {"username": "alice", "email": "alice@example.com"},
    2: {"username": "bob", "email": "bob@example.com"},
    3: {"username": "charlie", "email": "charlie@example.com"},
}
# A counter to simulate auto-incrementing IDs for new users
LAST_INSERT_ID = 3

# --- API Endpoints ---

@app.route("/users", methods=["GET"])
def get_users():
    """ Returns a list of all users. """
    # We need to convert the dictionary to a list of user objects, including their IDs.
    users_list = []
    for user_id, user_data in USERS_DB.items():
        user = {'id': user_id}
        user.update(user_data)
        users_list.append(user)
    return jsonify(users_list)

@app.route("/users", methods=["POST"])
def create_user():
    """ Creates a new user. """
    global LAST_INSERT_ID
    if not request.json or 'username' not in request.json or 'email' not in request.json:
        abort(400, description="Missing username or email in request body.")
    
    LAST_INSERT_ID += 1
    new_user_id = LAST_INSERT_ID
    
    new_user = {
        "username": request.json["username"],
        "email": request.json["email"],
    }
    
    USERS_DB[new_user_id] = new_user
    
    # The response should include the ID of the newly created user
    response_user = {'id': new_user_id}
    response_user.update(new_user)
    
    return jsonify(response_user), 201

@app.route("/users/<int:user_id>", methods=["GET"])
def get_user(user_id):
    """ Returns a single user by their ID. """
    if user_id not in USERS_DB:
        abort(404, description=f"User with ID {user_id} not found.")
    
    user_data = USERS_DB[user_id]
    user = {'id': user_id}
    user.update(user_data)
    
    return jsonify(user)

@app.route("/users/<int:user_id>", methods=["DELETE"])
def delete_user(user_id):
    """ Deletes a user by their ID. """
    if user_id not in USERS_DB:
        abort(404, description=f"User with ID {user_id} not found.")
    
    del USERS_DB[user_id]
    
    # A 204 No Content response is standard for successful deletions
    return '', 204

if __name__ == "__main__":
    app.run(debug=True, port=5000)

Wenn Sie nun python app.py erneut ausführen, haben Sie eine voll funktionsfähige (wenn auch einfache) API. Sie können sie mit curl oder einem ähnlichen Werkzeug testen:

Nachdem unsere API implementiert ist, haben wir ein konkretes Ziel für unsere Dokumentationsbemühungen. Der nächste Schritt ist die Verwendung von pyswagger, um jeden dieser Endpunkte detailliert zu beschreiben.


Teil 4: Automatische Generierung der OpenAPI-Spezifikation mit pyswagger

Dies ist der Kern unseres Tutorials. Wir werden nun ein separates Python-Skript erstellen, das pyswagger importiert, unsere API-Struktur mithilfe seines Objektmodells definiert und diese Struktur dann in eine vollständige openapi.json-Datei serialisiert. Dieser Ansatz entkoppelt die Spezifikationsgenerierung von der Anwendungslogik, was ein sehr sauberer und wartbarer Ansatz sein kann.

Erstellen des Spezifikationsgenerators

Erstellen Sie in Ihrem Projektverzeichnis eine neue Datei namens generate_spec.py. Dieses Skript ist für den Aufbau und das Speichern unserer OpenAPI-Spezifikation verantwortlich.

Schrittweiser Aufbau der Spezifikation

Bauen wir das Skript generate_spec.py Stück für Stück auf.

1. Importe und Initialisierung der App

Zuerst müssen wir das App-Objekt von pyswagger und PyYAML importieren, um beim Speichern der endgültigen Datei zu helfen. Wir erstellen unser Root-App-Objekt und füllen die grundlegenden Abschnitte info und servers, genau wie wir es in Teil 2 besprochen haben.Python

# generate_spec.py
import json
from pyswagger import App
from pyswagger.contrib.client.requests import Client

# --- 1. Initialize the root App object ---
app = App(version='3.0.0')

# --- 2. Populating the Info & Servers sections ---
app.info.title = "User API"
app.info.version = "1.0.0"
app.info.description = "A simple API to manage users, for the pyswagger tutorial."

server = app.prepare_obj('Server', {
    'url': 'http://127.0.0.1:5000',
    'description': 'Local development server'
})
app.servers.append(server)

2. Definieren wiederverwendbarer Komponenten (Schemata)

Gutes API-Design vermeidet Wiederholungen. Wir definieren unser User-Datenmodell einmal und verwenden es wieder. Wir definieren auch ein generisches Error-Schema für unsere Fehlerantworten (wie 404 Not Found).

Fügen Sie den folgenden Code zu generate_spec.py hinzu:Python

# --- 3. Defining Reusable Components (Schemas) ---

# Schema for the Error response
error_schema = app.prepare_obj('Schema', {
    'type': 'object',
    'properties': {
        'code': {'type': 'integer', 'format': 'int32'},
        'message': {'type': 'string'}
    }
})
app.components.schemas['Error'] = error_schema

# Schema for a single User. Note the properties match our USERS_DB structure.
user_schema = app.prepare_obj('Schema', {
    'type': 'object',
    'properties': {
        'id': {
            'type': 'integer',
            'description': 'Unique identifier for the user.',
            'readOnly': True # The client cannot set this value
        },
        'username': {
            'type': 'string',
            'description': 'The user\'s chosen username.'
        },
        'email': {
            'type': 'string',
            'description': 'The user\'s email address.',
            'format': 'email'
        }
    },
    'required': ['id', 'username', 'email']
})
app.components.schemas['User'] = user_schema

# Schema for creating a user (doesn't include the 'id' field)
new_user_schema = app.prepare_obj('Schema', {
    'type': 'object',
    'properties': {
        'username': {
            'type': 'string',
            'description': 'The user\'s chosen username.'
        },
        'email': {
            'type': 'string',
            'description': 'The user\'s email address.',
            'format': 'email'
        }
    },
    'required': ['username', 'email']
})
app.components.schemas['NewUser'] = new_user_schema

3. Dokumentieren der /users-Endpunkte

Nun definieren wir den Pfad /users und seine beiden Operationen: GET und POST.

<!-- end list -->Python

# --- 4. Documenting the Paths ---

# -- Path: /users --
path_users = app.define_path('/users')

# Operation: GET /users
op_get_users = path_users.define_op('get')
op_get_users.summary = "List all users"
op_get_users.description = "Returns a JSON array of all user objects."
op_get_users.tags.append('Users')

op_get_users.responses.A('200').description = "A list of users."
op_get_users.responses.A('200').content.A('application/json').schema.A(
    'array', items={'$ref': '#/components/schemas/User'}
)

# Operation: POST /users
op_post_users = path_users.define_op('post')
op_post_users.summary = "Create a new user"
op_post_users.description = "Adds a new user to the database."
op_post_users.tags.append('Users')

op_post_users.requestBody.description = "User object that needs to be added."
op_post_users.requestBody.required = True
op_post_users.requestBody.content.A('application/json').schema.set_ref('#/components/schemas/NewUser')

op_post_users.responses.A('201').description = "User created successfully."
op_post_users.responses.A('201').content.A('application/json').schema.set_ref('#/components/schemas/User')

op_post_users.responses.A('400').description = "Invalid input provided."
op_post_users.responses.A('400').content.A('application/json').schema.set_ref('#/components/schemas/Error')

Beachten Sie die Verwendung von set_ref und A (das für "access" steht) für eine prägnantere Syntax zum Aufbau der verschachtelten Objektstruktur.

4. Dokumentieren der /users/{user_id}-Endpunkte

Als Nächstes dokumentieren wir den Pfad für die Interaktion mit einem einzelnen Benutzer. Dieser Pfad enthält einen Pfadparameter, {user_id}.

<!-- end list -->Python

# -- Path: /users/{user_id} --
path_user_id = app.define_path('/users/{user_id}')

# We can define the parameter once and reuse it for all operations on this path.
user_id_param = app.prepare_obj('Parameter', {
    'name': 'user_id',
    'in': 'path',
    'description': 'ID of the user',
    'required': True,
    'schema': {'type': 'integer'}
})
path_user_id.parameters.append(user_id_param)

# Operation: GET /users/{user_id}
op_get_user_id = path_user_id.define_op('get')
op_get_user_id.summary = "Find user by ID"
op_get_user_id.description = "Returns a single user."
op_get_user_id.tags.append('Users')

op_get_user_id.responses.A('200').description = "Successful operation."
op_get_user_id.responses.A('200').content.A('application/json').schema.set_ref('#/components/schemas/User')

op_get_user_id.responses.A('404').description = "User not found."
op_get_user_id.responses.A('404').content.A('application/json').schema.set_ref('#/components/schemas/Error')

# Operation: DELETE /users/{user_id}
op_delete_user_id = path_user_id.define_op('delete')
op_delete_user_id.summary = "Deletes a user"
op_delete_user_id.description = "Deletes a single user from the database."
op_delete_user_id.tags.append('Users')

op_delete_user_id.responses.A('204').description = "User deleted successfully."

op_delete_user_id.responses.A('404').description = "User not found."
op_delete_user_id.responses.A('404').content.A('application/json').schema.set_ref('#/components/schemas/Error')

5. Validieren und Speichern der Spezifikation

Schließlich der befriedigendste Schritt. Wir werden pyswagger bitten, unseren konstruierten Objektgraphen anhand des OpenAPI 3.0 Schemas zu validieren. Wenn er gültig ist, speichern wir ihn in einer JSON-Datei.

Fügen Sie diesen letzten Codeblock zu generate_spec.py hinzu:Python

# --- 5. Validate and Save the Specification ---
if __name__ == '__main__':
    try:
        # Validate the generated specification
        app.validate()
        print("Specification is valid.")

        # Save the specification to a JSON file
        with open('openapi.json', 'w') as f:
            f.write(app.dump_json(indent=2))
        print("Successfully generated openapi.json")

    except Exception as e:
        print(f"Validation Error: {e}")

Ihre Datei generate_spec.py ist nun vollständig. Führen Sie sie von Ihrem Terminal aus:Bash

python generate_spec.py

Wenn alles korrekt ist, sehen Sie die Ausgabe:

Specification is valid.
Successfully generated openapi.json

Sie haben nun eine neue Datei, openapi.json, in Ihrem Projektverzeichnis. Öffnen Sie sie und erkunden Sie ihren Inhalt. Sie sehen ein perfekt strukturiertes OpenAPI 3.0 Dokument, das Ihre Flask-API bis ins kleinste Detail beschreibt.


Teil 5: Bereitstellen der Dokumentation

Eine openapi.json-Datei zu haben ist großartig für Maschinen und zur Generierung von Client-SDKs, aber für menschliche Entwickler ist eine interaktive Benutzeroberfläche weitaus nützlicher. In diesem letzten Teil werden wir unsere generierte Spezifikation in unsere Flask-App integrieren und sie mithilfe der beliebten Swagger UI bereitstellen.

Integrieren der Spezifikation in Flask

Zuerst müssen wir einen Endpunkt in unserer Flask-App erstellen, der die Datei openapi.json bereitstellt. Dies ermöglicht es Dokumentationstools, die Spezifikation direkt von unserer laufenden API abzurufen.

Ändern Sie app.py, um eine neue Route hinzuzufügen:Python

# app.py

# ... (keep all the existing Flask code) ...
import os

# ... (all the routes like /users, /users/{user_id}, etc.) ...

# --- Serving the OpenAPI Specification and UI ---

@app.route('/api/docs/openapi.json')
def serve_openapi_spec():
    """ Serves the generated openapi.json file. """
    # This assumes openapi.json is in the same directory as app.py
    # In a larger app, you might want a more robust way to find the file
    return app.send_static_file('openapi.json')

Damit dies funktioniert, muss Flask wissen, wo statische Dateien zu finden sind. Standardmäßig sucht es in einem Verzeichnis namens static. Erstellen wir eines und verschieben unsere Datei openapi.json dorthin.Bash

mkdir static
mv openapi.json static/

Führen Sie nun python app.py aus und navigieren Sie zu http://127.0.0.1:5000/api/docs/openapi.json. Sie sollten das rohe JSON Ihrer Spezifikation sehen.

Bereitstellen der interaktiven Benutzeroberfläche mit Swagger UI 🎨

Swagger UI ist eine sammlungsabhängigkeitsfreie Sammlung von HTML-,2 JavaScript- und CSS-Assets, die dynamisch schöne Dokumentation aus einer OpenAPI-kompatiblen API generiert. Wir können sie einfach von unserer Flask-Anwendung aus bereitstellen.

Erstellen eines Templates-Verzeichnisses: Flask verwendet ein Verzeichnis namens templates, um nach HTML-Templates zu suchen.Bash

mkdir templates

Erstellen des Swagger UI Templates: Erstellen Sie im Verzeichnis templates eine neue Datei namens swagger_ui.html. Fügen Sie den folgenden HTML-Code ein. Dieser Code lädt die Swagger UI-Assets von einem öffentlichen CDN und konfiguriert sie, um unsere Spezifikationsdatei zu laden.HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User API - Swagger UI</title>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui.min.css" >
    <style>
        html {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
        }
        *, *:before, *:after {
            box-sizing: inherit;
        }
        body {
            margin:0;
            background: #fafafa;
        }
    </style>
</head>

<body>
    <div id="swagger-ui"></div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui-bundle.js"> </script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui-standalone-preset.js"> </script>

<script>

window.onload = function() {

// Begin Swagger3 UI call region

const ui = SwaggerUIBundle({

url: "/api/docs/openapi.json", // The URL for our spec

dom_id: '#swagger-ui',

deepLinking: true,

presets: [

SwaggerUIBundle.presets.apis,

SwaggerUIStandalonePreset4

],

plugins: [

SwaggerUIBundle.plugins.DownloadUrl

],

layout: "StandaloneLayout"

})

// End Swagger UI call region

        window.ui = ui
    }
  </script>
</body>
</html>
```

Hinzufügen der Flask-Route: Fügen Sie schließlich eine Route zu app.py hinzu, um dieses HTML-Template zu rendern. Sie müssen render_template von Flask importieren.Python

# At the top of app.py
from flask import Flask, jsonify, request, abort, render_template

# ... (all other routes) ...

@app.route('/api/docs/')
def serve_swagger_ui():
    """ Serves the interactive Swagger UI documentation. """
    return render_template('swagger_ui.html')

Alles zusammenfügen

Ihre endgültige Projektstruktur sollte so aussehen:

pyswagger-tutorial/
├── app.py
├── generate_spec.py
├── requirements.txt
├── static/
│   └── openapi.json
├── templates/
│   └── swagger_ui.html
└── venv/

Nun zum Endergebnis. Stellen Sie sicher, dass Ihre Flask-App läuft (python app.py). Öffnen Sie Ihren Webbrowser und navigieren Sie zu:

http://127.0.0.1:5000/api/docs/

Sie sollten mit einer schönen, interaktiven Dokumentationsseite für Ihre API begrüßt werden. Sie können jeden Endpunkt erweitern, die von Ihnen definierten Schemata sehen und sogar die Schaltfläche "Try it out" verwenden, um Live-Anfragen direkt von Ihrem Browser an Ihre laufende Flask-Anwendung zu senden.

Fazit

In diesem Tutorial sind wir von einem leeren Verzeichnis zu einer vollständig dokumentierten API gereist. Wir haben pyswagger erfolgreich verwendet, um programmatisch eine detaillierte OpenAPI 3.0 Spezifikation zu konstruieren, indem wir ihr Objektmodell der Struktur unserer API zugeordnet haben. Wir haben gelernt, wie man Metadaten, Server, wiederverwendbare Schemata, Pfade und Operationen mit ihren Parametern und Antworten definiert.

Durch die Trennung der Spezifikationsgenerierung (generate_spec.py) von der Anwendungslogik (app.py) haben wir einen sauberen Workflow geschaffen: Implementieren Sie Ihre API, führen Sie dann den Generator aus, um die Dokumentation zu erstellen. Dieser Prozess ist zwar manueller als dekoratorbasierte Ansätze, bietet aber unvergleichliche Kontrolle und Flexibilität, was ihn ideal für komplexe Projekte, Altsysteme oder bei strengen Dokumentationsstandards macht.

Schließlich haben wir durch die Bereitstellung der generierten Spezifikation und einer Swagger UI-Instanz ein poliertes, professionelles und sehr nützliches Dokumentationsportal für die Konsumenten unserer API bereitgestellt. Sie verfügen nun über ein leistungsstarkes neues Werkzeug in Ihrem Python-Entwicklungsarsenal zur Erstellung erstklassiger API-Dokumentation.

💡
Möchten Sie ein großartiges API-Testwerkzeug, das schöne API-Dokumentation generiert?

Möchten Sie eine integrierte All-in-One-Plattform, auf der Ihr Entwicklerteam mit maximaler Produktivität zusammenarbeiten kann?

Apidog erfüllt all Ihre Anforderungen und ersetzt Postman zu einem viel günstigeren Preis!
button

Praktizieren Sie API Design-First in Apidog

Entdecken Sie eine einfachere Möglichkeit, APIs zu erstellen und zu nutzen