Skip to main content

Indian Railways split journey search tool - find booking opportunities by intelligently splitting long journeys into segments

Project description

PyInRail - Indian Railways Split Journey Search Tool

A Python-based utility to search Indian Railways trains and intelligently find split journey alternatives when direct bookings are unavailable. Split journey booking allows you to book multiple segments of the same train when the direct route shows no availability.

๐ŸŽฏ Overview

PyInRail is a comprehensive tool for Indian railway ticket hunters. It provides:

  1. Station Search - Find railway station codes and details
  2. Train Search - Search trains between two stations with availability and fare information
  3. Schedule Lookup - View complete train timetables and stop information
  4. Split Journey Search โญ - Intelligently find booking opportunities by splitting long journeys into multiple segments on the same train

The project includes both a command-line interface (CLI) and an interactive Streamlit web application for easy access.

๐Ÿ“ฆ Project Structure

pyinrail-master/
โ”œโ”€โ”€ pysplit_inrail/                   # Core package (library modules)
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ railway_api.py          # API wrapper for RailYatri and Ixigo
โ”‚   โ”œโ”€โ”€ split_journey.py        # Split journey algorithm (main feature)
โ”‚   โ”œโ”€โ”€ stations.py             # Station cache management
โ”‚   โ””โ”€โ”€ formatters.py           # Output formatting utilities
โ”‚
โ”œโ”€โ”€ rail_scrapper.py            # CLI interface
โ”œโ”€โ”€ streamlit_app.py            # Web UI
โ”œโ”€โ”€ create_station_cache.py     # Generate station database cache
โ”œโ”€โ”€ create_stations_endpoint.py # Create station API endpoint
โ”œโ”€โ”€ stations_cache.json         # Pre-built station data cache
โ”œโ”€โ”€ requirements.txt            # Python dependencies
โ”œโ”€โ”€ tests/                      # Unit tests
โ”‚   โ”œโ”€โ”€ test_railway_api.py
โ”‚   โ”œโ”€โ”€ test_split_journey.py
โ”‚   โ”œโ”€โ”€ test_stations.py
โ”‚   โ”œโ”€โ”€ test_formatters.py
โ”‚   โ””โ”€โ”€ test_cli.py
โ””โ”€โ”€ README.md                   # This file

๐Ÿš€ Quick Start

Prerequisites

  • Python 3.8+
  • pip or conda

Installation

  1. Clone the repository

    git clone https://github.com/yourusername/pysplit_inrail.git
    cd pysplit_inrail
    
  2. Create a virtual environment (recommended)

    python -m venv .venv
    # On Windows:
    .venv\Scripts\activate
    # On macOS/Linux:
    source .venv/bin/activate
    
  3. Install dependencies

    pip install -r requirements.txt
    
  4. Or install the published PyPI package

    pip install pysplit_inrail
    

Usage

Option 1: Web Application (Recommended for Most Users)

streamlit run streamlit_app.py

This opens an interactive web interface in your browser where you can:

  • Search stations
  • Check train availability
  • View schedules
  • Find split journey options with visual results

Option 2: Command-Line Interface

# Search stations
python rail_scrapper.py station mumbai --limit 5

# Find trains between stations
python rail_scrapper.py trains --from BBS --to MAS --date 31-07-2026

# View train schedule
python rail_scrapper.py schedule 16021

# Find split journey opportunities (main feature)
python rail_scrapper.py split --train 16021 --from MAS --to MYS --date 31-07-2026 --classes SL,3A,2A

Option 3: Use as a Python Library

from pysplit_inrail.railway_api import get_trains_between_stations, create_session
from pysplit_inrail.split_journey import find_same_train_split_journeys

# Create a session with retry logic
session = create_session(retries=2)

# Find split journey options
results = find_same_train_split_journeys(
    train_number="16021",
    from_station="MAS",
    to_station="MYS",
    journey_date="31-07-2026",
    classes="SL,3A,2A",
    max_segments=3,
    session=session,
)

print(results)

โญ Core Feature: Split Journey Search

What is Split Journey Booking?

Split journey booking is a legal alternative to traditional direct booking. Instead of booking a single ticket from A โ†’ C, you book multiple segment tickets:

  • A โ†’ B (Segment 1)
  • B โ†’ C (Segment 2)
  • ... all on the same train

