Skip to content

LLG-Mapper/api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

API

Overview

This project contains the API source code that is hosted on a different server.

The complete REST API is documented below. All endpoints return JSON responses and validate input using Marshmallow schemas.


Health Check:

GET /health → {"status": "ok"}

Main Endpoints:

  • /buildings - Building management
  • /rooms - Room availability and filtering
  • /classes - Class scheduling

🚀 Getting Started

Prerequisites

  • Python 3.8 or higher
  • pip (Python package manager)
  • Modern web browser (Chrome, Firefox, Safari, Edge)

Installation & Setup

1. Clone the Repository

git clone https://github.com/LLG-Mapper/api.git
cd api

Or clone using GitHub Desktop

2. First-Time Setup

Windows

# From api/ directory
scripts\setup

macOS/Linux

# From api/ directory
./scripts/setup.sh # macOS/Linux

3. Start the API Server

Windows

# From api/ directory
scripts\start

macOS/Linux

# From api/ directory
./scripts/start.sh # macOS/Linux

The API will be available at http://localhost:5000 (development mode).


🛠️ Technology Stack

  • Framework: Flask 3.1.2
  • ORM: SQLAlchemy 2.0.45
  • Database: SQLite (development), configurable for production
  • Serialization: Marshmallow 3.21.3
  • Migrations: Flask-Migrate with Alembic
  • CORS: Flask-CORS 6.0.2

📁 Project Structure

api/
├── app/
│   ├── __init__.py              # Flask app factory
│   ├── config.py                # Configuration
│   ├── extensions.py            # Flask extensions
│   ├── models/                  # SQLAlchemy ORM models
│   │   ├── building.py
│   │   ├── room.py
│   │   ├── class_.py
│   │   ├── teacher.py
│   │   ├── group.py
│   │   ├── subject.py
│   │   ├── feature.py
│   │   ├── room_type.py
│   │   └── enums.py
│   ├── schemas/                 # Marshmallow validation
│   │   ├── building.py
│   │   ├── room.py
│   │   ├── class_.py
│   │   ├── teacher.py
│   │   ├── group.py
│   │   ├── subject.py
│   │   ├── feature.py
│   │   └── room_type.py
│   ├── routes/                  # API endpoints
│   │   ├── buildings.py
│   │   ├── rooms.py
│   │   ├── classes.py
│   │   ├── health.py
│   │   └── __init__.py
│   └── services/                # Business logic
│       └── availability_service.py
├── migrations/                  # Database migrations
├── scripts/                     # Database setup
├── app.py                       # Entry point
├── requirements.txt
└── README.md                    # Project overview (this file)

📊 Database Schema

Data Models

Building

Main building/campus entity for organizing rooms.

Field Type Constraints
id Integer Primary Key
name String(50) Unique, Required
code String(3) Unique, Required
floor Integer Default: 0 (for uneven grounds)

Example:

{
  "id": 1,
  "name": "Victor Hugo",
  "code": "VH",
  "floor": 1
}

RoomType

Classification of room types (classroom, lab, auditorium, etc.).

Field Type Constraints
id Integer Primary Key
name String(50) Unique, Required
code String(10) Unique, Required

Example:

{
  "id": 1,
  "name": "Laboratory",
  "code": "LAB"
}

Feature

Room amenities/equipment (projector, whiteboard, computers, etc.).

Field Type Constraints
id Integer Primary Key
name String(50) Unique, Required
code String(10) Unique, Required

Example:

{
  "id": 1,
  "name": "Projector",
  "code": "PROJ"
}

Room

Physical classroom or space.

Field Type Constraints
id Integer Primary Key
number Integer Required
name String(50) Optional (auto: {building.code}{number})
building_id Integer Foreign Key → Building
floor Integer Required
capacity Integer Optional
is_open Boolean Default: true
type_id Integer Foreign Key → RoomType
locationX Integer Required (map coordinate)
locationY Integer Required (map coordinate)
sizeX Integer Required (map dimension)
sizeY Integer Required (map dimension)

Relationships:

  • Building (Many-to-One)
  • RoomType (Many-to-One)
  • Features (Many-to-Many via room_features)
  • Classes (One-to-Many)

Example:

