microdot — minimalny framework HTTP

Microdot to mały framework HTTP dla MicroPython, inspirowany Flaskiem. Działa na bazie asyncio, obsługuje wielu równoczesnych klientów bez wątków i udostępnia znajome API oparte na dekoratorach tras. Minimalna aplikacja wygląda następująco:

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

Instancja aplikacji HTTP. Jedna instancja jest tworzona w pobliżu początku skryptu i dekorowana procedurami obsługi tras; wywołanie run() lub oczekiwanie na start_server() rozpoczyna obsługę.

Rejestracja tras

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

Dekorator rejestrujący procedurę obsługi dla url_pattern dla wymienionych metod HTTP (domyślnie ['GET']). Zwraca dekorator, który po zastosowaniu do funkcji rejestruje ją jako procedurę obsługi i zwraca funkcję bez zmian.

url_pattern

Wzorzec ścieżki. Obsługuje segmenty statyczne (/users) oraz segmenty dynamiczne ujęte w < / >. Segmenty dynamiczne akceptują opcjonalny prefiks typu oddzielony :<int:id>, <path:rest>, <re:[0-9a-f]+:hex>. Domyślnym typem jest string.

methods

Lista nazw metod HTTP. Jeśli pominięta, dopasowywane jest wyłącznie GET.

Procedura obsługi jest wywoływana najpierw z obiektem żądania, a następnie z dowolnymi przechwyconymi segmentami dynamicznymi jako argumentami nazwanymi. Wartość zwracana przez procedurę obsługi staje się odpowiedzią HTTP: Response, ciąg znaków, krotka (body, status_code[, headers]) lub dict / list (wysyłane jako JSON).

get(url_pattern: str) Callable

Wygodny alias dla route(url_pattern, methods=['GET']) – rejestruje dekorowaną funkcję jako procedurę obsługi GET dla url_pattern. Zwraca dekorator.

post(url_pattern: str) Callable

Wygodny alias dla route(url_pattern, methods=['POST']) – rejestruje dekorowaną funkcję jako procedurę obsługi POST dla url_pattern. Zwraca dekorator.

put(url_pattern: str) Callable

Wygodny alias dla route(url_pattern, methods=['PUT']) – rejestruje dekorowaną funkcję jako procedurę obsługi PUT dla url_pattern. Zwraca dekorator.

patch(url_pattern: str) Callable

Wygodny alias dla route(url_pattern, methods=['PATCH']) – rejestruje dekorowaną funkcję jako procedurę obsługi PATCH dla url_pattern. Zwraca dekorator.

delete(url_pattern: str) Callable

Wygodny alias dla route(url_pattern, methods=['DELETE']) – rejestruje dekorowaną funkcję jako procedurę obsługi DELETE dla url_pattern. Zwraca dekorator.

Punkty zaczepienia cyklu życia

before_request(f: Callable) Callable

Dekorator rejestrujący f do uruchomienia przed każdym żądaniem. f przyjmuje obiekt żądania; jego wartość zwracana jest zwykle ignorowana. Aby przerwać przetwarzanie żądania, zwróć Response (lub wartość, która się na nią konwertuje) – pozostała część potoku jest wtedy pomijana i wysyłana jest ta odpowiedź. Zwraca f bez zmian.

after_request(f: Callable) Callable

Dekorator rejestrujący f do uruchomienia po każdym pomyślnym żądaniu. f przyjmuje (request, response) i musi zwrócić (ewentualnie zmodyfikowany) obiekt odpowiedzi. Zwraca f bez zmian.

after_error_request(f: Callable) Callable

Dekorator rejestrujący f do uruchomienia po wygenerowaniu przez Microdot odpowiedzi błędu (404, 500, zgłoszony wyjątek itp.). f przyjmuje (request, response) i musi zwrócić (ewentualnie zmodyfikowany) obiekt odpowiedzi. Zwraca f bez zmian.

errorhandler(status_code_or_exception_class) Callable

Dekorator rejestrujący niestandardową procedurę obsługi dla kodu stanu HTTP lub klasy wyjątku Python. Dla kodów stanu procedura obsługi przyjmuje wyłącznie żądanie; dla klas wyjątków – (request, exception). Zwraca dekorator.

Montowanie i przerywanie

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

