技術共有

Apispec、OpenAPI (Swagger) 仕様を生成するための Python ライブラリ

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

目次

01APIspecとは何ですか?

アピスペックを選ぶ理由

インストールと構成

02Apispecの基本的な使い方

簡単な API ドキュメントを生成する

1.Apispec インスタンスを作成する

2. API ルートとビューを定義する

3. Apispec へのパスを追加する

Flask と APIspec を統合する

1. Flask と Flask-Apispec をインストールする

2. Flask アプリケーションを作成する

Django と APIspec を統合する

1. Django と Django-Rest-Framework をインストールする

2. Django プロジェクトとアプリケーションを作成する

3. Django プロジェクトの構成

4. Django ビューを定義する

5. URLの設定

6. OpenAPI仕様の生成

03Apispecの先進的な機能

1. カスタムジェネレータ

2. 複数のフレームワークをサポート

3. インターフェースドキュメントを自動生成

4. サードパーティツールとの統合

04実践事例

1. プロジェクトの紹介

2. プロジェクトの構造

3. 依存関係をインストールする

4. モデルを定義する

5. ビューとシリアル化を定義する

6. メインアプリケーションを定義する

7. アプリを実行し、ドキュメントを表示します。

http://localhost:5000/swagger/ にアクセスして、生成された API ドキュメントを表示します。

05ベストプラクティス

06 まとめ



01APIスペックとは何ですか?

APIspec の概要

Apispec は、OpenAPI (Swagger) 仕様を生成するための Python ライブラリです。これは、開発者が API ドキュメントを自動的に生成および管理し、直感的で詳細なインターフェイスの説明を提供するのに役立ちます。 Apispec を使用すると、Python 関数またはクラスのドキュメント文字列を OpenAPI 仕様に準拠したドキュメントに簡単に変換でき、ドキュメントを手動で作成する手間が軽減されます。

アピスペックを選ぶ理由

  • シンプルで使いやすい: Apispec はシンプルで使いやすい API を提供するため、すぐに使い始めることができます。

  • 柔軟かつ強力: 複数のフレームワーク (Flask、Django など) と拡張機能をサポートし、必要に応じてドキュメント生成をカスタマイズできます。

  • オートメーション: ドキュメントを自動的に生成および更新することで、手動操作とメンテナンスのコストを削減します。

インストールと構成

Apispec の使用を開始する前に、まず Apispec をインストールする必要があります。 pip を使用してインストールできます。

pip install apispec

Github プロジェクトのアドレス:

https://github.com/marshmallow-code/apispec

02APIspecの基本的な使い方

いくつかの簡単な例を通して、Apispec の基本的な使用法を見てみましょう。

簡単な API ドキュメントを生成する

1.Apispec インスタンスを作成する

  1. from apispec import APISpec
  2. spec = APISpec(
  3.     title="My API",
  4.     version="1.0.0",
  5.     openapi_version="3.0.0",
  6.     info=dict(description="This is a sample API"),
  7. )

2. API ルートとビューを定義する

  1. def get_user(user_id):
  2.     """
  3.     ---
  4.     get:
  5.       description: Get a user by ID
  6.       parameters:
  7.         - name: user_id
  8.           in: path
  9.           required: true
  10.           schema:
  11.             type: integer
  12.       responses:
  13.         200:
  14.           description: A user object
  15.           content:
  16.             application/json:
  17.               schema:
  18.                 type: object
  19.                 properties:
  20.                   id:
  21.                     type: integer
  22.                   name:
  23.                     type: string
  24.     """
  25.     return {"id": user_id, "name""John Doe"}

3. Apispec へのパスを追加する

  1. spec.path(
  2.     path="/users/{user_id}",
  3.     operations=dict(
  4.         get=dict(
  5.             description="Get a user by ID",
  6.             parameters=[
  7.                 {
  8.                     "name""user_id",
  9.                     "in""path",
  10.                     "required"True,
  11.                     "schema": {"type""integer"},
  12.                 }
  13.             ],
  14.             responses={
  15.                 "200": {
  16.                     "description""A user object",
  17.                     "content": {
  18.                         "application/json": {
  19.                             "schema": {
  20.                                 "type""object",
  21.                                 "properties": {
  22.                                     "id": {"type""integer"},
  23.                                     "name": {"type""string"},
  24.                                 },
  25.                             }
  26.                         }
  27.                     },
  28.                 }
  29.             },
  30.         )
  31.     ),
  32. )

