Skip to main content

Impuls

GitHub | Documentation | Issue Tracker | PyPI

Impuls is a framework for processing static public transportation data. The internal model used is very close to GTFS.

The core entity for processing is called a pipeline, which is composed of multiple tasks that do the actual processing work.

The data is stored in an sqlite3 database with a very lightweight wrapper to map Impuls's internal model into SQL and GTFS.

Impuls has first-class support for pulling in data from external sources, using its resource mechanism. Resources are cached before the data is processed, which saves bandwidth if some of the input data has not changed, or even allows to stop the processing early if none of the resources have been modified.

A module for dealing with versioned, or multi-file sources is also provided. It allows for easy and very flexible processing of schedules provided in discrete versions into a single coherent file.

Installation and Compilation

Impuls is mainly written in Python, however a performance-critical part of this library is written in Rust and bundled alongside the shared library. To install, run the following, preferably inside of a virtual environment:

pip install impuls

Pre-built binaries are available for most platforms. To build from source Rust with Cargo and a C compiler needs to be installed.

The LoadBusManMDB task additionally requires mdbtools to be installed. This package is available in most package managers.

Examples

See https://impuls.readthedocs.io/en/stable/example.html for a tutorial and a more detailed walkthrough over Impuls features.

The examples directory contains 4 example configurations, processing data from four sources into a GTFS file. If you wish to run them, consult with the Development section of the readme to set up the environment correctly.

Kraków

Kraków provides decent GTFS files on https://gtfs.ztp.krakow.pl. The example pipeline removes unnecessary, confusing trip data and fixes several user-facing strings.

Run with python -m examples.krakow tram or python -m examples.krakow bus. The result GTFS will be created in _workspace_krakow/krakow.tram.out.zip or _workspace_krakow/krakow.bus.out.zip, accordingly.

PKP IC (PKP Intercity)

PKP Intercity provides their schedules in a single CSV table at ftp://ftps.intercity.pl. Unfortunately, the source data is not openly available. One needs to email PKP Intercity through the contact provided in the Polish MMTIS NAP in order to get the credentials.

The Pipeline starts by manually creating an Agency, loading the CSV data, pulling station data from https://github.com/MKuranowski/PLRailMap, adjusting some user-facing data - most importantly extracting trip legs operated by buses.

Run with python -m examples.pkpic FTP_USERNAME FTP_PASSWORD. The result GTFS will be created at _workspace_pkpic/pkpic.zip

Radom

MZDiK Radom provides schedules in a MDB database at http://mzdik.pl/index.php?id=145. It is the first example to use the multi-file pipeline support, as the source files are published in discrete versions.

Multi-file pipelines consist of four distinct parts:

  • an intermediate provider, which figures out the relevant input ("intermediate") feeds
  • a intermediate tasks factory, which returns the tasks necessary to load an intermediate feed into the SQLite database
  • a final tasks factory, which returns the tasks to perform after merging intermediate feeds
  • any additional resources, required by the intermediate or final tasks

Caching is even more involved - not only the input feeds are kept across runs, but the databases resulting from running intermediate pipelines are also preserved. If 3 of 4 feeds requested by the intermediate provider have already been processed - the intermediate pipeline will run only for the single new file, but the final (merging) pipeline will be run on all of the 4 feeds.

The intermediate provider for Radom scrapes the aforementioned website to find available databases.

Pipeline for processing intermediate feeds is a bit more complex: it involved loading the MDB database, cleaning up the data (removing virtual stops, generating and cleaning calendars) and pulling stop positions from http://rkm.mzdik.radom.pl/.

The final pipeline simply dumps the merged dataset into a GTFS.

Run with python -m examples.radom, the result GTFS will be created at _workspace_radom/radom.zip.

Warsaw

Warsaw is another city which requires multi-file pipelines. ZTM Warsaw publishes distinct input files for pretty much every other day at ftp://rozklady.ztm.waw.pl. The input datasets are in a completely custom text format, requiring quite involved parsing. More details are available at https://www.ztm.waw.pl/pliki-do-pobrania/dane-rozkladowe/ (in Polish).

The intermediate provider picks out relevant files from the aforementioned FTP server.