Dołącza trasy innej instancji Microdot pod url_prefix. Gdy local ma wartość False (domyślnie), procedury obsługi before / after / error podaplikacji są również dołączane do aplikacji nadrzędnej. Gdy True, te procedury obsługi działają wyłącznie dla tras podaplikacji. Zwraca None.

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

Zgłoś HTTPException, aby przerwać bieżące żądanie z podanym kodem stanu. Nigdy nie zwraca wartości w normalny sposób – framework przechwytuje wyjątek i zamienia go na odpowiednią odpowiedź błędu. Wygodne wewnątrz ciał tras:

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

Uruchamianie serwera

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

Blokuje wywołujący wątek, uruchamia asyncio.run() na start_server(). Zwraca None dopiero po wywołaniu shutdown() i zakończeniu pętli nasłuchiwania. Najprostszy sposób na uruchomienie samodzielnej aplikacji:

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

Uruchamia serwer jako korutynę. Użyj tego podczas integracji z istniejącą pętlą zdarzeń asyncio obok innych zadań. Korutyna nie zwraca wartości, dopóki nie zostanie wywołane shutdown()

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

Interfejs sieciowy, na którym ma nasłuchiwać serwer. '0.0.0.0' (domyślnie) oznacza wszystkie interfejsy; '127.0.0.1' oznacza wyłącznie pętlę zwrotną.

port

Port TCP, na którym ma nasłuchiwać serwer. Domyślnie 5000 – wybierz 80 dla zwykłego HTTP, 443 dla HTTPS.

debug

Jeśli True, rejestruje każde żądanie i zrzuca śledzenia stosu na stdout.

ssl

Obiekt ssl.SSLContext opakowujący przychodzące połączenia w TLS. None (domyślnie) oznacza zwykłe HTTP.

start_serving

Istotne wyłącznie w CPython; ignorowane w MicroPython.

shutdown() None

Żądanie płynnego zamknięcia serwera. Bezpieczne do wywołania z procedury obsługi trasy – bieżące żądanie zostaje ukończone, zanim pętla zakończy działanie. Zwraca natychmiast; faktyczne zamknięcie następuje po zakończeniu trwającego żądania.

Atrybuty

url_map: list

Lista zarejestrowanych tras jako krotki (methods, URLPattern, handler, url_prefix, subapp).

before_request_handlers: list

Lista wywoływalnych obiektów zarejestrowanych za pomocą before_request(), w kolejności rejestracji. Każdy uruchamia się z obiektem żądania przed procedurą obsługi trasy. Bezpośrednia modyfikacja listy działa, ale jest rzadko potrzebna – preferuj dekorator.

after_request_handlers: list

Lista wywoływalnych obiektów zarejestrowanych za pomocą after_request(), w kolejności rejestracji. Każdy uruchamia się z (request, response) po pomyślnym żądaniu i musi zwrócić (ewentualnie zmodyfikowaną) odpowiedź.

after_error_request_handlers: list

Lista wywoływalnych obiektów zarejestrowanych za pomocą after_error_request(), w kolejności rejestracji. Każdy uruchamia się z (request, response) po wygenerowaniu odpowiedzi błędu (przez framework lub przez procedurę obsługi błędów aplikacji) i musi zwrócić odpowiedź.

error_handlers: dict

Mapowanie kluczy błędów na wywoływalne procedury obsługi, wypełniane przez errorhandler(). Klucze to albo kody stanu HTTP (int), albo klasy wyjątków Python; wartości to zarejestrowane procedury obsługi. Procedury obsługi kodów stanu przyjmują (request); procedury obsługi klas wyjątków przyjmują (request, exception).

debug: bool

True, gdy serwer działa z debug=True.

class Request

class microdot.Request

Przychodzące żądanie HTTP. Instancje są przekazywane do procedur obsługi tras jako pierwszy argument pozycyjny. Aplikacje nie konstruują Request bezpośrednio.

Atrybuty klasy

max_content_length: int

Odrzuca żądania, których Content-Length przekracza tę liczbę bajtów, odpowiedzią 413. Domyślnie 16 KB.

max_body_length: int

Największe ciało, które jest buforowane w pamięci i udostępniane przez body. Większe ciała (do max_content_length) pozostają w gnieździe i muszą być odczytane przez stream. Domyślnie 16 KB.

max_readline: int

