💡 Also available: shared .NET version · JavaScript version · Java/Spring Boot version · Angular version · Kotlin version · Swift version
Duration: 15-20 minutes
Learning Objectives:
- Expand FastAPI endpoint coverage with pytest fixtures and
TestClient - Use Copilot to add clear Python docstrings without over-documenting
- Keep documentation aligned with the actual
src-python/files and commands - Write Conventional Commit drafts and a small review checklist for the Python track
- Treat testing, documentation, and workflow as part of the feature, not cleanup work
This lab focuses on the finishing work that often gets skipped when people are in a hurry:
- Testing - strengthen confidence in the POST and GET endpoints
- Documentation - add useful Python docstrings and concise usage notes
- Workflow - stage the right files and prepare clear commit or PR text
For the Python track, the workflow stays close to the code participants already built:
- FastAPI code lives under
src-python/task_manager_api/ - Application logic lives under
src-python/task_manager_application/ - starter persistence lives under
src-python/task_manager_infrastructure/ - tests live under
src-python/tests/ - verification runs with
pytest
- ✅ Labs 1-3 are complete, or you have equivalent Python-track code
- ✅ POST
/tasksand GET/tasksboth work in the FastAPI app - ✅
pytestalready runs successfully fromsrc-python/ - ✅ You are comfortable asking Copilot for tests, docs, and workflow text
Baseline verification:
cd src-python
pytestBy now, the Python track should have at least two endpoints:
POST /tasksGET /tasks
This is a good moment to stop testing one request at a time and introduce reusable pytest fixtures.
Prompt Copilot:
Add pytest fixture-based integration tests for the Python FastAPI track.
Requirements:
- files live under src-python/tests/task_manager_integration_tests/
- create a fixture that provides a fresh InMemoryTaskRepository
- create a fixture that provides a FastAPI TestClient wired to that repository
- test POST /tasks and GET /tasks
- keep the setup simple and workshop-friendly
A representative test file might look like this:
import pytest
from fastapi.testclient import TestClient
from task_manager_api.app import create_app
from task_manager_infrastructure import InMemoryTaskRepository
@pytest.fixture
def repository() -> InMemoryTaskRepository:
return InMemoryTaskRepository()
@pytest.fixture
def client(repository: InMemoryTaskRepository) -> TestClient:
app = create_app(repository)
return TestClient(app)
def test_create_task_returns_201(client: TestClient) -> None:
response = client.post(
"/tasks",
json={
"title": "Draft lab notes",
"description": "Prepare Python examples",
"priority": "HIGH",
},
)
assert response.status_code == 201
def test_get_tasks_returns_created_task(client: TestClient) -> None:
client.post(
"/tasks",
json={
"title": "Draft lab notes",
"description": "Prepare Python examples",
"priority": "HIGH",
},
)
response = client.get("/tasks")
assert response.status_code == 200
payload = response.json()
assert len(payload) == 1
assert payload[0]["title"] == "Draft lab notes"Strong additions usually cover things like:
- a valid POST returns
201 Created - invalid priority input returns a
4xxresponse - GET returns only active tasks
- GET returns tasks in the expected order
- each test gets a fresh in-memory repository via a fixture
cd src-python
pytestIf the tests pass, the API now has a stronger safety net.
In the .NET and Java tracks, this lab leans on XML doc comments or Javadoc. For Python, a better fit is short, accurate docstrings.
Good places to document include:
- the
CreateTaskHandlerorlist_tasks(...)application workflow - any mapping helper that turns Domain objects into response models
- the FastAPI app factory if you introduced one
- refactored helpers that encapsulate non-obvious legacy behavior
Try this prompt:
Review the Python track under src-python/ and suggest Google-style or reST-style docstrings for the public application functions, handlers, and API helpers.
Only add docstrings where they explain intent, parameters, or return values.
Do not add noisy comments that just repeat the code.
A useful result might look like:
class CreateTaskHandler:
"""Create and persist a new task using the configured repository."""
async def handle(self, command: CreateTaskCommand) -> Task:
"""Build a task from validated application input and save it."""Or for an application function:
async def list_tasks(repository: TaskRepository) -> list[Task]:
"""Return active tasks ordered from newest to oldest."""Useful docstrings explain:
- what the function is for
- what the main inputs mean
- what gets returned
- any business intent that is not obvious from the name alone
Avoid docstrings that just restate the function name.
For this track, documentation can also mean checking module-level docstrings or a small track README if one exists.
Try a prompt like:
Review the Python track documentation and module docstrings under src-python/.
Point out any mismatch between the documented commands, file paths, and the actual code layout.
Keep suggestions concise.
What you want to catch:
- paths that forgot the
src-python/prefix - commands that mention tools not used in this track
- docstrings that refer to Java or .NET concepts too literally
A typical Python-track change set might include:
git add src-python/task_manager_application/
git add src-python/task_manager_api/
git add src-python/task_manager_infrastructure/
git add src-python/tests/task_manager_integration_tests/
git add src-python/tests/task_manager_unit_tests/Try:
Write a Conventional Commit message for the Python workshop track.
The change expanded FastAPI integration tests, added Python docstrings, and cleaned up workflow documentation.
Include a short subject and a helpful body.
A good result might look like:
test(python): expand FastAPI coverage and docs
- add fixture-based pytest coverage for POST and GET task endpoints
- document application handlers and API helpers with concise docstrings
- align workflow guidance with the Python track file layout
Prompt Copilot Chat:
@workspace Draft a pull request description for the Python workshop track.
Include:
- summary of testing improvements
- documentation updates
- validation performed with pytest
- a short reviewer checklist
Use Markdown.
A representative result might look like:
## Summary
This change strengthens the Python workshop track by expanding FastAPI endpoint coverage,
adding concise docstrings to the application and API layers, and aligning workflow guidance
with the `src-python/` structure.
## Testing Performed
```bash
cd src-python
pytest
```
## Reviewer Checklist
- [ ] tests cover both POST and GET task flows
- [ ] fixtures provide isolated repository state per test
- [ ] docstrings explain intent rather than repeating code
- [ ] documented file paths start with `src-python/`Review the output before using it. Copilot is a drafting partner, not the final approver.
Run the Python track tests from src-python/:
cd src-python
pytestExpected result: ✅ tests pass.
You've completed this lab successfully when:
- ✅ endpoint tests use pytest fixtures instead of copy-pasted setup
- ✅ POST and GET routes both have realistic integration coverage
- ✅ public Python functions or handlers have concise, useful docstrings
- ✅ documented commands and paths match the real
src-python/layout - ✅ you can generate a Conventional Commit and PR draft for the Python track
- ✅
pyteststill passes
Problem: one test leaves data behind for the next test
Solution: make sure each fixture returns a new InMemoryTaskRepository instance and that the TestClient is created from that fresh instance.
Problem: every private helper now has a long block of text
Solution: keep docstrings for public or non-obvious code paths. Remove anything that only repeats the implementation.
Problem: Copilot introduced pytest-asyncio or other packages
Solution: stay within the workshop dependencies. Use FastAPI TestClient and regular pytest fixtures unless you truly need more.
Problem: the generated text says src/ or references another track
Solution: correct every command to use src-python/ and compare the draft against the actual repository structure.
After Lab 4, the Python track should leave you with the same overall workflow as the other tracks:
- write tests first
- translate requirements into small code changes
- refactor for readability
- document the important intent
- prepare clear commit and review text
That is the workshop journey, translated into Python and FastAPI.