GitHubじゃ!Pythonじゃ!

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

timothycrosley

hug – 将来のAPIを受け入れる。 Hugは、できるだけシンプルにAPIを開発することを目指していますが、単純ではありません

投稿日:

将来のAPIを受け入れる。 Hugは、できるだけシンプルにAPIを開発することを目指していますが、単純ではありません。

注:詳細なドキュメントについては、 hugのWebサイトを参照してください。

hugは、Pythonで開発されたAPIをできるだけシンプルに開発することを目指しています。 その結果、Python APIの開発が大幅に簡素化されます。

ハグのデザイン目標:

  • 書かれた定義と同じように、Python主導のAPIを開発するようにしてください。
  • フレームワークは、自己文書化するコードを奨励する必要があります。
  • それは速くなければならない。 開発者は、パフォーマンス上の理由から他の場所を探す必要性を決して感じるべきではありません。
  • ハグの上に書かれたAPIのテストを書くのは簡単で直感的でなければなりません。
  • APIフレームワークで一度実行されたマジックは、問題をAPIフレームワークのユーザーにプッシュするよりも優れています。
  • 最新の技術を取り入れた次世代Python APIの基礎となります。

これらの目標の結果として、HugはPython 3+のみであり、 Falconの高性能HTTPライブラリ

ハグをインストールする

ハグをインストールするのは簡単です:

pip3 install hug --upgrade

理想的には、 仮想環境内。

入門

単純なエンドポイントを数行で作成し、サンプルAPIを構築します。

# filename: happy_birthday.py
"""A basic (single function) API written using hug"""
import hug


@hug.get('/happy_birthday')
def happy_birthday(name, age:hug.types.number=1):
    """Says happy birthday to a user"""
    return "Happy {age} Birthday {name}!".format(**locals())

実行するには、コマンドラインから次のように入力します。

hug -f happy_birthday.py

ブラウザの例では、 localhost:8000/happy_birthday?name=hug&age=1アクセスできます。 次に、 localhost:8000/documentation APIのドキュメントをチェックしてください

パラメータはURLにエンコードすることもできます(例全体についてはhappy_birthday.pyをチェックしてください)。

@hug.get('/greet/{event}')
def greet(event: str):
    """Greets appropriately (from http://blog.ketchum.com/how-to-write-10-common-holiday-greetings/)  """
    greetings = "Happy"
    if event == "Christmas":
        greetings = "Merry"
    if event == "Kwanzaa":
        greetings = "Joyous"
    if event == "wishes":
        greetings = "Warm"

    return "{greetings} {event}!".format(**locals())

上記のようにサーバーを実行すると、次のように使用できます。

curl http://localhost:8000/greet/wishes
"Warm wishes!"

ハグでバージョン管理

# filename: versioning_example.py
"""A simple example of a hug API call with versioning"""
import hug

@hug.get('/echo', versions=1)
def echo(text):
    return text


@hug.get('/echo', versions=range(2, 5))
def echo(text):
    return "Echo: {text}".format(**locals())

この例を実行するには:

hug -f versioning_example.py

次に、 localhost:8000/v1/echo?text=Hi / localhost:8000/v2/echo?text=Hiからのサンプルにアクセスするlocalhost:8000/v2/echo?text=Hilocalhost:8000からAPIのドキュメントにアクセスしてください

注:バージョン管理では、バージョンヘッダーと直接URLベースの仕様の両方が自動的にサポートされます。

APIをテストする

ハグのhttpメソッドデコレータは元の関数を変更しません。 これにより、他のPython関数をテストするのと同じくらい簡単にAPIをテストできます。 さらに、これは、他のPythonコードでAPI関数とやりとりすることは、PythonのみのAPI関数を呼び出すこととまったく同じことです。 hugは、 hug.testモジュールを使用して、APIのPythonスタック全体を簡単にテストhug.testます。

import hug
import happy_birthday

hug.test.get(happy_birthday, 'happy_birthday', {'name': 'Timothy', 'age': 25}) # Returns a Response object

テストアサーションに対してこのResponseオブジェクトを使用することができます( test_happy_birthday.pyチェックしてtest_happy_birthday.py ):