Maksymalna długość pojedynczego wiersza żądania / wiersza nagłówka w bajtach. Domyślnie 2 KB.

Atrybuty instancji

app: Microdot

Instancja Microdot obsługująca żądanie.

client_addr: tuple

Adres klienta jako (host, port).

method: str

Ciąg metody HTTP ('GET', 'POST', …).

scheme: str

'http' lub 'https'.

url: str

Pełna ścieżka URL żądania oraz ciąg zapytania (wszystko po hoście).

path: str

Tylko część ścieżki.

query_string: str | None

Surowa część ciągu zapytania lub None.

args: MultiDict

Sparsowany ciąg zapytania jako MultiDict.

headers: NoCaseDict

Nagłówki żądania jako NoCaseDict (wyszukiwanie bez rozróżniania wielkości liter).

cookies: dict

Sparsowany nagłówek Cookie jako dict.

content_length: int

Całkowita wartość Content-Length lub 0, jeśli jest nieobecna.

content_type: str | None

Wartość nagłówka Content-Type lub None.

g: object

Dowolny kontener dla danego żądania (goły obiekt). Przypisz mu atrybuty, aby przekazywać wartości między punktami zaczepienia a procedurami obsługi (request.g.user = ...).

route: Callable

Funkcja obsługi, która dopasowała się do tego żądania.

url_prefix: str

Prefiks, pod którym zamontowano trasę, lub ''.

subapp: Microdot | None

Zamontowana instancja podaplikacji lub None.

Dostęp do ciała

body: bytes

Pełne ciało żądania jako bytes. Puste, gdy ciało jest strumieniowane (zobacz stream).

stream: object

Asynchroniczny obiekt strumienia udostępniający read() nad ciałem. Użyj tego dla ciał większych niż max_body_length.

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

Ciało sparsowane jako JSON (dict, list, str, int, float lub bool – cokolwiek koduje ładunek) lub None, jeśli Content-Type nie jest application/json.

form: MultiDict | None

Pola formularza zakodowane w URL jako MultiDict lub None. Dla multipart/form-data udekoruj trasę za pomocą microdot.multipart.with_form_data().

files: dict | None

Przesłane pliki jako {name: FileUpload}, wypełniane przez microdot.multipart.with_form_data(). None do czasu uruchomienia tego dekoratora.

after_request(f: Callable) Callable

Rejestruje punkt zaczepienia after-request lokalny dla żądania – uruchamia się po procedurach obsługi after-request na poziomie aplikacji, wyłącznie w przypadku powodzenia. f przyjmuje (request, response) i musi zwrócić (ewentualnie zmodyfikowany) obiekt odpowiedzi. Zwraca f bez zmian.

class Response

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

Odpowiedź HTTP. Większość procedur obsługi zwraca wartości, które Microdot automatycznie konwertuje na Response; skonstruuj ją bezpośrednio, gdy potrzebujesz niestandardowych nagłówków lub określonego kodu stanu.

body

Ciało odpowiedzi. str jest kodowany w UTF-8; dict / list jest kodowany jako JSON i odpowiednio ustawiany jest Content-Type; bytes jest wysyłany bez zmian; obiekt plikopodobny lub asynchroniczny generator jest strumieniowany.

status_code

Liczbowy stan HTTP. Domyślnie 200.

headers

Słownik nagłówków odpowiedzi (bez rozróżniania wielkości liter).

reason

Niestandardowa fraza przyczyny. Domyślnie "OK" dla 200 i "N/A" w pozostałych przypadkach.

Atrybuty klasy

default_content_type: str

Content-Type używany, gdy żaden nie jest ustawiony jawnie. Domyślnie 'text/plain'.

default_send_file_max_age: int | None

Wartość Cache-Control: max-age dla send_file(), gdy max_age nie jest podane. None (domyślnie) oznacza brak nagłówka Cache-Control.

send_file_buffer_size: int

Rozmiar fragmentu dla strumieniowania send_file(). Domyślnie 1024.

already_handled: None

Wartownik zwracany przez procedury obsługi, które już bezpośrednio zapisały odpowiedź (używany przez ulepszenia WebSocket). Zawsze None; liczy się tożsamość.

types_map: dict

Mapa rozszerzeń na typy mime używana przez send_file() do wnioskowania typu zawartości. Mapuje css, gif, html, jpg, js, json, png, txt, svg.

