choo¶
choo is a python3 library providing a uniform interface for public transport APIs.
Contents:¶
Getting Started¶
The Choo Data Model¶
Before we start using choo, you have to understand its underlying Models.
- Stop
- A Stop is a group of Platforms (e.g. Berlin Hbf).
- Platform
- A Platform is a place where rides stop (e.g. Gleis 7). It belongs to one Stop.
- Ride
- A Ride is the journey of a bus/train/etc. It only happens once. Even the “same” ride on the next day is handled as another Ride.
- Line
- A Line is a name for a group of Rides (e.g. Bus Line 495). Every Ride belongs to one Line.
- Trip
- A Trip is a connection between two Stops (or AbstractLocations to be precise, see below) with rides, interchanges and/or footpaths in between.
The models Stop, Adress and POI (Point of Interest) are all subclasses of Location which describes a stand-alone Location with City and Name
Also, Location and Platform are subclasses of AbstractLocation which describes anything that has a static position.
Those models are called Searchables because you can search for them with choo. You can...
- provide an instance of them. choo will try to retrieve it and return a more complete version of it to you
- use their
Request
submodel to specify what you are looking. choo will use theResult
submodel to give you the search results.
Some other Models that are part of choo but can not be searched for:
- Way
- A path between two AbstractLocation objects.
- TimeAndPlace
- A time and place object describes the time, stop and platform and coordinates where a ride meets a stop.
- RideSegment
- In most cases, we are only interested in a part of a Ride – from where you enter the train/bus/etc. to where you leave it. That part is called a RideSegment – it consists of a Ride and the start and end point of the segment.
- RealtimeTime
- Points in time are always given as a RealtimeTime object, which consists of a datetime and a delay (if known).
- Coordinates
- Each
AbstractLocation
may have Coordinates. They consist of latitude and longitude. - WayType
- Each Way has a waytype. A WayType has one of the values
walk
,bike
,car
ortaxi
- LineType
Each Line has a linetype. A Linetype has one of the values
(empty string)
,train
,train.local
,train.longdistance
,train.longdistance.highspeed
,urban
,metro
,tram
,bus
,bus.regional
,bus.city
,bus.express
,suspended
,ship
,dialable
, orother
.An empty string means that it can be anyone of the other linetypes, The linetype
bus
means that it could be any of the bus-subtypes. The reason for this is that not all networks differentiate between some subtyes (e.g. bus types). See the network reference for which linetypes it may output.
For more information, see Model Reference.
Command Line Interface¶
usage: choo [-h] [--pretty] network query
positional arguments:
network network to use, e.g. vrr
query any Searchable or Searchable.Request as JSON
optional arguments:
-h, --help show this help message and exit
--pretty pretty-print output JSON
To get startet, let’s look up Essen Hauptbahnhof in the VRR network using the command line interface.
To do so, we first have to describe Essen Hauptbahnhof as a Stop
:
["Stop", {
"name": "Essen Hauptbahnhof"
}]
Now we pass this data to the API. We use the network vrr
. --pretty
means that the resulting JSON should be pretty printed.
$ choo --pretty vrr '["Stop", {"name": "Essen Hauptbahnhof"}]'
We get the following result:
[
"Stop",
{
"id": 20009289,
"source": "vrr",
"coords": [
51.451137,
7.012941
],
"country": "de",
"city": "Essen",
"name": "Hauptbahnhof",
"full_name": "Essen Hbf",
"ifopt": "de:5113:9289",
"rides": { },
"lines": { }
}
]
As you can see, the API returned a Stop with more information.
The stop now is defined by it’s correct country, city, name and full_name attribute. Also, we have its coordinates now. source
contains the name of the network that gave us this data. id
is the ID of the Stop in this network.
The rides
and lines
attributes were shortened in this example but will give you Ride.Results
and Line.Results
if the API provides this information. If not, you can still use a Ride.Request
oder Line.Request
to request it explicitely.
For more information about the JSON format, see Model Reference and Model Serialization.
For more information about how to query information, see Network API.
Python Interface¶
Let’s see how you would access this via the Python interface.
from choo.models import Stop
from choo.networks.de import vrr
essen = Stop(name='Essen Hauptbahnhof')
essen = vrr.query(essen)
We created the Stop, got the network and used the generic .query() function of the VRR api wich gave us the same result as above.
print(essen.city) # Essen
print(essen.name) # Hauptbahnhof
print(essen.full_name) # Essen Hbf
# iterates through all lines
for line in essen.lines:
print(line.shortname) # RB40 and similar
# iterates through all rides
for ridesegment in essen.rides:
ride = ridesegment.ride
print(ride.number) # train number or similar
print(ride.line.shortname) # 106 or similar
# all Ride attributes can also accessed using the RideSegment
print(ridesegment.number) # same as ride.number
# iterate through all stops of the RideSegment
for timeandplace in ridesegment:
if timeandplace is not None: # this is not a gap
if timeandplace.departure is not None: # we now the departure
print(timeandplace.departure.time) # planned time as datetime.datetime
print(timeandplace.departure.delay) # expceted delay as datetime.datetimeplanned time as datetime.datetime
print(timeandplace.departure.is_live) # shortcut for delay is not None
print(timeandplace.departure.livetime) # expceted time if real time information is available, otherwise planned time
print(timeandplace.stop.name) # Hauptbahnhof or similar
# iterate through all stops of the Ride
for timeandplace in ridesegment.ride:
# same as above, but without boundaries
# you can also slice a ride or ride segment to get another ride segment
newsegment = ridesegment.ride[1:]
For more information, see Model Reference.
HTTP API¶
usage: choo-server [-h] [--host HOST] [--port PORT]
optional arguments:
-h, --help show this help message and exit
--host HOST set address to listen on (default: 0.0.0.0)
--port PORT set tcp port (default: random unused port)
Just start it and open it in your browser to see the API.
How to search for a Trip¶
Just query the Request-submodel of Trip, like explained above. Simple example:
["Trip.Request", {
"origin:" ["Stop", {
"name": "Essen Hauptbahnhof"
}],
"destination:" ["Stop", {
"name": "Dortmund Hauptbahnhof"
}]
}]
Trip.Request(origin=Stop(name='Essen Hauptbahnhof'),
destination=Stop(name='Dortmund Hauptbahnhof'))
Network Reference¶
-
class
API
¶ The base class for all other APIs.
-
query
(obj)¶ Pass a Searchable and it will return a Searchable from the API or None/null if it could not be found. Pass a Searchable.Request and you will get a corresponding Searchable.Results.
-
-
class
EFA
¶ Public transport API used world wide by many network operators.
Model Reference¶
Note
Every attribute can be None when no data is available, unless noted otherwise.
Base Classes¶
All choo models are based upon one of the following three base classes that build on top of each other.
-
class
Serializable
¶ All models are Serializables. See Model Serialization for more information.
-
validate
()¶ Checks if all attributes have valid values. Raises an exception if the object is not valid. This method is also called by
serialize()
.
-
serialize
()¶ Serializes this object in a JSON-encodable format. This is a shortcut for Serializable.serialize(serializable).
Return type: the serialized object
-
classmethod
serialize
(obj) Serializes the given instance of this model in a JSON-encodable format, using typed serialization if the given object is an instance of a submodel.
>>> stop.serialize() {…} >>> Stop.serialize(stop) == stop.serialize() True >>> Location.serialize(stop) ['Stop', {…}] >>> Location.serialize(stop)[1] == stop.serialize() True
Parameters: obj – A serialized representation of a choo object Return type: the serialized object
-
classmethod
unserialize
(data)¶ Unserializes an object of this model or one of its child classes from a JSON-encodable format. Always use the same model for unserialization as you used for serialization.
Parameters: data – A serialized representation of an object of this model or one of its submodels. Return type: the unserialized object
-
-
class
Searchable
¶ An
Serializable
that can be searched for. You can pass it to the API and to get its complete information.All subclasses have a
Request
and aResults
subclass. You can pass the and instance of the Request subclass to the API to get search results in a Results subclass.-
class
Request
(Serializable)¶ A request template for this Model with lots of possible search criteria that can be set.
-
class
Searchable.
Results
(Serializable)¶ A list (of Request-Results) of instances of this object. Those lists can have match scores.
You can just iterate over this object to get its contents.
-
scored
(obj)¶ Returns an iterator over tuples of (results, score).
-
filter
(request)¶ Remove all objects that do not match the given Request.
-
filtered
(request)¶ Returns a new
Results
instance with all objects that do not match the given Request removed.
Note
For serialization, the list of results is stored in the property
results
as a list. Each element of this list is a two-element list containing the serialized result and the match score.Please note that the serialized result is typed serialized if the Model has submodels (e.g.
Location
, which hasStop
etc…)-
-
class
-
class
Collectable
¶ A
Searchable
that can be collected. It has an ID and it really exists and is not some kind of data construct.-
source
¶ Source Network of this object. All APIs set this attribute, but it is not mandatory for input.
-
id
¶ ID of this object (as
str
) in the source network.
-
Main Models¶
Submodels of Collectable
.
-
class
AbstractLocation
¶ Base class for everything that has a fixed position.
-
coords
¶ The
Coordinates
of this location.
-
class
Request
¶ Submodel of
Searchable.Request
.
-
class
AbstractLocation.
Results
¶ Submodel of
Searchable.Results
.
-
-
class
Ride
(line=None, number=None)¶ A ride is implemented as a list of
TimeAndPlace
objects.Although a
Ride
is iterable, most of the time not all stops of the rides are known and the list of known stations can change. This makes the use of integer indices impossible. To avoid this problem, dynamic indices are used for aRide
.If you iterate over a
Ride
each item you get isNone
or aTimeAndPlace
object. Each item that isNone
stands for n missing stations. It can also mean that theTimeAndPlace
before and after the item are in fact the same. To get rid of allNone
items, pass an incomplete ride to a network API.You can use integer indices to get, set or delete single
TimeAndPlace
objects which is usefull if you want the first (0) or last (-1). But, as explained above, these integer indices may point to another item when theRide
changes or becomes more complete.If you iterate over
ride.items()
you get(RideStopPointer, TimeAndPlace)
tuples. When used as an indice, aRide.StopPointer
used as an indice will always point to the sameTimeAndPlace
object.You can slice a
Ride
(using integer indices or :py:class RideStopPointer`) which will get you aRideSegment
that will always have the correct boundaries. Slicing with no start or no end point is also supported.Caution
Slicing a
Ride
is inclusive! For example, slicing from element 2 to element 5 results in aRideSegment
containing 4 elements in total!-
canceled
¶ A boolean indicating whether this ride has been canceled.
-
bike_friendly
¶ A boolean indicating whether this is a bike-friendly vehicle.
-
items
()¶ A
(RideStopPointer, TimeAndPlace)
iterator as explained above.
-
append
(item)¶ Append a
TimeAndPlace
object.
-
prepend
(item)¶ Prepend a
TimeAndPlace
object.
-
insert
(position, item)¶ Insert a
TimeAndPlace
as the new positionposition
.
Attention
The following attributes are dynamic and can not be set.
-
path
¶ Get the geographic path of the ride as a list of
Coordinates
.Falls back to just directly connecting the platform or stop coordinates if no other information is available. If some information is still missing, its value is
None
.
-
is_complete
¶ True
if theTimeAndPlace
list is complete and there are no Nones in the list, otherwiseFalse
.
-
class
StopPointer
¶ See above. Immutable. Do not use this class directly. You can cast it to int.
Note
For serialization, pointers are not used. The property
stops
is created containing with each item being either a serializedTimeAndPlace
object orNone
.The property
path
is created containing a dictionary containing paths between consecutive ride stops with the index of the origin stop as keys.-
class
Ride.
Request
¶ Submodel of
Searchable.Request
.
-
class
Ride.
Results
¶ Submodel of
Searchable.Results
.
-
-
class
Line
(linetype=None)¶ A group of Rides (e.g. Bus Line 495). Every
Ride
belongs to one Line.-
product
¶ The product name, for example InterCity, Hamburg-Köln-Express or Niederflurbus.
-
route
¶ The route description.
-
operator
¶ The name of the company that operates this line.
-
class
Request
¶ Submodel of
Searchable.Request
.
-
class
Line.
Results
¶ Submodel of
Searchable.Results
.
-
Locations¶
Submodels of AbstractLocation
.
-
class
Platform
(stop, name=None, full_name=None)¶ An
AbstractLocation
where rides stop (e.g. Gleis 7). It belongs to oneStop
.-
ifopt
¶ The globally unique ID of this Platform according to Identification of Fixed Objects in Public Transport supported by some APIs.
-
name
¶ The name of this Platform (e.g. 7 or 2b).
-
full_name
¶ The full name of this Platform (e.g. Bussteig 7 or Gleis 2b)
-
class
Request
¶ Submodel of
AbstractLocation.Request
.
-
class
Platform.
Results
¶ Submodel of
AbstractLocation.Results
.
-
-
class
Location
(country=None, city=None, name=None)¶ An
AbstractLocation
that is named and not a sublocation like a Platform.-
country
¶ The country of this location as a two-letter country code.
-
city
¶ The name of the city this location is located in.
-
name
¶ The name of this location. If the
city
attribute isNone
this it may also included in the name.
-
near_stops
¶ Other stops near this one as a
Stop.Results
, if available. You can always search for Stops near anAbstractLocation
directly usingAbstractLocation.Request
.
-
class
Request
¶ Submodel of
AbstractLocation.Request
.-
name
¶ A search string for the name of the Location.
-
city
¶ City of the Location.
-
-
class
Location.
Results
¶ Submodel of
AbstractLocation.Results
.
-
-
class
Stop
(country=None, city=None, name=None)¶ A
Location
describing a stop, for example: Düsseldorf Hbf.-
ifopt
¶ The globally unique ID of this Stop according to Identification of Fixed Objects in Public Transport supported by some APIs.
-
uic
¶ The is the international train station id by the International Union of Railways.
-
full_name
¶ The full name of this Stop. Can be just the city and the name, but does’nt have to.
-
lines
¶ The Lines that are available at this stop as a
Line.Results
object, if available. You can always search for Lines at aStop
usingLine.Request
.
-
rides
¶ The next rides at this stop as a
Ride.Results
object, if available. You can always search for Rides at aStop
usingRide.Request
.
-
class
Request
¶ Submodel of
Location.Request
.
-
class
Stop.
Results
¶ Submodel of
Location.Results
.
-
-
class
Address
(country=None, city=None, name=None)¶ A
Location
describing an address. Thename
attribute contains the address in one string, but more detailed attributes may be available:-
street
¶ The name of the street.
-
number
¶ The house number as a string.
-
class
Request
¶ Submodel of
Location.Request
.
-
class
Address.
Results
¶ Submodel of
Location.Results
.
-
-
class
POI
(country=None, city=None, name=None)¶ A
Location
describing a Point of Interest.-
class
Request
¶ Submodel of
Location.Request
.
-
class
POI.
Results
¶ Submodel of
Location.Results
.
-
class
Trips¶
Submodel of Searchable
.
-
class
Trip
¶ A connection from a
AbstractLocation
to anotherAbstractLocation
.It consists of a list of
RideSegment
andWay
objects. Just iterate over it to get its elements.-
time
¶ The fetching time of this object as a
datetime
object. This is relevant to know how up to date the contained real time data (delays, cancellation, platform changes, etc.) is. All APIs set this attribute, but it is not mandatory for input.
-
tickets
¶ TicketList
of available tickets for this trip.
Attention
The following attributes are dynamic and can not be set.
-
origin
¶ The start
AbstractLocation
of this trip.
-
destination
¶ The end
AbstractLocation
of this trip.
-
departure
¶ The departure at the first
AbstractLocation
of this trip asRealtimeTime
. (If there are leadingWay
objects they need to have theduration
attribute set in order for this to work)
-
arrival
¶ The arrival at the last
AbstractLocation
of this trip asRealtimeTime
. (If there are trailingWay
objects they need to have theduration
attribute set in order for this to work)
-
changes
¶ The number of changes in this trip (number of
RideSegments
minus one with a minimum of zero)
-
bike_friendly
¶ False
if at least oneRide
that is part of this trip is not bike friendly.True
if all of them are.None
if there is no bike friendly information for all rides but those that have the information are bike friendly.
Note
For serialization, the property
parts
is created containing the list of typed serialized trip parts.-
class
Request
¶ Submodel of
Searchable.Request
.-
origin
¶ Not None. The start
AbstractLocation
of the trip.
-
destination
¶ Not None. The end
AbstractLocation
of the trip.
-
departure
¶ The minimum departure time as
RealtimeTime
ordatetime.datetime
.If both times are
None
the behaviour is as if you would have set the departure time to the current time right before sending the request. (Default:None
)
-
arrival
¶ The latest allowed arrival as
RealtimeTime
ordatetime.datetime
. (Default:None
)
-
max_changes
¶ The maximum number of changes allowed or
None
for no limit. (Default:None
)
-
with_bike
¶ Whether a bike should be taken along. (Default:
False
)
-
wheelchair
¶ Whether to allow only vehicles that support wheelchairs. (Default:
False
)
-
low_floor_only
¶ Whether to allow only low floor vehicles. (Default:
False
)
-
allow_solid_stairs
¶ Whether to allow solid stairs. (Default:
True
)
-
allow_escalators
¶ Whether to allow escalators. (Default:
True
)
-
allow_elevators
¶ Whether to allow elevators. (Default:
True
)
-
waytype_origin
¶ Waytype at the beginning of the trip. (Default: walk)
-
waytype_via
¶ Waytype at changes or ways during the trip. (Default: walk)
-
waytype_destination
¶ Waytype at the end of the trip. (Default: walk)
-
wayduration_origin
¶ Maximum duration of a way at the beginning of the trip as a
datetime.timedelta
. (Default: 10 minutes)
-
wayduration_via
¶ Maximum duration of changes of ways during the trip as a
datetime.timedelta
. (Default: 10 minutes)
-
wayduration_destination
¶ Maximum duration of a way at the end of the trip as a
datetime.timedelta
. (Default: 10 minutes)
-
-
class
Trip.
Results
¶ Submodel of
Searchable.Results
.-
origin
¶ Not None. The start
AbstractLocation
of the trip.
-
destination
¶ Not None. The end
AbstractLocation
of the trip.
-
-
Trip parts¶
Submodels of Serializable
.
-
class
RideSegment
¶ -
This class created by slicing :py:class:`Ride` objects.
Integer indices are not too useful in this class, either, although you can for example still use 0 and -1 to get the first or last
RideStopPointer
of this segment.This model is usable in the same way as a
Ride
. Slicing it will return anotherRideSegment
for the sameRide
.Caution
Slicing a
RideSegment
is inclusive! For example, slicing from element 2 to element 5 results in aRideSegment
containing 4 elements in total!-
items
()¶ A
(RideStopPointer, TimeAndPlace)
iterator over this segment.
All attributes of the
Ride
are also directly accessible through aRideSegment
.Attention
The following attributes are dynamic and can not be set.
-
path
¶ Get the geographic path of the ride segment as a list of
Coordinates
.Falls back to just directly connecting the platform or stop coordinates if no other information is available. If some information is still missing, its value is
None
.
-
is_complete
¶ True
if theTimeAndPlace
list of this Segment is complete.
-
departure
¶ The departure at the first
Stop
of this segment asRealtimeTime
. Shortcut forsegment[0].departure
.
-
arrival
¶ The arrival at the last
Stop
of this segment asRealtimeTime
. Shortcut forsegment[-1].arrival
.
Note
For serialization, the boundaries are given as integer indexes as properties
origin
anddestination
. Each one can be missing if the boundary is not set. (e.g.ride[5:]
)Dont forget that Ride slicing is inclusive (see above)!
-
-
class
Way
(origin: Location, destination: Location, distance: int=None)¶ Individual transport (walk, bike, taxi…) with no schedule. Used for example to get from a
Address
to aStop
and for changes but also for trips that are faster by foot.-
distance
¶ The distance in meters as
int
.
-
duration
¶ The expected duration as
datetime.timedelta
.
-
path
¶ The path as a list of
Coordinates
.
-
Other Models¶
Submodels of Serializable
.
-
class
TimeAndPlace
(platform, arrival=None, departure=None)¶ Time and place of a
Ride
stopping at aPlatform
.-
arrival
¶ The arrival time of the
Ride
asRealtimeTime
.
-
departure
¶ The departure time of the
Ride
asRealtimeTime
.
-
-
class
RealtimeTime
(time, delay=None)¶ A point in time with optional real time data.
Parameters: - time – The originally planned time as a datetime.datetime object.
- delay – The (expected) delay as a datetime.timedelta object if known.
-
time
¶ Not None. The originally planned time as a datetime.datetime object.
-
delay
¶ The (expected) delay as a datetime.timedelta object or None. Please note that a zero delay is not the same as None. None stands for absence of real time information.
Attention
The following attributes are dynamic and can not be set.
-
is_live
¶ True if there is real time data available. Shortcut for
delay is not None
-
livetime
¶ The (expected) actual time as a datetime.datetime object if real time data is available, otherwise the originally planned time.
-
class
TicketList
(all_types: bool=True)¶ A list of tickets.
-
currency
¶ Not None. The name or abbreviation of the currency.
-
level_name
¶ How a level is named at this network.
-
single
¶ Not None. The single ticket as
TicketData
.
-
bike
¶ The single ticket as
TicketData
.
-
other
¶ Not None. Other available tickets as a dictionary with the name of the tickets as keys and
TicketData
objects as values.
-
Data types¶
Submodels of Serializable
.
-
class
TicketData
(authority=None, level=None, price=None, price_child=None)¶ Information about a ticket.
The name of the authority selling this ticket.
-
level
¶ The level of this ticket, e.g. A or something similar, depending on the network
-
price
¶ Not None. The price of this ticket as float.
-
price_child
¶ The children’s price for this ticket if this ticket is not a ticket for children only but has a different price for children.
-
class
LineType
(name)¶ Each
Line
has a line type. A line type has one of the values(empty string)
,train
,train.local
,train.longdistance
,train.longdistance.highspeed
,urban
,metro
,tram
,bus
,bus.regional
,bus.city
,bus.express
,bus.longdistance
,suspended
,ship
,dialable
, orother
.An empty string means that it can be anyone of the other linetypes, The linetype
bus
means that it could be any of the bus-subtypes. The reason for this is that not all networks differentiate between some subtyes (e.g. bus types). See the network reference for which linetypes it may output.All identical linetypes are the same instance:
>>> LineType('bus') is LineType('bus') True
To compare against a linetype, use the
in
operator. Be aware that this operator is not transitive!>>> linetype = LineType('bus.express') >>> linetype in LineType('bus') True >>> LineType('bus') in linetype False >>> LineType('bus') in LineType('') True >>> LineType('') in LineType('bus') False >>> LineType('bus') in LineType('bus') True
You can cast a
LineType
to string if needed:>>> str(LineType('train.local')) 'train.local'
Note
The serialized representation of this model is its string representation.
-
class
LineTypes
(include=('', ), exclude=())¶ A selector for
LineType
object. It is defined as a list of included line types and a list of excluded linetypes. By default, all line types are included.>>> LineType('bus') in LineTypes() True >>> LineType('bus') in LineTypes(exclude=('bus', )) False >>> LineType('bus.express') in LineTypes(exclude=('bus', )) False >>> LineType('bus') in LineTypes(exclude=('bus.express', )) True >>> LineType('bus.express') in LineTypes(exclude=('bus.express', )) False >>> LineType('train') in LineTypes(include=('bus', ), exclude=('bus.express', )) False >>> LineType('bus') in LineTypes(include=('bus', ), exclude=('bus.express', )) True >>> LineType('bus.express') in LineTypes(include=('bus', ), exclude=('bus.express', )) False
You can modify the selector using the following methods:
-
include
(*linetypes)¶ Parameters: linetypes – one or more line types as string or LineType
Make sure that the given line types and all of their subtypes are matched by the selector.
-
exclude
(*linetypes)¶ Parameters: linetypes – one or more line types as string or LineType
Make sure that the given line types and all of their subtypes are not matched by the selector.
Note
For serialization, the properties
included
andexcluded
are created, each one containing a list of line types.-
-
class
WayType
(name)¶ Each
Way
has a line type. A Linetype has one of the valueswalk
,bike
,car
,taxi
.All identical way types are the same instance:
>>> WayType('walk') is WayType('walk') True
You can cast a
WayType
to string if needed:>>> str(WayType('walk')) 'walk'
Note
The serialized representation of this model is its string representation.
-
class
WayEvent
(name, direction)¶ A way
Way
events one of the namesstairs
,escalator
orelevator
and one of the directionsup
ordown
.All identical way types are the same instance:
>>> WayType('escalator', 'down') is WayType('escalator', 'down') True
Attention
The following attributes are dynamic and can not be set.
-
name
¶ Not None.
stairs
,escalator
orelevator
-
direction
¶ Not None.
up
ordown
Note
The serialized representation of this model is a
(name, direction)
tuple.-
Model Serialization / JSON¶
All choo models can be (un)serialized to/from a JSON-encodable format.
In Python¶
from models import Stop, Location, Serializable
# Create a Stop
stop = Stop(city='Essen', name='Hauptbahnhof')
# simple serialization
serialized = stop.serialize()
stop = Stop.unserialize(serialized)
# possibly typed serialization
# this will save the model type if the given object is a submodel
serialized = Location.serialize(stop)
stop = Location.unserialize(serialized)
# this will be a simple serialization because the given Model is not a submodel
serialized = Stop.serialize(stop)
stop = Stop.unserialize(serialized)
# always typed serialization
serialized = Serializable.serialize(stop)
stop = Serializable.unserialize(serialized)
How it works¶
Caution
Some models have a non-dictionary representation or some additional attributes in their dictionary representation. See the Model Reference for more information.
All public attributes that are not dynamic and not None
are put into a dictionary. All values are serialized.
YYYY-MM-DD HH:II:SS
format.{
"_ids": {"vrr": 20009289},
"country": "de",
"city": "Essen",
"name": "Hauptbahnhof",
"coords": [51.451139, 7.012937]
}
If the serialization is typed, the output is a two element list with name of the model and the constructed dictionary (or other respresentation).
["Stop", {
"_ids": {"vrr": 20009289},
"country": "de",
"city": "Essen",
"name": "Hauptbahnhof",
"coords": [51.451139, 7.012937]
}]