GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

zalando

connexion – Swagger / OpenAPI自動エンドポイント検証とOAuth2サポートを備えたFlaskの上にあるPythonの最初のフレームワ..

投稿日:

Swagger / OpenAPI自動エンドポイント検証とOAuth2サポートを備えたFlaskの上にあるPythonの最初のフレームワーク https: //connexion.readthedocs.io/en/l…

接続

ConnexionはFlaskの上にあるフレームワークで、 YAML形式で記述されたAPIのOpenAPI 2.0仕様 (旧称Swagger Spec)に基づいてHTTPリクエストを自動的に処理します。 ConnexionではSwagger仕様書を作成し、エンドポイントをPython関数にマップすることができます。 多くのツールがPythonコードに基づいて仕様を生成するので、これはユニークです。 REST APIについては、必要なだけ詳細に記述することができます。 Connexionは指定したとおりに動作することを保証します。

Connexionをこのようにして作成しました。

  • 開発プロセスを簡素化する
  • APIがどのように見えるかについての期待を確認する

コネクション機能:

  • 仕様に基づいて、要求とエンドポイント・パラメーターを自動的に検証します。
  • Web Swagger Console UIを提供します。これにより、APIのユーザーはライブ文書を持ち、APIを通じてAPIのエンドポイントを呼び出すことができます
  • OAuth 2トークンベース認証を処理する
  • APIのバージョン管理をサポート
  • ペイロードの自動シリアル化をサポートします。 エンドポイントがJSONを返すと仕様で定義されている場合、Connexionは自動的に戻り値をシリアル化し、HTTPヘッダーに正しいコンテンツタイプを設定します。

なぜコネクション?

Connexionでは、最初に仕様を記述します。 ConnexionはPythonコードを呼び出し、仕様からコードへのマッピングを処理します。 これは、コードの単一行を記述する前であっても、すべての開発者がAPIの機能を理解できるように仕様を書くことを促します。

複数のチームがAPIに依存する場合は、Connexionを使用してAPIのドキュメントを簡単に送信できます。 これにより、APIが記述した仕様に従うことが保証されます。 これはHugのようなフレームワークが提供するプロセスとは異なるプロセスで、コードを記述した後に仕様を生成します。 コードに基づいて仕様を生成することのいくつかの欠点は、多くの場合、詳細が不足したり、アプリケーションのコードロジックとドキュメントが混在することです。

その他の出典/覚書

使い方

前提条件

Python 2.7またはPython 3.4以上

それをインストールする

コマンドラインに次のように入力します。

$ pip install connexion

それを実行する

API YAMLをアプリケーションのルートパスのフォルダ( swagger/ )に配置します。 次に、

import connexion

app = connexion.App(__name__, specification_dir='swagger/')
app.add_api('my_api.yaml')
app.run(port=8080)

サンプル仕様については、 Connexion Pet Storeのサンプルアプリケーションを参照してください。

Connexionを実行して使用することができます。

OAuth 2の認証と認可

Connexionは、3つのOAuth 2処理メソッドの1つをサポートしています。 Connexionでは、APIセキュリティ定義に ‘x-tokenInfoUrl’または ‘x-tokenInfoFunc(またはそれぞれTOKENINFO_URLまたはTOKENINFO_FUNC env varを設定)をTOKENINFO_URL必要があります。 ‘x-tokenInfoUrl’には、 トークン情報を検証して取得するためのURLが含まれていなければならず、 ‘x-tokenInfoFuncにはトークン情報を取得するための関数への参照が含まれていなければなりません。 ‘x-tokenInfoUrl’と ‘x-tokenInfoFunc’の両方が使用されている場合、Connexionは関数メソッドに優先順位を付けます。 Connexionは、 AuthorizationヘッダーフィールドにOAuthトークンをRFC 6750 section 2.1で記述されいる形式で受け取ることを期待しています。 この側面は、通常のOAuthフローとの大きな違いを表します。

仕様のダイナミックレンダリング