Metody

Dodaje nagłówek Set-Cookie. expires może być wstępnie sformatowanym ciągiem lub obiektem przypominającym datetime z timetuple(). Zwraca None; nagłówek jest dołączany do tej odpowiedzi w miejscu.

Ustawia Set-Cookie, który natychmiast wygasza podane ciasteczko. kwargs przyjmuje te same opcje co set_cookie() (path, domain, secure, http_only, partitioned); expires i max_age są ignorowane. Zwraca None; nagłówek jest dołączany do tej odpowiedzi w miejscu.

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

Zwraca odpowiedź przekierowania:

@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

Strumieniuje plik z systemu plików jako ciało odpowiedzi. content_type jest wnioskowany z rozszerzenia za pomocą types_map, jeśli nie został podany. compressed=True ustawia Content-Encoding: gzip (plik musi być już skompresowany).

Ostrzeżenie

filename jest otwierany bezpośrednio. Nigdy nie przekazuj nieoczyszczonej ścieżki dostarczonej przez użytkownika – umożliwia to ujawnienie dowolnego pliku.

Wyjątki

exception microdot.HTTPException

Zgłaszany przez abort() w celu przerwania żądania z określonym kodem stanu. Microdot przechwytuje go i zamienia na odpowiednią odpowiedź błędu.

status_code: int

Liczbowy kod stanu HTTP do zwrócenia – wartość przekazana do abort().

reason: str

Fraza przyczyny do uwzględnienia w odpowiedzi błędu. Jeśli nie zostanie podana do abort(), domyślnie przyjmuje "<status_code> error" (np. "404 error").

class URLPattern

class microdot.URLPattern(url_pattern: str)

Skompilowana postać wzorca URL trasy. Konstruowana automatycznie przez Microdot.route(); aplikacje rzadko tworzą ją bezpośrednio.

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

Rejestruje nowy typ segmentu dynamicznego do użycia we wzorcach tras. Zwraca None; typ jest dodawany do rejestru typów na poziomie klasy. Na przykład, aby dodać typ <uuid:...>

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

parser to opcjonalny obiekt wywoływalny, który konwertuje przechwycony ciąg, zanim dotrze on do procedury obsługi.

match(path: str) dict | None

Dopasowuje path do wzorca i zwraca słownik przechwyconych grup lub None przy braku dopasowania.

Klasy pomocnicze

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

Podklasa dict przechowująca wiele wartości na klucz. Używana dla ciągów zapytań i ciał formularzy zakodowanych w URL, w których ten sam klucz może pojawić się więcej niż raz (?tag=a&tag=b).

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

Zwraca pierwszą wartość dla key, opcjonalnie skonwertowaną za pomocą type (obiektu wywoływalnego). Zwraca default, jeśli klucza brakuje lub konwersja się nie powiedzie; w przeciwnym razie zwraca (ewentualnie skonwertowaną) wartość.

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

Zwraca wszystkie wartości dla key jako listę, opcjonalnie z każdą wartością skonwertowaną przez type. Zwraca pustą listę, jeśli key nie jest obecny.

class microdot.NoCaseDict

Podklasa dict z kluczami będącymi ciągami bez rozróżniania wielkości liter. Używana dla Request.headers i Response.headers.

Funkcje na poziomie modułu

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

Skrót dla Microdot.abort(). Nigdy nie zwraca wartości w normalny sposób – zgłasza HTTPException. Importowalny jako from microdot import abort.

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

Skrót dla Response.redirect(). Importowalny jako from microdot import redirect.

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

Skrót dla Response.send_file().

microdot.urlencode(s: str) str

Koduje komponent URL w postaci procentowej. Zastępuje znaki mające zarezerwowane znaczenie w URL (/, ?, &, =, #, spacja, …) ich szesnastkowymi sekwencjami %xx, dzięki czemu wynik może bezpiecznie znaleźć się wewnątrz segmentu ścieżki lub wartości zapytania. Zwraca zakodowany str.

microdot.urldecode(s: str) str

Dekoduje komponent URL z postaci procentowej – odwrotność urlencode(). Sekwencje %xx są zastępowane bajtem, który kodują, a + jest konwertowany na spację (historyczna konwencja ciągów zapytań). Zwraca zdekodowany str.

Podmoduły