# sanketsaurav/pnrapi architecture

> Architecture diagram of the GitHub repository sanketsaurav/pnrapi, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/sanketsaurav/pnrapi
- Repository: https://github.com/sanketsaurav/pnrapi

## Overview

1. **Repository shape**
   - This is a small, single-purpose Python API service for Indian Railways PNR status lookup.
   - There is no multi-service backend, no database, and no frontend. The architecture is basically one HTTP entrypoint plus a few support files.

2. **Public API boundary**
   - The service exposes one main route: `GET /pnr/<pnr>`.
   - The input is a 10-digit PNR number.
   - The output is a JSON payload with a top-level `status` field and a `data` object containing train, route, and passenger status details.

3. **Request handling layer**
   - `api.py` is the application entrypoint and likely contains the web route/controller logic.
   - Its job is to accept the PNR request, decide whether to serve a dummy/test response or query live data, and return the final JSON response.

4. **External data dependency**
   - The core business function depends on an upstream Indian Railways PNR information source.
   - This repo acts as a proxy/adapter over that external system, normalizing whatever raw response it gets into a stable JSON contract for callers.

5. **Transformation and normalization**
   - `utils.py` appears to hold helper logic for parsing, cleaning, or reshaping fetched PNR data.
   - The README’s sample response suggests the service converts upstream data into a consistent structure with fields like train number, train name, travel date, boarding/alighting stations, class, and passenger status.

6. **Station metadata boundary**
   - `station_codes.json` is a local lookup table for station code-to-name mapping.
   - This indicates a normalization step in the response pipeline: raw station codes from upstream are resolved into human-readable station names before returning JSON.

7. **Test/dummy response path**
   - `dummy_response.json` is a fixture used for testing and development.
   - The README explicitly documents PNR `0123456789` as a special test input that returns this dummy payload, which means the service has a deterministic offline/fixture branch separate from live lookups.

8. **Configuration**
   - `settings.py` likely contains runtime configuration such as upstream URLs, timeouts, environment-specific toggles, or constants used by the request pipeline.
   - This separates deploy-time settings from request-handling code.

9. **Deployment/runtime**
   - `Procfile` suggests the service is designed to run on a process manager / PaaS-style host using a web worker command.
   - `requirements.txt` defines the Python runtime dependencies for the API and any scraping/parsing libraries it relies on.

10. **Response contract**
   - The API always returns a status plus a structured data payload.
   - Notable result states documented in the README are:
     - `OK` for successful lookups
     - `PNR FLUSHED / SERVICE UNAVAILABLE` when the PNR is unavailable or upstream is down
     - `ERROR` for unexpected fetch/parse failures
   - This makes the service a stable adapter around an unreliable upstream source.

11. **Data flow summary**
   - Client sends PNR request → `api.py` handles route → helper/config/lookup files enrich or normalize the request → upstream PNR source is queried or `dummy_response.json` is returned → response is transformed into the documented JSON schema → JSON is sent back to the client.

12. **Architectural takeaway**
   - The repo is best diagrammed as a thin API façade over an external rail PNR source, with local support files for configuration, station metadata, and deterministic test fixtures.

