Skip to main content
📄 HTML & the platform·Module A3 · Lesson 10
TaskBuild an upload form: enctype='multipart/form-data', method='post', action='/api/upload'. <input type='file' name='photo' accept='image/*'>, <input type='file' name='docs' multiple accept='.pdf'>, submit button.

<input type=file>: uploads + multipart

100 XP8 min
Theory

File uploads need multipart enctype

<form action="/api/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="avatar" />
  <input type="file" name="docs" multiple accept=".pdf,.docx" />
  <button type="submit">Upload</button>
</form>

Two changes vs a regular form:

  1. `enctype="multipart/form-data"` — without it, the browser only submits the filename, not the file content. Always set this on forms with file inputs.
  2. `accept=…` on the file input — restricts the OS picker to matching files. Either MIME types (image/png) or extensions (.pdf).

multiple

<input multiple> lets the user pick more than one file at once. Submitted as repeated form keys (same name, multiple files).

Accept patterns

<input type="file" accept="image/*" />              <!-- any image MIME -->
<input type="file" accept=".jpg,.png,.webp" />      <!-- specific extensions -->
<input type="file" accept="image/png,image/jpeg" /> <!-- specific MIMEs -->
<input type="file" accept="application/pdf" />

accept is a HINT — browsers honor it loosely. Backend MUST re-validate by reading the actual file content (magic bytes), not just the extension.

FastAPI side

from fastapi import UploadFile

@app.post("/api/upload")
async def upload(avatar: UploadFile, docs: list[UploadFile] = []):
    return {"avatar": avatar.filename, "docs": [d.filename for d in docs]}

The form's name="avatar" becomes the function arg. multiple becomes list[UploadFile].

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 15 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.