apeescape2.com
  • メイン
  • ツールとチュートリアル
  • 革新
  • 収益と成長
  • ヒントとツール
Webフロントエンド

ボトルフレームワークを使用したRESTAPIの構築

REST APIは、Web間のインターフェースを確立するための一般的な方法になりました バックエンド そして フロントエンド 、および異なるWebサービス間。この種のインターフェースのシンプルさと、さまざまなネットワークやフレームワークにわたるHTTPおよびHTTPSプロトコルのユビキタスサポートにより、相互運用性の問題を検討する際に簡単に選択できます。

ボトル ミニマリストのPythonWebフレームワークです。軽量、高速、使いやすく、RESTfulサービスの構築に最適です。 A 必要最低限​​の比較 作られた Andriy Kornatskyy 応答時間とスループット(1秒あたりのリクエスト数)の観点から、上位3つのフレームワークの1つに入れてください。 DigitalOceanから入手できる仮想サーバーでの私自身のテストでは、uWSGIサーバースタックとBottleの組み合わせにより、要求ごとに140μsのオーバーヘッドを達成できることがわかりました。

この記事では、Bottleを使用してRESTfulAPIサービスを構築する方法のウォークスルーを提供します。



ボトル:高速で軽量のPythonWebフレームワーク

インストールと構成

ボトルフレームワークは、その軽量さのおかげで、その印象的なパフォーマンスを実現しています。実際、ライブラリ全体が1つのファイルモジュールとして配布されています。これは、他のフレームワークほど手を握らないことを意味しますが、より柔軟性があり、多くの異なる技術スタックに適合するように適合させることができます。したがって、Bottleは、パフォーマンスとカスタマイズ性が重要視され、より頑丈なフレームワークの時間節約の利点があまり考慮されていないプロジェクトに最適です。

ボトルの柔軟性により、プラットフォームのセットアップについての詳細な説明は、独自のスタックを反映していない可能性があるため、少し無駄になります。ただし、オプションの概要と、オプションの設定方法の詳細については、ここで説明します。

インストール

Bottleのインストールは、他のPythonパッケージのインストールと同じくらい簡単です。オプションは次のとおりです。

  • システムのパッケージマネージャーを使用してシステムにインストールします。 Debian Jessie(現在の安定版)はバージョン0.12を次のようにパッケージ化します python-bottle 。
  • pip install bottleでPythonPackageIndexを使用してシステムにインストールします。
  • 仮想環境にインストールします(推奨)。

ボトルを仮想環境にインストールするには、 virtualenv そして ピップ ツール。それらをインストールするには、を参照してください virtualenv そして ピップ ドキュメントは、おそらくすでにシステムにありますが。

Bashで、Python3を使用して環境を作成します。

$ virtualenv -p `which python3` env

-p `which python3`の抑制パラメータを指定すると、システムに存在するデフォルトのPythonインタプリタ(通常はPython 2.7)がインストールされます。 Python 2.7がサポートされていますが、このチュートリアルではPython3.4を想定しています。

次に、環境をアクティブにして、Bottleをインストールします。

$ . env/bin/activate $ pip install bottle

それでおしまい。ボトルが取り付けられ、すぐに使用できます。よく知らない場合 virtualenv または ピップ 、彼らのドキュメントは一流です。見てください!彼らはそれだけの価値があります。

サーバ

ボトルはPythonの標準に準拠しています Webサーバーゲートウェイインターフェイス(WSGI) 、つまり、WSGI準拠の任意のサーバーで使用できます。これも uWSGI 、 ツイスター 、 Gunicorn 、 Apache 、 アマゾンビーンズトーク 、 Google App Engine 、 その他。

正しい設定方法は、環境ごとに若干異なります。ボトルはWSGIインターフェースに準拠するオブジェクトを公開し、サーバーはこのオブジェクトと対話するように構成する必要があります。

サーバーの設定方法の詳細については、サーバーのドキュメントとボトルのドキュメントを参照してください。 ここに 。

データベース

ボトルはデータベースに依存せず、データがどこから来ているかを気にしません。アプリでデータベースを使用する場合は、 Python PackageIndex のようないくつかの興味深いオプションがあります SQLAlchemy 、 PyMongo 、 MongoEngine 、 CouchDB そして 投票 DynamoDBの場合。選択したデータベースで動作させるには、適切なアダプタのみが必要です。

