microdot --- kerangka kerja HTTP minimal

Microdot adalah kerangka kerja HTTP kecil yang terinspirasi dari Flask untuk MicroPython. Berjalan di atas asyncio, menangani beberapa klien secara bersamaan tanpa thread, dan menyajikan API dekorator route yang familiar. Contoh aplikasi minimal terlihat seperti:

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

Sebuah instans aplikasi HTTP. Satu instans dibuat di bagian atas skrip dan didekorasi dengan handler route; memanggil run() atau menunggu start_server() memulai proses serving.

Pendaftaran route

route(url_pattern: str, methods: list | None = None) Callable

Dekorator yang mendaftarkan handler untuk url_pattern di bawah metode HTTP yang tercantum (default ['GET']). Mengembalikan dekorator yang, ketika diterapkan pada fungsi, mendaftarkannya sebagai handler dan mengembalikan fungsi tersebut tanpa perubahan.

url_pattern

Pola path. Mendukung segmen statis (/users) dan segmen dinamis yang diapit < / >. Segmen dinamis menerima awalan tipe opsional yang dipisahkan oleh : -- <int:id>, <path:rest>, <re:[0-9a-f]+:hex>. Tipe default adalah string.

methods

Daftar nama metode HTTP. Jika dihilangkan, hanya GET yang dicocokkan.

Handler dipanggil dengan objek request sebagai argumen pertama, lalu segmen dinamis yang ditangkap sebagai argumen kata kunci. Nilai kembalian handler menjadi respons HTTP: sebuah Response, string, tuple (body, status_code[, headers]), atau dict / list (dikirim sebagai JSON).

get(url_pattern: str) Callable

Alias praktis untuk route(url_pattern, methods=['GET']) -- mendaftarkan fungsi yang didekorasi sebagai handler GET untuk url_pattern. Mengembalikan dekorator.

post(url_pattern: str) Callable

Alias praktis untuk route(url_pattern, methods=['POST']) -- mendaftarkan fungsi yang didekorasi sebagai handler POST untuk url_pattern. Mengembalikan dekorator.

put(url_pattern: str) Callable

Alias praktis untuk route(url_pattern, methods=['PUT']) -- mendaftarkan fungsi yang didekorasi sebagai handler PUT untuk url_pattern. Mengembalikan dekorator.

patch(url_pattern: str) Callable

Alias praktis untuk route(url_pattern, methods=['PATCH']) -- mendaftarkan fungsi yang didekorasi sebagai handler PATCH untuk url_pattern. Mengembalikan dekorator.

delete(url_pattern: str) Callable

Alias praktis untuk route(url_pattern, methods=['DELETE']) -- mendaftarkan fungsi yang didekorasi sebagai handler DELETE untuk url_pattern. Mengembalikan dekorator.

Hook siklus hidup

before_request(f: Callable) Callable

Dekorator yang mendaftarkan f untuk dijalankan sebelum setiap request. f menerima objek request; nilai kembaliannya biasanya diabaikan. Untuk memutus alur request, kembalikan sebuah Response (atau nilai yang dapat dikonversi menjadi satu) -- sisa pipeline kemudian dilewati dan respons tersebut dikirim. Mengembalikan f tanpa perubahan.

after_request(f: Callable) Callable

Dekorator yang mendaftarkan f untuk dijalankan setelah setiap request berhasil. f menerima (request, response) dan harus mengembalikan objek respons (yang mungkin sudah dimodifikasi). Mengembalikan f tanpa perubahan.

after_error_request(f: Callable) Callable

Dekorator yang mendaftarkan f untuk dijalankan setelah Microdot menghasilkan respons error (404, 500, pengecualian yang dipicu, dll.). f menerima (request, response) dan harus mengembalikan objek respons (yang mungkin sudah dimodifikasi). Mengembalikan f tanpa perubahan.

errorhandler(status_code_or_exception_class) Callable

Dekorator yang mendaftarkan handler kustom untuk kode status HTTP atau kelas pengecualian Python. Untuk kode status, handler hanya menerima request; untuk kelas pengecualian, (request, exception). Mengembalikan dekorator.

Mounting dan abort