All segments are on the same train, same date, and same class, making it functionally equivalent to a direct booking.

Why Use Split Journey?

Indian Railways often show "No Availability" for direct routes during peak seasons, even when the train isn't fully booked. Split journey booking helps because:

  1. More Availability - Different segments may have different occupancy levels
  2. Algorithmic Search - Checks multiple segment combinations automatically
  3. Better Success Rate - Increases chances of getting tickets during high-demand periods
  4. Same Train Experience - You stay on the same train; no need to change

Algorithm Overview

The find_same_train_split_journeys() function:

  1. Fetches Train Schedule - Gets all stops for the specified train
  2. Generates Combinations - Creates all possible segment combinations (2-N segments)
  3. Checks Availability - Queries availability for each segment combination
  4. Filters Results - Keeps only combinations with acceptable availability status:
    • โœ… Available (best)
    • โš ๏ธ RAC (Reservation Against Cancellation) - optional
    • โณ WL (Waiting List) - with configurable limit
  5. Ranks Results - Prioritizes by:
    • Fewest segments
    • Preferred travel class
    • Best availability status
  6. Returns Top Results - Delivers N best options for user selection

Configuration Parameters

When using split journey search, you can customize:

Parameter Default Description
train_number Required Train number (e.g., "16021")
from_station Required Source station code (e.g., "MAS")
to_station Required Destination station code (e.g., "MYS")
journey_date Required Travel date in DD-MM-YYYY format
classes "SL,3A,2A" Comma-separated preferred classes
max_segments 3 Maximum segments to try (2-8)
max_wl 20 Max waiting list position to accept
accept_rac True Accept RAC (Reservation Against Cancellation)
quota "GN" Booking quota (GN, TQ, PT, LD, etc.)
provider "ixigo" API provider: "ixigo" or "railyatri"
max_results 10 Maximum results to return
search_deeper False Continue searching all depths if True

Example: Split Journey Search

from railway_api import create_session
from split_journey import find_same_train_split_journeys

session = create_session()

# Search for split journeys on train 16021
# from Chennai Central (MAS) to Mysore (MYS)
results = find_same_train_split_journeys(
    train_number="16021",
    from_station="MAS",
    to_station="MYS",
    journey_date="31-07-2026",
    classes="SL,3A,2A,1A",  # Check multiple classes
    max_segments=4,          # Try up to 4 segments
    max_wl=15,              # Accept WL up to position 15
    accept_rac=True,        # Accept RAC status
    session=session,
)

# Results contain:
# - split_journeys: List of viable segment combinations
# - schedule: Full train schedule
# - route_analysis: Detailed breakdown

๐Ÿ—‚๏ธ Module Reference

railway_api.py

Core API wrapper for train data providers (RailYatri and Ixigo).

Key Functions:

  • create_session(retries, backoff_factor) - Creates resilient HTTP session
  • get_trains_between_stations() - Searches trains with availability
  • get_ixigo_train_availability() - Ixigo-specific availability fetch
  • get_schedule_from_page(train_number) - Scrapes train timetable
  • validate_journey_date() - Validates date format

Supported Providers:

  • Ixigo - More detailed class-wise availability
  • RailYatri - Alternative data source with caching support

split_journey.py

Split journey search engine - The main feature!

Key Classes:

  • RouteStop - Represents a train stop with timing info
  • Segment - Represents a journey segment (from_stop โ†’ to_stop)

Key Functions:

  • find_same_train_split_journeys() - Main split journey search algorithm
  • extract_route_stops() - Parses schedule into structured stops
  • find_route_slice() - Finds relevant stops between source and destination
  • generate_split_segments() - Creates all possible segment combinations
  • parse_availability_status() - Classifies availability strings (Available, RAC, WL, etc.)
  • is_acceptable_status() - Checks if availability meets criteria

Algorithm Complexity:

  • Time: O(2^n) where n = number of stops (mitigated by early exit and caching)
  • Space: O(n) for stop storage + cache storage
  • Practical performance: Searches 100+ combinations in < 5 seconds typically

rail_scrapper.py

Command-line interface with subcommands for different operations.

Available Commands:

station      Search stations by name or code
trains       Find trains between two stations
schedule     View full train timetable
split        Find split journey opportunities (main command)
demo         Run demonstration with sample data