ボトルフレームワークの基本

それでは、Bottleで基本的なアプリを作成する方法を見てみましょう。コード例では、Python> = 3.4と仮定します。ただし、ここで説明する内容のほとんどは、Python2.7でも機能します。

ボトルの基本的なアプリは次のようになります。

import bottle app = application = bottle.default_app() if __name__ == '__main__': bottle.run(host = '127.0.0.1', port = 8000)

基本と言えば、このプログラムは「HelloWorld」でさえありません。 (「HelloWorld?」と応答したRESTインターフェースに最後にアクセスしたのはいつですか?)127.0.0.1:8000へのすべてのHTTPリクエスト404 NotFound応答ステータスを受け取ります。

ボトルに入ったアプリ

ボトルにはアプリのインスタンスがいくつか作成されている場合がありますが、便宜上、最初のインスタンスが作成されます。これがデフォルトのアプリです。ボトルは、これらのインスタンスをモジュール内部のスタックに保持します。ボトルを使用して何か(アプリの実行やルートの添付など)を行い、話しているアプリを指定しない場合は常に、デフォルトのアプリを参照します。実際、app = application = bottle.default_app()この基本的なアプリにlineが存在する必要はありませんが、Gunicorn、uWSGI、または一般的なWSGIサーバーを使用してデフォルトのアプリを簡単に呼び出すことができるように存在します。

複数のアプリの可能性は最初は混乱しているように見えるかもしれませんが、Bottleに柔軟性を追加します。アプリケーションのさまざまなモジュールについて、他のボトルクラスをインスタンス化し、必要に応じてさまざまな構成でセットアップすることにより、特殊なボトルアプリを作成できます。これらのさまざまなアプリには、BottleのURLルーターを介してさまざまなURLからアクセスできます。このチュートリアルでは詳しく説明しませんが、Bottleのドキュメントをご覧になることをお勧めします。 ここに そして ここに 。

サーバーの呼び出し

スクリプトの最後の行は、指定されたサーバーを使用してBottleを実行します。ここの場合のようにサーバーが示されていない場合、デフォルトのサーバーはPythonの組み込みWSGI参照サーバーであり、開発目的にのみ適しています。次のように別のサーバーを使用できます。

bottle.run(server='gunicorn', host = '127.0.0.1', port = 8000)

これは、このスクリプトを実行してアプリを起動できるシンタックスシュガーです。たとえば、このファイルの名前がmain.pyの場合、python main.pyを実行するだけです。アプリを起動します。ボトルキャリー サーバーアダプタの非常に広範なリスト これはこのように使用できます。

一部のWSGIサーバーにはボトルアダプターがありません。これらは、サーバー独自の実行コマンドで開始できます。たとえば、uWSGIでは、uwsgiに電話するだけです。このような:

$ uwsgi --http :8000 --wsgi-file main.py

ファイル構造に関する注記

ボトルは、アプリのファイル構造を完全にあなたに任せます。ファイル構造ポリシーはプロジェクトごとに進化しますが、MVC哲学に基づいている傾向があります。

RESTAPIの構築

もちろん、要求されたURIごとに404を返すだけのサーバーは必要ありません。 REST APIを構築することを約束したので、それを実行しましょう。

あなたがしたいとします インターフェースを構築する 名前のセットを操作します。実際のアプリでは、おそらくこれにデータベースを使用しますが、この例では、インメモリsetを使用します。データ構造。

APIのスケルトンは次のようになります。このコードはプロジェクトのどこにでも配置できますが、api/names.pyなどの別のAPIファイルをお勧めします。

from bottle import request, response from bottle import post, get, put, delete _names = set() # the set of names @post('/names') def creation_handler(): '''Handles name creation''' pass @get('/names') def listing_handler(): '''Handles name listing''' pass @put('/names/') def update_handler(name): '''Handles name updates''' pass @delete('/names/') def delete_handler(name): '''Handles name deletions''' pass

ルーティング

ご覧のとおり、Bottleでのルーティングはデコレータを使用して行われます。インポートされたデコレータpost、get、put、およびdeleteこれらの4つのアクションのハンドラーを登録します。これらの作業を次のように分類する方法を理解します。

  • 上記のデコレータはすべて、default_appへのショートカットです。ルーティングデコレータ。たとえば、@get()デコレータが適用されますbottle.default_app().get()ハンドラーに。
  • default_appのルーティング方法route()のすべてのショートカットです。だからdefault_app().get('/') default_app().route(method='GET', '/')と同等です。