Main entry points: [`README.md`](https://github.com/sanketsaurav/pnrapi/blob/master/README.md) (Response contract), [`api.py`](https://github.com/sanketsaurav/pnrapi/blob/master/api.py) (Lookup flow), [`utils.py`](https://github.com/sanketsaurav/pnrapi/blob/master/utils.py) (Normalizer), [`dummy_response.json`](https://github.com/sanketsaurav/pnrapi/blob/master/dummy_response.json) (Dummy payload)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_grp_api["HTTP API"]
  node_api["API entrypoint<br/>Flask app<br/>[api.py]"]
  node_pnr_route(("PNR route<br/>controller<br/>[api.py]"))
  node_response_contract["Response contract<br/>JSON schema<br/>[README.md]"]
  node_readme["Docs<br/>usage guide<br/>[README.md]"]
  node_train_details["Train details<br/>payload section<br/>[README.md]"]
  node_passenger_status["Passenger status<br/>payload section<br/>[README.md]"]
end

subgraph group_grp_core["Core logic"]
  node_lookup_orchestrator{{"Lookup flow<br/>adapter<br/>[api.py]"}}
  node_upstream_source[("Rail source<br/>external upstream")]
  node_parser_utils["Parse utils<br/>transform helpers<br/>[utils.py]"]
  node_normalizer{{"Normalizer<br/>mapping layer<br/>[utils.py]"}}
  node_status_mapper{{"Status mapper<br/>result shaping<br/>[utils.py]"}}
end

subgraph group_grp_data["Local data"]
  node_station_lookup["Station codes<br/>reference data<br/>[station_codes.json]"]
  node_dummy_fixture["Dummy payload<br/>fixture"]
end

subgraph group_grp_runtime["Runtime"]
  node_settings["Settings<br/>runtime config<br/>[settings.py]"]
  node_requirements["Dependencies<br/>python packages<br/>[requirements.txt]"]
  node_procfile["Procfile<br/>deployment entry"]
end

node_api -->|"routes"| node_pnr_route
node_pnr_route -->|"dispatches"| node_lookup_orchestrator
node_lookup_orchestrator -->|"special-case"| node_dummy_fixture
node_lookup_orchestrator -->|"queries"| node_upstream_source
node_lookup_orchestrator -->|"configures"| node_settings
node_upstream_source -->|"raw data"| node_parser_utils
node_parser_utils -->|"shapes"| node_normalizer
node_normalizer -->|"resolves"| node_station_lookup
node_normalizer -->|"formats"| node_status_mapper
node_status_mapper -->|"emits"| node_response_contract
node_dummy_fixture -->|"matches"| node_response_contract
node_response_contract -->|"includes"| node_train_details
node_response_contract -->|"includes"| node_passenger_status
node_readme -.->|"documents"| node_response_contract
node_requirements -.->|"supports"| node_api
node_procfile -.->|"launches"| node_api

click node_api "https://github.com/sanketsaurav/pnrapi/blob/master/api.py"
click node_pnr_route "https://github.com/sanketsaurav/pnrapi/blob/master/api.py"
click node_response_contract "https://github.com/sanketsaurav/pnrapi/blob/master/README.md"
click node_lookup_orchestrator "https://github.com/sanketsaurav/pnrapi/blob/master/api.py"
click node_parser_utils "https://github.com/sanketsaurav/pnrapi/blob/master/utils.py"
click node_normalizer "https://github.com/sanketsaurav/pnrapi/blob/master/utils.py"
click node_station_lookup "https://github.com/sanketsaurav/pnrapi/blob/master/station_codes.json"
click node_dummy_fixture "https://github.com/sanketsaurav/pnrapi/blob/master/dummy_response.json"
click node_settings "https://github.com/sanketsaurav/pnrapi/blob/master/settings.py"
click node_requirements "https://github.com/sanketsaurav/pnrapi/blob/master/requirements.txt"
click node_procfile "https://github.com/sanketsaurav/pnrapi/tree/master/Procfile"
click node_readme "https://github.com/sanketsaurav/pnrapi/blob/master/README.md"
click node_status_mapper "https://github.com/sanketsaurav/pnrapi/blob/master/utils.py"
click node_train_details "https://github.com/sanketsaurav/pnrapi/blob/master/README.md"
click node_passenger_status "https://github.com/sanketsaurav/pnrapi/blob/master/README.md"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_api,node_pnr_route,node_response_contract,node_readme,node_train_details,node_passenger_status toneBlue
class node_lookup_orchestrator,node_upstream_source,node_parser_utils,node_normalizer,node_status_mapper toneAmber
class node_station_lookup,node_dummy_fixture toneMint
class node_settings,node_requirements,node_procfile toneRose
```

## Components

### HTTP API

Public request handling and response boundary

- [API entrypoint](https://github.com/sanketsaurav/pnrapi/blob/master/api.py): Flask app · Handles GET /pnr/<pnr> and returns the JSON response · `api.py`
- [PNR route](https://github.com/sanketsaurav/pnrapi/blob/master/api.py): controller · Validates request input and dispatches lookup flow · `api.py`
- [Response contract](https://github.com/sanketsaurav/pnrapi/blob/master/README.md): JSON schema · Top-level status plus structured data payload · `README.md`
- [Docs](https://github.com/sanketsaurav/pnrapi/blob/master/README.md): usage guide · Describes API behavior, status codes, and examples · `README.md`
- [Train details](https://github.com/sanketsaurav/pnrapi/blob/master/README.md): payload section · Train number, name, date, class, and route fields · `README.md`
- [Passenger status](https://github.com/sanketsaurav/pnrapi/blob/master/README.md): payload section · Passenger-wise reservation and boarding/alighting details · `README.md`

### Core logic

Lookup, normalization, and status shaping

- [Lookup flow](https://github.com/sanketsaurav/pnrapi/blob/master/api.py): adapter · Chooses dummy response or live upstream lookup · `api.py`
- **Rail source**: external upstream · Indian Railways PNR information source
- [Parse utils](https://github.com/sanketsaurav/pnrapi/blob/master/utils.py): transform helpers · Cleans and reshapes raw PNR data · `utils.py`
- [Normalizer](https://github.com/sanketsaurav/pnrapi/blob/master/utils.py): mapping layer · Converts upstream fields into stable API output · `utils.py`
- [Status mapper](https://github.com/sanketsaurav/pnrapi/blob/master/utils.py): result shaping · Produces OK, SERVICE UNAVAILABLE, and ERROR states · `utils.py`

### Local data

Bundled fixture and station metadata

- [Station codes](https://github.com/sanketsaurav/pnrapi/blob/master/station_codes.json): reference data · Maps station codes to human-readable names · `station_codes.json`
- [Dummy payload](https://github.com/sanketsaurav/pnrapi/blob/master/dummy_response.json): fixture · Deterministic offline response for test PNR · `dummy_response.json`

### Runtime

Deployment and dependency packaging

- [Settings](https://github.com/sanketsaurav/pnrapi/blob/master/settings.py): runtime config · Upstream URL, timeouts, and environment toggles · `settings.py`
- [Dependencies](https://github.com/sanketsaurav/pnrapi/blob/master/requirements.txt): python packages · Runtime and parsing libraries for the service · `requirements.txt`
- [Procfile](https://github.com/sanketsaurav/pnrapi/tree/master/Procfile): deployment entry · Process manager command for the web worker · `Procfile`

## Connections

- API entrypoint → PNR route: routes · HTTP entrypoint hands requests to the PNR controller
- PNR route → Lookup flow: dispatches · Route decides whether to use fixture or live lookup
- Lookup flow → Dummy payload: special-case · PNR 0123456789 returns deterministic test data
- Lookup flow → Rail source: queries · Live requests are proxied to the external rail source
- Lookup flow → Settings: configures · Uses runtime settings for upstream and behavior toggles
- Rail source → Parse utils: raw data · Fetched upstream payload is parsed and cleaned
- Parse utils → Normalizer: shapes · Parsed values are mapped into the API contract
- Normalizer → Station codes: resolves · Station codes are expanded to human-readable names
- Normalizer → Status mapper: formats · Lookup outcome is converted into documented status values
- Status mapper → Response contract: emits · Final result conforms to the JSON response shape
- Dummy payload → Response contract: matches · Fixture follows the same response contract as live data
- Response contract → Train details: includes · Documented payload contains train and route fields
- Response contract → Passenger status: includes · Documented payload contains passenger status fields
- Docs → Response contract: documents · README describes the output schema and status codes
- Dependencies → API entrypoint: supports · Python dependencies make the service runnable
- Procfile → API entrypoint: launches · Deployment command starts the web process