def tests_happy_birthday():
    response = hug.test.get(happy_birthday, 'happy_birthday', {'name': 'Timothy', 'age': 25})
    assert response.status == HTTP_200
    assert response.data is not None

他のWSGIベースのサーバーとの抱擁の実行

hugは、すべてのAPIモジュールで自動的に__hug_wsgi__マジックメソッドを公開します。 任意の標準wsgiサーバー上であなたのハグベースのAPIを実行するのは、 module_name__hug_wsgi__を指すように簡単__hug_wsgi__

例えば:

uwsgi --http 0.0.0.0:8000 --wsgi-file examples/hello_world.py --callable __hug_wsgi__

hello world hugサンプルAPIを実行するには

ハグAPIのビルディングブロック

ハグフレームワークを使用してAPIを構築する場合は、次の概念を使用します。

メソッドデコレータは getpostupdateなどHTTPメソッドデコレータで、Pythonメソッドを変更せずにAPIとして公開します。

@hug.get() # <- Is the hug METHOD decorator
def hello_world():
    return "Hello"

hugは、APIのユーザーのためのドキュメントを自動的に生成するために、飾る関数の構造を使用します。 hugは、関数定義のparamsが定義されている場合、常にrequest、response、およびapi_version変数を関数に渡します。

オプションでメソッドの引数にアタッチされるAnnotations関数を入力して 、引数の検証方法とPython型への変換方法を指定します

@hug.get()
def math(number_1:int, number_2:int): #The :int after both arguments is the Type Annotation
    return number_1 + number_2

タイプアノテーションはまた、 hugの自動ドキュメンテーション生成にも役立ち、APIのユーザーはどのデータを提供するのかを知ることができます。

api_functionの引数として要求されたことに基づいて要求/応答データとともに実行される関数を指示します。 これらは入力パラメータとしてのみ適用され、現在は出力フォーマットまたは変換として適用することはできません。

@hug.get()
def test_time(hug_timer):
    return {'time_taken': float(hug_timer)}

ディレクティブは、 hug_接頭辞付きの引数、またはPython 3タイプの注釈を使用してアクセスできます。 後者はより現代的なアプローチであり、推奨されています。 モジュールで宣言されたディレクティブは、型名(例: module.directive_name )として完全修飾名を使用してアクセスできます。

明示的な入力変換ユースケースの他にも、リクエストクエリ文字列、POST本体などに存在しない場合でも、ディレクティブを使用してAPI関数にデータをパイプすることができます。このようにディレクティブを使用する方法の例については、 examplesフォルダの認証の例を参照してください。

独自のディレクティブを追加することは簡単です。

@hug.directive()
def square(value=1, **kwargs):
    '''Returns passed in parameter multiplied by itself'''
    return value * value

@hug.get()
@hug.local()
def tester(value: square=10):
    return value

tester() == 100

完全性のために、ここでは、魔法名アプローチを介してディレクティブにアクセスする例を示します。

@hug.directive()
def multiply(value=1, **kwargs):
    '''Returns passed in parameter multiplied by itself'''
    return value * value

@hug.get()
@hug.local()
def tester(hug_multiply=10):
    return hug_multiply

tester() == 100

出力 API関数の出力を受け取り、APIのユーザーに転送するための書式を設定する関数を書式設定します。

@hug.default_output_format()
def my_output_formatter(data):
    return "STRING:{0}".format(data)

@hug.get(output=hug.output_format.json)
def hello():
    return {'hello': 'world'}

このように、API全体と個々のAPI呼び出しの両方の出力形式を簡単に変更することができます

InputあなたのAPIのユーザから与えられたデータの本体を取り、処理のためにフォーマットするための関数をフォーマットします。

@hug.default_input_format("application/json")
def my_input_formatter(data):
    return ('Results', hug.input_format.json(data))

入力フォーマッタは、要求データのcontent_typeに基づいてマッピングされ、基本的な解析のみを実行します。 より詳細な解析は、 api_functionあるType Annotationによって行う必要があります

ハグAPIが処理するすべてのリクエストに対して呼び出されるミドルウェア機能

@hug.request_middleware()
def process_data(request, response):
    request.env['SERVER_NAME'] = 'changed'

@hug.response_middleware()
def process_data(request, response, resource):
    response.set_header('MyHeader', 'Value')