Example CLI Usage:

# Search for stations starting with "delhi"
python rail_scrapper.py station delhi --limit 10

# List trains from Chennai to Mysore on July 31, 2026
python rail_scrapper.py trains --from MAS --to MYS --date 31-07-2026

# Find split journeys for train 16021
python rail_scrapper.py split --train 16021 --from MAS --to MYS --date 31-07-2026 --max-segments 4 --classes SL,3A,2A

streamlit_app.py

Interactive web application built with Streamlit.

Features:

  • ๐Ÿ” Station search with autocomplete
  • ๐Ÿš† Train search with real-time availability
  • ๐Ÿ“… Schedule viewer with visual stop timeline
  • ๐ŸŽซ Split journey search with result visualization
  • โš™๏ธ Advanced filtering and preferences
  • ๐Ÿ“Š Result ranking and comparison

To Run:

streamlit run streamlit_app.py

stations.py

Station cache management for offline station search.

Functions:

  • load_station_cache() - Loads pre-built station database
  • search_station_local() - Searches stations by name/code
  • Station data includes: code, name, zone, state, etc.

Note: Run create_station_cache.py to generate or update the station cache.


formatters.py

Output formatting utilities for CLI and terminal display.

Key Functions:

  • format_station_results() - Formats station search results
  • format_train_info() - Formats train search output
  • format_schedule_info() - Formats timetable display
  • format_split_journey_results() - Formats split journey results
  • minutes_to_hhmm() - Converts minutes to HH:MM format

๐Ÿงช Testing

Run the test suite:

# Run all tests
python -m pytest tests/

# Run specific test file
python -m pytest tests/test_split_journey.py -v

# Run with coverage
pip install pytest-cov
python -m pytest tests/ --cov=. --cov-report=html

Test Files:

  • test_split_journey.py - Split journey algorithm tests
  • test_railway_api.py - API wrapper tests
  • test_stations.py - Station search tests
  • test_formatters.py - Output formatting tests
  • test_cli.py - CLI interface tests

๐Ÿ”ง Configuration

Hardcoded Defaults

Edit rail_scrapper.py lines 24-42 to change defaults:

DEFAULT_COMMAND = "split"           # Default subcommand
DEFAULT_FROM_STATION = "MAS"        # Default source
DEFAULT_TO_STATION = "MYS"          # Default destination
DEFAULT_JOURNEY_DATE = "31-07-2026" # Default travel date
DEFAULT_SPLIT_CLASSES = "SL,3A,2A" # Default class preferences
DEFAULT_SPLIT_MAX_SEGMENTS = 3      # Default max segments
DEFAULT_SPLIT_MAX_WL = 20           # Default WL limit
DEFAULT_SPLIT_MAX_RESULTS = 10      # Default result limit

Environment Variables

You can also pass arguments via CLI flags (see rail_scrapper.py for full list):

python rail_scrapper.py split \
  --train 16021 \
  --from MAS \
  --to MYS \
  --date 31-07-2026 \
  --classes SL,3A,2A \
  --max-segments 4 \
  --max-wl 15 \
  --accept-rac true \
  --provider ixigo

๐Ÿ“Š Output Examples

Split Journey Results

SPLIT JOURNEY RESULTS FOR TRAIN 16021
=====================================

Train: Chennai Central to Mysore Express
Journey Date: 31-07-2026
Segments: 3-4 recommended

โœ… OPTION 1 (3 Segments, Class: SL)
  Score: 0.95
  Segment 1: MAS โ†’ BWT (Available)
  Segment 2: BWT โ†’ KPD (Available)
  Segment 3: KPD โ†’ MYS (Available)
  Split Points: BWT, KPD

โš ๏ธ OPTION 2 (2 Segments, Class: 3A)
  Score: 0.80
  Segment 1: MAS โ†’ KPD (Available)
  Segment 2: KPD โ†’ MYS (RAC - 5)

โณ OPTION 3 (4 Segments, Class: 2A)
  Score: 0.70
  Segment 1: MAS โ†’ BWT (WL - 8)
  Segment 2: BWT โ†’ KPD (Available)
  Segment 3: KPD โ†’ AJJ (Available)
  Segment 4: AJJ โ†’ MYS (Available)

