microdot --- 最小限のHTTPフレームワーク¶
Microdotは、MicroPython向けの小さなFlaskにインスパイアされたHTTPフレームワークです。asyncio の上で動作し、スレッドを使わずに複数の同時クライアントを処理し、おなじみのルートデコレータAPIを公開します。最小限のアプリケーションは次のようになります:
from microdot import Microdot
app = Microdot()
@app.route('/')
async def index(request):
return 'Hello, world!'
app.run(host='0.0.0.0', port=80)
class Microdot¶
- class microdot.Microdot¶
HTTPアプリケーションのインスタンスです。スクリプトの先頭付近で1つのインスタンスを構築し、ルートハンドラでデコレートします。
run()を呼び出すかstart_server()をawaitすると、サービスの提供が始まります。ルートの登録
- route(url_pattern: str, methods: list | None = None) Callable¶
url_pattern に対して、指定されたHTTPメソッド(デフォルトは
['GET'])でハンドラを登録するデコレータです。関数に適用されると、その関数をハンドラとして登録し、関数をそのまま返すデコレータを返します。- url_pattern
パスのパターンです。静的なセグメント(
/users)と、</>で囲まれた動的なセグメントをサポートします。動的なセグメントは、:で区切ったオプションの型プレフィックスを受け付けます --<int:id>、<path:rest>、<re:[0-9a-f]+:hex>。デフォルトの型はstringです。- methods
HTTPメソッド名のリストです。省略した場合は
GETのみがマッチします。
ハンドラは、まずリクエストオブジェクトとともに呼び出され、続いてキャプチャされた動的セグメントがキーワード引数として渡されます。ハンドラの戻り値がHTTPレスポンスになります。すなわち
Response、文字列、タプル(body, status_code[, headers])、または辞書 / リスト(JSONとして送信)です。
- get(url_pattern: str) Callable¶
route(url_pattern, methods=['GET'])の便利なエイリアスです -- デコレートした関数を url_pattern のGETハンドラとして登録します。デコレータを返します。
- post(url_pattern: str) Callable¶
route(url_pattern, methods=['POST'])の便利なエイリアスです -- デコレートした関数を url_pattern のPOSTハンドラとして登録します。デコレータを返します。
- put(url_pattern: str) Callable¶
route(url_pattern, methods=['PUT'])の便利なエイリアスです -- デコレートした関数を url_pattern のPUTハンドラとして登録します。デコレータを返します。
- patch(url_pattern: str) Callable¶
route(url_pattern, methods=['PATCH'])の便利なエイリアスです -- デコレートした関数を url_pattern のPATCHハンドラとして登録します。デコレータを返します。
- delete(url_pattern: str) Callable¶
route(url_pattern, methods=['DELETE'])の便利なエイリアスです -- デコレートした関数を url_pattern のDELETEハンドラとして登録します。デコレータを返します。
ライフサイクルフック
- before_request(f: Callable) Callable¶
すべてのリクエストの前に実行する f を登録するデコレータです。f はリクエストオブジェクトを受け取り、その戻り値は通常は無視されます。リクエストをショートサーキットするには、
Response(またはそれに変換される値)を返します -- そうするとパイプラインの残りはスキップされ、そのレスポンスが送信されます。f をそのまま返します。
- after_request(f: Callable) Callable¶
成功したすべてのリクエストの後に実行する f を登録するデコレータです。f は
(request, response)を受け取り、(場合によっては変更された)レスポンスオブジェクトを返さなければなりません。f をそのまま返します。
- after_error_request(f: Callable) Callable¶
Microdotがエラーレスポンス(404、500、発生した例外など)を生成した後に実行する f を登録するデコレータです。f は
(request, response)を受け取り、(場合によっては変更された)レスポンスオブジェクトを返さなければなりません。f をそのまま返します。
- errorhandler(status_code_or_exception_class) Callable¶
HTTPステータスコードまたはPython例外クラスに対するカスタムハンドラを登録するデコレータです。ステータスコードの場合、ハンドラはリクエストのみを受け取ります。例外クラスの場合は
(request, exception)を受け取ります。デコレータを返します。
マウントと中断
- mount(subapp: Microdot, url_prefix: str = '', local: bool = False) None¶
別の
Microdotインスタンスのルートを url_prefix の下にアタッチします。local がFalse(デフォルト)の場合、サブアプリのbefore / after / errorハンドラも親にアタッチされます。Trueの場合、それらのハンドラはサブアプリのルートに対してのみ実行されます。Noneを返します。
- static abort(status_code: int, reason: str | None = None) None¶
HTTPExceptionを発生させ、指定したステータスコードで現在のリクエストを中断します。通常どおりに戻ることはありません -- フレームワークが例外をキャッチし、対応するエラーレスポンスに変換します。ルート本体の中で便利です:from microdot import abort @app.get('/users/<int:id>') def get_user(request, id): user = lookup(id) if user is None: abort(404) return user.to_dict()
サーバーの実行
- run(host: str = '0.0.0.0', port: int = 5000, debug: bool = False, ssl=None) None¶
呼び出し元のスレッドをブロックし、
start_server()に対してasyncio.run()を実行します。shutdown()が呼び出されてリスニングループが終了した後にのみNoneを返します。スタンドアロンアプリを起動する最も簡単な方法です:app.run(host='0.0.0.0', port=80)
- async start_server(host: str = '0.0.0.0', port: int = 5000, debug: bool = False, ssl=None, start_serving: bool = True) None¶
サーバーをコルーチンとして起動します。他のタスクとともに既存の
asyncioイベントループに統合する場合に使用します。このコルーチンはshutdown()が呼び出されるまで戻りません:async def main(): await asyncio.gather( app.start_server(port=80), capture_loop(), )
- host
リッスンするネットワークインターフェイスです。
'0.0.0.0'(デフォルト)はすべてのインターフェイスを意味し、'127.0.0.1'はループバックのみを意味します。- port
リッスンするTCPポートです。デフォルトは
5000-- プレーンHTTPには80、HTTPSには443を選びます。- debug
Trueの場合、すべてのリクエストをログに記録し、トレースバックを標準出力にダンプします。- ssl
受信接続をTLSでラップするための
ssl.SSLContextです。None(デフォルト)はプレーンHTTPを意味します。- start_serving
CPythonでのみ関係します。MicroPythonでは無視されます。
- shutdown() None¶
サーバーの正常なシャットダウンを要求します。ルートハンドラから呼び出しても安全です -- ループが終了する前に現在のリクエストが完了します。すぐに戻ります。実際のシャットダウンは処理中のリクエストが完了した後に発生します。
属性
- before_request_handlers: list¶
before_request()で登録された呼び出し可能オブジェクトのリストで、登録順に並びます。それぞれがルートハンドラの前にリクエストオブジェクトとともに実行されます。このリストを直接変更することもできますが、ほとんど必要ありません -- デコレータの使用を推奨します。
- after_request_handlers: list¶
after_request()で登録された呼び出し可能オブジェクトのリストで、登録順に並びます。それぞれが成功したリクエストの後に(request, response)とともに実行され、(場合によっては変更された)レスポンスを返さなければなりません。
- after_error_request_handlers: list¶
after_error_request()で登録された呼び出し可能オブジェクトのリストで、登録順に並びます。それぞれが(フレームワークまたはアプリケーションのエラーハンドラによって)エラーレスポンスが生成された後に(request, response)とともに実行され、レスポンスを返さなければなりません。
- error_handlers: dict¶
errorhandler()によって設定される、エラーキーからハンドラ呼び出し可能オブジェクトへのマッピングです。キーはHTTPステータスコード(int)またはPython例外クラスのいずれかで、値は登録されたハンドラです。ステータスコードのハンドラは(request)を受け取り、例外クラスのハンドラは(request, exception)を受け取ります。
class Request¶
- class microdot.Request¶
受信したHTTPリクエストです。インスタンスは最初の位置引数としてルートハンドラに渡されます。アプリケーションが
Requestを直接構築することはありません。クラス属性
- max_body_length: int¶
メモリにバッファされ、
bodyを介して公開される本文の最大サイズです。これより大きい本文(max_content_lengthまで)はソケット上に残り、streamを介して読み取る必要があります。デフォルトは16KBです。
インスタンス属性
- headers: NoCaseDict¶
リクエストヘッダーで、
NoCaseDict(大文字小文字を区別しない検索)として格納されます。
- g: object¶
リクエストごとの自由形式のコンテナ(裸のオブジェクト)です。これに属性を割り当てることで、フック間やハンドラ間で値を受け渡すことができます(
request.g.user = ...)。
- route: Callable¶
このリクエストにマッチしたハンドラ関数です。
本文へのアクセス
- stream: object¶
本文に対する
read()を公開する非同期ストリームオブジェクトです。max_body_lengthより大きい本文にはこれを使用します。
- json: dict | list | str | int | float | bool | None¶
JSONとして解析された本文(
dict、list、str、int、float、bool-- ペイロードがエンコードするもの)、またはContent-Typeがapplication/jsonでない場合はNoneです。
- form: MultiDict | None¶
URLエンコードされたフォームフィールドで、
MultiDict、またはNoneです。multipart/form-dataの場合は、ルートをmicrodot.multipart.with_form_data()でデコレートします。
- files: dict | None¶
アップロードされたファイルで、
{name: FileUpload}として、microdot.multipart.with_form_data()によって設定されます。そのデコレータが実行されるまではNoneです。
- after_request(f: Callable) Callable¶
リクエストローカルなafter-requestフックを登録します -- アプリケーションレベルのafter-requestハンドラの後、成功時のみ実行されます。f は
(request, response)を受け取り、(場合によっては変更された)レスポンスオブジェクトを返さなければなりません。f をそのまま返します。
class Response¶
- class microdot.Response(body=b'', status_code: int = 200, headers: dict | None = None, reason: str | None = None)¶
HTTPレスポンスです。ほとんどのハンドラは、Microdotが自動的に
Responseに変換する値を返します。カスタムヘッダーや特定のステータスコードが必要な場合は、直接構築します。- body
レスポンス本文です。
strはUTF-8でエンコードされ、dict/listはJSONでエンコードされてContent-Typeがそれに応じて設定され、bytesはそのまま送信され、ファイルライクオブジェクトや非同期ジェネレータはストリーミングされます。- status_code
数値のHTTPステータスです。デフォルトは200です。
- headers
レスポンスヘッダーの辞書です(大文字小文字を区別しません)。
- reason
カスタムの理由フレーズです。200の場合は
"OK"、それ以外の場合は"N/A"がデフォルトです。
クラス属性
- default_send_file_max_age: int | None¶
max_ageが指定されていない場合にsend_file()で使用されるCache-Control: max-ageの値です。None(デフォルト)はCache-Controlヘッダーがないことを意味します。
- send_file_buffer_size: int¶
send_file()のストリーミングのチャンクサイズです。デフォルトは1024です。
- already_handled: None¶
レスポンスをすでに直接書き込んだハンドラから返されるセンチネルです(WebSocketアップグレードで使用)。常に
Noneであり、重要なのはその同一性です。
- types_map: dict¶
send_file()がコンテンツタイプの推論に使用する、拡張子からMIMEタイプへのマップです。css、gif、html、jpg、js、json、png、txt、svgをマッピングします。
メソッド
- set_cookie(cookie: str, value: str, path: str | None = None, domain: str | None = None, expires=None, max_age: int | None = None, secure: bool = False, http_only: bool = False, partitioned: bool = False) None¶
Set-Cookieヘッダーを追加します。expires は事前にフォーマットされた文字列、またはtimetuple()を持つdatetimeライクなオブジェクトです。Noneを返します。ヘッダーはこのレスポンスにその場で追加されます。
- delete_cookie(cookie: str, **kwargs) None¶
指定したクッキーをただちに期限切れにする
Set-Cookieを設定します。kwargsはset_cookie()と同じオプション(path、domain、secure、http_only、partitioned)を受け付けます。expiresとmax_ageは無視されます。Noneを返します。ヘッダーはこのレスポンスにその場で追加されます。
- classmethod redirect(location: str, status_code: int = 302) Response¶
リダイレクトレスポンスを返します:
@app.get('/old') def old(request): return Response.redirect('/new')
- classmethod send_file(filename: str, status_code: int = 200, content_type: str | None = None, stream=None, max_age: int | None = None, compressed: bool | str = False, file_extension: str = '') Response¶
ファイルシステムからファイルをレスポンス本文としてストリーミングします。
content_typeが指定されていない場合は、types_mapを介して拡張子から推論されます。compressed=TrueはContent-Encoding: gzipを設定します(ファイルはすでに圧縮されている必要があります)。警告
filename は直接開かれます。サニタイズされていないユーザー提供のパスを決して渡さないでください -- そうすると任意のファイルの漏洩を許してしまいます。
例外¶
class URLPattern¶
- class microdot.URLPattern(url_pattern: str)¶
ルートのURLパターンをコンパイルした形式です。
Microdot.route()によって自動的に構築されます。アプリケーションが直接インスタンス化することはほとんどありません。- classmethod register_type(type_name: str, pattern: str = '[^/]+', parser: Callable | None = None) None¶
ルートパターンで使用する新しい動的セグメント型を登録します。
Noneを返します。型はクラスレベルの型レジストリに追加されます。例えば<uuid:...>型を追加するには:URLPattern.register_type('uuid', '[0-9a-f-]{36}')parser はオプションの呼び出し可能オブジェクトで、キャプチャされた文字列をハンドラに到達する前に変換します。
ヘルパークラス¶
- class microdot.MultiDict(initial_dict: dict | None = None)¶
キーごとに複数の値を格納するdictのサブクラスです。同じキーが複数回現れることがあるクエリ文字列やURLエンコードされたフォーム本文(
?tag=a&tag=b)に使用されます。
- class microdot.NoCaseDict¶
大文字小文字を区別しない文字列キーを持つdictのサブクラスです。
Request.headersとResponse.headersに使用されます。
モジュールレベルの関数¶
- microdot.abort(status_code: int, reason: str | None = None) None¶
Microdot.abort()のショートカットです。通常どおりに戻ることはありません --HTTPExceptionを発生させます。from microdot import abortとしてインポートできます。
- microdot.redirect(location: str, status_code: int = 302) Response¶
Response.redirect()のショートカットです。from microdot import redirectとしてインポートできます。
- microdot.send_file(filename: str, **kwargs) Response¶
Response.send_file()のショートカットです。
- microdot.urlencode(s: str) str¶
URLコンポーネントをパーセントエンコードします。URL内で予約された意味を持つ文字(
/、?、&、=、#、スペースなど)を%xxの16進エスケープに置き換え、結果をパスセグメントやクエリ値の中に安全に配置できるようにします。エンコードされたstrを返します。
- microdot.urldecode(s: str) str¶
URLコンポーネントをパーセントデコードします --
urlencode()の逆です。%xxエスケープはそれがエンコードするバイトに置き換えられ、+はスペースに変換されます(歴史的なクエリ文字列の慣習)。デコードされたstrを返します。