ConnexionはJinja2を使用して、argumentsパラメーターを使用してパラメーターを指定できるようにします。 アプリケーションの仕様引数は、グローバルに(connexion.Appコンストラクタを使用して)、または特定のAPIごとに(connexion.App#add_apiメソッドを使用して)定義できます。

app = connexion.App(__name__, specification_dir='swagger/',
                    arguments={'global': 'global_value'})
app.add_api('my_api.yaml', arguments={'api_local': 'local_value'})
app.run(port=8080)

値がグローバルおよびAPIの両方に提供される場合、API値が優先されます。

エンドポイントからPythonビューへのルーティング

Connexionは、各操作オブジェクトの operationIdを使用して、どのPython関数が各URLを処理するかを識別します。

明示的ルーティング

paths:
  /hello_world:
    post:
      operationId: myapp.api.hello_world

http://MYHOST/hello_worldへの指定POSTリクエストでこのパスを指定すると、 myapp.apiモジュールのhello_world関数によって処理されます。 オプションで、操作定義にx-swagger-router-controllerで、 operationId relativeを作成することができます。

paths:
  /hello_world:
    post:
      x-swagger-router-controller: myapp.api
      operationId: hello_world

自動ルーティング

この動作をカスタマイズするために、Connexionでは代替Resolvers RestyResolverなど)を使用できます。 RestyResolverは、指定されたエンドポイントのパスとHTTPメソッドに基づいてRestyResolverを作成します。

from connexion.resolver import RestyResolver

app = connexion.App(__name__)
app.add_api('swagger.yaml', resolver=RestyResolver('api'))
paths:
  /:
    get:
       # Implied operationId: api.get
  /foo:
    get:
       # Implied operationId: api.foo.search
    post:
       # Implied operationId: api.foo.post

  '/foo/{id}':
    get:
       # Implied operationId: api.foo.get
    put:
       # Implied operationId: api.foo.put
    copy:
       # Implied operationId: api.foo.copy
    delete:
       # Implied operationId: api.foo.delete

RestyResolverは、仕様で遭遇したoperationId RestyResolverに優先RestyResolverを与えます。 また、 x-router-controllerも尊重しx-router-controller connexion.resolver.Resolverをインポートおよび拡張して、独自のoperationId (および関数)解決アルゴリズムを実装することができます。

自動パラメータ処理

Connexionは、エンドポイント仕様で定義されたパラメータを、名前付きパラメータとしてPythonビューの引数に自動的にマッピングします。可能であれば、値のキャストも行います。 ビュー引数と同じ名前のエンドポイントのパラメータを定義するだけです。

たとえば、エンドポイントが次のように指定されているとします。

paths:
  /foo:
    get:
      operationId: api.foo_get
      parameters:
        - name: message
          description: Some message.
          in: query
          type: string
          required: true

ビュー機能:

# api.py file

def foo_get(message):
    # do something
    return 'You send the message: {}'.format(message), 200

この例では、Connexionは、ビュー関数がmessageという名前の引数を期待していることを自動的に認識し、エンドポイントパラメータメッセージの値をビュー関数に代入します。

警告

エンドポイントで必須ではないパラメータを定義し、Pythonビューに名前のない引数がある場合は、このエンドポイントをパラメータなしで呼び出すたびに「位置指定引数がありません」という例外が発生します。

タイプキャスト

可能な限り、Connexionは引数の値を解析し、関連するPythonネイティブ値に型変換します。 現在利用可能な鋳造品は以下のとおりです。

スワッガータイプ Pythonタイプ
整数 int
文字列 str
浮く
ブール値 ブール
アレイ リスト
オブジェクト dict

配列型を使用する場合Swagger定義では、認識されないようにcollectionFormatを定義できます。 Connexionは現在、 “pipe”と “csv”のコレクション形式をサポートしています。 デフォルトのフォーマットは “csv”です。

パラメータの検証

Connexionは、クエリおよびフォームデータパラメータに対して厳密なパラメータ検証を適用できます。 これを有効にすると、swagger specに定義されていないパラメータを含む要求は400エラーを返します。 アプリケーションにAPIを追加するときに有効にすることができます:

app.add_api('my_apy.yaml', strict_validation=True)

APIのバージョン管理とベースパス

また、API仕様の最上位レベルでbasePathを定義することもできます。 これはバージョン管理されたAPIに便利です。 http://MYHOST/1.0/hello_worldから前のエンドポイントを提供するには、 http://MYHOST/1.0/hello_worldに入力します。

basePath: /1.0

paths:
  /hello_world:
    post:
      operationId: myapp.api.hello_world

仕様に基本パスを含めたくない場合は、APIをアプリケーションに追加するときにそれを指定できます。

app.add_api('my_api.yaml', base_path='/1.0')

Swagger JSON

Connexionは、JSON形式のOpenAPI / Swagger仕様を、APIの基本パスのswagger.jsonから利用可能にします。

アプリケーションレベルでSwagger JSONを無効にすることができます:

app = connexion.App(__name__, specification_dir='swagger/',
                    swagger_json=False)
app.add_api('my_api.yaml')

APIレベルで無効にすることもできます:

