Adding a new system to pybikes
You can scaffold a new bike share system by running
$ python -m utils.scaffold example
================================================
Here is your 'Example' implementation
System: pybikes/example.py
Data: pybikes/data/example.json
Run tests by:
$ pytest -k Example
Visualize result:
$ make map! T_FLAGS+='-k Example'
Happy hacking :)
================================================
This is what you need to get started adding a new system to pybikes.
Pybikes acts as a bike share instance factory.
An instance represents a bike share system in a particular city or region.
A system is the implementation of a bike share system. It's the code and logic to access an endpoint and extract bike share information. One system can have many instances.
Instances are declared on json files and are stored in pybikes/data
. It contains meta information about the instance in particular and the arguments to initialize the system.
Let's look through the example
Example
is a subclass of BikeShareSystem
. It is implemented in pybikes/example.py
.
import json
from pybikes import BikeShareSystem, BikeShareStation, PyBikesScraper
from pybikes.base import Vehicle, VehicleTypes
class Example(BikeShareSystem):
meta = {
# Name of the company behind the system
"company": ["Some company name"],
# XXX add license if it applies
"license": {
"name": "Name of the license",
"url": "https://link.to.license.example"
}
}
def __init__(self, tag, meta, endpoint):
super().__init__(tag, meta)
self.endpoint = endpoint
def update(self, scraper=None):
scraper = scraper or PyBikesScraper()
data = scraper.request(self.endpoint)
data = json.loads(data)
# XXX remove if system does not support stations
self.stations = [
BikeShareStation(
name=st["name"],
latitude=st["latitude"],
longitude=st["longitude"],
bikes=st["bikes"],
free=st["free"],
# Add more extra fields if available
extra={
"uid": st["id"],
"online": st["online"],
},
) for st in data["stations"]
]
# XXX remove if system does not support vehicles
self.vehicles = [
Vehicle(
latitude=vh["latitude"],
longitude=vh["longitude"],
system=self,
vehicle_type=getattr(VehicleTypes, vh["type"]),
extra={
"uid": vh["id"],
"online": vh["online"],
}
) for vh in data["vehicles"]
]
Example
instances are declared on a pybikes/data/example.json
file.
{
"class": "Example",
"system": "example",
"instances": [
{
"tag": "example-foo",
"endpoint": "https://gist.githubusercontent.com/eskerda/919bb934b999f296ec189c4b33ef5d59/raw/6ad847524666a16104a0e750cf90ef06ece0d8b5/feed.json",
"meta": {
"name": "Some name",
"city": "City or region of the system",
"latitude": 1.1,
"longitude": 1.1,
"country": "Two letter country code"
}
}
]
}
When we call pybikes.get("example-foo")
, the library will instantiate a Example object with the arguments declared in the data file.