Skip to content

Commit

Permalink
Updates for the new rail.co.il API
Browse files Browse the repository at this point in the history
  • Loading branch information
sh0oki committed Oct 5, 2023
1 parent f6e8db5 commit 26b39f2
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 42 deletions.
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Israel Rail API

[![image](https://img.shields.io/pypi/v/israel-rail-api.svg)](https://pypi.org/project/israel-rail-api/)
[![image](https://img.shields.io/pypi/l/israel-rail-api.svg)](https://pypi.org/project/israel-rail-api/)
[![Build Status](https://travis-ci.org/sh0oki/israel-rail-api.svg?branch=master)](https://travis-ci.org/sh0oki/israel-rail-api)
Expand All @@ -8,19 +9,21 @@ This is a unofficial wrapping of the API of Israeli Rail network in Python.
Use this script for checking your own train schedule, integrating with Alexa, and so on!

## Installing
Tested with Python 3.6, should probably work fine with other versions too.

pip install israel-rail-api
Tested with Python 3.11, should probably work fine with other versions too.

pip install israel-rail-api

## Usage
import israelrailapi
s = israelrailapi.TrainSchedule()
print(s.query('Tel Aviv University', 'Jerusalem Yitzhak Navon'))

import israelrailapi
s = israelrailapi.TrainSchedule()
print(s.query('Tel Aviv University', 'Jerusalem Yitzhak Navon'))

A simple test, to make sure the script is working is included in `schedule.py`:

python schedule.py "tel aviv hahagana" "ben gurion airport" 2018-12-24 0900
python3 schedule.py "tel aviv hahagana" "ben gurion airport" 2023-06-24 0900

## Contributing
We'd love your contributions! Fire up a (tested!) Pull request and we'll be happy to approve it.

We'd love your contributions! Fire up a (tested!) Pull request, and we'll be happy to approve it.
61 changes: 39 additions & 22 deletions israelrailapi/api.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
import requests
import time

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 ' \
'Safari/537.36'
API_BASE = 'https://www.rail.co.il/apiinfo/api/Plan'
DEFAULT_HEADERS = {'User-Agent': USER_AGENT}
import requests

from train_station import station_name_to_id

# API key bundled in main.js of rail.co.il
API_KEY = "4b0d355121fe4e0bb3d86e902efe9f20"

USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 ' \
'Safari/605.1.15'
API_BASE = 'https://israelrail.azurefd.net/rjpa-prod/api/v1'
DEFAULT_HEADERS = {'User-Agent': USER_AGENT,
"ocp-apim-subscription-key": API_KEY}


class TrainRoutePart(object):
def __init__(self, data):
self.data = data

self.src = data['OrignStation']
self.dst = data['DestinationStation']
self.arrival = data['ArrivalTime']
self.departure = data['DepartureTime']
self.platform = data['Platform']
self.dst_platform = data['DestPlatform']
self.src = data['orignStation']
self.dst = data['destinationStation']
self.arrival = data['arrivalTime']
self.departure = data['departureTime']
self.platform = data['originPlatform']
self.dst_platform = data['destPlatform']

@staticmethod
def parse_time(t):
return time.strptime(t, "%d/%m/%Y %H:%M:%S")

def __repr__(self):
return "%s (%s) to %s (%s)" % (self.src, self.departure, self.dst, self.arrival)
return "%s (%s) to %s (%s)" % (
station_name_to_id(self.src), self.departure, station_name_to_id(self.dst), self.arrival)


class TrainRoute(object):
Expand All @@ -48,7 +56,10 @@ def __repr__(self):


class IsraelRailApi(object):
def __init__(self, url, params, headers=DEFAULT_HEADERS):
def __init__(self, url, params, headers=None):
self.arguments = None
if headers is None:
headers = DEFAULT_HEADERS
self.url = '/'.join((API_BASE, url))
self.params = params
self.headers = headers
Expand All @@ -71,20 +82,26 @@ def parse(self, result):
return result

def request(self, **kwargs):
arguments = self.prepare_arguments(kwargs)
return self.parse(requests.get(self.url, params=arguments, headers=self.headers))
self.arguments = self.prepare_arguments(kwargs)
return self.parse(requests.get(self.url, params=self.arguments, headers=self.headers))


class GetRoutesApi(IsraelRailApi):
def __init__(self):
super().__init__('GetRoutes',
{'OId': {}, 'TId': {},
'Date': {},
'Hour': {'default': '0900'},
'isGoing': {'default': 'true', 'required': False}
super().__init__('timetable/searchTrainLuzForDateTime',
{'fromStation': {}, 'toStation': {},
'date': {},
'hour': {'default': '09:00'},
'scheduleType': {'default': 1},
'systemType': {"default": 2},
"languageId": {"default": "English"}
})

def parse(self, raw_result):
raw_result.raise_for_status()
routes = raw_result.json()['Data']['Routes']
return [TrainRoute(r['Train']) for r in routes]
result = raw_result.json()['result']
size = result['numOfResultsToShow']
index = result['startFromIndex']

routes = result['travels'][index: index + size]
return [TrainRoute(r['trains']) for r in routes]
24 changes: 14 additions & 10 deletions israelrailapi/schedule.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
import logging
import time
import sys
import time

from israelrailapi.train_station import translate_station
from israelrailapi.api import GetRoutesApi
from api import GetRoutesApi
from train_station import translate_station


class TrainSchedule(object):
def query(self, src_station, dst_station, start_date=None, start_hour=None):
@staticmethod
def query(src_station, dst_station, start_date=None, start_hour=None):
src_station = translate_station(src_station)
dst_station = translate_station(dst_station)
if start_date is None:
start_date = time.strftime("%Y-%m-%d")
if start_hour is None:
start_hour = "09:00"
start_date = start_date.strip().replace('-', '').replace('/', '').replace('.', '')
start_hour = start_hour.strip().replace(':', '')
start_hour = start_hour.strip().replace(':', '').replace('-', '')
start_hour = f"{start_hour[:2]}:{start_hour[2:]}"
start_date = f"{start_date[:4]}-{start_date[4:6]}-{start_date[6:8]}"

logging.info("Query: %s->%s (%s %s)" % (src_station, dst_station,
start_date, start_hour))
result = GetRoutesApi().request(OId=src_station, TId=dst_station,
Date=start_date, Hour=start_hour)
result = GetRoutesApi().request(fromStation=src_station, toStation=dst_station,
date=start_date, hour=start_hour)
logging.info(result)
return result


if '__main__' == __name__:
logging.basicConfig(level=logging.DEBUG)
t = TrainSchedule()
if len(sys.argv) >= 4:
t.query(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
if len(sys.argv) == 5:
q = t.query(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
print(q)
else:
print("Usage: %s <src> <dst> <YYYY-MM-DD> <hh:mm>" % (sys.argv[0], ))
print("Usage: %s <src> <dst> <YYYY-MM-DD> <hh:mm>" % (sys.argv[0],))
6 changes: 5 additions & 1 deletion israelrailapi/train_station.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from israelrailapi.stations import STATIONS, STATION_INDEX
except ImportError:
logging.warning("Unable to load station list")
from stations import STATIONS, STATION_INDEX


def cleanup_name(n):
Expand All @@ -24,6 +25,9 @@ def translate_station(station_name):
return lookup_station(station_name)


def station_name_to_id(station_id, default_language='Eng'):
return STATIONS[str(station_id)][default_language]


if __name__ == '__main__':
print(STATION_INDEX)

0 comments on commit 26b39f2

Please sign in to comment.