Processing of intermediate feeds starts with the import of the text file into the database. Rather uniquely, this step also prettifies stop names - as this would be hard to do in a separate task, due to the presence of indicators (two-digit codes uniquely identifying a stop around an intersection) in the name field. The pipeline continues by adding version meta-data, merging railway stations into a single stops.txt entry (ZTM separates railway departures into virtual stops) and attribute prettifying (namely trip_headsign and stop_lat,stop_lon - not all stops have positions in the input file). Last steps involve cleaning up unused entities from the database.

The final pipeline simply dumps the merged dataset into a GTFS, yet again.

Additional data for stop positions and edge-cases for prettifying stop names comes from https://github.com/MKuranowski/WarsawGTFS/blob/master/data_curated/stop_names.json.

Run with python -m examples.warsaw, the result GTFS will be created at _workspace_warsaw/warsaw.zip.

License

Impuls is distributed under GNU GPL v3 (or any later version).

© Copyright 2022-2026 Mikołaj Kuranowski

Impuls is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

Impuls is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Impuls. If not, see http://www.gnu.org/licenses/.

Impuls pre-built binaries come with sqlite3, which is placed in the public domain.

Development

Impuls uses meson-python. The project layout is quite unorthodox, as Impuls in neither a pure-python module, nor a project with a bog-standard C/C++ extension. Instead, the Rust code is compiled into a shared library which is bundled alongside the Python module.

Development requires Python, Rust with Cargo, a C compiler, and mdbtools (usually all will be available in your package manager repositories) to be installed. To then set up the environment on Linux, run:

$ python -m venv --upgrade-deps .venv
$ . .venv/bin/activate
$ pip install -Ur requirements.dev.txt
$ pip install --no-build-isolation -Cbuild-dir=builddir --editable .
$ ln -s ../../builddir/libextern.so impuls/extern

On MacOS, change the shared library file extension to .dylib. On Windows, change the extension of the shared library to .dll.

To run Python tests, simply execute pytest. To run Rust tests, run meson test -C builddir, or cargo test in the <impuls/extern/> subdirectory.

To run the examples, install their dependencies first (pip install -Ur requirements.examples.txt), then execute the example module, e.g. python -m examples.krakow.

meson-python will automatically recompile the Rust library whenever an editable Impuls install is imported; set the MESONPY_EDITABLE_VERBOSE environment variable to 1 to see meson logs for build details.

By default, the extern Rust library will be built in debug mode. To change that, run meson configure --buildtype=release builddir (buildtype can also be set to debug). To recompile the library, run meson compile -C builddir.

Unfortunately, meson-python requires all Python and Rust source files listed in meson.build. Python files need to be listed for packaging to work, while Rust source files need to be listed for the build backend to properly detect whether libextern needs to be recompiled.

Building wheels

Thanks to cargo-zigbuild and cargo-xwin wheels can be automatically cross-compiled to all major platforms.