だから@get('/')は@route(method='GET', '/')と同じです。これは@bottle.default_app().route(method='GET', '/')と同じであり、これらは同じ意味で使用できます。

@routeに関する1つの役立つことデコレータは、たとえば、同じハンドラを使用してオブジェクトの更新と削除の両方を処理する場合、次のように処理するメソッドのリストを渡すことができます。

@route('/names/', method=['PUT', 'DELETE']) def update_delete_handler(name): '''Handles name updates and deletions''' pass

それでは、これらのハンドラーのいくつかを実装しましょう。

完璧なRESTAPIをBottleFrameworkで作成します。

RESTful APIは、最新のWeb開発の定番です。ボトルバックエンドを使用して、APIクライアントに強力な組み合わせを提供します。 つぶやき

POST:リソースの作成

POSTハンドラーは次のようになります。

import re, json namepattern = re.compile(r'^[a-zA-Zd]{1,64}$') @post('/names') def creation_handler(): '''Handles name creation''' try: # parse input data try: data = request.json() except: raise ValueError if data is None: raise ValueError # extract and validate name try: if namepattern.match(data['name']) is None: raise ValueError name = data['name'] except (TypeError, KeyError): raise ValueError # check for existence if name in _names: raise KeyError except ValueError: # if bad request data, return 400 Bad Request response.status = 400 return except KeyError: # if name already exists, return 409 Conflict response.status = 409 return # add name _names.add(name) # return 200 Success response.headers['Content-Type'] = 'application/json' return json.dumps({'name': name})

まあ、それはかなりたくさんです。これらの手順を少しずつ確認してみましょう。

ボディ解析

このAPIでは、ユーザーが「name」という名前の属性を持つJSON文字列を本文にPOSTする必要があります。

request bottleから以前にインポートされたオブジェクト常に現在のリクエストを指し、リクエストのすべてのデータを保持します。そのbody属性には、リクエスト本文のバイトストリームが含まれます。これには、ストリームオブジェクトを読み取ることができる任意の関数(ファイルの読み取りなど)からアクセスできます。

request.json()メソッドは、リクエストのヘッダーで「application / json」コンテンツタイプをチェックし、正しい場合は本文を解析します。 Bottleが不正な形式のボディ(例:空または間違ったコンテンツタイプ)を検出した場合、このメソッドはNoneを返します。したがって、ValueErrorを発生させます。不正な形式のJSONコンテンツがJSONパーサーによって検出された場合。これもまたValueErrorとしてキャッチしてリレイズするという例外を発生させます。

オブジェクトの解析と検証

エラーがない場合は、リクエストの本文をdataによって参照されるPythonオブジェクトに変換しました。変数。 「名前」キーが付いた辞書を受け取った場合は、data['name']からアクセスできます。このキーのない辞書を受け取った場合、それにアクセスしようとするとKeyErrorになります。例外。辞書以外のものを受け取った場合は、TypeErrorを受け取ります例外。これらのエラーのいずれかが発生した場合は、もう一度、ValueErrorとして再レイズし、入力が正しくないことを示します。

名前キーの形式が正しいかどうかを確認するには、namepatternなどの正規表現マスクに対してテストする必要があります。ここで作成したマスク。キーの場合name文字列ではありません、namepattern.match() TypeErrorを発生させ、一致しない場合はNoneを返します。

この例のマスクでは、名前は1〜64文字の空白のないASCII英数字である必要があります。これは単純な検証であり、たとえば、ガベージデータを含むオブジェクトをテストしません。より複雑で完全な検証は、次のようなツールを使用して実現できます。 FormEncode 。

存在のテスト

要求を満たす前の最後のテストは、指定された名前がセットにすでに存在するかどうかです。より構造化されたアプリでは、そのテストはおそらく専用モジュールによって実行され、特殊な例外を介してAPIに通知される必要がありますが、セットを直接操作しているため、ここで実行する必要があります。

KeyErrorを上げることで、名前の存在を知らせます。

エラー応答

リクエストオブジェクトがすべてのリクエストデータを保持するのと同じように、レスポンスオブジェクトもレスポンスデータに対して同じことを行います。応答ステータスを設定するには、次の2つの方法があります。

