sequenceDiagram
participant Client as Client
participant Router as API Router (main)
participant WS as PlayerController
participant Service as PlayerService
participant DAO as PlayerDao
Client->>Router: GET /player/1
Note right of Router: Route matching /player
Router->>WS: player_by_id(id_player=1)
WS->>Service: find_by_id(1)
Service->>DAO: find_by_id(1)
DAO-->>DAO: Database request <br/>SELECT *<br/>FROM player<br/> WHERE id = 1
DAO-->>Service: Player instance (or None)
Service-->>WS: Player instance (or None)
alt Player found
WS-->>Client: 200 OK <br/> JSON {id_player: 1, username: "...", ...}
else Player not found
WS-->>Client: 404 Not Found <br/> {"detail": "Player not found"}
end
Git, Example of Application
- pyproject.toml -> remplace requirements.txt & co
- typst
Objectives
The objectives of this first tutorial are as follows:
- Overview of the structure of a backend/frontend application
- Getting to grips with VS Code and its settings
- Reminders on using Git
- Init your projet tools
This tutorial combines explanations and code phases.
The explanations in this tutorial should not take precedence over those of your instructor. Use them as a knowledge base for later, but always prefer oral explanations.
You will be using the following tools:
- Python 3.13
- Visual Studio Code
- Git
- PostgreSQL
- cloudBeaver
Don’t skip a step that didn’t work, telling yourself that it doesn’t matter.
This may cause problems later.
1 Accounts and Configuration
The practical labs will be carried out on Datalab SSPCloud: https://datalab.sspcloud.fr/
You can also work on the GENES Datalab, but you’ll have to perform certain steps manually.
1.1 GitHub account
GitHub is a web-based platform that provides hosting for software development and version control using Git.
It’s widely used by developers to collaborate on projects.
-
- or sign up if you don’t already have one
1.2 GitHub Token
To avoid having to identify yourself every time you want to push code onto GitHub from a Datalab service, you will to generate a Token.
If you’re sure your token is still active, you can skip this step. If not, create a new one.
Follow instructions on ENSAI-tools to:
1.3 AI agent
AI is a force multiplier, not a substitute for expertise. If you know your subject, it will elevate your work; if you don’t, it will simply help you make mistakes faster.
Using AI without a solid foundation is like driving a high-speed car without knowing how to steer: you’ll get somewhere quickly, but you might crash along the way.
Using an AI agent directly within VSCode transforms your editor from a simple text tool into an intelligent collaborator.
By having full access to your local files and project structure, the agent understands the specific context of your codebase. This allows it to suggest highly relevant code snippets, automate repetitive boilerplate, and perform complex refactoring tasks without you ever having to leave your development environment.
To use it in VS Code, there are a few steps you need to take first:
2 Repositories creation
For this first tutorial, you will work with your project team on a single remote repository.
One member of the team will create a repository on GitHub and then all the members (including the creator of the GitHub repository) will create their local repositories by cloning this remote repository.
2.1 Remote repository
A single team member creates this remote repository.
This is the shared central repository for all project members to synchronize their work during labs.
-
- Button Use this template
-
- On the repository page > ⚙️ Settings > Collaborators >
2.2 Datalab service
Before creating your local repositories, you will launch a VSCode-python service.
But you will not launch directly the catalog service. You will custom it first by:
- adding/removing some extensions
- installing needed packages
- opening ports to the internet
Let’s do this manually:
If you don’t expose both ports, you will have no choice but to start over with creating your VScode-python service and everything that follows.
When you change the default settings for starting a service, you can:
- save that configuration
- also generate a link that starts the service using that configuration
2.3 Local repositories
Once the VSCode service is up and running, your local clone should already be created. 🪄
Let’s check it using a terminal:
-
- Top left, icon with 3 horizontal bars > Terminal > New
- or use shortcut CTRL + SHIFT + C
-
- You should see your cloned repository
-
- Manually: File > Open Folder >
/home/onyxia/work/<repo_name>> OK - Or command:
code-server /home/onyxia/work/ENSAI-2A-projet-info-template
- Manually: File > Open Folder >
This opens a new tab with your project set as the root of your file explorer.
-
- Close the previous tab
-
git remote -v
You should be connected via push and fetch (pull) to the URL of your remote repository, including the token:
$ git remote -v
origin https://ghp_dadadirladada@github.com/ludo2ne/ENSAI-2A-projet-info-template.git (fetch)
origin https://ghp_dadadirladada@github.com/ludo2ne/ENSAI-2A-projet-info-template.git (push)Otherwise, check the same link as above (“If the clone creation failed”) to connect your repository properly.
3 Repository content
| Folder | Description |
|---|---|
| backend/ | The heart of your application, following a Layered Architecture |
| frontend/ | The user interface code (Streamlit application). |
| doc/ | Stores project documentation, diagrams, tracking and report |
| data/ | Used for storing persistent data, such as database files or datasets. |
| .github/ | Contains CI/CD workflows (GitHub Actions) and automation scripts. |
| .vscode/ | Stores editor settings, extensions, and debugger configurations. |
In both backend and frontend folders, you will find these files :
| File | Description |
|---|---|
| pyproject.toml | Defines project metadata, dependencies, and build configurations. |
| uv.lock | A lockfile that ensures exact, reproducible dependency versions. |
| logging.yaml | Configuration file defining how the application logs information. |
Let’s focus on some files.
3.1 README
The README file is essential for every project. It contains all the information needed to describe, install and use the application.
Follow instructions to :
You will notice that you need to connect to a PostgreSQL database.
-
- Ressources tab > Persistent volume size: 1Gi
3.2 VSCode settings
The .vscode/settings.json file is the central configuration file for VS Code, allowing you to customize the editor through code instead of menus.
You use it to control everything from themes and fonts to code formatting, auto-completion behaviors, and extension settings.
Most of these settings concern the automatic formatting of code when you save a file:
- Formatter: Ruff
"editor.formatOnSave": true: apply format when you save a file"editor.insertSpaces": true: replace tabulation by spaces
3.3 pyproject.toml
A pyproject.toml file centralizes project configuration. Here is what it contains:
- Project Metadata: Name, version, description, authors, etc.
- Dependencies: Core libraries required to run the app
- including dev libraries (only for development)
- Build System: Instructions for Python tools on how to install and build your package.
- Tool Configuration: Settings for various tools (e.g.,
pytest,ruff, etc.) to avoid having multiple config files.
3.4 uv.lock
uv is the engine that manages your project, and uv.lock is the snapshot that guarantees everyone uses the exact same setup.
uv is an extremely fast Python package and project manager, written in Rust. It is designed to replace multiple tools at once (like pip and venv).
- It is significantly faster than
pipfor installing dependencies - It manages Python versions, virtual environments, and package dependencies
The uv.lock file is a “lockfile” that records the exact state of your project’s dependency tree.
- Deterministic Installs: While
pyproject.tomlmight say “I need FastAPI version 0.100 or higher,” theuv.lockfile records that you are using exactlyFastAPI 0.109.2and specifies the exact versions of every sub-dependency - Reproducibility: It ensures that if a teammate clones your repo or if you deploy to a server, they get the identical environment you have. It eliminates the “it works on my machine” problem
- Integrity: It contains hashes for every package, ensuring that the files downloaded are exactly what was expected and haven’t been tamelred with
4 Application example
You might design a Web services (mandatory) and/or a Menu-driven interface (optional):
- Web services: User interaction via API endpoints to retrieve data
- Menu-driven apps: User interaction via navigation menus
4.2 A webservice
We will discuss webservices in more detail in Lab 3.
-
- Once it starts, don’t click on the pop-up. It won’t work!
- Internal: Use curl within the service environment.
- External: Use the public URL to access the service through the exposed port (5000).
Let’s start by querying the web service from the inside:
Then from the outside:
Using this link, even your neighbor can access it.
You are being redirected to the /docs endpoint, the Swagger API.
If the request was successful, you will receive an HTTP 200 code and a response body.
| Code Range | Type | Category | Brief Description |
|---|---|---|---|
| 2xx | Success | Success | The action was successfully received, understood, and accepted. |
| 4xx | Client Error | Client Error | The request contains bad syntax or cannot be fulfilled by the client. |
| 5xx | Server Error | Server Error | The server failed to fulfill an apparently valid request. |
| Code | Type | Description |
|---|---|---|
| 200 | Success | OK: The request succeeded. |
| 201 | Success | Created: Request fulfilled and a new resource was created. |
| 400 | Client Error | Bad Request: The server cannot process the request due to client error. |
| 401 | Client Error | Unauthorized: Authentication is required and has failed or not been provided. |
| 403 | Client Error | Forbidden: The client does not have access rights to the content. |
| 404 | Client Error | Not Found: The server cannot find the requested resource. |
| 405 | Client Error | Method Not Allowed: The request method (GET, POST, etc.) is not supported. |
| 500 | Server Error | Internal Server Error: A generic error message when an unexpected condition was encountered. |
| 502 | Server Error | Bad Gateway: The server received an invalid response from an upstream server. |
| 503 | Server Error | Service Unavailable: The server is not ready to handle the request (e.g., maintenance). |
🚧
TODO Pas la bonne manière de faire, il faut utiliser un PlayerReadModel sans pwd et token
Feel free to test GET requests using curl and/or the Swagger
For other types of http request (PUT, POST, DELETE), you will see how to make these requests in a later tutorial.
This diagram shows how a request to fetch a player travels through the application layers, from the API router to the database.
Now that our API is up and running, it’s quite satisfying to see it working. However, interacting with raw JSON isn’t exactly a luxury—this is where a proper user interface comes in.
5 Git
You’re going to do a few basic things with Git :
- Add files to the repository
- Create save points
- Send your local modifications to remote repositories
- Update your local repository
5.1 Git routine
You modified some files, it’s time to update the remote repository:
if "you're the first teammate to push the code":
everything_is_fine = True
else:
action = "you have to pull first"
conflict_probability = 0.95The sequence of Git commands should become automatic.
Read the Git messages carefully!
If you need to simulate a conflict, ask a teammate to edit the first line of the README, then add, commit, and push.
On your end, do the same thing; it will prompt you to pull, and that’s it.
5.2 Handling conflicts
If a teammate has already pushed changes to the same file you are working on, Git will block your push and ask you to pull first. During this process, you might encounter a Merge Conflict.
Don’t panic! A conflict just means Git doesn’t know which version of the code to keep. Follow these steps:
<<<<<<< HEAD
Your local changes (the ones you just wrote)
=======
The remote changes (the ones your teammate pushed)
>>>>>>> [commit_hash_or_branch_name]
-
- Keep only your code: Accept Current Change
- Keep only the teammate’s code: Accept incoming change
- Combine both: manually edit the code, then delete all markers
Having a conflict isn’t a big deal!
Having a conflict isn’t a big deal!
Having a conflict isn’t a big deal!
Conflict ≠ Error
This simply happens when Git encounters 2 versions and it doesn’t have a 🔮 or a 🎲 to choose which is the right one.
To avoid conflicts, get organised with your team to avoid working on the same files at the same time as much as possible.
Now that you’ve seen what an application looks like and you’re up and running with Git, let’s create your real project repository.
6 Create your project repository
You can start from scratch, or use a template.
A team member :
-
- Repository name:
ensai-it-project-2a-team<N>. - Public (recommended) or Private
- Check Add a README file
- .gitignore : Python
- Choose a license : Apache, GNU, MIT…
- Repository name:
Next, each team member :
-
- In the same VSCode service (⚠️ use your token) or in a new one
-
- doc/tracking/2025.09.03-week1.md: the first weekly point
- README.md
- main.py
Afterwards, you’ll make sure that your depot is “tidy”, in the same way as described in the previous section.
6.1 .env file
This file will contain environment variables that will be used, for example, to connect to the PostgreSQL database.
6.2 PostgreSQL database
You can either:
- Each set up your own PostgreSQL service and connect your application to it
- Set up and share a single database and have everyone connect to it
| Approach | Pros | Cons |
|---|---|---|
| Shared DB | Zero setup: Everyone connects to the same URL. Data Sync: Everyone sees the same rows. |
High Risk: One accidental DROP TABLE or DELETE breaks the project for everyone. Conflict: You can’t test “deleting a user” if your teammate is currently using that user. |
| Isolated DB | Safety: You can break your local table without consequences. Independence: You can test different data states simultaneously. |
Sync Effort: You must remember to git commit the .sql file every time you change a column. Drift: If someone forgets to commit, the team’s environments will diverge. |
In any case, be sure to version one or more SQL files so that you can rebuild your database and data from scratch.
The aim of this tutorial was to get you up to speed on using Git, and to help you discover and understand how a layered application works.
End of the Lab
When you have finished coding, don’t forget to:
-
- If your service is terminated, all unpushed code is lost…
-
- to free up reserved resources