Flask と APIspec を統合する

1. Flask と Flask-Apispec をインストールする

pip install Flask Flask-Apispec

2. Flask アプリケーションを作成する

  1. from flask import Flask, jsonify
  2. from flask_apispec import FlaskApiSpec, doc, marshal_with
  3. from flask_apispec.views import MethodResource
  4. from marshmallow import Schema, fields
  5. app = Flask(__name__)
  6. class UserSchema(Schema):
  7.     id = fields.Int()
  8.     name = fields.Str()
  9. class UserResource(MethodResource):
  10.     @doc(description='Get a user by ID', tags=['User'])
  11.     @marshal_with(UserSchema)
  12.     def get(self, user_id):
  13.         return {"id": user_id, "name""John Doe"}
  14. app.add_url_rule('/users/<int:user_id>', view_func=UserResource.as_view('user_resource'))
  15. docs = FlaskApiSpec(app)
  16. docs.register(UserResource)
  17. @app.route('/swagger/')
  18. def swagger_ui():
  19.     return jsonify(docs.spec.to_dict())
  20. if __name__ == '__main__':
  21.     app.run()

Django と APIspec を統合する

1. Django と Django-Rest-Framework をインストールする

pip install django djangorestframework

2. Django プロジェクトとアプリケーションを作成する

  1. django-admin startproject myproject
  2. cd myproject
  3. django-admin startapp myapp

3. Django プロジェクトの構成

settings.py にrest_framework と apispec を追加します。

  1. INSTALLED_APPS = [
  2.     ...
  3.     'rest_framework',
  4.     'myapp',
  5.     'apispec',
  6. ]

4. Django ビューを定義する

myapp/views.py 内:

  1. from rest_framework.views import APIView
  2. from rest_framework.response import Response
  3. from rest_framework.schemas import AutoSchema
  4. class UserView(APIView):
  5.     schema = AutoSchema(
  6.         manual_fields=[
  7.             coreapi.Field('user_id', required=True, location='path', schema={'type''integer'})
  8.         ]
  9.     )
  10.     def get(self, request, user_id):
  11.         """
  12.         Get a user by ID.
  13.         ---
  14.         responses:
  15.           200:
  16.             description: A user object
  17.             content:
  18.               application/json:
  19.                 schema:
  20.                   type: object
  21.                   properties:
  22.                     id:
  23.                       type: integer
  24.                     name:
  25.                       type: string
  26.         """
  27.         return Response({"id": user_id, "name""John Doe"})

5. URLの設定

myapp/urls.py 内:

  1. from django.urls import path
  2. from .views import UserView
  3. urlpatterns = [
  4.     path('users/<int:user_id>/', UserView.as_view(), name='user-view'),
  5. ]

6. OpenAPI仕様の生成

manage.py 内:

  1. from apispec import APISpec
  2. from rest_framework.schemas import get_schema_view
  3. spec = APISpec(
  4.     title="My API",
  5.     version="1.0.0",
  6.     openapi_version="3.0.0",
  7. )
  8. schema_view = get_schema_view(title="My API")
  9. schema = schema_view.get_schema(request=None, public=True)
  10. spec.components.schema('User', schema)
  11. spec.path(path='/users/{user_id}/', operations=schema['paths']['/users/{user_id}/'])
  12. print(spec.to_yaml())

03APIspec の高度な機能

1. カスタムジェネレータ