mount(subapp: Microdot, url_prefix: str = '', local: bool = False) None

Lampirkan route instans Microdot lain di bawah url_prefix. Ketika local adalah False (default), handler before / after / error sub-app juga dilampirkan ke parent. Ketika True, handler tersebut hanya berjalan untuk route sub-app. Mengembalikan None.

static abort(status_code: int, reason: str | None = None) None

Picu HTTPException untuk membatalkan request saat ini dengan kode status yang diberikan. Tidak pernah kembali secara normal -- kerangka kerja menangkap pengecualian dan mengubahnya menjadi respons error yang sesuai. Berguna di dalam body route:

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()

Menjalankan server

run(host: str = '0.0.0.0', port: int = 5000, debug: bool = False, ssl=None) None

Blokir thread yang memanggil, jalankan asyncio.run() pada start_server(). Mengembalikan None hanya setelah shutdown() dipanggil dan loop listening keluar. Cara paling sederhana untuk meluncurkan aplikasi mandiri:

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

Mulai server sebagai coroutine. Gunakan ini saat mengintegrasikan dengan event loop asyncio yang sudah ada bersama task lain. Coroutine tidak kembali sampai shutdown() dipanggil:

async def main():
    await asyncio.gather(
        app.start_server(port=80),
        capture_loop(),
    )
host

Antarmuka jaringan yang akan didengarkan. '0.0.0.0' (default) berarti semua antarmuka; '127.0.0.1' berarti hanya loopback.

port

Port TCP yang akan didengarkan. Default 5000 -- pilih 80 untuk HTTP biasa, 443 untuk HTTPS.

debug

Jika True, catat setiap request dan tampilkan traceback ke stdout.

ssl

Sebuah ssl.SSLContext untuk membungkus koneksi masuk dalam TLS. None (default) berarti HTTP biasa.

start_serving

Hanya relevan pada CPython; diabaikan pada MicroPython.

shutdown() None

Minta shutdown server yang graceful. Aman untuk dipanggil dari handler route -- request saat ini selesai sebelum loop keluar. Mengembalikan segera; shutdown sebenarnya terjadi setelah request yang sedang berjalan selesai.

Atribut

url_map: list

Daftar route yang terdaftar sebagai tuple (methods, URLPattern, handler, url_prefix, subapp).

before_request_handlers: list

Daftar callable yang terdaftar dengan before_request(), sesuai urutan pendaftaran. Setiap callable dijalankan dengan objek request sebelum handler route. Mengubah daftar secara langsung bisa dilakukan tetapi jarang diperlukan -- lebih disarankan menggunakan dekorator.

after_request_handlers: list

Daftar callable yang terdaftar dengan after_request(), sesuai urutan pendaftaran. Setiap callable dijalankan dengan (request, response) setelah request berhasil dan harus mengembalikan respons (yang mungkin sudah dimodifikasi).

after_error_request_handlers: list

Daftar callable yang terdaftar dengan after_error_request(), sesuai urutan pendaftaran. Setiap callable dijalankan dengan (request, response) setelah respons error dihasilkan (oleh kerangka kerja atau oleh handler error aplikasi) dan harus mengembalikan respons.

error_handlers: dict

Pemetaan kunci error ke callable handler, diisi oleh errorhandler(). Kunci adalah kode status HTTP (int) atau kelas pengecualian Python; nilainya adalah handler yang terdaftar. Handler kode status menerima (request); handler kelas pengecualian menerima (request, exception).

debug: bool

True selama server berjalan dengan debug=True.

class Request

class microdot.Request

Request HTTP yang masuk. Instans diteruskan ke handler route sebagai argumen posisional pertama. Aplikasi tidak membuat Request secara langsung.

Atribut kelas

max_content_length: int

Tolak request yang Content-Length-nya melebihi jumlah byte ini dengan respons 413. Default 16 KB.

max_body_length: int

Body terbesar yang di-buffer ke memori dan diekspos melalui body. Body yang lebih besar (hingga max_content_length) tetap di socket dan harus dibaca melalui stream. Default 16 KB.

max_readline: int

Panjang maksimum baris request / baris header tunggal dalam byte. Default 2 KB.

