Since every HaFAS deployment is different we have the concept of profilesG for managing the differences between them.
For a “standard” HaFAS we have the
BaseProfile which contains code working for most HaFAS deployments.
This profile inherits the methods of all classes living in the folder of the profile. That classes all have an interface that defines the abstract methods of the class.
Most methods are instance methods, so they have a self parameter. Since the class using the method is the profile we use as type hint for self
This interface defines the variables and methods a profile has.
How to build a profile?¶
You need to know how to authenticate to the HaFAS deployment. In most cases, you need to know if the authentication is via mic-mac or checksum+salt and you need the salt. The salt can get out of the source code of official apps of the transport provider or you can look if other HaFAS libraries already support the transport provider and get the salt from them
You need the general requests body. You can get this best with mitmproxy on the official app of the transport provider or of other libraries as in the other requirement
One good source for both requirements is hafas-client in the specific profile folder.
Read the API of a profile. See below.
Have a look at the already existing profiles and the
ProfileInterfaceto get the structure of a profile.
Create a new product folder with an __init__.py file containing the profile class
Fill the required variables
Add your profile to /pyhafas/profile/__init__.py
Test if everything works
Yes? Perfect, add your profile in the documentation and create a pull request! No? Go on with step 8.
Log the request pyHaFAS sends and compare this request with the one the official app sends. Is the difference only in one specific request type or in all? If it is only in one go on stop step 8a otherwise step 8b.
You could create a new class overwriting the format-method of the request. An example where this is done is in the VSNProfile the
format_journey_request()method in the
Please make sure the requestBody in your profile is correct. If it is, please contact us or try to find the method causing the error yourself.
If you need help with any of that you can contact us always!
Here are the minimum required variables of a profile (generated from
The profile interface is the abstract class of a profile.
It inherits all interfaces, so it has all methods a normal profile has available as abstract methods. Therefore it can be used as type hint for self in methods which are inherited by profiles.
Whether the checksum authentication method should be activated. Exclusive with addMicMac
Whether the mic-mac authentication method should be activated. Exclusive with addChecksum
availableProducts: Dict[str, List[int]]
Should contain all products available in HaFAS. The key is the name the end-user will use, the value is a list of bitmasks (numbers) needed for the product. In most cases, this is only one number. This bitmasks will be add up to generate the final bitmask.
Complete http(s) URL to mgate.exe of the HaFAS deployment. Other endpoints are (currently) incompatible with pyHaFAS
List of products (item must be a key in availableProducts) which should be activated by default
(optional) User-Agent in header when connecting to HaFAS. Defaults to pyhafas. A good option would be the app ones. Can be overwritten by the user.
(used in future) Locale used for i18n. Should be an IETF Language-Region Tag
Static part of the request body sent to HaFAS. Normally contains informations about the client and another authentication
(required if addMicMac or addChecksum is true). The salt for calculating the checksum or mic-mac
Timezone HaFAS lives in. Should be a pytz timezone object
(optional) Do not change, unless you know what you’re doing. Disallows the user to change the user agent. For usage in internal code to get the user-agent which should be used.