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:
- Station Search - Find railway station codes and details
- Train Search - Search trains between two stations with availability and fare information
- Schedule Lookup - View complete train timetables and stop information
- 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
-
Clone the repository
git clone https://github.com/yourusername/pysplit_inrail.git cd pysplit_inrail
-
Create a virtual environment (recommended)
python -m venv .venv # On Windows: .venv\Scripts\activate # On macOS/Linux: source .venv/bin/activate
-
Install dependencies
pip install -r requirements.txt
-
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:
- More Availability - Different segments may have different occupancy levels
- Algorithmic Search - Checks multiple segment combinations automatically
- Better Success Rate - Increases chances of getting tickets during high-demand periods
- Same Train Experience - You stay on the same train; no need to change
Algorithm Overview
The find_same_train_split_journeys() function:
- Fetches Train Schedule - Gets all stops for the specified train
- Generates Combinations - Creates all possible segment combinations (2-N segments)
- Checks Availability - Queries availability for each segment combination
- Filters Results - Keeps only combinations with acceptable availability status:
- โ Available (best)
- โ ๏ธ RAC (Reservation Against Cancellation) - optional
- โณ WL (Waiting List) - with configurable limit
- Ranks Results - Prioritizes by:
- Fewest segments
- Preferred travel class
- Best availability status
- 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 sessionget_trains_between_stations()- Searches trains with availabilityget_ixigo_train_availability()- Ixigo-specific availability fetchget_schedule_from_page(train_number)- Scrapes train timetablevalidate_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 infoSegment- Represents a journey segment (from_stop โ to_stop)
Key Functions:
find_same_train_split_journeys()- Main split journey search algorithmextract_route_stops()- Parses schedule into structured stopsfind_route_slice()- Finds relevant stops between source and destinationgenerate_split_segments()- Creates all possible segment combinationsparse_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 databasesearch_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 resultsformat_train_info()- Formats train search outputformat_schedule_info()- Formats timetable displayformat_split_journey_results()- Formats split journey resultsminutes_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 teststest_railway_api.py- API wrapper teststest_stations.py- Station search teststest_formatters.py- Output formatting teststest_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
timeoutparameter - Use
max_segmentslimit 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=Trueto explore more combinations
Split Journey Not Recommended
Reasons availability may not show splits:
- Train is fully booked across all segments
- No intermediate stops between source and destination
- Waiting list position exceeds
max_wlthreshold - 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
- Accuracy - Data provided is as-is from public APIs. Always verify on official railway websites before booking.
- Reliability - API endpoints may change or become unavailable without notice.
- Rate Limiting - Excessive requests may result in temporary IP bans from upstream servers.
- Legal Use - This tool is for information gathering only. Actual booking must be done through official channels.
- Split Journey Legality - Split journey booking is legal, but verify with railway authorities if unsure.
๐ค Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7da77eb14924a23d20ccbd7d3dbcd087efa3ae03832672e88c3edbafd95fa5d
|
|
| MD5 |
7516cac26a608199ef3933360109885f
|
|
| BLAKE2b-256 |
9135d966f5318da2b96a9927207a459686c50e11f5d43309a7e7297a547b8ed8
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26b5363540ef6df780df307c6cdcefac95873ba43ef5d40062b6af2a4e51a625
|
|
| MD5 |
777d8f6d883148dab8e24aef83d49dfa
|
|
| BLAKE2b-256 |
0f332cd6eab8d402111a8ddf308e698bf67eb261e7cee0acc47894a0b155b322
|