{
  "id": 1,
  "number": 209,
  "name": "VH209",
  "building": {"id": 1, "name": "Victor Hugo", "code": "VH", "floor": 1},
  "floor": 2,
  "capacity": 40,
  "is_open": true,
  "type": {"id": 1, "name": "Classroom", "code": "CLASS"},
  "location": [130, 47],
  "size": [60, 40],
  "features": [
    {"id": 1, "name": "Projector", "code": "PROJ"},
    {"id": 2, "name": "Whiteboard", "code": "WBOARD"}
  ]
}

Subject

Academic subject (Math, French, Physics, etc.).

Field Type Constraints
id Integer Primary Key
name String(50) Unique, Required
code String(10) Unique, Required
color Enum(Color) Default: BLUE

Color Options: BLUE, GREEN, RED, YELLOW, PURPLE, ORANGE, GRAY

Example:

{
  "id": 1,
  "name": "Mathematics",
  "code": "MATH",
  "color": "BLUE"
}

Teacher

Instructor information.

Field Type Constraints
id Integer Primary Key
name String(50) Required
surname String(50) Required
gender Boolean Required (true=F, false=M)
subject_id Integer Foreign Key → Subject (Optional)

Relationships:

  • Subject (Many-to-One)
  • Classes (One-to-Many)

Example:

{
  "id": 1,
  "name": "Michel Dupont",
  "surname": "Dupont",
  "gender": false,
  "subject": {"id": 1, "name": "Mathematics", "code": "MATH", "color": "BLUE"}
}

Note: Response includes formatted name with gender prefix (M/Mme.)


Group

Student class/cohort.

Field Type Constraints
id Integer Primary Key
name String(50) Required
grade Enum(Grade) Required

Grade Options:

  • 10 = 2nde (Grade 10)
  • 11 = 1ère (Grade 11)
  • 12 = Terminale (Grade 12)
  • 13 = CPGE 1 (Grade 13)
  • 14 = CPGE 2 (Grade 14)

Example:

{
  "id": 1,
  "name": "2nd-1",
  "grade": 10
}

Class

Scheduled class session.

Field Type Constraints
id Integer Primary Key
room_id Integer Foreign Key → Room (Required)
teacher_id Integer Foreign Key → Teacher (Required)
group_id Integer Foreign Key → Group (Required)
subject_id Integer Foreign Key → Subject (Required)
start_date Date Required
end_date Date Optional (NULL = one-off session)
start_time Time Required
end_time Time Required
recurrence Enum(Frequency) Default: WEEKLY
weekday Integer 0=Monday, 6=Sunday (optional)

Weekdays 0 = Monday ... 6 = Sunday

Recurrence Options:

  • ONCE = One-time session
  • WEEKLY = Every week
  • WEEK_A = Alternating week A
  • WEEK_B = Alternating week B

Relationships:

  • Room (Many-to-One)
  • Teacher (Many-to-One)
  • Group (Many-to-One)
  • Subject (Many-to-One)

Example:

{
  "id": 1,
  "room": {...},
  "teacher": {...},
  "group": {...},
  "subject": {...},
  "start_date": "2024-01-15",
  "end_date": "2024-06-30",
  "start_time": "09:00:00",
  "end_time": "10:00:00",
  "recurrence": "WEEKLY",
  "weekday": 0
}

API Endpoints

Endpoint Reference

Active Endpoints:

Planned Endpoints (Coming Soon):

  • Room Types

    • GET /room-types - List room types
    • POST /room-types - Create room type
  • Features

    • GET /features - List features
    • POST /features - Create feature
  • Teachers

    • GET /teachers - List teachers
    • GET /teachers/{id} - Get teacher by ID
    • POST /teachers - Create teacher
  • Groups

    • GET /groups - List groups
    • POST /groups - Create group

Health Check

GET /health

Response (200 OK):

{
  "status": "ok"
}

Buildings

List All Buildings

GET /buildings

Response (200 OK):

[
  {
    "id": 1,
    "name": "Victor Hugo",
    "code": "VH",
    "floor": 1
  }
]

Get Building by ID

GET /buildings/{id}

Create Building

POST /buildings
Content-Type: application/json

{
  "name": "Molière",
  "code": "M",
  "floor": 0
}

Response (201 Created):

{
  "id": 1,
  "name": "Molière",
  "code": "M",
  "floor": 0
}

Update Building

PUT /buildings/{id}
Content-Type: application/json

{
  "floor": 1
}

Delete Building

DELETE /buildings/{id}

Response (204 No Content)


Rooms

List Rooms (with filtering & availability)

GET /rooms?building_id=1&floor=2&feature_codes=PROJ,WBOARD&is_available=true&availability_at=2024-01-15T09:00:00

