REST API built with Python + FastAPI that exposes read and write operations directly on the RackTables MySQL database, eliminating the need to interact manually with raw SQL queries or the legacy web interface.
Once running, interactive documentation is available at
http://localhost:8000/docs(Swagger UI) andhttp://localhost:8000/redoc(ReDoc).
- About
- Tech Stack
- Project Structure
- Prerequisites
- Installation and Configuration
- Running the API
- Endpoints
- Usage Examples
- HTTP Status Codes
The RackTables REST API is an integration layer developed by INPE — National Institute for Space Research (Brazil). It abstracts RackTables SQL queries into standardized RESTful endpoints for managing data center inventory resources: Locations, Rows, Racks, Objects, and Allocations.
This is a free and open-use API.
Covered resources:
- Health Check — API status monitoring
- Locations — physical data center location management
- Rows — rack row organization and location binding
- Racks — creation, renaming, and per-unit occupancy queries
- Objects — registration and update of equipment (servers, switches, UPS, etc.)
- Object Summary — read and write of fixed and dynamic attributes per equipment
- Allocations — mounting and unmounting equipment at specific rack units
- Move — atomic server transfer between racks
| Technology | Purpose |
|---|---|
| Python 3 | Primary language |
| FastAPI | Web framework |
| Pydantic | Data validation and serialization |
| mysql-connector | MySQL connector |
| Uvicorn | ASGI server |
| Docker | Containerization |
| python-dotenv | Environment variable management |
racktables-rest-api/
│
├── app/
│ ├── main.py # FastAPI entry point
│ │
│ ├── core/
│ │ └── databaseConnection.py # MySQL connection management
│ │
│ ├── routers/ # HTTP routing layer
│ │ ├── objects/
│ │ │ ├── objects_router.py
│ │ │ └── allocateObjects_router.py
│ │ └── rackspace/
│ │ ├── manageLocations_router.py
│ │ ├── rack_router.py
│ │ └── rows_router.py
│ │
│ ├── service/ # Business logic layer
│ │ ├── objects/
│ │ │ ├── objects_service.py
│ │ │ └── allocateObjects_service.py
│ │ └── rackspace/
│ │ ├── manageLocations_service.py
│ │ ├── rack_service.py
│ │ └── rows_service.py
│ │
│ ├── repository/ # Data access layer (SQL queries)
│ │ ├── objects/
│ │ │ ├── objects_repository.py
│ │ │ └── allocateObjects_repository.py
│ │ └── rackspace/
│ │ ├── manageLocations_repository.py
│ │ ├── rack_repository.py
│ │ └── rows_repository.py
│ │
│ └── schema/ # Pydantic schemas
│ ├── objects/
│ │ ├── objects_schema.py
│ │ └── allocateObjects_schema.py
│ └── rackspace/
│ ├── manageLocations_schema.py
│ ├── rack_schema.py
│ └── rows_schema.py
Request flow:
HTTP Client
│
▼
[Router] → validates route and HTTP method
│
▼
[Service] → applies business rules
│
▼
[Repository] → executes MySQL queries
│
▼
[MySQL — RackTables Database]
- Python 3.8+
- MySQL with the RackTables database configured
- Docker (optional)
1. Clone the repository
git clone https://github.com/luisfilippe650/racktables-rest-api.git
cd racktables-rest-api2. Install dependencies
pip install -r requirements.txt3. Configure environment variables
Create a .env file at the project root:
DB_HOST=localhost
DB_PORT=3307
DB_USER=root
DB_PASSWORD=root
DB_NAME=racktablesDevelopment mode (with hot reload):
uvicorn app.main:app --reloadSpecifying host and port:
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reloadWith Docker:
docker build -t racktables-api .
docker run -p 8000:8000 --env-file .env racktables-apiThe API will be available at http://localhost:8000.
All endpoints use the prefix /v1/racktables/. For full request and response schemas, see http://localhost:8000/docs.
| Method | Route | Description |
|---|---|---|
GET |
/v1/racktables/status/ |
Checks whether the API is online and operational |
| Method | Route | Description |
|---|---|---|
GET |
/v1/racktables/locations/ |
Lists all locations |
POST |
/v1/racktables/locations/ |
Creates a new location |
DELETE |
/v1/racktables/locations/{location_id} |
Removes a location by ID |
GET |
/v1/racktables/locations/rows |
Lists locations with their associated rows |
Schema — Create Location:
{
"name": "string"
}| Method | Route | Description |
|---|---|---|
GET |
/v1/racktables/rows/ |
Lists all rows |
POST |
/v1/racktables/rows/ |
Creates a new row |
DELETE |
/v1/racktables/rows/{row_id} |
Removes a row by ID |
PATCH |
/v1/racktables/rows/{row_id} |
Updates a row name |
GET |
/v1/racktables/rows/racks |
Lists rows with their associated racks |
PUT |
/v1/racktables/rows/{row_id}/{location_id} |
Binds a row to a location |
DELETE |
/v1/racktables/rows/{row_id}/{location_id} |
Removes the binding between a row and a location |
Schema — Create / Rename Row:
{
"name": "string"
}| Method | Route | Description |
|---|---|---|
GET |
/v1/racktables/racks/ |
Lists all racks |
POST |
/v1/racktables/racks/ |
Creates a new rack |
GET |
/v1/racktables/racks/{rack_id} |
Returns details of a specific rack |
PATCH |
/v1/racktables/racks/{rack_id} |
Updates a rack name |
DELETE |
/v1/racktables/racks/{rack_id} |
Removes a rack by ID |
GET |
/v1/racktables/racks/occupancy |
Returns occupancy for all racks |
GET |
/v1/racktables/racks/{rack_id}/occupancy |
Returns occupancy for a specific rack |
Schema — Create Rack:
{
"name": "string",
"rack_height": 42,
"row_id": 0,
"asset_no": "string"
}
rack_heightis optional (default:42).row_idis required.
| Method | Route | Description |
|---|---|---|
GET |
/v1/racktables/objects/ |
Lists all registered objects |
POST |
/v1/racktables/objects/ |
Creates a new object |
DELETE |
/v1/racktables/objects/{object_id} |
Removes an object by ID |
PATCH |
/v1/racktables/objects/{object_id} |
Updates an object's name or comment |
GET |
/v1/racktables/objects/types |
Lists all available object types |
Schema — Create Object:
{
"name": "string",
"label": "string",
"asset_no": "string",
"objtype_id": 0
}Schema — Update Object (PATCH):
{
"name": "string",
"comment": "string"
}Both fields are optional. Send only what you want to update.
Allows querying and updating detailed attributes of an equipment item, including fixed fields (name, label, asset_no) and dynamic RackTables attributes (Serial, Height, etc.).
| Method | Route | Description |
|---|---|---|
GET |
/v1/racktables/summary/{object_id} |
Returns all attributes of an object |
PATCH |
/v1/racktables/summary/{object_id}/attributes |
Updates fixed and/or dynamic attributes of an object |
Schema — Update Attributes (PATCH):
The body accepts a free-form JSON object with any combination of fixed fields and dynamic attributes:
{
"name": "srv-prod-01",
"asset_no": "PAT-0042",
"Serial": "SN123456",
"Height": 2
}| Method | Route | Description |
|---|---|---|
POST |
/v1/racktables/mount/ |
Mounts an object at a rack position |
DELETE |
/v1/racktables/mount/{object_id} |
Unmounts an object from the rack |
Schema — Mount Object:
{
"rack_id": 0,
"object_id": 0,
"start_unit": 0,
"height": 0
}All fields are required.
| Method | Route | Description |
|---|---|---|
POST |
/v1/racktables/move/ |
Moves a server from one rack to another |
Schema — Move Server:
{
"object_id": 0,
"destination_rack_id": 0,
"start_unit": 0,
"source_rack_id": 0,
"height": 0
}
start_unitandheightrefer to the position in the destination rack.source_rack_idandheightare optional.
curl http://localhost:8000/v1/racktables/status/curl -X POST http://localhost:8000/v1/racktables/locations/ \
-H "Content-Type: application/json" \
-d '{"name": "Server Room A"}'{
"id": 29,
"name": "Server Room A",
"message": "Location created successfully"
}# Create the row
curl -X POST http://localhost:8000/v1/racktables/rows/ \
-H "Content-Type: application/json" \
-d '{"name": "Row 01"}'
# Bind row (id: 10) to location (id: 29)
curl -X PUT http://localhost:8000/v1/racktables/rows/10/29curl -X POST http://localhost:8000/v1/racktables/racks/ \
-H "Content-Type: application/json" \
-d '{
"name": "Rack A1",
"rack_height": 42,
"row_id": 10,
"asset_no": "PAT-001"
}'{
"message": "Rack created successfully",
"rack_id": 27
}curl http://localhost:8000/v1/racktables/racks/27/occupancy{
"rack_id": 27,
"rack_name": "Rack A1",
"total_units": 42,
"occupied_units": [1, 2],
"free_units": [3, 4, 5, "..."]
}# Create the object
curl -X POST http://localhost:8000/v1/racktables/objects/ \
-H "Content-Type: application/json" \
-d '{
"name": "srv-prod-01",
"label": "Production Server",
"asset_no": "PAT-0042",
"objtype_id": 4
}'
# Mount object (id: 31) in rack (id: 27), starting at unit 10, height 2U
curl -X POST http://localhost:8000/v1/racktables/mount/ \
-H "Content-Type: application/json" \
-d '{
"rack_id": 27,
"object_id": 31,
"start_unit": 10,
"height": 2
}'{
"message": "Server allocated successfully",
"rack_id": 27,
"object_id": 31,
"start_unit": 10,
"end_unit": 9,
"height": 2
}curl -X PATCH http://localhost:8000/v1/racktables/summary/31/attributes \
-H "Content-Type: application/json" \
-d '{
"name": "srv-prod-01-renamed",
"Serial": "SN987654",
"Height": 2
}'curl -X POST http://localhost:8000/v1/racktables/move/ \
-H "Content-Type: application/json" \
-d '{
"object_id": 31,
"source_rack_id": 27,
"destination_rack_id": 35,
"start_unit": 5,
"height": 2
}'curl -X DELETE http://localhost:8000/v1/racktables/mount/31{
"message": "Server deallocated successfully",
"object_id": 31,
"rack_id": 27,
"units_removed": [9, 10]
}| Code | Status | Description |
|---|---|---|
200 |
OK | Request processed successfully |
201 |
Created | Resource created successfully |
400 |
Bad Request | Invalid data in the request body |
404 |
Not Found | Resource not found |
422 |
Unprocessable Entity | Missing or malformed JSON body |
500 |
Internal Server Error | Server error or database connection failure |