This API provides communication between end-users and the Fleet Management system. It enables a user to
- register and manage existing cars,
- define new stops and routes and make changes,
- send orders to the cars and review and manage them.
The data sent to the API is processed in other parts of the Fleet system into commands sent to the respective cars. In the other direction, the data from the cars is sent back to the API to make it accessible to the end-users.
The server code is written in Python language using the Flask framework.
The HTTP server uses a PostgreSQL database to store the data.
The HTTP API is described by the openapi/openapi.yaml
according to OpenAPI Specification.
A full specification can be found in the openapi
folder in the root folder.
The base of the server (e.g., entity models) was generated by the OpenAPI Generator project.
Python 3.10.12+
A list of the files created by the OpenAPI Generator can be found in the .openapi-generator/FILES
in the root directory. These files are not to be modified manually, as they are overwritten during the server re-generation.
The only exception is the fleet_management_api/controllers/security_controller.py
file, containing methods related to OAuth and API keys, that could not be moved to a manually maintainedfleet_management_api/api_impl
directory.
The server settings can be found in the config/config.json
, including the database logging information and parameters for the database cleanup.
The main parts of the configuration file are the following:
logging
- contains the keysconsole
andfile
for printing the logs into a console and a file, respectively. Thefile
contains fieldpath
to set the (absolute or relative) path to the directory to store the logs. Both contain the following keys:level
- logging level as a string (DEBUG
,INFO
,WARNING
,ERROR
,CRITICAL
). Case-insensitive.use
- set toTrue
to allow to print the logs, otherwise set toFalse
.
http_server
. Contains the server's URI and port.security
. Described here.database
. This contains the database connection configuration and the tables' parameters (e.g., the maximum number of stored records).api
. This sets up the behavior of the API (e.g., timeout of waiting for initially unavailable content).
Activate virtual environment and install dependencies.
python3 -m venv .venv
source .venv/bin/activate
pip3 install -r requirements.txt
Run the server:
python -m fleet_management_api <path-to-config-file> [OPTIONS]
The server automatically connects to the PostgreSQL database using data from the config file. If you want to override these values, start the server with some of the following options:
Option | Short | Description |
---|---|---|
--username |
-usr |
Username for the PostgreSQL database |
--password |
-pwd |
Password for the PostgreSQL database |
--location |
-l |
Location of the database (e.g., localhost ) |
--port |
-p |
Port number (e.g., 5430 ) |
--database-name |
-db |
Database name |
--test |
-t |
Valid path to file of testing database. Ignores previous options and use sqlite database instead. |
To visualize the API of the running server, go to http://localhost:8080/v2/management/ui
.
Your OpenAPI definition lives here: http://localhost:8080/v2/management/openapi.json
.
To rebuild and start the server in a Docker container, use
docker compose up --build
You must have the OpenAPI Generator installed (see link). Before the server generation, the server must be STOPPED.
To regenerate the server, run the regen.sh
script in the root directory:
If you have trouble with running the generator, visit docs.
In the root folder, run
pip install [-e] .
where -e
flag stands for editable installation.
You can uninstall the package using pip
by running
pip uninstall fleet_management_api
Set up the virtual environment and install the dependencies as described in the Starting the server locally section.
Install the tests dependencies and the project itself in editable mode:
pip install -r tests/requirements.txt
pip install -e .
In the root folder, run the following
python -m tests [-h] [PATH1] [PATH2] ...
Each PATH is specified relative to the tests
folder. If no PATH is specified, all the tests will run. Otherwise
- when PATH is a directory, the script will run all tests in this directory (and subdirectories),
- when PATH is a Python file, the script will run all tests in the file.
The -h
flag makes the script display tests' coverage in an HTML format, for example in your web browser.
python -m tests database controllers/test_car_controller.py
To generate a new API key (passed as a query parameter "api_key") run the following in the root directory:
python scripts/add_api_key.py <api-key-name> <path-to-config-file> [OPTIONS].
Option | Short | Description |
---|---|---|
--username |
-usr |
Username for the PostgreSQL database |
--password |
-pwd |
Password for the PostgreSQL database |
--location |
-l |
Location of the database (e.g., localhost ) |
--port |
-p |
Port number (e.g., 5430 ) |
--database-name |
-db |
Database name |
--test |
-t |
Valid path to file of testing database. Ignores previous options and use sqlite database instead. |
Working example for test database built from docker-compose (username and password can be found in the config/config.json
).
python scripts/add_api_key.py 'Bob' config/config.json
After running the script, the api_key is printed to the console:
Admin 'Bob' added with key:
MzLwgWGitBSDTNLjqktSnzNZQAjKaC
To get Keycloak authentication working, all parameters in the security section of config/config.json
need to be filled in. Most information is found in the Keycloak GUI.
"security": {
"keycloak_url": "https://keycloak.bringauto.com",
"client_id": "",
"client_secret_key": "",
"scope": "",
"realm": ""
}
- keycloak_url : base URL of a working Keycloak instance.
- client_id : ID of client in keycloak (Clients -> click on client representing http api -> Settings -> Client ID).
- client_secret_key : secret key of client (Clients -> click on client representing http api -> Credentials -> Client Secret).
- scope : checking of scopes is not yet implemented (must be
email
for now). - realm : realm in which the client belongs (seen on top of the left side panel in Keycloak GUI).
The API supports multi-tenancy. Each entity except for API keys and Tenants has a Tenant ID attribute representing the Tenant to which the entity belongs.
When creating or updating non-state Entities (including e.g. Car and excluding CarState), the tenant has to be set in a cookie or in the header of the request to inform the server to which tenant the entity belongs.
The server supports the semi-automatic setup of the tenant cookie for cases, when it cannot be set up directly (an example is the Swagger UI).
This is done by calling the HEAD
method on the endpoint /v2/management/tenant/{tenantId}
- the server will then send response including the header Set-Cookie
with the tenant ID.
The given client should then use this header to set up the tenant cookie.
Note that when the tenant name is known, its corresponding tenantId
can be found by calling the GET method on the endpoint /v2/management/tenant
, listing all tenants the client has access to.
See the docs for more information on the access to tenants.
Before contributing to the project, make sure you have read the section (testing)[#testing] and (server re-generation)[#server-re-generation].
Also, see the docs that might contain important notes on how to create and modify API models and controllers.