API Reference: Client¶
mobility_db_api.api.MobilityAPI(data_dir='data', refresh_token=None, log_level='INFO', logger_name='mobility_db_api', force_csv_mode=False)
¶
A client for interacting with the Mobility Database API.
This class provides methods to search for GTFS providers, download datasets, and manage downloaded data. It handles authentication, caching, and metadata tracking automatically.
The client can operate in two modes: 1. API mode (default): Uses the Mobility Database API with authentication 2. CSV mode: Uses the CSV catalog when no API key is provided or when force_csv_mode is True
Attributes:
Name | Type | Description |
---|---|---|
data_dir |
Path
|
Directory where downloaded datasets are stored |
refresh_token |
str
|
Token used for API authentication |
datasets |
Dict
|
Dictionary of downloaded dataset metadata |
force_csv_mode |
bool
|
If True, always use CSV catalog even if API key is available |
Example
api = MobilityAPI(data_dir="data") # Will try API first, fallback to CSV api_csv = MobilityAPI(force_csv_mode=True) # Will always use CSV providers = api.get_providers_by_country("HU") dataset_path = api.download_latest_dataset("tld-5862")
Initialize the API client.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data_dir
|
str
|
Base directory for all GTFS downloads |
'data'
|
refresh_token
|
Optional[str]
|
Optional refresh token. If not provided, will try to load from .env file |
None
|
log_level
|
str
|
Logging level (DEBUG, INFO, WARNING, ERROR). Defaults to INFO. |
'INFO'
|
logger_name
|
str
|
Name for the logger instance. Defaults to 'mobility_db_api'. |
'mobility_db_api'
|
force_csv_mode
|
bool
|
If True, always use CSV catalog even if API key is available. |
False
|
Source code in src/mobility_db_api/api.py
Attributes¶
base_url = 'https://api.mobilitydatabase.org/v1'
instance-attribute
¶
csv_catalog
property
¶
Lazy initialization of CSV catalog.
data_dir = Path(data_dir)
instance-attribute
¶
force_csv_mode = force_csv_mode
instance-attribute
¶
logger = setup_logger(name=f'{logger_name}_{data_dir}', level=log_level)
instance-attribute
¶
metadata_file = self.data_dir / 'datasets_metadata.json'
instance-attribute
¶
refresh_token = refresh_token
instance-attribute
¶
Functions¶
delete_all_datasets()
¶
Delete all downloaded datasets. The main data directory is preserved, only dataset directories are removed.
Returns:
Type | Description |
---|---|
bool
|
True if all datasets were deleted successfully, False if any deletion failed |
Source code in src/mobility_db_api/api.py
delete_dataset(provider_id, dataset_id=None)
¶
Delete a downloaded dataset.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
provider_id
|
str
|
The ID of the provider |
required |
dataset_id
|
Optional[str]
|
Optional specific dataset ID. If not provided, deletes the latest dataset |
None
|
Returns:
Type | Description |
---|---|
bool
|
True if the dataset was deleted, False if it wasn't found or couldn't be deleted |
Source code in src/mobility_db_api/api.py
delete_provider_datasets(provider_id)
¶
Delete all downloaded datasets for a specific provider.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
provider_id
|
str
|
The ID of the provider whose datasets should be deleted |
required |
Returns:
Type | Description |
---|---|
bool
|
True if all datasets were deleted successfully, False if any deletion failed |
Source code in src/mobility_db_api/api.py
download_latest_dataset(provider_id, download_dir=None, use_direct_source=False, force_bounding_box_calculation=False)
¶
Download the latest dataset for a provider.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
provider_id
|
str
|
The ID of the provider to download the dataset for. |
required |
download_dir
|
Optional[str]
|
Optional directory to download the dataset to. |
None
|
use_direct_source
|
bool
|
Whether to use direct download URL instead of hosted dataset. |
False
|
force_bounding_box_calculation
|
bool
|
Whether to force recalculation of the bounding box from stops.txt. |
False
|
Returns:
Type | Description |
---|---|
Optional[Path]
|
The path to the extracted dataset directory, or None if the download failed. |
Source code in src/mobility_db_api/api.py
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 |
|
ensure_metadata_current()
¶
Ensure the in-memory metadata is current with the file. This is a convenience method that should be called before any operation that reads from the metadata.
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
True if metadata was reloaded, False if no reload was needed |
Source code in src/mobility_db_api/api.py
get_access_token()
¶
Get a valid access token for API authentication.
This method handles token refresh automatically when needed. It uses the refresh token to obtain a new access token from the API.
Returns:
Type | Description |
---|---|
Optional[str]
|
A valid access token string if successful, None if token refresh fails |
Optional[str]
|
or if no refresh token is available. |
Example
api = MobilityAPI() token = api.get_access_token() if token: ... print(token) ... 'eyJ0eXAiOiJKV1QiLCJhbGc...' ... else: ... print("Using CSV fallback mode")
Source code in src/mobility_db_api/api.py
get_provider_by_id(provider_id)
¶
Get information about a specific provider by ID.
This method is similar to get_provider_info but follows the naming convention of get_providers_by_country and get_providers_by_name. It returns information about a single provider, including any downloaded dataset.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
provider_id
|
str
|
The unique identifier of the provider |
required |
Returns:
Type | Description |
---|---|
Optional[Dict]
|
Dictionary containing provider information and downloaded dataset details |
Optional[Dict]
|
if available, None if the provider doesn't exist or is inactive/deprecated. |
Example
api = MobilityAPI() info = api.get_provider_by_id("mdb-123") if info: ... print(f"Provider: {info['provider']}") ... if 'downloaded_dataset' in info: ... print(f"Downloaded: {info['downloaded_dataset']['download_path']}")
Source code in src/mobility_db_api/api.py
get_provider_info(provider_id=None, country_code=None, name=None)
¶
Get information about providers based on search criteria.
This method is the central provider search functionality that powers get_provider_by_id, get_providers_by_country, and get_providers_by_name. It can search by ID, country code, or name, and returns either a single provider or a list of providers.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
provider_id
|
Optional[str]
|
Optional provider ID for exact match |
None
|
country_code
|
Optional[str]
|
Optional two-letter ISO country code for filtering |
None
|
name
|
Optional[str]
|
Optional provider name for partial matching |
None
|
Returns:
Type | Description |
---|---|
Union[Optional[Dict], List[Dict]]
|
If provider_id is specified: Dictionary containing provider information and downloaded dataset details if available, None if the provider doesn't exist or is inactive/deprecated. |
Union[Optional[Dict], List[Dict]]
|
If country_code or name is specified: List of matching provider dictionaries. |
Union[Optional[Dict], List[Dict]]
|
If no criteria specified: Empty list. |
Example
api = MobilityAPI()
Get by ID¶
info = api.get_provider_info(provider_id="mdb-123")
Get by country¶
be_providers = api.get_provider_info(country_code="BE")
Get by name¶
sncb = api.get_provider_info(name="SNCB")
Source code in src/mobility_db_api/api.py
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 |
|
get_providers_by_country(country_code)
¶
Search for GTFS providers by country code.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
country_code
|
str
|
Two-letter ISO country code (e.g., "HU" for Hungary) |
required |
Returns:
Type | Description |
---|---|
List[Dict]
|
List of provider dictionaries containing provider information. |
List[Dict]
|
Each dictionary includes: - id: Provider's unique identifier - provider: Provider's name - country: Provider's country - source_info: Information about data sources |
Example
api = MobilityAPI() providers = api.get_providers_by_country("HU") for p in providers: ... print(f"{p['provider']}: {p['id']}") 'BKK: o-u-dr_bkk'
Source code in src/mobility_db_api/api.py
get_providers_by_name(name)
¶
Search for providers by name.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name
|
str
|
Provider name to search for (case-insensitive partial match) |
required |
Returns:
Type | Description |
---|---|
List[Dict]
|
List of matching provider dictionaries. |
Source code in src/mobility_db_api/api.py
list_downloaded_datasets()
¶
Get a list of all downloaded datasets in the data directory.
Returns:
Type | Description |
---|---|
List[DatasetMetadata]
|
List of DatasetMetadata objects for all downloaded datasets |
Source code in src/mobility_db_api/api.py
reload_metadata(force=False)
¶
Reload metadata from file if it has been modified or if forced.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
force
|
bool
|
If True, reload metadata regardless of modification time. If False, only reload if the file has been modified. |
False
|
Returns:
Name | Type | Description |
---|---|---|
bool |
True if metadata was reloaded, False if no reload was needed |
Source code in src/mobility_db_api/api.py
Common Exceptions¶
The client can raise the following exceptions:
ValueError¶
Raised in cases like: - Missing or invalid refresh token - Failed token refresh - Invalid provider ID
requests.exceptions.RequestException¶
Raised for network-related issues: - Connection errors - API errors - Timeout issues
OSError¶
Raised for file system issues: - Permission errors - Disk space issues - File access problems
Environment Variables¶
The following environment variables can be used to configure the client:
MOBILITY_API_REFRESH_TOKEN
: The API refresh token for authenticationMOBILITY_API_BASE_URL
: The base URL of the Mobility Database APIMOBILITY_API_DATA_DIR
: The default directory for storing downloaded datasets
Type Hints¶
from typing import Dict, List, Optional, Union
from pathlib import Path
from datetime import datetime
from dataclasses import dataclass
@dataclass
class DatasetMetadata:
provider_id: str
provider_name: str
dataset_id: str
download_date: datetime
source_url: str
is_direct_source: bool
api_provided_hash: Optional[str]
file_hash: str
download_path: Path
feed_start_date: Optional[str] = None
feed_end_date: Optional[str] = None
# Function signatures
def get_providers_by_country(country_code: str) -> List[Dict]: ...
def get_providers_by_name(name: str) -> List[Dict]: ...
def get_provider_by_id(provider_id: str) -> Optional[Dict]: ...
def get_provider_info(
provider_id: Optional[str] = None,
country_code: Optional[str] = None,
name: Optional[str] = None
) -> Union[Optional[Dict], List[Dict]]: ...
def download_latest_dataset(
provider_id: str,
download_dir: Optional[str] = None,
use_direct_source: bool = False
) -> Optional[Path]: ...
def list_downloaded_datasets() -> List[DatasetMetadata]: ...
def delete_dataset(provider_id: str, dataset_id: Optional[str] = None) -> bool: ...
def delete_provider_datasets(provider_id: str) -> bool: ...
def delete_all_datasets() -> bool: ...
Usage Examples¶
Basic Usage¶
from mobility_db_api import MobilityAPI
# Initialize client
api = MobilityAPI()
# Search for providers
providers = api.get_providers_by_country("BE")
for provider in providers:
print(f"Found provider: {provider['provider']}")
# Download dataset
dataset_path = api.download_latest_dataset(providers[0]['id'])
print(f"Dataset downloaded to: {dataset_path}")
Dataset Management¶
from mobility_db_api import MobilityAPI
api = MobilityAPI()
# List downloaded datasets
datasets = api.list_downloaded_datasets()
for dataset in datasets:
print(f"Dataset: {dataset.dataset_id}")
print(f"Provider: {dataset.provider_name}")
print(f"Downloaded: {dataset.download_date}")
# Delete specific dataset
api.delete_dataset("tld-5862", "20240315")
# Delete all datasets for a provider
api.delete_provider_datasets("tld-5862")
# Delete all datasets
api.delete_all_datasets()
Error Handling¶
from mobility_db_api import MobilityAPI
import requests
api = MobilityAPI()
try:
dataset_path = api.download_latest_dataset("invalid-id")
except ValueError as e:
print(f"Invalid input: {e}")
except requests.exceptions.RequestException as e:
print(f"Network error: {e}")
except OSError as e:
print(f"File system error: {e}")
Implementation Details¶
Authentication Flow¶
- Initialize client with refresh token
- Client automatically handles token refresh
- Access token is used for API requests
- Refresh token is used to obtain new access tokens
Download Process¶
- Get provider information
- Choose download source (hosted or direct)
- Download dataset to specified directory
- Update metadata with download information
- Return path to downloaded dataset
Metadata Management¶
- Each download directory has its own metadata file
- Metadata is locked during updates
- Changes are detected using checksums
- Failed downloads are cleaned up
Client API Reference¶
MobilityAPI¶
The main client class for interacting with the Mobility Database API.
Constructor¶
MobilityAPI(data_dir: str = "data",
refresh_token: Optional[str] = None,
log_level: str = "INFO",
logger_name: str = "mobility_db_api",
force_csv_mode: bool = False)
Parameters:
- data_dir
: Base directory for all GTFS downloads (default: "data")
- refresh_token
: Optional refresh token. If not provided, will try to load from .env file
- log_level
: Logging level (DEBUG, INFO, WARNING, ERROR). Defaults to INFO
- logger_name
: Name for the logger instance. Defaults to 'mobility_db_api'
- force_csv_mode
: If True, always use CSV catalog even if API key is available
The client can operate in two modes: 1. API mode (default): Uses the Mobility Database API with authentication 2. CSV mode: Uses the CSV catalog when no API key is provided or when force_csv_mode is True
Operating Modes¶
API Mode¶
When a valid refresh token is available (either passed directly or through environment variables), the client operates in API mode. This mode provides: - Full access to all API features - Real-time dataset information - Provider search capabilities - Dataset downloads with hash verification
CSV Mode¶
The client automatically falls back to CSV mode when:
- No API key is available
- Authentication fails
- API requests return errors (e.g., 413 Request Entity Too Large)
- force_csv_mode=True
is set
CSV mode provides: - Basic provider information from a local CSV catalog - Dataset download URLs - Provider search by country and name - ID normalization for consistent provider lookup
ID Normalization¶
The CSV catalog supports the following ID formats: - Direct numeric IDs (e.g., "123") - MDB-prefixed IDs (e.g., "mdb-123") - Other prefixed IDs are not resolvable (e.g., "tld-123")
Methods¶
get_providers_by_country¶
Search for GTFS providers by country code.Parameters:
- country_code
: Two-letter ISO country code (e.g., "HU" for Hungary)
Returns: - List of provider dictionaries containing provider information
Example:
api = MobilityAPI()
providers = api.get_providers_by_country("HU")
for p in providers:
print(f"{p['provider']}: {p['id']}")
get_providers_by_name¶
Search for providers by name.Parameters:
- name
: Provider name to search for (case-insensitive partial match)
Returns: - List of matching provider dictionaries
Example:
get_provider_by_id¶
Get information about a specific provider by ID.Parameters:
- provider_id
: The unique identifier of the provider
Returns: - Dictionary containing provider information and downloaded dataset details if available - None if the provider doesn't exist or is inactive/deprecated
Example:
api = MobilityAPI()
info = api.get_provider_by_id("mdb-123")
if info:
print(f"Provider: {info['provider']}")
if 'downloaded_dataset' in info:
print(f"Downloaded: {info['downloaded_dataset']['download_path']}")
get_provider_info¶
get_provider_info(
provider_id: Optional[str] = None,
country_code: Optional[str] = None,
name: Optional[str] = None
) -> Union[Optional[Dict], List[Dict]]
get_provider_by_id
, get_providers_by_country
, and get_providers_by_name
into a single method.
Parameters:
- provider_id
: Optional provider ID for exact match
- country_code
: Optional two-letter ISO country code for filtering
- name
: Optional provider name for partial matching
Returns:
- If provider_id
is specified:
- Dictionary containing provider information and downloaded dataset details if available
- None if the provider doesn't exist or is inactive/deprecated
- If country_code
or name
is specified:
- List of matching provider dictionaries
- If no criteria specified:
- Empty list
Example:
api = MobilityAPI()
# Get by ID
info = api.get_provider_info(provider_id="mdb-123")
# Get by country
be_providers = api.get_provider_info(country_code="BE")
# Get by name
sncb = api.get_provider_info(name="SNCB")
download_latest_dataset¶
download_latest_dataset(provider_id: str,
download_dir: Optional[str] = None,
use_direct_source: bool = False) -> Optional[Path]
Parameters:
- provider_id
: The unique identifier of the provider
- download_dir
: Optional custom directory to store the dataset
- use_direct_source
: Whether to use direct download URL instead of hosted dataset
Returns: - Path to the extracted dataset directory if successful, None if download fails
Example:
Error Handling¶
The client includes robust error handling: - Graceful fallback to CSV mode on API errors - Automatic retry with CSV catalog on authentication failures - Clear error messages and logging - Safe handling of network issues and invalid responses
Best Practices¶
- Mode Selection:
- Use API mode when real-time data is critical
- Use CSV mode for basic provider information or when API access is not available
-
Consider
force_csv_mode=True
for better performance when only basic features are needed -
Error Handling:
- Always check return values for None/empty lists
- Use try/except blocks for network operations
-
Monitor logs for important messages
-
Resource Management:
- Use custom data directories for better organization
- Clean up downloaded datasets when no longer needed
- Monitor disk space usage
Example:
# API mode with fallback
api = MobilityAPI()
providers = api.get_providers_by_country("HU")
# Force CSV mode for better performance
api_csv = MobilityAPI(force_csv_mode=True)
providers = api_csv.get_providers_by_country("HU")
# Custom data directory
api = MobilityAPI(data_dir="custom/path")
dataset = api.download_latest_dataset("mdb-123")
Features¶
- Search for GTFS providers by country code or name
- Download and extract GTFS datasets
- Track dataset metadata including:
- Feed validity dates from feed_info.txt
- Geographical bounding box from stops.txt
- Dataset hashes for version control
- Automatic fallback to CSV catalog when API is unavailable
- Support for direct source downloads
Metadata¶
The client tracks various metadata for each downloaded dataset:
provider_id
: Unique identifier of the providerprovider_name
: Human-readable name of the providerdataset_id
: Unique identifier of the datasetdownload_date
: When the dataset was downloadedsource_url
: URL or path where the dataset was downloaded fromis_direct_source
: Whether the dataset was downloaded directly from the providerapi_provided_hash
: Hash provided by the Mobility Database API (if available)file_hash
: SHA-256 hash of the downloaded filedownload_path
: Path where the dataset is storedfeed_start_date
: Start date from feed_info.txt (YYYYMMDD format)feed_end_date
: End date from feed_info.txt (YYYYMMDD format)minimum_latitude
: Southern boundary of the dataset's coverage areamaximum_latitude
: Northern boundary of the dataset's coverage areaminimum_longitude
: Western boundary of the dataset's coverage areamaximum_longitude
: Eastern boundary of the dataset's coverage area
Bounding Box Calculation¶
The client automatically calculates geographical bounding boxes for datasets:
- For datasets from the Mobility Database API, it uses the bounding box provided by the API
- For datasets from the CSV catalog, it uses the bounding box information from the catalog
- For direct source downloads and external GTFS files, it calculates the bounding box from stops.txt
- The calculation handles missing or invalid coordinates gracefully
- Coordinates are validated to be within valid ranges (-90/90 for latitude, -180/180 for longitude)
Example Usage¶
from mobility_db_api import MobilityAPI
# Initialize the client
api = MobilityAPI()
# Download a dataset
dataset_path = api.download_latest_dataset("mdb-123")
# Get dataset metadata including bounding box
datasets = api.list_downloaded_datasets()
for dataset in datasets:
print(f"Dataset: {dataset.provider_name}")
if dataset.minimum_latitude is not None:
print(f"Coverage area: ({dataset.minimum_latitude}, {dataset.minimum_longitude}) to "
f"({dataset.maximum_latitude}, {dataset.maximum_longitude})")
ExternalGTFSAPI¶
Extension of MobilityAPI for handling external GTFS files not in the Mobility Database.
Features¶
- Extract and process external GTFS ZIP files
- Generate unique provider IDs for external sources
- Extract agency names from GTFS files
- Handle versioning of datasets
- Match files to existing providers
- Calculate bounding boxes from stops.txt
Example Usage¶
from mobility_db_api import ExternalGTFSAPI
from pathlib import Path
# Initialize the client
api = ExternalGTFSAPI()
# Extract a GTFS file
dataset_path = api.extract_gtfs(Path("gtfs.zip"))
# Get dataset metadata including bounding box
datasets = api.list_downloaded_datasets()
for dataset in datasets:
print(f"Dataset: {dataset.provider_name}")
if dataset.minimum_latitude is not None:
print(f"Coverage area: ({dataset.minimum_latitude}, {dataset.minimum_longitude}) to "
f"({dataset.maximum_latitude}, {dataset.maximum_longitude})")