Profile (Developer)

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 ProfileInterface. This interface defines the variables and methods a profile has.

How to build a profile?

Requirements

  • 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.

Steps

  1. Read the API of a profile. See below.

  2. Have a look at the already existing profiles and the ProfileInterface to get the structure of a profile.

  3. Create a new product folder with an __init__.py file containing the profile class

  4. Fill the required variables

  5. Add your profile to /pyhafas/profile/__init__.py

  6. Test if everything works

  7. Yes? Perfect, add your profile in the documentation and create a pull request! No? Go on with step 8.

  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.

  1. 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 pyhafas.profile.vsn.requests.journey.VSNJourneyRequest class.

  2. 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!

API

Here are the minimum required variables of a profile (generated from ProfileInterface):

class pyhafas.profile.interfaces.ProfileInterface[source]

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.

addChecksum: bool

Whether the checksum authentication method should be activated. Exclusive with addMicMac

addMicMac: bool

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.

baseUrl: str

Complete http(s) URL to mgate.exe of the HaFAS deployment. Other endpoints are (currently) incompatible with pyHaFAS

defaultProducts: List[str]

List of products (item must be a key in availableProducts) which should be activated by default

defaultUserAgent: str

(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.

locale: str

(used in future) Locale used for i18n. Should be an IETF Language-Region Tag

Examples: https://tools.ietf.org/html/bcp47#appendix-A

requestBody: dict

Static part of the request body sent to HaFAS. Normally contains informations about the client and another authentication

salt: str

(required if addMicMac or addChecksum is true). The salt for calculating the checksum or mic-mac

timezone: datetime.tzinfo

Timezone HaFAS lives in. Should be a pytz timezone object

userAgent: str

(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.