AXV

Fayllar (UploadFile)

UploadFile va File, fayl validatsiyasi (tur, hajm), xavfsiz saqlash, yuklab olish (FileResponse)

10-sinfAdvanced Python Back-end6-hafta · 16-dars

Bugun nimalarni o'rganamiz?

UploadFile va File

Fayl qabul qilish

Validatsiya va xavfsiz saqlash

Tur, hajm, nom

Yuklab olish

FileResponse

Takrorlash

limit ga nima uchun yuqori chegara (le=100) qo'yamiz?

Aks holda limit=1000000 bilan serverni yuklash mumkin.
01

UploadFile va File

Fayl qabul qilish

Fayl yo'li

Mijoz faylnitanlaydi multipartso'rov UploadFile await read() Server fayl obyektini oladi

Fayl qabul qilish


from fastapi import FastAPI, File, UploadFile

app = FastAPI()

@app.post("/books/{book_id}/cover")
async def upload_cover(book_id: int, file: UploadFile = File(...)):
    data = await file.read()
    return {"filename": file.filename,
            "type": file.content_type,
            "size": len(data)}
  
Fayl yuboruvchi endpoint da Body (JSON) bilan File ni aralashtirib bo'lmaydi: qo'shimcha maydonlar Form(...) bilan beriladi.

Mini-test

Fayl yuklash uchun qaysi paket kerak?

multipart/form-data ni o'qish uchun python-multipart kerak.
02

Validatsiya va xavfsiz saqlash

Tur, hajm, nom

Tekshiruv zanjiri

Tur (415) Hajm (413) Xavfsiz nom Diskka yozish Har bir qadam xato bersa to'xtaydi

Validatsiya va saqlash


ALLOWED = {"image/jpeg": ".jpg", "image/png": ".png"}
MAX_SIZE = 2 * 1024 * 1024

ext = ALLOWED.get(file.content_type)
if ext is None:
    raise HTTPException(415, "Faqat JPEG yoki PNG")
data = await file.read(MAX_SIZE + 1)
if len(data) > MAX_SIZE:
    raise HTTPException(413, "Fayl 2 MB dan katta")
name = f"{book_id}_{uuid4().hex}{ext}"
(UPLOAD_DIR / name).write_bytes(data)
  
content_type ni mijoz yuboradi, uni soxtalashtirish mumkin: jiddiy loyihada fayl sarlavhasi (magic bytes) ham tekshiriladi.

Mini-test

Fayl hajmi chegaradan oshsa qaysi status qaytariladi?

413 — Payload Too Large.
03

Yuklab olish

FileResponse

Yuklab olish

GET /files/nom resolve() Papkaichidami? FileResponse Papkadan chiqsa 404

Xavfsiz yuklab olish


@app.get("/files/{name}")
async def download(name: str):
    path = (UPLOAD_DIR / name).resolve()
    if path.parent != UPLOAD_DIR.resolve() or not path.is_file():
        raise HTTPException(404, "Fayl topilmadi")
    return FileResponse(path)
  
Foydalanuvchining o'z fayli bo'lsa, get_current_user bilan egasini ham tekshiring.

Mini-test

Path traversal nima?

Tashqi fayllarga kirishga urinish.

bytes va UploadFile

bytes

Butun fayl xotiraga olinadi
VS

UploadFile

Katta fayl diskda turadi, filename va content_type bor

Fayl uchun UploadFile tavsiya etiladi.

Atamalar. Bosing

UploadFile

bosing

Yuklangan faylni ifodalovchi obyekt

multipart

bosing

Fayl yuboriladigan so'rov formati

413

bosing

Fayl juda katta

415

bosing

Fayl turi qo'llab-quvvatlanmaydi

Yuklash endpointini yozish

1. Qabul qiling

UploadFile = File(...).

2. Tekshiring

Tur va hajm.

3. Saqlang

uuid4 nomi bilan.

Fayl xatolari

HolatStatusSabab
Tur noto'g'ri415ruxsat etilmagan content_type
Hajm katta413MAX_SIZE dan oshdi
Fayl yo'q404yo'l noto'g'ri
Muvaffaqiyat201fayl saqlandi
Fayl yuborilmadi422file maydoni yo'q

Pastga bosing: statuslar

Swagger da sinash

  1. uvicorn app.main:app --reload ni ishga tushiring.
  2. /docs da POST /books/1/cover ga PNG yuklang.
  3. /files/<nom> bilan yuklab oling; .txt bilan 415 ni tekshiring.

Xavfsiz nom


path = UPLOAD_DIR / file.filename
  

Xavfsiz nom


path = UPLOAD_DIR / f"{uuid4().hex}.png"
  

Fayllar raqamlarda

0
MB — namunadagi hajm chegarasi
0
ta tekshiruv: tur, hajm, nom
0
ta xato kodi: 413 va 415

Foydalanuvchi yuborgan hamma narsani tekshiring.

Amaliy topshiriq 20 daqiqa

OsonFayl qabul qiling: /upload endpointi yozing: fayl nomi va hajmini qaytarsin.
OsonTur tekshiruvi: Faqat PNG va JPEG ga ruxsat bering, boshqasida 415.
O'rtaHajm chegarasi: 2 MB dan katta faylga 413 qaytaring.
O'rtaXavfsiz nom: Faylni uuid4 nomi bilan saqlang.
QiyinYuklab olish: /files/{name} endpointini path traversal dan himoyalab yozing.
BonusBazaga bog'lash: Book.cover maydoniga fayl nomini yozing.

Dars xulosasi

Qabul

UploadFile = File(...), python-multipart.

Tekshiruv

Tur (415), hajm (413), uuid4 nomi.

Yuklab olish

FileResponse va path traversal himoyasi.

Uyga vazifa: Fayl yuklash va yuklab olish.

Keyingi dars: Loyihani yakunlash

Struktura, sozlamalar, xatolar

6-hafta · 17-dars