APIspec は、ジェネレーターをカスタマイズできる柔軟な拡張メカニズムを提供します。 Apispec が提供する基本クラスを継承および拡張することで、独自の生成ロジックを実装できます。

  1. from apispec import BasePlugin
  2. class MyPlugin(BasePlugin):
  3.     def path_helper(self, operations, *, resource, **kwargs):
  4.         operations.update({
  5.             'get': {
  6.                 'description''Get a user by ID',
  7.                 'parameters': [
  8.                     {'name''user_id''in''path''required'True'schema': {'type''integer'}}
  9.                 ],
  10.                 'responses': {
  11.                     '200': {
  12.                         'description''A user object',
  13.                         'content': {
  14.                             'application/json': {
  15.                                 'schema': {
  16.                                     'type''object',
  17.                                     'properties': {
  18.                                         'id': {'type''integer'},
  19.                                         'name': {'type''string'}
  20.                                     }
  21.                                 }
  22.                             }
  23.                         }
  24.                     }
  25.                 }
  26.             }
  27.         })
  28. spec = APISpec(
  29.     title="My API",
  30.     version="1.0.0",
  31.     openapi_version="3.0.0",
  32.     plugins=[MyPlugin()],
  33. )

2. 複数のフレームワークをサポート

Apispec は、Flask、Django、Falcon など、さまざまな一般的な Python フレームワークをサポートしています。ニーズに応じて適切なフレームワークとプラグインを選択し、API ドキュメントを迅速に生成できます。

3. インターフェースドキュメントを自動生成

Apispec は、関数またはクラスのドキュメント文字列に基づいてインターフェイス ドキュメントを自動的に生成できるため、ドキュメントを手動で作成する作業負荷が軽減されます。

  1. def get_user(user_id):
  2.     """
  3.     ---
  4.     get:
  5.       description: Get a user by ID
  6.       parameters:
  7.         - name: user_id
  8.           in: path
  9.           required: true
  10.           schema:
  11.             type: integer
  12.       responses:
  13.         200:
  14.           description: A user object
  15.           content:
  16.             application/json:
  17.               schema:
  18.                 type: object
  19.                 properties:
  20.                   id:
  21.                     type: integer
  22.                   name:
  23.                     type: string
  24.     """
  25.     return {"id": user_id, "name""John Doe"}

4. サードパーティツールとの統合

Apispec は、Swagger UI、ReDoc などの多くのサードパーティ ツールと統合して、直感的なインターフェイスのドキュメント表示およびテスト機能を提供できます。

  1. from flask import Flask, jsonify
  2. from flask_apispec import FlaskApiSpec
  3. app = Flask(__name__)
  4. @app.route('/users/<int:user_id>', methods=['GET'])
  5. def get_user(user_id):
  6.     """
  7.     ---
  8.     get:
  9.       description: Get a user by ID
  10.       parameters:
  11.         - name: user_id
  12.           in: path
  13.           required: true
  14.           schema:
  15.             type: integer
  16.       responses:
  17.         200:
  18.           description: A user object
  19.           content:
  20.             application/json:
  21.               schema:
  22.                 type: object
  23.                 properties:
  24.                   id:
  25.                     type: integer
  26.                   name:
  27.                     type: string
  28.     """
  29.     return jsonify({"id": user_id, "name""John Doe"})
  30. docs = FlaskApiSpec(app)
  31. docs.register(get_user)
  32. if __name__ == '__main__':
  33.     app.run()

04実践事例

完全な API ドキュメント システムを構築する

1. プロジェクトの紹介

単純なユーザー管理システムがあり、その API を文書化する必要があるとします。当社の API には、ユーザーの追加、削除、変更、クエリ操作に加えて、いくつかの基本的な ID 認証機能が含まれています。

2. プロジェクトの構造

  1. user_management/
  2. ├── app.py
  3. ├── models.py
  4. ├── views.py
  5. ├── serializers.py
  6. └── requirements.txt

3. 依存関係をインストールする

依存関係をrequirements.txtに追加します。

  1. Flask
  2. Flask-RESTful
  3. Flask-SQLAlchemy
  4. Flask-Migrate
  5. apispec
  6. flask-apispec

次のコマンドを実行して依存関係をインストールします。

pip install -r requirements.txt

4. モデルを定義する

models.py でユーザー モデルを定義します。

  1. from flask_sqlalchemy import SQLAlchemy
  2. db = SQLAlchemy()
  3. class User(db.Model):
  4.     id = db.Column(db.Integer, primary_key=True)
  5.     name = db.Column(db.String(80), nullable=False)
  6.     email = db.Column(db.String(120), unique=True, nullable=False)