Falconスタイルのミドルウェアを簡単に追加することもできます:

__hug__.http.add_middleware(MiddlewareObject())

複数のファイルにまたがるAPIの分割

抱擁を使用すると、大規模なプロジェクトを任意の方法で整理できます。 ハグデコレーションされた関数(リクエスト処理、ディレクティブ、型ハンドラなど)を含むモジュールをインポートし、そのモジュールでベースAPIを拡張することができます。

例えば:

something.py

import hug

@hug.get('/')
def say_hi():
    return 'hello from something'

メインAPIファイルにインポートすることができます:

__init__.py

import hug
from . import something

@hug.get('/')
def say_hi():
    return "Hi from root"

@hug.extend_api('/something')
def something_api():
    return [something]

代わりに、 – このような場合 – URLルートごとに1つのモジュールしか含まれていない場合:

#alternatively
hug.API(__name__).extend(something, '/something')

ハグ404の設定

デフォルトでは、ユーザーが定義されていないエンドポイントにアクセスしようとすると、自動的に生成されたAPI仕様が返されます。 この仕様を返却したくない場合は、404ドキュメントを無効にすることができます:

コマンドラインアプリケーションから:

hug -nd -f {file} #nd flag tells hug not to generate documentation on 404

さらに、 hug.not_foundデコレータを使用してカスタム404ハンドラを簡単に作成できます。

@hug.not_found()
def not_found_handler():
    return "Not Found"

このデコレータは、Hug HTTPメソッドデコレータと同じように動作し、バージョンを認識しています。

@hug.not_found(versions=1)
def not_found_handler():
    return ""

@hug.not_found(versions=2)
def not_found_handler():
    return "Not Found"

Asyncioのサポート

コルーチンでgetおよびcliメソッドデコレータを使用する場合、hugはコルーチンの実行をスケジュールします。

asyncioコルーチンデコレータの使用

@hug.get()
@asyncio.coroutine
def hello_world():
    return "Hello"

Python 3.5 asyncキーワードを使用する。

@hug.get()
async def hello_world():
    return "Hello"

注:ハグは、非同期サーバーではないトップファルコンで実行されています。 asyncioを使用しても、リクエストは同期して処理されます。

ドッカーを使用する

Dockerで開発してシステムをきれいに保つことができれば、それを行うことができますが、まずDocker Composeをインストールする必要があります。

これを済ませたら、dockerディレクトリにcdして./docker/gunicorn/Dockerfileで指定されたWebサーバー(Gunicorn)を実行する必要があります。その後、ブラウザのAPIであなたのAPIの出力をプレビューできます。ホストマシン。

$ cd ./docker
# This will run Gunicorn on port 8000 of the Docker container.
$ docker-compose up gunicorn

# From the host machine, find your Dockers IP address.
# For Windows & Mac:
$ docker-machine ip default

# For Linux:
$ ifconfig docker0 | grep 'inet' | cut -d: -f2 | awk '{ print $1}' | head -n1

デフォルトでは、IPは172.17.0.1です。 表示されているIPであると仮定すると、ブラウザでhttp://172.17.0.1:8000/にアクセスしてAPIを表示します。

Dockerコンテナにログインして、作業スペースと考えることもできます。 このワークスペースにはPythonとPipがインストールされているため、Docker内でこれらのツールを使用できます。 たとえば、CLIインターフェイスをテストする必要がある場合は、これを使用します。

$ docker-compose run workspace bash

Docker workspaceコンテナでは、ホストコンピュータの./docker/templatesディレクトリがDockerコンテナの/srcにマウントされます。 これは./docker/docker-compose.yml services > appで指定しservices

bash-4.3# cd /src
bash-4.3# tree
.
├── __init__.py
└── handlers
    ├── birthday.py
    └── hello.py

1 directory, 3 files

なぜ抱擁?

HUGは、ほんとうに便利なガイドの略です。 これは、開発者がよく書かれた直感的なAPIを作成できるようにするプロジェクトの目標を表しています。


ありがとう、私はあなたが次のPython APIを開発する際に役立つこの抱擁を見つけることを願っています!

〜ティモシー・クロスレイ







-timothycrosley

執筆者: