8000 GitHub - Mario-SO/project-polaris: Accessible Renfe API.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Mario-SO/project-polaris

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

34 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš„ Renfe Timetables API πŸš†

Welcome to the Renfe Timetables API project! This project aims to provide a super easy-to-use REST API for accessing Renfe CercanΓ­as (commuter rail) timetables in Spain, making this valuable data more accessible for developers to build their own applications. πŸ‡ͺπŸ‡Έβœ¨

Currently, the official data is provided in GTFS format, which, while comprehensive, isn't directly API-friendly. Another option is to use their official site, which is also not the best, or third party apps, which, even though they work cool and all, normally they dont provide an open API. This project bridges that gap!

⭐ Current Features

  • βœ… Daily Data Fetching: Automatically downloads the latest GTFS data for Renfe CercanΓ­as daily via a GitHub Action.
  • πŸ’Ύ SQLite Database: Parses and stores the GTFS data into an SQLite database for efficient querying.
  • πŸš€ API Endpoints:
    • GET /: Welcome message.
    • GET /stations: Lists all stations. Supports fuzzy search with ?q={query}.
    • GET /stations/{stationId}: Retrieves details for a specific station by its ID.
    • GET /timetable/{departureStation}/{arrivalStation}: Retrieves direct trip schedules. Defaults to today's date. Supports specific date querying with ?date={YYYY-MM-DD}. Results are grouped to show unique departure/arrival time slots for the effective date.
    • GET /timetable/{departureStation}/{arrivalStation}/next: Retrieves the very next available train for the route based on the current time in Spain.
    • GET /stations/{stationId}/departures?date=YYYY-MM-DD&time=HH:MM: Get all departures from a specific station. Defaults to current date/time if omitted.
    • GET /routes: List all available routes (e.g., C1, C2, C3).
    • GET /routes/{routeId}: Get details for a specific route, including its stops.
  • πŸ§ͺ Unit & Integration Tests: Comprehensive test suite for API endpoints and logic.

πŸ› οΈ Technology Stack

  • Runtime & Toolkit: Bun (JavaScript runtime, package manager, bundler)
  • Web Framework: HonoJS (Fast, lightweight, and works great with Bun!)
  • Language: TypeScript
  • Database: SQLite (using bun:sqlite)
  • Data Source: Renfe's official GTFS feed.
  • CI/CD: GitHub Actions (for daily data fetching and processing).
  • Large File Storage: Git LFS (for handling large data files in the repository).

πŸ“‚ Project Structure

project-polaris/
β”œβ”€β”€ .github/workflows/        # GitHub Actions workflows (e.g., fetch-timetables.yml)
β”œβ”€β”€ api/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ config/           # Configuration files
β”‚   β”‚   β”œβ”€β”€ controllers/      # Request handlers
β”‚   β”‚   β”œβ”€β”€ routes/           # API route definitions
β”‚   β”‚   β”œβ”€β”€ services/         # Business logic
β”‚   β”‚   β”œβ”€β”€ utils/            # Utility functions
β”‚   β”‚   β”œβ”€β”€ index.ts          # Hono API application entry point
β”‚   β”‚   β”œβ”€β”€ index.test.ts     # Tests for the API
β”‚   β”‚   └── load-data.ts      # Script to load GTFS data into SQLite
β”‚   β”œβ”€β”€ package.json          # API dependencies (Hono, etc.)
β”‚   β”œβ”€β”€ tsconfig.json         # TypeScript configuration for the API
β”‚   β”œβ”€β”€ bun.lockb             # Bun lockfile
β”‚   └── .gitignore            # Git ignore for api directory
β”œβ”€β”€ data/                     # Stores raw GTFS .txt files and the gtfs.sqlite database
β”œβ”€β”€ scripts/
β”‚   └── get-timetables.ts     # Script to download and unzip GTFS data
β”œβ”€β”€ .gitattributes            # Git LFS attributes
β”œβ”€β”€ .gitignore                # Git ignore for project root
β”œβ”€β”€ README.md                 # This file!
└── ...                       # Other project files (e.g. .git/)

πŸš€ Getting Started & Running Locally

  1. Clone the repository:

    git clone https://github.com/Mario-SO/project-polaris.git
    cd project-polaris
  2. Install Git LFS: Make sure you have Git LFS installed. Download it from git-lfs.github.com and run git lfs install once on your system.

  3. Install Bun: If you don't have Bun, install it from bun.sh.

  4. Fetch GTFS Data: (This is normally done by the GitHub Action, but you can run it manually too)

    bun run ./scripts/get-timetables.ts
  5. Install API Dependencies:

    cd api
    bun install
    cd ..
  6. Load Data into SQLite Database:

    bun run ./api/src/load-data.ts

    This will create/update data/gtfs.sqlite.

  7. Run the API Server:

    bun run ./api/src/index.ts

    The API should now be running, typically on http://localhost:3000.

  8. Test the Endpoints: Use curl or a tool like Postman. Examples:

    • Get welcome message:
      curl "http://localhost:3000/"
    • List all stations:
      curl "http://localhost:3000/stations"
    • Search for stations (e.g., "madrid"):
      curl "http://localhost:3000/stations?q=madrid"
    • Get details for a specific station ID (replace 10000 with a valid ID):
      curl "http://localhost:3000/stations/10000"
    • Get timetable between Valdemoro and Sol (defaults to today):
      curl "http://localhost:3000/timetable/Valdemoro/Sol"
    • Get timetable for a specific date:
      curl "http://localhost:3000/timetable/Valdemoro/Sol?date=2024-08-15"
    • Get the next train from Valdemoro to Sol:
      curl "http://localhost:3000/timetable/Valdemoro/Sol/next"

    Replace station names and IDs with your desired values. Partial, case-insensitive matching is supported for station names in path parameters.

  9. Run Tests: To execute the test suite:

    bun test ./api/src/index.test.ts

πŸ“– API Endpoints Detailed

Here's a breakdown of the available API endpoints:

GET /

  • Description: Returns a simple welcome message from the API.
  • Example: curl "http://localhost:3000/"
  • Response: Hello from Renfe Timetables API!

GET /stations

  • Description: Retrieves a list of all available train stations.
  • Query Parameters:
    • q (optional): A string to filter station names. Performs a case-insensitive "LIKE" search (e.g., q=Madrid will find "Madrid-Principe Pio", "MADRID-CHAMARTIN-CLARA CAMPOAMOR", etc.). Returns a maximum of 50 results when q is used.
  • Examples:
    • curl "http://localhost:3000/stations" (gets all stations)
    • curl "http://localhost:3000/stations?q=Atocha" (searches for stations 8000 containing "Atocha")
  • Response: An array of station objects, each with stop_id, stop_name, stop_lat, stop_lon.

GET /stations/{stationId}

  • Description: Fetches details for a specific station using its stop_id.
  • Path Parameters:
    • stationId: The unique identifier of the station (e.g., 10000).
  • Example: curl "http://localhost:3000/stations/10000"
  • Response: A station object with stop_id, stop_name, stop_lat, stop_lon, or a 404 error if not found.

GET /stations/{stationId}/departures

  • Description: Retrieves all departure times from a specific station. Supports optional date (YYYY-MM-DD) and time (HH:MM) query parameters (defaults to current date and time in Spain).
  • Path Parameters:
    • stationId: The unique identifier or name (partial match) of the station.
  • Query Parameters:
    • date (optional): Date in YYYY-MM-DD format.
    • time (optional): Time in HH:MM format.
  • Example:
    curl "http://localhost:3000/stations/10000/departures?date=2024-07-01&time=08:00"
  • Response: A JSON object containing station_found, station_id, date_queried, time_queried, and an array of departures.

GET /routes

  • Description: Lists all available routes.
  • Example:
    curl "http://localhost:3000/routes"
  • Response: An array of route objects with route_id, route_short_name, and route_long_name.