5. ビューとシリアル化を定義する

serializers.py でユーザー シリアライザーを定義します。

  1. from marshmallow import Schema, fields
  2. class UserSchema(Schema):
  3.     id = fields.Int(dump_only=True)
  4.     name = fields.Str(required=True)
  5.     email = fields.Email(required=True)

views.py でビューを定義します。

  1. from flask import request
  2. from flask_restful import Resource
  3. from models import User, db
  4. from serializers import UserSchema
  5. class UserResource(Resource):
  6.     def get(self, user_id):
  7.         user = User.query.get_or_404(user_id)
  8.         schema = UserSchema()
  9.         return schema.dump(user)
  10.     def post(self):
  11.         schema = UserSchema()
  12.         user = schema.load(request.json)
  13.         db.session.add(user)
  14.         db.session.commit()
  15.         return schema.dump(user), 201
  16.     def put(self, user_id):
  17.         user = User.query.get_or_404(user_id)
  18.         schema = UserSchema(partial=True)
  19.         updated_user = schema.load(request.json, instance=user)
  20.         db.session.commit()
  21.         return schema.dump(updated_user)
  22.     def delete(self, user_id):
  23.         user = User.query.get_or_404(user_id)
  24.         db.session.delete(user)
  25.         db.session.commit()
  26.         return ''204

6. メインアプリケーションを定義する

app.py 内:

  1. from flask import Flask
  2. from flask_restful import Api
  3. from flask_migrate import Migrate
  4. from models import db
  5. from views import UserResource
  6. from flask_apispec import FlaskApiSpec
  7. from flask_apispec.extension import FlaskApiSpec
  8. app = Flask(__name__)
  9. app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
  10. db.init_app(app)
  11. migrate = Migrate(app, db)
  12. api = Api(app)
  13. api.add_resource(UserResource, '/users/<int:user_id>')
  14. docs = FlaskApiSpec(app)
  15. docs.register(UserResource)
  16. if __name__ == '__main__':
  17.     app.run()

7. アプリを実行し、ドキュメントを表示します。

次のコマンドを実行してアプリケーションを起動します。

python app.py

http://localhost:5000/swagger/ にアクセスして、生成された API ドキュメントを表示します。

05ベストプラクティス

1. ドキュメントとコードの同期を保つ

ドキュメントと実際の API の間の不一致を避けるために、ドキュメントが常にコードと同期していることを確認してください。 CI/CD ツールを使用して、ドキュメントを自動的に生成および展開できます。

2. アノテーションとデコレータを使用する

コメントとデコレータを使用すると、ドキュメントをより簡潔で読みやすくすることができます。たとえば、Flask-Apispec の @doc デコレーターを使用して、ドキュメント情報をビュー関数に追加します。

3. グローバルパラメータと応答を定義する

よく使用されるパラメータと応答については、Apispec でグローバル パラメータと応答テンプレートを定義して、コードの繰り返しを減らすことができます。

  1. spec.components.parameter("user_id""path", schema={"type""integer"}, required=True)
  2. spec.components.response("User", {
  3.     "description""A user object",
  4.     "content": {
  5.         "application/json": {
  6.             "schema": {
  7.                 "type""object",
  8.                 "properties": {
  9.                     "id": {"type""integer"},
  10.                     "name": {"type""string"}
  11.                 }
  12.             }
  13.         }
  14.     }
  15. })

4. ドキュメントを定期的に確認して更新する

正確さと完全性を確保するために、ドキュメントを定期的に確認して更新します。これは、文書レビューサイクルを設定するか、文書レビュープロセスを導入することで実現できます。

その他の機能と詳細な使用方法については、公式ドキュメントを参照してください。

https://apispec.readthedocs.io/en/latest

06まとめ

この記事を通じて、Apispec の基本を理解し、習得できたと思います。基本的な使い方から高度な機能、実践事例やベストプラクティスまで、Apispec を使用して API ドキュメントを生成および保守する方法を包括的に紹介します。

この知識を実際のプロジェクトに適用して、API に明るさを加えていただければ幸いです。