response.status = 400

そして:

response.status = '400 Bad Request'

この例では、より単純な形式を選択しましたが、2番目の形式を使用してエラーのテキストの説明を指定できます。内部的に、Bottleは2番目の文字列を分割し、数値コードを適切に設定します。

成功への対応

すべてのステップが成功した場合、セット_namesに名前を追加し、Content-Typeを設定することで、リクエストを実行します。応答ヘッダー、および応答を返します。関数によって返される文字列はすべて、200 Successの応答本文として扱われます。応答なので、json.dumpsで単純に生成します。

GET:リソースリスト

名前の作成から進んで、名前リストハンドラーを実装します。

@get('/names') def listing_handler(): '''Handles name listing''' response.headers['Content-Type'] = 'application/json' response.headers['Cache-Control'] = 'no-cache' return json.dumps({'names': list(_names)})

名前をリストするのはずっと簡単でしたね。名前の作成と比較して、ここで行うことはあまりありません。いくつかの応答ヘッダーを設定し、すべての名前のJSON表現を返すだけで、完了です。

PUT:リソースの更新

それでは、updateメソッドを実装する方法を見てみましょう。 createメソッドと大差ありませんが、この例を使用してURIパラメータを導入します。

@put('/names/') def update_handler(name): '''Handles name updates''' try: # parse input data try: data = json.load(utf8reader(request.body)) except: raise ValueError # extract and validate new name try: if namepattern.match(data['name']) is None: raise ValueError newname = data['name'] except (TypeError, KeyError): raise ValueError # check if updated name exists if oldname not in _names: raise KeyError(404) # check if new name exists if name in _names: raise KeyError(409) except ValueError: response.status = 400 return except KeyError as e: response.status = e.args[0] return # add new name and remove old name _names.remove(oldname) _names.add(newname) # return 200 Success response.headers['Content-Type'] = 'application/json' return json.dumps({'name': newname})

更新アクションの本体スキーマは作成アクションの場合と同じですが、新しいoldnameもあります。ルート@put('/names/')で定義されているURIのパラメーター。

Googleはどのバージョン管理を使用しますか

URIパラメータ

ご覧のとおり、URIパラメータのBottleの表記は非常に簡単です。必要な数のパラメーターを使用してURIを作成できます。ボトルはそれらをURIから自動的に抽出し、リクエストハンドラーに渡します。

@get('//') def handler(param1, param2): pass

カスケードルートデコレータを使用して、オプションのパラメータを使用してURIを作成できます。

@get('/') @get('//') def handler(param1, param2 = None) pass

また、Bottleでは、URIで次のルーティングフィルターを使用できます。

  • int

intに変換される可能性のあるパラメーターのみに一致し、変換された値をハンドラーに渡します。

@get('/') def handler(param): pass
  • float

intと同じですが、浮動小数点値があります。

@get('/') def handler(param): pass
  • re (正規表現)

指定された正規表現に一致するパラメーターのみに一致します。

@get('/') def handler(param): pass
  • path

柔軟な方法でURIパスのサブセグメントを照合します。

@get('//id>') def handler(param): pass

一致:

  • /x/id、合格x paramとして。
  • /x/y/id、合格x/y paramとして。

削除:リソースの削除

GETメソッドと同様に、DELETEメソッドはほとんどニュースをもたらしません。 Noneを返すことに注意してくださいステータスを設定しないと、本文が空でステータスコードが200の応答が返されます。

@delete('/names/') def delete_handler(name): '''Handles name updates''' try: # Check if name exists if name not in _names: raise KeyError except KeyError: response.status = 404 return # Remove name _names.remove(name) return

最終ステップ:APIのアクティブ化

名前APIをapi/names.pyとして保存したとします。 、メインアプリケーションファイルmain.pyでこれらのルートを有効にできるようになりました。

import bottle from api import names app = application = bottle.default_app() if __name__ == '__main__': bottle.run(host = '127.0.0.1', port = 8000)

namesのみをインポートしたことに注意してくださいモジュール。すべてのメソッドをデフォルトのアプリにアタッチされたURIで装飾しているため、これ以上設定する必要はありません。私たちのメソッドはすでに配置されており、アクセスする準備ができています。

よくできたRESTAPIほどフロントエンドを満足させるものはありません。チャームのように機能します!