GET /routes/{routeId}

  • Description: Retrieves details for a specific route, including the ordered list of stops.
  • Path Parameters:
    • routeId: The identifier of the route (e.g., C1).
  • Example:
    curl "http://localhost:3000/routes/C1"
  • Response: A JSON object containing route_id, route_short_name, route_long_name, and an array of stops each with stop_id, stop_name, and stop_sequence.

πŸ’‘ Important Notes on API Usage

  • Station Name Matching: For endpoints using station names in path parameters (/timetable/{departureStation}/{arrivalStation} and /timetable/.../next), the API performs a case-insensitive, partial match against station names in the database. It will use the first station found that matches the provided term. For more precise control, use station IDs where possible or ensure your search terms are specific enough. The /stations?q= endpoint can help identify full names and IDs.
  • Date Handling:
    • The GET /timetable/{departureStation}/{arrivalStation} endpoint defaults to the current server's local date if no date query parameter is supplied.
    • When a date is provided (e.g., ?date=2024-08-20), the API will query for that specific date.
    • Invalid date formats for the date parameter will result in a 400 error.
  • "Next Train" Timezone: The GET /timetable/{departureStation}/{arrivalStation}/next endpoint specifically uses the current time in Spain (Europe/Madrid) to determine the "next" train. This ensures relevance for users in Spain, regardless of the server's physical location or local time.
  • Character Encoding in Station Names:
    • When querying station names that include special characters (e.g., tildes like in "ChamartΓ­n", or other accented characters), these characters must be URL-encoded in the request path or query parameters.
    • For example, to search for "ChamartΓ­n":
      • Incorrect (likely to fail or give wrong results): curl http://localhost:3000/timetable/ChamartΓ­n/Atocha
      • Correct (URL-encoded Γ­ as %C3%AD): curl http://localhost:3000/timetable/Chamart%C3%ADn/Atocha
    • Similarly, if using the /stations?q= endpoint:
      • Incorrect: curl "http://localhost:3000/stations?q=ChamartΓ­n"
      • Correct: curl "http://localhost:3000/stations?q=Chamart%C3%ADn"
    • Most HTTP clients and libraries will handle URL encoding automatically if you construct the URL correctly with the special characters. However, if you are manually crafting curl commands or building URLs, ensure proper encoding for reliable results. The API itself handles UTF-8 correctly on the backend, but the URL must be valid.

πŸ“ TODO List & Next Steps

Here's a roadmap of planned enhancements and features:

API Enhancements βš™οΈ

  • Date & Day Filtering: Defaults to today, specific date via query param.
  • Improved Station Matching:
    • Handle ambiguous station names more gracefully (e.g., return multiple candidates for user selection instead of just the first match).
  • Transfer Support: Add logic to find journeys that require one or more transfers.
  • Input Validation: Add more robust input validation for API parameters (some basic validation for date format exists).

New API Endpoints πŸ—ΊοΈ

  • GET /stations: List all available stations (perhaps with autocomplete support ?q=partial_name).
  • GET /stations/{station_id}: Get details for a specific station.
  • GET /stations/{station_name_or_id}/departures?date=YYYY-MM-DD&time=HH:MM: Get all departures from a specific station.
  • GET /routes: List all available routes (e.g., C1, C2, C3).
  • GET /routes/{route_id}: Get details for a specific route, including its stops.

Deployment & Operations 🚒

  • Automated API Deployment: Set up CI/CD to deploy the Hono API (e.g., to Cloudflare Workers, Fly.io, Vercel, or a similar platform).
  • Health Check Endpoint: Add a /health endpoint for monitoring.
  • Logging & Monitoring: Implement more structured logging and monitoring for the API.

Documentation & Development Experience πŸ“š

  • API Documentation: Generate OpenAPI (Swagger) documentation.
  • Testing: Add unit and integration tests for the API logic and data loading scripts. (Implemented for API endpoints)
  • Refine CSV Parsing: Make the CSV parser in load-data.ts more robust (e.g., handle escaped quotes/commas within fields if present in source data).

πŸ™Œ Contributing

Contributions are welcome! If you have ideas or want to help, feel free to open an issue or submit a pull request.

About

Accessible Renfe API.

Resources

Stars

Watchers

Forks

Languages

0