microdot --- เฟรมเวิร์ก HTTP ขนาดเล็ก¶
Microdot เป็นเฟรมเวิร์ก HTTP ขนาดเล็กที่ได้รับแรงบันดาลใจจาก Flask สำหรับ MicroPython ทำงานบนพื้นฐานของ asyncio รองรับหลายไคลเอนต์พร้อมกันโดยไม่ต้องใช้เธรด และเปิดเผย API แบบ route-decorator ที่คุ้นเคย ตัวอย่างแอปพลิเคชันขั้นต่ำมีลักษณะดังนี้:
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 สร้างอินสแตนซ์หนึ่งไว้ใกล้ส่วนบนของสคริปต์และตกแต่งด้วย route handler แล้วเรียก
run()หรือรอstart_server()เพื่อเริ่มให้บริการการลงทะเบียน Route
- route(url_pattern: str, methods: list | None = None) Callable¶
Decorator ที่ลงทะเบียน handler สำหรับ url_pattern ภายใต้ HTTP method ที่ระบุ (ค่าเริ่มต้น
['GET']) คืนค่า decorator ซึ่งเมื่อนำไปใช้กับฟังก์ชันจะลงทะเบียนเป็น handler และคืนฟังก์ชันนั้นโดยไม่เปลี่ยนแปลง- url_pattern
รูปแบบ path รองรับส่วนคงที่ (
/users) และส่วนไดนามิกที่ล้อมรอบด้วย</>ส่วนไดนามิกยอมรับคำนำหน้าประเภทที่คั่นด้วย:--<int:id>,<path:rest>,<re:[0-9a-f]+:hex>ประเภทเริ่มต้นคือstring- methods
รายการชื่อ HTTP method หากละไว้จะจับคู่เฉพาะ
GETเท่านั้น
Handler ถูกเรียกด้วย request object เป็นอาร์กิวเมนต์แรก ตามด้วยส่วนไดนามิกที่ดักจับได้เป็น keyword argument ค่าที่ handler คืนกลับมาจะกลายเป็น HTTP response ได้แก่
Response, string, tuple(body, status_code[, headers]), หรือ dict / list (ส่งเป็น JSON)
- get(url_pattern: str) Callable¶
ชื่อแทนสำหรับ
route(url_pattern, methods=['GET'])-- ลงทะเบียนฟังก์ชันที่ตกแต่งเป็นGEThandler สำหรับ url_pattern คืนค่า decorator
- post(url_pattern: str) Callable¶
ชื่อแทนสำหรับ
route(url_pattern, methods=['POST'])-- ลงทะเบียนฟังก์ชันที่ตกแต่งเป็นPOSThandler สำหรับ url_pattern คืนค่า decorator
- put(url_pattern: str) Callable¶
ชื่อแทนสำหรับ
route(url_pattern, methods=['PUT'])-- ลงทะเบียนฟังก์ชันที่ตกแต่งเป็นPUThandler สำหรับ url_pattern คืนค่า decorator
- patch(url_pattern: str) Callable¶
ชื่อแทนสำหรับ
route(url_pattern, methods=['PATCH'])-- ลงทะเบียนฟังก์ชันที่ตกแต่งเป็นPATCHhandler สำหรับ url_pattern คืนค่า decorator
- delete(url_pattern: str) Callable¶
ชื่อแทนสำหรับ
route(url_pattern, methods=['DELETE'])-- ลงทะเบียนฟังก์ชันที่ตกแต่งเป็นDELETEhandler สำหรับ url_pattern คืนค่า decorator
Lifecycle hooks
- before_request(f: Callable) Callable¶
Decorator ที่ลงทะเบียน f ให้ทำงานก่อนทุก request f รับ request object และค่าที่คืนมักถูกละเว้น หากต้องการหยุดการประมวลผล request ให้คืนค่า
Response(หรือค่าที่แปลงเป็นหนึ่งได้) -- pipeline ที่เหลือจะถูกข้ามและส่ง response นั้น คืนค่า f โดยไม่เปลี่ยนแปลง
- after_request(f: Callable) Callable¶
Decorator ที่ลงทะเบียน f ให้ทำงานหลัง request ที่สำเร็จทุกรายการ f รับ
(request, response)และต้องคืน response object (ที่อาจปรับแล้ว) คืนค่า f โดยไม่เปลี่ยนแปลง
- after_error_request(f: Callable) Callable¶
Decorator ที่ลงทะเบียน f ให้ทำงานหลังจาก Microdot สร้าง error response (404, 500, exception ที่เกิดขึ้น ฯลฯ) f รับ
(request, response)และต้องคืน response object (ที่อาจปรับแล้ว) คืนค่า f โดยไม่เปลี่ยนแปลง
- errorhandler(status_code_or_exception_class) Callable¶
Decorator ที่ลงทะเบียน handler กำหนดเองสำหรับ HTTP status code หรือ Python exception class สำหรับ status code handler รับเฉพาะ request เท่านั้น สำหรับ exception class รับ
(request, exception)คืนค่า decorator
การ Mount และการยกเลิก
- mount(subapp: Microdot, url_prefix: str = '', local: bool = False) None¶
แนบ route ของอินสแตนซ์
Microdotอื่นภายใต้ url_prefix เมื่อ local เป็นFalse(ค่าเริ่มต้น) before / after / error handler ของ sub-app จะถูกแนบกับ parent ด้วย เมื่อเป็นTruehandler เหล่านั้นจะทำงานเฉพาะสำหรับ sub-app route เท่านั้น คืนค่าNone
- static abort(status_code: int, reason: str | None = None) None¶
เรียก
HTTPExceptionเพื่อยกเลิก request ปัจจุบันด้วย status code ที่กำหนด ไม่มีการคืนค่าปกติ -- เฟรมเวิร์กจะดักจับ exception และแปลงเป็น error response ที่สอดคล้อง ใช้งานได้สะดวกภายใน route body: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¶
บล็อก thread ที่เรียก รัน
asyncio.run()บนstart_server()คืนค่าNoneเฉพาะหลังจากshutdown()ถูกเรียกและ listening loop ออก วิธีที่ง่ายที่สุดในการเปิดแอปแบบ standalone: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¶
เริ่มเซิร์ฟเวอร์เป็น coroutine ใช้สิ่งนี้เมื่อรวมกับ
asyncioevent loop ที่มีอยู่พร้อมกับ task อื่น coroutine จะไม่คืนค่าจนกว่าshutdown()จะถูกเรียก:async def main(): await asyncio.gather( app.start_server(port=80), capture_loop(), )
- host
Network interface ที่จะรับฟัง
'0.0.0.0'(ค่าเริ่มต้น) หมายถึงทุก interface;'127.0.0.1'หมายถึง loopback เท่านั้น- port
TCP port ที่จะรับฟัง ค่าเริ่มต้น
5000-- เลือก80สำหรับ HTTP ธรรมดา,443สำหรับ HTTPS- debug
หากเป็น
Trueจะบันทึกทุก request และแสดง traceback ไปยัง stdout- ssl
ssl.SSLContextสำหรับห่อการเชื่อมต่อขาเข้าใน TLSNone(ค่าเริ่มต้น) หมายถึง HTTP ธรรมดา- start_serving
ใช้ได้เฉพาะบน CPython เท่านั้น ถูกละเว้นบน MicroPython
- shutdown() None¶
ขอปิดเซิร์ฟเวอร์อย่างนุ่มนวล ปลอดภัยที่จะเรียกจาก route handler -- request ปัจจุบันเสร็จสิ้นก่อนที่ loop จะออก คืนค่าทันที การปิดเซิร์ฟเวอร์จริงจะเกิดขึ้นเมื่อ request ที่กำลังดำเนินการเสร็จสิ้น
Attribute
- url_map: list¶
รายการ route ที่ลงทะเบียนแล้วเป็น tuple
(methods, URLPattern, handler, url_prefix, subapp)
- before_request_handlers: list¶
รายการ callable ที่ลงทะเบียนด้วย
before_request()ตามลำดับการลงทะเบียน แต่ละรายการทำงานกับ request object ก่อน route handler การปรับเปลี่ยน list โดยตรงใช้งานได้แต่แทบไม่จำเป็น -- แนะนำให้ใช้ decorator
- after_request_handlers: list¶
รายการ callable ที่ลงทะเบียนด้วย
after_request()ตามลำดับการลงทะเบียน แต่ละรายการทำงานกับ(request, response)หลัง request ที่สำเร็จและต้องคืน response (ที่อาจปรับแล้ว)
- after_error_request_handlers: list¶
รายการ callable ที่ลงทะเบียนด้วย
after_error_request()ตามลำดับการลงทะเบียน แต่ละรายการทำงานกับ(request, response)หลังจาก error response ถูกสร้าง (โดยเฟรมเวิร์กหรือ application error handler) และต้องคืน response
- error_handlers: dict¶
Mapping ของ error key ไปยัง handler callable ที่เติมข้อมูลโดย
errorhandler()key เป็น HTTP status code (int) หรือ Python exception class; value คือ handler ที่ลงทะเบียน Status-code handler รับ(request); exception-class handler รับ(request, exception)
class Request¶
- class microdot.Request¶
HTTP request ขาเข้า อินสแตนซ์ถูกส่งไปยัง route handler เป็นอาร์กิวเมนต์ตำแหน่งแรก แอปพลิเคชันไม่สร้าง
RequestโดยตรงClass attribute
- max_content_length: int¶
ปฏิเสธ request ที่มี
Content-Lengthเกินจำนวนไบต์นี้ด้วย response 413 ค่าเริ่มต้น 16 KB
- max_body_length: int¶
ขนาด body ที่ใหญ่ที่สุดที่บัฟเฟอร์ไว้ในหน่วยความจำและเปิดเผยผ่าน
bodybody ที่ใหญ่กว่า (ไม่เกินmax_content_length) จะอยู่บน socket และต้องอ่านผ่านstreamค่าเริ่มต้น 16 KB
- max_readline: int¶
ความยาวสูงสุดของ request line หรือ header line หนึ่งบรรทัดในหน่วยไบต์ ค่าเริ่มต้น 2 KB
Instance attribute
- headers: NoCaseDict¶
Request header เป็น
NoCaseDict(การค้นหาแบบไม่คำนึงถึงตัวพิมพ์)
- g: object¶
คอนเทนเนอร์แบบอิสระต่อ request (object ว่างเปล่า) กำหนด attribute เพื่อส่งค่าระหว่าง hook และ handler (
request.g.user = ...)
- route: Callable¶
ฟังก์ชัน handler ที่จับคู่กับ request นี้
การเข้าถึง Body
- stream: object¶
async stream object ที่เปิดเผย
read()บน body ใช้สิ่งนี้สำหรับ body ที่ใหญ่กว่าmax_body_length
- json: dict | list | str | int | float | bool | None¶
Body ที่แปลงเป็น JSON (
dict,list,str,int,float, หรือbool-- ตามที่ payload เข้ารหัส) หรือNoneหากContent-Typeไม่ใช่application/json
- form: MultiDict | None¶
Form field ที่เข้ารหัส URL เป็น
MultiDictหรือNoneสำหรับmultipart/form-dataให้ตกแต่ง route ด้วยmicrodot.multipart.with_form_data()
- files: dict | None¶
ไฟล์ที่อัปโหลดเป็น
{name: FileUpload}ถูกเติมข้อมูลโดยmicrodot.multipart.with_form_data()Noneจนกว่า decorator นั้นจะทำงาน
- after_request(f: Callable) Callable¶
ลงทะเบียน after-request hook เฉพาะ request -- ทำงานหลัง application-level after-request handler เฉพาะเมื่อสำเร็จ f รับ
(request, response)และต้องคืน response object (ที่อาจปรับแล้ว) คืนค่า f โดยไม่เปลี่ยนแปลง
class Response¶
- class microdot.Response(body=b'', status_code: int = 200, headers: dict | None = None, reason: str | None = None)¶
HTTP response ส่วนใหญ่ handler คืนค่าที่ Microdot แปลงเป็น
Responseโดยอัตโนมัติ สร้างโดยตรงเมื่อต้องการ header กำหนดเองหรือ status code เฉพาะ- body
Response body
strเข้ารหัสเป็น UTF-8;dict/listเข้ารหัสเป็น JSON และตั้งContent-Typeตามนั้น;bytesส่งตรง; file-like object หรือ async generator จะ stream- status_code
HTTP status แบบตัวเลข ค่าเริ่มต้น 200
- headers
Dict ของ response header (ไม่คำนึงถึงตัวพิมพ์)
- reason
วลีเหตุผลกำหนดเอง ค่าเริ่มต้นคือ
"OK"สำหรับ 200 และ"N/A"สำหรับอื่น ๆ
Class attribute
- default_content_type: str¶
Content-Type ที่ใช้เมื่อไม่ได้ตั้งค่าอย่างชัดเจน ค่าเริ่มต้น
'text/plain'
- default_send_file_max_age: int | None¶
ค่า
Cache-Control: max-ageสำหรับsend_file()เมื่อไม่ได้กำหนดmax_ageNone(ค่าเริ่มต้น) หมายถึงไม่มี Cache-Control header
- send_file_buffer_size: int¶
ขนาด chunk สำหรับ streaming ของ
send_file()ค่าเริ่มต้น 1024
- already_handled: None¶
Sentinel ที่คืนจาก handler ที่เขียน response โดยตรงแล้ว (ใช้โดย WebSocket upgrade) เสมอ
None; สิ่งสำคัญคือ identity
- types_map: dict¶
Map ของ extension ไปยัง mime-type ที่ใช้โดย
send_file()สำหรับการอนุมาน content-type จับคู่css,gif,html,jpg,js,json,png,txt,svg
Method
- 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-Cookieheader expires อาจเป็น string ที่จัดรูปแบบล่วงหน้าหรือ object คล้ายdatetimeที่มีtimetuple()คืนค่าNone; header ถูกต่อท้าย response นี้ในที่เดิม
- delete_cookie(cookie: str, **kwargs) None¶
ตั้ง
Set-Cookieที่ทำให้ cookie ที่กำหนดหมดอายุทันทีkwargsยอมรับตัวเลือกเดียวกับset_cookie()(path,domain,secure,http_only,partitioned);expiresและmax_ageถูกละเว้น คืนค่าNone; header ถูกต่อท้าย response นี้ในที่เดิม
- classmethod redirect(location: str, status_code: int = 302) Response¶
คืน redirect 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¶
Stream ไฟล์จาก filesystem เป็น response body
content_typeอนุมานจาก extension ผ่านtypes_mapหากไม่ระบุcompressed=Trueตั้งContent-Encoding: gzip(ไฟล์ต้องถูกบีบอัดไว้แล้ว)Warning
filename ถูกเปิดโดยตรง ห้ามส่ง path ที่ผู้ใช้กำหนดโดยไม่ผ่านการตรวจสอบ -- การทำเช่นนั้นทำให้เปิดเผยไฟล์ตามอำเภอใจได้
Exception¶
class URLPattern¶
- class microdot.URLPattern(url_pattern: str)¶
รูปแบบที่คอมไพล์แล้วของ URL pattern ของ route สร้างโดยอัตโนมัติโดย
Microdot.route(); แอปพลิเคชันแทบไม่สร้างอินสแตนซ์โดยตรง- classmethod register_type(type_name: str, pattern: str = '[^/]+', parser: Callable | None = None) None¶
ลงทะเบียนประเภทส่วนไดนามิกใหม่สำหรับใช้ใน route pattern คืนค่า
None; ประเภทถูกเพิ่มในรีจิสทรีระดับ class ตัวอย่างเช่น การเพิ่มประเภท<uuid:...>URLPattern.register_type('uuid', '[0-9a-f-]{36}')parser คือ callable ที่ไม่บังคับซึ่งแปลง string ที่ดักจับได้ก่อนที่จะถึง handler
Helper class¶
- class microdot.MultiDict(initial_dict: dict | None = None)¶
dict subclass ที่เก็บค่าหลายค่าต่อ key ใช้สำหรับ query string และ URL-encoded form body ที่ key เดียวกันอาจปรากฏมากกว่าหนึ่งครั้ง (
?tag=a&tag=b)
- class microdot.NoCaseDict¶
dict subclass ที่มี key string แบบไม่คำนึงถึงตัวพิมพ์ ใช้สำหรับ
Request.headersและResponse.headers
ฟังก์ชันระดับ module¶
- microdot.abort(status_code: int, reason: str | None = None) None¶
ชื่อแทนสำหรับ
Microdot.abort()ไม่มีการคืนค่าปกติ -- เรียกHTTPExceptionสามารถ import ได้เป็นfrom microdot import abort
- microdot.redirect(location: str, status_code: int = 302) Response¶
ชื่อแทนสำหรับ
Response.redirect()สามารถ import ได้เป็นfrom microdot import redirect
- microdot.send_file(filename: str, **kwargs) Response¶
ชื่อแทนสำหรับ
Response.send_file()
- microdot.urlencode(s: str) str¶
เข้ารหัส URL component แบบ percent สลับตัวอักษรที่มีความหมายพิเศษใน URL (
/,?,&,=,#, space, ...) ด้วย hex escape%xxเพื่อให้ผลลัพธ์วางภายใน path segment หรือ query value ได้อย่างปลอดภัย คืนค่าstrที่เข้ารหัสแล้ว
- microdot.urldecode(s: str) str¶
ถอดรหัส URL component แบบ percent -- ตรงข้ามกับ
urlencode()%xxescape ถูกแทนที่ด้วยไบต์ที่เข้ารหัส และ+แปลงเป็น space (ธรรมเนียม query-string ในอดีต) คืนค่าstrที่ถอดรหัสแล้ว
Submodule¶
microdot.auth--- การยืนยันตัวตน HTTPmicrodot.cors--- การแชร์ทรัพยากรข้ามต้นทาง (Cross-Origin Resource Sharing)microdot.csrf--- การป้องกัน CSRFmicrodot.login--- ขั้นตอนการล็อกอินผู้ใช้microdot.multipart--- การแยกวิเคราะห์ multipart/form-datamicrodot.session--- session แบบ signed cookiemicrodot.sse--- Server-Sent Eventsmicrodot.websocket--- รองรับ WebSocket