Backend Web Development with Python · Lesson 1 of 10

Free preview

How the web works, and your first FastAPI app

Understand what a backend does with an HTTP request, then build and run a first FastAPI app with uvicorn and see the automatic docs.

time
55 min
on completion
+110 XP

Why this matters

Almost every application you use talks to a backend: a program running on a server that accepts requests over HTTP, does something useful — looks up data, saves a change, checks a permission — and sends back a response. A mobile app, a website's JavaScript, another service, or a command-line tool all speak the same protocol to that backend. If you can build a backend, you can power any of them.

This course builds one real backend from nothing: a Task API where each user keeps a private list of tasks. By the end it will validate input, store data in PostgreSQL, require a login, run under Docker, and have a test suite. We start today with the smallest possible version — a service that answers two requests — so you can see the whole request-and-response loop end to end before we add anything to it.

You will work on your lab machine linux01, which has Python 3.12, Docker and the tools you need. No cloud account, no framework magic you cannot inspect: everything runs locally and you can read every line.

Concepts

HTTP is a request/response protocol. A client sends a request; your backend returns a response. That is the entire conversation, repeated for every interaction.

A request has four parts you care about:

  • a method — the verb. GET reads, POST creates, PUT/PATCH update, DELETE removes.
  • a path — what resource, for example /tasks or /tasks/42.
  • headers — metadata, such as Content-Type: application/json or an Authorization header carrying a token.
  • an optional body — data sent with the request, usually JSON for an API.

A response has three parts: a status code, headers, and a body. The status code is a three-digit number in families: 2xx success (200 OK, 201 Created, 204 No Content), 4xx the client's fault (400 bad request, 401 unauthenticated, 403 forbidden, 404 not found, 422 unprocessable), 5xx the server's fault (500 internal error, 503 unavailable). Returning the *right* status code is part of doing the job correctly — a caller reads it to decide what to do next.

An API (application programming interface) is a backend meant for programs rather than browsers, so it speaks JSON instead of returning pages. This course builds a JSON API.

FastAPI is a modern Python web framework for building APIs. You write ordinary Python functions and decorate them to say which method and path they handle; FastAPI turns a returned dictionary into a JSON response, validates input for you, and generates interactive documentation automatically. uvicorn is the *server* that actually listens on a network port and runs your FastAPI app. You will meet two others for contrast later — Flask (smaller, synchronous, you assemble the pieces) and Django (batteries-included, with its own ORM and admin) — but FastAPI's validation and docs make it an excellent place to learn the ideas.

Guided exercise

Open a terminal on linux01. Confirm your tools:

bash
python3 --version
text
Python 3.12.3

1. Create a project and a virtual environment. A virtual environment keeps this project's packages separate from the system Python:

bash
mkdir -p ~/taskapi
cd ~/taskapi
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

Your prompt now shows (.venv). Everything you install lands in ~/taskapi/.venv, not system-wide.

2. Install FastAPI and uvicorn.

bash
pip install "fastapi==0.141.1" "uvicorn[standard]==0.52.4"
uvicorn --version
text
Running uvicorn 0.52.4 with CPython 3.12.3 on Linux

Pinning exact versions means your service behaves the same today and next month. We will collect all pins into a requirements.txt in lesson 3.

3. Write the first app. Create main.py:

python
from fastapi import FastAPI

app = FastAPI(title="Task API", version="0.1.0")


@app.get("/")
def root():
    return {"service": "task-api", "version": "0.1.0"}


@app.get("/health")
def health():
    return {"status": "ok"}

app is your application. @app.get("/") registers the function below it to answer GET /. Returning a dict makes FastAPI send it as a JSON response with status 200.

4. Run it with uvicorn. main:app means "the object called app in main.py". --reload restarts the server when you edit a file — convenient while developing, never in production:

bash
uvicorn main:app --reload --port 8000
text
INFO:     Started server process [5006]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

5. Send it requests. Open a *second* terminal (leave the server running) and use curl:

bash
curl -s http://127.0.0.1:8000/
curl -s http://127.0.0.1:8000/health
text
{"service":"task-api","version":"0.1.0"}
{"status":"ok"}

You just made two HTTP requests and got two JSON responses. In the server's terminal you will see a log line for each, for example GET /health HTTP/1.1" 200 OK.

6. See the automatic documentation. FastAPI reads your routes and generates interactive API docs. Confirm the docs page is served:

bash
curl -s -o /dev/null -w "GET /docs -> HTTP %{http_code}\n" http://127.0.0.1:8000/docs
text
GET /docs -> HTTP 200

In a browser you would open http://127.0.0.1:8000/docs and try each endpoint from the page. The docs are generated from an OpenAPI schema FastAPI builds from your code; you will see it grow as you add routes. Stop the server with <kbd>Ctrl</kbd>+<kbd>C</kbd> when you are done.

Troubleshooting

Symptom → command not found: uvicorn. Cause: the virtual environment is not active. Fix: source ~/taskapi/.venv/bin/activate (the prompt shows (.venv)), then reinstall if needed.

Symptom → curl: (7) Failed to connect to 127.0.0.1 port 8000. Cause: the server is not running, or is on another port. Fix: check the server terminal for the "Uvicorn running on" line and match the port.

Symptom → Address already in use when starting uvicorn. Cause: an old server is still running on 8000. Fix: stop it with <kbd>Ctrl</kbd>+<kbd>C</kbd> in its terminal, or run on a different port with --port 8001.

Symptom → ModuleNotFoundError: No module named 'fastapi'. Cause: you installed into a different environment than the one running uvicorn. Fix: activate .venv, run pip install fastapi uvicorn[standard], and start uvicorn from the same shell.

Symptom → editing main.py does nothing. Cause: you started uvicorn without --reload. Fix: stop and restart with --reload during development.

Check your understanding

What are the three parts of an HTTP response, and which one tells the caller whether it succeeded?

A status code, headers, and a body. The status code signals success or failure — 2xx success, 4xx client error, 5xx server error — and the caller reads it to decide what to do next.

What is the difference between FastAPI and uvicorn?

FastAPI is the framework you write your routes and validation in. uvicorn is the server that listens on a network port and runs the FastAPI app. You need both: FastAPI defines *what* to do, uvicorn *runs* it.

Summary and next step

  • A backend answers HTTP requests (method, path, headers, body) with responses (status code, headers, body); an API speaks JSON.
  • FastAPI turns decorated Python functions into JSON routes and generates interactive docs; uvicorn serves the app.
  • You built and ran a two-route service in a virtual environment and called it with curl.

Next, in lesson 2, you will add real routes with path, query and body parameters, and let Pydantic validate the input and shape the output.

References

  • FastAPI documentation — https://fastapi.tiangolo.com/ (accessed 2026-09-13)
  • FastAPI — First Steps — https://fastapi.tiangolo.com/tutorial/first-steps/ (accessed 2026-09-13)
  • Uvicorn documentation — https://www.uvicorn.org/ (accessed 2026-09-13)
  • MDN — An overview of HTTP — https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview (accessed 2026-09-13)

Sign in to record your progress

Signing in saves eligible progress. It does not enroll you or include a lab; review the career path for access terms.

Sign in