๐Ÿ› Troubleshooting

"Station cache not found" Error

Solution: Generate the station cache:

python create_station_cache.py

API Rate Limiting

If you get timeout errors:

  • Reduce concurrent requests
  • Increase timeout parameter
  • Use max_segments limit to reduce API calls

Availability Data Outdated

The API data is real-time but may have slight delays. Try:

  • Refreshing the search
  • Checking directly on railway websites for verification
  • Using search_deeper=True to explore more combinations

Split Journey Not Recommended

Reasons availability may not show splits:

  1. Train is fully booked across all segments
  2. No intermediate stops between source and destination
  3. Waiting list position exceeds max_wl threshold
  4. RAC status not acceptable (set accept_rac=True)

๐Ÿ“‹ Class Codes Reference

Code Class
SL Sleeper
3A 3-tier AC
2A 2-tier AC
1A 1-tier AC (First Class)
CC Chair Car
EC Executive Chair Car
2S Second Sitting
3E 3-tier Non-AC
FC First Class Non-AC
EA Economy AC

๐ŸŽซ Quota Codes Reference

Code Quota
GN General
TQ Tatkal
PT Premium Tatkal
LD Ladies
SS Lower Berth
HP Physically Handicapped
DF Defence

๐Ÿ“š API Response Structure

Split journey results follow this structure:

{
    "success": True,
    "split_journeys": [
        {
            "train_number": "16021",
            "train_name": "Chennai Central - Mysore Express",
            "class": "SL",
            "quota": "GN",
            "segment_count": 3,
            "segments": [
                {
                    "from": {"code": "MAS", "name": "Chennai Central"},
                    "to": {"code": "KPD", "name": "Katpadi"},
                    "availability": "Available",
                    "fare": 145
                },
                # ... more segments
            ],
            "split_stations": [
                {"code": "BWT", "name": "Bowenpally"}
                # ... more split points
            ],
            "score": 0.95
        }
    ],
    "schedule": {...},
    "checked_combinations": 487,
    "execution_time_ms": 3421
}

๐Ÿšซ Limitations & Disclaimers

  1. Accuracy - Data provided is as-is from public APIs. Always verify on official railway websites before booking.
  2. Reliability - API endpoints may change or become unavailable without notice.
  3. Rate Limiting - Excessive requests may result in temporary IP bans from upstream servers.
  4. Legal Use - This tool is for information gathering only. Actual booking must be done through official channels.
  5. Split Journey Legality - Split journey booking is legal, but verify with railway authorities if unsure.

๐Ÿค Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Areas for contribution:

  • Additional train data providers
  • Performance optimization
  • Web UI improvements
  • Documentation
  • Test coverage

๐Ÿ“ License

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

๐Ÿ‘จโ€๐Ÿ’ป Author

Created as a utility tool for Indian railway ticket hunters.

๐Ÿ“ž Support & Feedback

  • Issues: Report bugs on GitHub Issues
  • Discussions: Share ideas and ask questions
  • Feature Requests: Suggest improvements on GitHub Discussions

๐Ÿ”— Related Resources


Last Updated: July 2026
Python Version: 3.8+
Status: Active Development

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysplit_inrail-1.0.1.tar.gz (31.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysplit_inrail-1.0.1-py3-none-any.whl (22.3 kB view details)

Uploaded Python 3

File details

Details for the file pysplit_inrail-1.0.1.tar.gz.

File metadata

  • Download URL: pysplit_inrail-1.0.1.tar.gz
  • Upload date:
  • Size: 31.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for pysplit_inrail-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f7da77eb14924a23d20ccbd7d3dbcd087efa3ae03832672e88c3edbafd95fa5d
MD5 7516cac26a608199ef3933360109885f
BLAKE2b-256 9135d966f5318da2b96a9927207a459686c50e11f5d43309a7e7297a547b8ed8

See more details on using hashes here.

File details

Details for the file pysplit_inrail-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: pysplit_inrail-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 22.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for pysplit_inrail-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 26b5363540ef6df780df307c6cdcefac95873ba43ef5d40062b6af2a4e51a625
MD5 777d8f6d883148dab8e24aef83d49dfa
BLAKE2b-256 0f332cd6eab8d402111a8ddf308e698bf67eb261e7cee0acc47894a0b155b322

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page