Atribut instans

app: Microdot

Instans Microdot yang menangani request.

client_addr: tuple

Alamat klien sebagai (host, port).

method: str

String metode HTTP ('GET', 'POST', ...).

scheme: str

'http' atau 'https'.

url: str

URL path dan query string request lengkap (semua yang ada setelah host).

path: str

Hanya bagian path.

query_string: str | None

Bagian query string mentah, atau None.

args: MultiDict

Query string yang sudah diurai sebagai MultiDict.

headers: NoCaseDict

Header request sebagai NoCaseDict (pencarian tidak peka huruf besar-kecil).

cookies: dict

Header Cookie yang sudah diurai sebagai dict.

content_length: int

Nilai integer Content-Length, atau 0 jika tidak ada.

content_type: str | None

Nilai header Content-Type, atau None.

g: object

Wadah per-request berbentuk bebas (objek kosong). Tetapkan atribut padanya untuk meneruskan nilai antara hook dan handler (request.g.user = ...).

route: Callable

Fungsi handler yang cocok dengan request ini.

url_prefix: str

Prefix tempat route di-mount, atau ''.

subapp: Microdot | None

Instans sub-app yang di-mount, atau None.

Akses body

body: bytes

Body request lengkap sebagai bytes. Kosong ketika body sedang di-stream (lihat stream).

stream: object

Objek stream async yang mengekspos read() atas body. Gunakan ini untuk body yang lebih besar dari max_body_length.

json: dict | list | str | int | float | bool | None

Body yang diurai sebagai JSON (dict, list, str, int, float, atau bool -- apapun yang dikodekan oleh payload), atau None jika Content-Type bukan application/json.

form: MultiDict | None

Field form yang dikodekan URL sebagai MultiDict, atau None. Untuk multipart/form-data, dekorasi route dengan microdot.multipart.with_form_data().

files: dict | None

File yang diunggah sebagai {name: FileUpload}, diisi oleh microdot.multipart.with_form_data(). None sampai dekorator tersebut berjalan.

after_request(f: Callable) Callable

Daftarkan hook after-request lokal untuk request -- dijalankan setelah handler after-request level aplikasi, hanya pada keberhasilan. f menerima (request, response) dan harus mengembalikan objek respons (yang mungkin sudah dimodifikasi). Mengembalikan f tanpa perubahan.

class Response

class microdot.Response(body=b'', status_code: int = 200, headers: dict | None = None, reason: str | None = None)

Respons HTTP. Sebagian besar handler mengembalikan nilai yang Microdot konversi ke Response secara otomatis; buat satu secara langsung ketika Anda membutuhkan header kustom atau kode status tertentu.

body

Body respons. str dikodekan UTF-8; dict / list dikodekan JSON dan Content-Type diset sesuai; bytes dikirim apa adanya; objek seperti file atau async generator di-stream.

status_code

Status HTTP numerik. Default 200.

headers

Dict header respons (tidak peka huruf besar-kecil).

reason

Frasa alasan kustom. Default ke "OK" untuk 200 dan "N/A" selainnya.

Atribut kelas

default_content_type: str

Content-Type yang digunakan ketika tidak ada yang diset secara eksplisit. Default 'text/plain'.

default_send_file_max_age: int | None

Nilai Cache-Control: max-age untuk send_file() ketika max_age tidak diberikan. None (default) berarti tidak ada header Cache-Control.

send_file_buffer_size: int

Ukuran chunk untuk streaming send_file(). Default 1024.

already_handled: None

Sentinel yang dikembalikan dari handler yang sudah menulis respons secara langsung (digunakan oleh upgrade WebSocket). Selalu None; identitasnya yang penting.

types_map: dict

Peta ekstensi-ke-tipe-mime yang digunakan oleh send_file() untuk inferensi content-type. Memetakan css, gif, html, jpg, js, json, png, txt, svg.

Metode

Tambahkan header Set-Cookie. expires bisa berupa string yang sudah diformat atau objek seperti datetime dengan timetuple(). Mengembalikan None; header ditambahkan ke respons ini di tempat.