app = connexion.App(__name__, specification_dir='swagger/')
app.add_api('my_api.yaml', swagger_json=False)

HTTPSサポート

API YAMLファイルのスキームとしてHTTPSを指定する場合、配信されるSwagger UIのすべてのURIはHTTPSエンドポイントです。 問題:実行されるデフォルトのサーバーは、通常のHTTPサーバーです。 つまり、Swagger UIを使用してAPIを使用することはできません。 Connexionを使用してHTTPSサーバを起動する正しい方法は何ですか?

Flaskによって記述された 1つの方法は、次のようになります。

from OpenSSL import SSL
context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file('yourserver.key')
context.use_certificate_file('yourserver.crt')

app.run(host='127.0.0.1', port='12344',
        debug=False/True, ssl_context=context)

ただし、Connexionはssl_contextパラメータを提供しません。 これは、Flaskはどちらかではありませんが、** kwargsを使用して、基礎となる[werkzeug]( http://werkzeug.pocoo.org/ )サーバーにパラメータを送信します。

スワッガーUIコンソール

APIのSwagger UIは、デフォルトで{base_path}/ui/ありますbase_pathはAPIの基本パスです。

アプリケーションレベルでSwagger UIを無効にすることができます:

app = connexion.App(__name__, specification_dir='swagger/',
                    swagger_ui=False)
app.add_api('my_api.yaml')

APIレベルで無効にすることもできます:

app = connexion.App(__name__, specification_dir='swagger/')
app.add_api('my_api.yaml', swagger_ui=False)

必要に応じて、swagger-uiを使用してディレクトリへのパスを明示的に指定して、connexion-embedded swagger-uiディストリビューションを使用しないようにすることができます。 これを行うには、次のオプションを指定する必要があります。

options = {'swagger_path': '/path/to/swagger_ui/'}
app = connexion.App(__name__, specification_dir='swagger/', options=options)

swagger_ui / index.htmlがデフォルトでローカルswagger jsonをロードすることを確認してください。 この目的には、api_url jinja変数を使用できます。

const ui = SwaggerUIBundle({ url: "{{ api_url }}/swagger.json"})

サーバーバックエンド

ConnexionはデフォルトのFlaskサーバーを使用します。 非同期アプリケーションの場合、 TornadoをHTTPサーバーとして使用することもできます。 これを行うには、サーバーをtornado設定します。

import connexion

app = connexion.App(__name__, specification_dir='swagger/')
app.run(server='tornado', port=8080)

どのようなWSGIコンテナでもFlask WSGIアプリケーションを使用することができます。たとえば、FlaskとuWSGIを使用することができます(これは一般的です)。

app = connexion.App(__name__, specification_dir='swagger/')
application = app.app # expose global WSGI application object

aiohttpフレームワークをサーバーのバックエンドとしても使用できます。

import connexion

app = connexion.AioHttpApp(__name__, specification_dir='swagger/')
app.run(port=8080)

注: aiohttpハンドラのも確認してください。

インストールコードをセットアップして実行します。

$ sudo pip3 install uwsgi
$ uwsgi --http :8080 -w app -p 16  # use 16 worker processes

詳細については、 uWSGIのマニュアルを参照してください。

ドキュメンテーション

追加情報については、 Connexionのドキュメントページを参照してください

変更点

完全な変更履歴は、 GitHubのリリースページで管理されています

コネクション/ TODOに貢献する

あなたのアイデア、問題、プルリクエストを歓迎します。 通常の/標準のGitHubプラクティスに従います。

明示的に明示しない限り、本プロジェクトに本リポジトリ(Zalando SE、Berlin)のスチュワードに意図的に提出された非自明な貢献は、以下のApache License 2.0の条件に従うものとします。著作権情報、条件

TODO

Connexionの一貫性のある貢献者になりたい場合は、寄稿を希望している問題のリストがあります

ありがとう

このプロジェクトを担当してくれたConnexionの貢献者全員、そしてSwagger / OpenAPIに感謝したいと思います。

ライセンス

Copyright 2015 Zalando SE

Apache License、Version 2.0(以下「ライセンス」)の下でライセンスされています。 ライセンスに従わない限り、このファイルを使用することはできません。 お客様は、 http://www.apache.org/licenses/LICENSE-2.0でライセンスのコピーを入手することができます

適用法または書面による合意が必要な場合を除き、本ライセンスに基づいて配布されるソフトウェアは、明示的または黙示的にいかなる種類の保証または条件もなく「現状有姿」で配布されます。 ライセンスに基づいて許可および制限を規定する特定の言語については、ライセンスを参照してください。







-zalando
-, , , ,

執筆者: