microdot.multipart — ניתוח multipart/form-data¶
מנתח גופי בקשה מסוג Content-Type: multipart/form-data – הקידוד שדפדפנים משתמשים בו עבור טפסים הכוללים שדות <input type="file">. שני סוגים של API:
FormDataIterבזרימה שמניב שדות בזה אחר זה – שימושי כאשר היישום צריך לטפל בהעלאות גדולות מאוד חתיכה אחר חתיכה בהתקן מוגבל-זיכרון.דקורטור
with_form_data()שמחזיק הכול בחוצץ (buffer) ומאכלס אתrequest.form/request.files– ה-API הנוח עבור העלאות בגודל רגיל.
class FormDataIter¶
- class microdot.multipart.FormDataIter(request)¶
איטרטור אסינכרוני על החלקים של גוף ה-multipart של request. הערכים המונבים הם tuples מסוג
(name, value); value הואstrעבור שדות רגילים ו-FileUploadעבור שדות קובץ.בשימוש ישיר כאשר הזיכרון חשוב יותר מהארגונומיה:
from microdot.multipart import FormDataIter, FileUpload @app.post('/upload') async def upload(request): async for name, value in FormDataIter(request): if isinstance(value, FileUpload): await value.save('/sdcard/' + value.filename) else: print(name, '=', value) return 'ok'
הערה
בעת איטרציה על שדות קובץ, יש לצרוך את הקובץ (באמצעות
FileUpload.read()אוFileUpload.save()) לפני איטרציית ה-async forהבאה – הזרם הבסיסי מתבטל כאשר האיטרציה מתקדמת.
class FileUpload¶
- class microdot.multipart.FileUpload(filename: str, content_type: str | None, read)¶
קובץ יחיד שהועלה. מופעים מונבים על ידי
FormDataIterונאספים אלrequest.filesעל ידיwith_form_data(). יישומים בדרך כלל אינם בוניםFileUploadישירות.- max_memory_size: int¶
תכונת מחלקה. סף (בבתים) שמעליו
copy()עובר מהחזקה בזיכרון לקובץ זמני. ברירת מחדל 1024.
- async save(path_or_file)¶
שומרת את ההעלאה אל path_or_file, שיכול להיות נתיב במערכת הקבצים או אובייקט קובץ פתוח כבר.
- async copy(max_memory_size: int | None = None)¶
מחזיקה את ההעלאה בחוצץ (buffer) (ב-RAM או בקובץ זמני, בהתאם ל-
max_memory_size) כך שניתן לנתח את שאר גוף ה-multipart מבלי שהזרם המקורי יתבטל. הדקורטורwith_form_data()קורא לזה אוטומטית.
- async close()¶
משחררת כל קובץ זמני שנוצר על ידי
copy(). נקראת אוטומטית כאשר הבקשה מסתיימת אם ההעלאה הגיעה אלrequest.filesבאמצעותwith_form_data().
דקורטורים ברמת המודול¶
- microdot.multipart.with_form_data(f)¶
דקורטור שמנתח את גוף ה-multipart מראש ומאכלס את
request.formואתrequest.filesלפני שה-handler רץ:from microdot import Microdot from microdot.multipart import with_form_data app = Microdot() @app.post('/upload') @with_form_data async def upload(request): print('fields:', dict(request.form)) for name, file in request.files.items(): await file.save('/sdcard/' + sanitize(file.filename)) return 'ok'
העלאות קבצים מוחזקות בחוצץ (buffer) באמצעות
FileUpload.copy(), כך שה-handler יכול לבצע איטרציה עלrequest.filesו-request.formבחופשיות. קבצים זמניים מנוקים אוטומטית כאשר הבקשה מסתיימת.
עבור העלאות גדולות מכמה מגה-בתים, העדיפו את ה-API FormDataIter בזרימה; with_form_data() צובר את כל הבקשה בזיכרון או במערכת הקבצים לפני שה-handler רץ.