CurlやPostmanなどのツールを使用してAPIを使用し、手動でテストできます。 (Curlを使用している場合は、 JSONフォーマッター 応答がすっきりと見えるようにします。)

ボーナス:クロスオリジンリソースシェアリング(CORS)

REST APIを構築する一般的な理由の1つは、AJAXを介してJavaScriptフロントエンドと通信することです。一部のアプリケーションでは、これらのリクエストは、APIのホームドメインだけでなく、任意のドメインからの送信を許可する必要があります。デフォルトでは、ほとんどのブラウザはこの動作を許可していないので、設定方法を紹介します クロスオリジンリソースシェアリング(CORS) これを可能にするためにボトルで:

from bottle import hook, route, response _allow_origin = '*' _allow_methods = 'PUT, GET, POST, DELETE, OPTIONS' _allow_headers = 'Authorization, Origin, Accept, Content-Type, X-Requested-With' @hook('after_request') def enable_cors(): '''Add headers to enable CORS''' response.headers['Access-Control-Allow-Origin'] = _allow_origin response.headers['Access-Control-Allow-Methods'] = _allow_methods response.headers['Access-Control-Allow-Headers'] = _allow_headers @route('/', method = 'OPTIONS') @route('/', method = 'OPTIONS') def options_handler(path = None): return

hookデコレータを使用すると、各リクエストの前後に関数を呼び出すことができます。この場合、CORSを有効にするには、Access-Control-Allow-Origin、-Allow-Methodsを設定する必要があります。および-Allow-Headers各応答のヘッダー。これらは、指定されたリクエストを処理することをリクエスターに示します。

また、クライアントはサーバーに対してOPTIONS HTTP要求を行って、他の方法で実際に要求を行うことができるかどうかを確認する場合があります。このサンプルのキャッチオールの例では、200のステータスコードと空の本文ですべてのOPTIONSリクエストに応答します。

これを有効にするには、保存してメインモジュールからインポートするだけです。

要約

これですべてです。

このチュートリアルでは、BottleWebフレームワークを使用してPythonアプリ用のRESTAPIを作成するための基本的な手順について説明しました。

この小さいながらも強力なフレームワークについての知識を深めるには、 チュートリアル そして APIリファレンスドキュメント 。

関連: Node.js / TypeScript REST APIの構築、パート1:Express.js

なぜより多くの起業家が新しい会社ではなくサーチファンドを作ることを選んでいるのですか?

財務プロセス

なぜより多くの起業家が新しい会社ではなくサーチファンドを作ることを選んでいるのですか?
UXにおける色の役割

UXにおける色の役割

Uxデザイン

人気の投稿
シニアコーポレートカウンセル
シニアコーポレートカウンセル
エンタープライズクライアントサービスディレクター、産業用製品およびサービス
エンタープライズクライアントサービスディレクター、産業用製品およびサービス
フリーランスのファイナンスコンサルタントが大企業をどのように打ち負かしているか
フリーランスのファイナンスコンサルタントが大企業をどのように打ち負かしているか
あなたのスキルを披露する–ポートフォリオを作成する方法
あなたのスキルを披露する–ポートフォリオを作成する方法
Reactフックをテストするための完全ガイド
Reactフックをテストするための完全ガイド
 
かんばんとTrelloを使用してソフトウェア開発を管理するための初心者向けガイド
かんばんとTrelloを使用してソフトウェア開発を管理するための初心者向けガイド
生存のための再編成:シナリオの構築
生存のための再編成:シナリオの構築
Android開発のためのReactNativeに飛び込む
Android開発のためのReactNativeに飛び込む
安全で健全–パスワードUXへのアプローチ方法
安全で健全–パスワードUXへのアプローチ方法
.NETプロジェクトをブートストラップして作成する方法
.NETプロジェクトをブートストラップして作成する方法
人気の投稿
  • C ++のヘッダーファイル
  • アカウント設計のベストプラクティスチャート
  • 需要の価格弾力性は
  • 新しい演算子を使用するときはいつでも、
  • ネット用のユニットテストツール
  • パートナーシップまたは法人として課税されることを選択できるLLC。
カテゴリー
ツールとチュートリアル モバイルデザイン 設計プロセス 投資家と資金調達 バックエンド Kpiと分析 人とチーム 製品の担当者とチーム モバイル 革新

© 2021 | 全著作権所有

apeescape2.com