Query Parameters:

Parameter Type Description
building_id integer Filter by building
floor integer Filter by floor number
feature_codes string[] Filter by features (comma-separated codes)
is_available boolean Filter by availability status
availability_at ISO datetime Check availability at specific time

Response (200 OK):

[
  {
    "id": 1,
    "number": 209,
    "name": "VH209",
    "building": {...},
    "floor": 2,
    "capacity": 40,
    "is_open": true,
    "type": {...},
    "location": [130, 47],
    "size": [60, 40],
    "features": [...]
  }
]

Or with availability:

{
  "availability_at": "2024-01-15T09:00:00",
  "rooms": [...]
}

Get Room by ID

GET /rooms/{id}

Create Room

POST /rooms
Content-Type: application/json

{
  "number": 209,
  "name": "VH209",
  "building_id": 1,
  "floor": 2,
  "capacity": 40,
  "is_open": true,
  "type_id": 1,
  "locationX": 130,
  "locationY": 47,
  "sizeX": 60,
  "sizeY": 40,
  "feature_ids": [1, 2]
}

Response (201 Created):

{
  "id": 1,
  "number": 209,
  "name": "VH209",
  ...
}

Update Room

PUT /rooms/{id}
Content-Type: application/json

{
  "capacity": 45,
  "is_open": false,
  "feature_ids": [1, 3]
}

Delete Room

DELETE /rooms/{id}

Response (204 No Content)


Classes

List Classes

GET /classes

Response (200 OK):

[
  {
    "id": 1,
    "room": {...},
    "teacher": {...},
    "group": {...},
    "subject": {...},
    "start_date": "2024-01-15",
    "end_date": "2024-06-30",
    "start_time": "09:00:00",
    "end_time": "10:00:00",
    "recurrence": "WEEKLY",
    "weekday": 0
  }
]

Get Class by ID

GET /classes/{id}

Create Class

POST /classes
Content-Type: application/json

{
  "room_id": 1,
  "teacher_id": 1,
  "group_id": 1,
  "subject_id": 1,
  "start_date": "2024-01-15",
  "end_date": "2024-06-30",
  "start_time": "09:00:00",
  "end_time": "10:00:00",
  "recurrence": "WEEKLY",
  "weekday": 0
}

Response (201 Created):

{
  "id": 1,
  ...
}

Update Class

PUT /classes/{id}
Content-Type: application/json

{
  "start_time": "10:00:00",
  "end_time": "11:00:00"
}

Delete Class

DELETE /classes/{id}

Response (204 No Content)


Request/Response Examples

Error Handling

All endpoints return validation errors with detailed messages:

POST /buildings
Content-Type: application/json

{
  "name": "Test"
}

Response (400 Bad Request):

{
  "errors": {
    "code": ["Missing data for required field."]
  }
}

Date/Time Formatting

  • Dates: ISO format YYYY-MM-DD
  • Times: ISO format HH:MM:SS
  • DateTime: ISO format YYYY-MM-DDTHH:MM:SS

Location & Size

Room coordinates are returned as arrays:

{
  "location": [130, 47],  // [X, Y]
  "size": [60, 40]        // [width, height]
}

Data Types & Enums

Frequency (Class Recurrence)

ONCE   - "once"
WEEKLY - "weekly"
WEEK_A - "weekA"
WEEK_B - "weekB"

Color (Subject Color)

BLUE
GREEN
RED
YELLOW
PURPLE
ORANGE
GRAY

Grade (Student Grade Level)

10 → 2nde (Grade 10)
11 → 1ère (Grade 11)
12 → Terminale (Grade 12)
13 → CPGE 1 (Grade 13)
14 → CPGE 2 (Grade 14)

🔧 Development Notes

Database Migrations

# Create new migration
flask db migrate -m "Description"

# Apply migrations
flask db upgrade

# Rollback
flask db downgrade

Validation

All POST/PUT requests are validated using Marshmallow schemas:

  • Type checking
  • Required field validation
  • Relationship integrity

Serialization

Responses automatically handle:

  • Enum value conversion
  • Datetime/Date/Time formatting
  • Nested relationship serialization
  • Field inclusion/exclusion based on context

📞 Support & Questions

For issues or questions about the API or project setup, please refer to the main project README or open an issue on the repository.


📝 License

This project is licensed under the MIT License. See the LICENSE file for details.

About

This project contains the api source code that is hosted on a different server

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published