Cross-compilation however required multiple extra dependencies: Zig, clang and llvm-tools (mostly llvm-lib and llvm-strip). Rust should also be installed through rustup, along with all of the targets from cross/*.ini files added with rustup add target XXX.

Two extra dependencies need to be installed in the venv as well: pip install -U build wheel.

To build the wheels, simply run python build_wheels.py.

See python build_wheels.py --help for all available options. To debug failed builds, run python build_wheels.py --verbose --jobs 1 FAILED_CONFIG_NAME.

See CONFIGURATION in build_wheels.py for available configurations.

To build the source distribution, run python -m build -so dist.

Download files

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

Source Distribution

impuls-2.5.0.tar.gz (2.4 MB view details)

Uploaded Source

Built Distributions

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

impuls-2.5.0-py3-none-win_arm64.whl (1.2 MB view details)

Uploaded Python 3Windows ARM64

impuls-2.5.0-py3-none-win_amd64.whl (1.2 MB view details)

Uploaded Python 3Windows x86-64

impuls-2.5.0-py3-none-musllinux_1_1_x86_64.whl (1.3 MB view details)

Uploaded Python 3musllinux: musl 1.1+ x86-64

impuls-2.5.0-py3-none-musllinux_1_1_aarch64.whl (1.2 MB view details)

Uploaded Python 3musllinux: musl 1.1+ ARM64

impuls-2.5.0-py3-none-manylinux_2_17_x86_64.whl (1.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

impuls-2.5.0-py3-none-manylinux_2_17_aarch64.whl (1.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

impuls-2.5.0-py3-none-macosx_11_0_x86_64.whl (1.7 MB view details)

Uploaded Python 3macOS 11.0+ x86-64

impuls-2.5.0-py3-none-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file impuls-2.5.0.tar.gz.

File metadata

  • Download URL: impuls-2.5.0.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for impuls-2.5.0.tar.gz
Algorithm Hash digest
SHA256 3791d416e24f2086c1d5a99d0188853d85debc4ac60143b62d97105a5d5f6636
MD5 d8998e69a88ef05ebe04e05e382d78ff
BLAKE2b-256 7b0a49136061f6db874415667be89f2b7762006d9231087a01b0dd24c7f7588f

See more details on using hashes here.

File details

Details for the file impuls-2.5.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: impuls-2.5.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for impuls-2.5.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 23032a955922aaf07584797dc24cb942a6e98c8a103b33a78fd252b6d46369d0
MD5 dc3fcd1f3502babc4c2672cb9725b74c
BLAKE2b-256 c26892bb61f1de002c83bc35912c5eb69c3f9b648624441d678bee40b1b18b12

See more details on using hashes here.

File details

Details for the file impuls-2.5.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: impuls-2.5.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for impuls-2.5.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 b0fced2fac2ebcd7adf49d926cc6319fd59607771afbdb97a4b098857ffd54c2
MD5 d264e475fb2f92dc8a36531fbe4d06be
BLAKE2b-256 fd57725b257cd3dabefcd82220d8513a9b13fba05dcd6b76effbc44c2dcd619f

See more details on using hashes here.

File details

Details for the file impuls-2.5.0-py3-none-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for impuls-2.5.0-py3-none-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 acbfdb6bd85ebe88c0750d3f1d4590ec311d8b9f265c77c00b1fd38267aa1df8
MD5 509b93287187fb95696a0f10a89efbab
BLAKE2b-256 817a156d811c352db278de3fd40d59e7142cdef4b1a1fb7a490200a5e295b32a

See more details on using hashes here.

File details

Details for the file impuls-2.5.0-py3-none-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for impuls-2.5.0-py3-none-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 956ee59a7c069895f365246dde6e44ad77558f14bd25d4059e47336c52d7a594
MD5 0c1697690064e0f8cd3a5509707d72d4
BLAKE2b-256 c8615ad388b6752b2071240d99fb0b458d2ef23c41ce96afded38be0511e1793

See more details on using hashes here.

File details

Details for the file impuls-2.5.0-py3-none-manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for impuls-2.5.0-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 9788953743066672e4cce11a7edb51e286f9ea06b02f0027ab323741b176339e
MD5 8c63fc1bf7b1d7f6bc601b49f4942d4c
BLAKE2b-256 67fac5c22298636b915914e31ba648e1183a94bad0ed907d193f0ea5fa28e305

See more details on using hashes here.

File details

Details for the file impuls-2.5.0-py3-none-manylinux_2_17_aarch64.whl.

File metadata

File hashes

Hashes for impuls-2.5.0-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 cce39b64e46e9573bcfd351ccec163dbc5f30aa0e6e63b76c206987e81b07e6b
MD5 76704193a8eff9893b666c5fefc08f97
BLAKE2b-256 ff392a7450d6b3736aa6fbc2cfa08c3378860ed2d374dd5b3fa8edf3f19ad327

See more details on using hashes here.

File details

Details for the file impuls-2.5.0-py3-none-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for impuls-2.5.0-py3-none-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 3246d5284ebeeaa3223ab6b8270390f32c20db0f9ef5c03e6a96ad1180e2c1d1
MD5 a80e8c9282faeda37824ad275bca170e
BLAKE2b-256 063760f4a036d20274e00ed5acb8c7a78ddb2a5aa41d50c08c4041b8c3689550

See more details on using hashes here.

File details

Details for the file impuls-2.5.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for impuls-2.5.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e5e2e72b1162bb3bf47eb0f6414f3045bbe5c75e8f4a96165233ed1e900a9944
MD5 20d3731653393a62fd1a910db53198d8
BLAKE2b-256 b161fcb08374ac91eab8a0398c8f1b45f3a77938d72565c3c28a85288cc6c742

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 Sentry Error logging StatusPage Status page