Skip to main content

An unofficial interface to timetable information of the Münchner Verkehrsgesellschaft (MVG).

Project description

mvg

This package aims to provide a clean, performant and barrier-free interface to timetable information of the Münchner Verkehrsgesellschaft (MVG), responsible for public transport in Munich. It exports the class MvgApi to retrieve stations, lines and departures from the unofficial JSON API at https://www.mvg.de.

Disclaimer

This project is not an official project from the Münchner Verkehrsgesellschaft (MVG). It was developed as a private project from lack of a documented and openly accessible API. It simply reproduces the requests made by https://www.mvg.de to provide a barrier-free access to local timetable information.

Therefore, the following usage restrictions from the MVG Imprint do apply to all users of this package:

Our systems are used for direct customer interaction. The processing of our content or data by third parties requires our express consent. For private, non-commercial purposes, moderate use is tolerated without our explicit consent. Any form of data mining does not constitute moderate use. We reserve the right to revoke this permission in principle or in individual cases. Please direct any questions to: redaktion@mvg.de

(from https://www.mvg.de/impressum.html, accessed on 04. Feb 2023)

Why another MVG package?

The project was inspired by two existing packages:

  • The package PyMVGLive from 2017 does provide an interface to the former MVGLive API at mvg-live.de. As of 2022 the MVGLive website does not exist anymore and the package has been archived. Although the old API still works for some stations, it does not for others - mainly due to updated station identifiers. Therefore, the package is considered deprecated and cannot be used for new designs.
  • The newer package mvg-api offers an implementation from 2020 based on the API at www.mvg.de/api/fahrinfo, which went offline in 2024. It considered the updated station identifiers and provided the basis for other projects such as mvg-cli.

So why another MVG API package? In the end three reasons were decisive:

  • The recent website at uses a new API at www.mvg.de/api/bgw-pt/v3, which seems to be more performant than the previous one.
  • None of the existing packages offer asynchronous calls for concurrent code projects.
  • An optimized package was required to develop a Home Assistant integration.

Installation

Install from the Python Package Index (PyPI) using pip:

pip install mvg

Basic Usage

The interface was designed to be simple and intuitive. Basic usage follows these steps:

  • Find a station using MvgApi.station(station) by its name and place (e.g. "Universität, München") or its global station identifier (e.g. "de:09162:70").
  • Alternatively, MvgApi.nearby(latitude, longitude) finds the nearest station.
  • Create an API instance using MvgApi(station) by its global identifier.
  • Use the method .departures() to retrieve information from the API.

A basic example looks like this:

from mvg import MvgApi

station = MvgApi.station('Universität, München')
if station:
    mvgapi = MvgApi(station['id'])
    departures = mvgapi.departures()
    print(station, departures)

Available Stations and Lines

The static methods MvgApi.stations() and MvgApi.lines() expose a list of all available stations and a list of all available lines from designated API endpoints. While these calls are great for reference, they are also quite extensive and should not be used within a frequent query loop.

Filters

The results from .departures(limit, offset, transport_types) can be filtered using the following arguments:

  • limit limits the output to the given number of departures, defaults to 10
  • offset adds an offset (e.g. walking distance to the station) in minutes, defaults to 0
  • transport_types filters the result by a list of transport types (e.g. [TransportType.UBAHN])

A filtered example looks like this:

from mvg import MvgApi, TransportType

station = MvgApi.station('Universität, München')
if station:
    mvgapi = MvgApi(station['id'])
    departures = mvgapi.departures(
        limit=3,
        offset=5,
        transport_types=[TransportType.UBAHN])
    print(station, departures)

Example results

station() or nearby() results a dict:

{ 
'id': 'de:09162:70', 
'name': 'Universität', 
'place': 'München'
'latitude': 48.15007, 
'longitude': 11.581
}

departures() results a list of dict:

[{
'time': 1668524580,
'planned': 1668524460,
'delay': 0,
'platform': 1,
'realtime': True,
'line': 'U3',
'destination': 'Fürstenried West',
'type': 'U-Bahn',
'icon': 'mdi:subway',
'cancelled': False,
'messages': []
}, ... ]

Advanced Usage: Asynchronous Methods

The class MvgApi internally calls asynchronous methods using asyncio and aiohttp to perform web requests efficiently. These asynchronous methods are marked by the suffix _async and can be utilized by users in projects with concurrent code.

Session management:

  • Only async methods (ending with _async) accept an optional session parameter, which must be an aiohttp.ClientSession.
  • Synchronous methods do not accept a session parameter and manage their own session internally.

Example: Using a shared aiohttp session for multiple async calls

import asyncio
import aiohttp
from mvg import MvgApi

async def demo() -> None:
    async with aiohttp.ClientSession() as session:
        station = await MvgApi.station_async('Universität, München', session=session)
        if station:
            departures = await MvgApi.departures_async(station['id'], session=session)
            print(station, departures)

asyncio.run(demo())

Note about notebooks and running event loops

If you call the synchronous helpers (for example MvgApi.station()) from an environment that already has an active asyncio event loop (such as Jupyter notebooks), Python's asyncio.run() would normally raise RuntimeError. This library detects that case and transparently submits the underlying coroutine to a background event loop so the synchronous convenience methods continue to work from notebooks and similar environments.

Notable Contributions

  • Thanks to jrester for adding support of reusable aiohttp HTTP sessions.
  • Thanks to jrester for adding additional information to departures.
  • Thanks to jrester for improving lines endpoint.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mvg-1.6.0.tar.gz (13.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mvg-1.6.0-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file mvg-1.6.0.tar.gz.

File metadata

  • Download URL: mvg-1.6.0.tar.gz
  • Upload date:
  • Size: 13.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.18

File hashes

Hashes for mvg-1.6.0.tar.gz
Algorithm Hash digest
SHA256 8e993a0d469062d2fb3870cece7860029d0df2a6a8d30408e5b7a77cf5f08492
MD5 710bdf7f3df9184fbd7d93681d1d1d30
BLAKE2b-256 985533e16cad16aef7e18eb076d178fabf5ac552fee2fd625d5dd857edd4e553

See more details on using hashes here.

File details

Details for the file mvg-1.6.0-py3-none-any.whl.

File metadata

  • Download URL: mvg-1.6.0-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.18

File hashes

Hashes for mvg-1.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 349763655f03c9a32b39c4de440c14ed4a11b5c8c925550b8c0eaa77b70eec94
MD5 2c3b36b5b14d6dd521a2b5cb2db2b4e7
BLAKE2b-256 c6885271783f11467d57d2b3012e4c8e8642d436e73f3452691ad98d54178772

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page