Set Set-Cookie yang segera mendaluarsakan cookie yang diberikan. kwargs menerima opsi yang sama seperti set_cookie() (path, domain, secure, http_only, partitioned); expires dan max_age diabaikan. Mengembalikan None; header ditambahkan ke respons ini di tempat.

classmethod redirect(location: str, status_code: int = 302) Response

Kembalikan respons redirect:

@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

Stream file dari filesystem sebagai body respons. content_type disimpulkan dari ekstensi melalui types_map jika tidak diberikan. compressed=True menetapkan Content-Encoding: gzip (file harus sudah dikompres).

Peringatan

filename dibuka secara langsung. Jangan pernah meneruskan path yang disediakan pengguna tanpa sanitasi -- melakukan hal ini memungkinkan pengungkapan file sembarang.

Pengecualian

exception microdot.HTTPException

Dipicu oleh abort() untuk memutus request dengan kode status tertentu. Microdot menangkap ini dan mengubahnya menjadi respons error yang sesuai.

status_code: int

Kode status HTTP numerik yang akan dikembalikan -- nilai yang diteruskan ke abort().

reason: str

Frasa alasan yang disertakan dalam respons error. Jika tidak diberikan ke abort(), defaultnya adalah "<status_code> error" (mis. "404 error").

class URLPattern

class microdot.URLPattern(url_pattern: str)

Bentuk terkompilasi dari pola URL route. Dibuat secara otomatis oleh Microdot.route(); aplikasi jarang membuat instans secara langsung.

classmethod register_type(type_name: str, pattern: str = '[^/]+', parser: Callable | None = None) None

Daftarkan tipe segmen dinamis baru untuk digunakan dalam pola route. Mengembalikan None; tipe ditambahkan ke registry tipe level kelas. Misalnya untuk menambahkan tipe <uuid:...>

URLPattern.register_type('uuid', '[0-9a-f-]{36}')

parser adalah callable opsional yang mengonversi string yang ditangkap sebelum mencapai handler.

match(path: str) dict | None

Cocokkan path dengan pola dan kembalikan dict grup yang ditangkap, atau None jika tidak ada kecocokan.

Kelas pembantu

class microdot.MultiDict(initial_dict: dict | None = None)

Subkelas dict yang menyimpan beberapa nilai per kunci. Digunakan untuk query string dan body form yang dikodekan URL di mana kunci yang sama dapat muncul lebih dari sekali (?tag=a&tag=b).

get(key, default=None, type: Callable | None = None)

Kembalikan nilai pertama untuk key, dengan konversi opsional menggunakan type (sebuah callable). Mengembalikan default jika kunci tidak ada atau konversi gagal; selainnya mengembalikan nilai (yang opsional sudah dikonversi).

getlist(key, type: Callable | None = None) list

Kembalikan semua nilai untuk key sebagai list, dengan setiap nilai opsional dikonversi oleh type. Mengembalikan list kosong jika key tidak ada.

class microdot.NoCaseDict

Subkelas dict dengan kunci string tidak peka huruf besar-kecil. Digunakan untuk Request.headers dan Response.headers.

Fungsi level modul

microdot.abort(status_code: int, reason: str | None = None) None

Pintasan untuk Microdot.abort(). Tidak pernah kembali secara normal -- memicu HTTPException. Dapat diimpor sebagai from microdot import abort.

microdot.redirect(location: str, status_code: int = 302) Response

Pintasan untuk Response.redirect(). Dapat diimpor sebagai from microdot import redirect.

microdot.send_file(filename: str, **kwargs) Response

Pintasan untuk Response.send_file().

microdot.urlencode(s: str) str

Encode URL komponen dengan persen. Mengganti karakter yang memiliki arti khusus dalam URL (/, ?, &, =, #, spasi, ...) dengan escape hex %xx sehingga hasilnya dapat ditempatkan dengan aman di dalam segmen path atau nilai query. Mengembalikan str yang sudah di-encode.

microdot.urldecode(s: str) str

Decode URL komponen dengan persen -- kebalikan dari urlencode(). Escape %xx diganti dengan byte yang dikodekannya, dan + dikonversi menjadi spasi (konvensi query string historis). Mengembalikan str yang sudah di-decode.

Submodul