922760de3e1a99dd237c18e8fb562b74f01c862a
🚧 Carrramba! Encore raté! 🚧
Resident of the Ile-de-France,
- Tired of missing your bus/train/metro ?
- Tired of having to walk to know where your bus/train/metro will stop ?
- Are you looking to display its next passages in the same way as Ile De France Mobilité ?
Visit carrramba.adrien.run
Technical stack
The following figure list the building blocks (docker images) and their interactions to provide the service:
@startuml
!include <C4/C4_Container>
!define ICONURL https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.4.0
!includeurl ICONURL/common.puml
!includeurl ICONURL/font-awesome-5/users.puml
!includeurl ICONURL/devicons2/redis.puml
!includeurl ICONURL/devicons2/sqlalchemy.puml
!includeurl ICONURL/devicons2/postgresql.puml
title Carrramba-encore-rate - Back-end
LAYOUT_WITH_LEGEND()
Person(user, "User", "The service user", $sprite="users")
System_Boundary(cb1, "carrramba-encore-rate") {
Container(app, "SPA", "SolidJS", "The graphical interface used by users to consume services provided")
Container(api, "carrramba-encore-rate-api", "FastAPI / Pydantic 2 / SQLAlchemy 2", "Provides the functionalities serving API endpoints", $sprite="sqlalchemy")
ContainerDb(db, "Postgres", "PostgreSQL database", "Stores stops/stop areas/lines/shapes and associations information.", $sprite="postgresql")
ContainerDb(cache, "In-Memory cache", "Redis", "Store previously computed results (stop, line, destination, next passages, shapes).", $sprite="redis")
Container(db_updater, "db-updater", "Sync the service static data with the IDFM ones")
}
System_Boundary(idfm, "IDFM") {
Container_Ext(static_, "Static data")
Container_Ext(dynamic_, "Dynamic data")
}
Rel(user, app, "Uses")
Rel(app, api, "Uses", "JSON/HTTPS")
Rel_R(api, db, "Reads from", "sync, PSQL")
Rel_L(api, cache, "Reads from and writes to", "sync, REdis Serialization Protocol")
Rel(api, dynamic_, "Get next passages", "JSON/HTTPS")
Rel_L(db_updater, db, "Writes to", "sync, PSQL")
Rel(db_updater, static_, "Get stops, lines andshapes")
@enduml
Back-end
Conventional but efficient:
- FastAPI: FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.8+ based on standard Python type hints.
- Pydantic 2: Pydantic is the most widely used data validation library for Python.
- Sqlalchemy 2: SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL.
The Msgspec library is used to serialize JSON objects collected from IDFM API endpoints, this library being faster than Pydantic.
Front-end
The component is developed using the SolidJS library. It brings the following interesting specificities:
- Share with React the same programmatic structures and support for component.
- Fine-grained reactivity architecture: no virtual DOM used to update the components, the browser DOM is directly updated by SolidJS.
The front-end tries to be as close as possible to the design defined by the IDFM for the displays deployed by the transport operators in Ile-de-France. These specifications are public and available here: PRIM-IDFM.
TODO
Features
- Integration with Matrix.org ecosystem: make the app able to send message to a room when a bus/train/metro will arriving in X minutes.
- Add the capability for the users to pin his/her favorite stops.
- Add the address to the stop location.
Docs
- Describe how to build the front-end and back-end docker images.
- Describe how to deploy them using
docker compose
. - Add back-end API description (openAPI) + generate documentation (mkdoc, Redoc). The best would be to build and deploy it (as docker images) using CI/CD... need to test Agola, Jaypore CI (pipelines configured in Python), Woodpecker or Drone before.
Front-end
- Add unit tests.
- Make the StopNameInput component liquid.
- Liquid to responsive Design.
Back-end
- Add unit tests.
- Use alembic to manage the future updates of the database schemas.
- Add the capability to reload the application configuration on configuration file update (e.g.: credential update by the vault).
- Rework how the database is updated with the IDFM data: For now the database is cleaned before refilling. It could be useful to avoid to empty the database and only apply deltas (update/add/remove rows).
- Could be nice to compare FastAPI with Litestar.
Description
Languages
TypeScript
45.5%
Python
44.1%
SCSS
9.8%
HTML
0.3%
Shell
0.2%