Skip to main content

Python SDK for MapFlow route optimization API - v2 with hierarchical product support

Project description

MapFlow Python SDK

Official Python SDK for MapFlow — Route Optimization & Delivery Management API

PyPI version Python License: MIT API Docs

MapFlow is a SaaS platform for route optimization, delivery planning, and logistics management. This SDK gives Python developers full programmatic access to the MapFlow API — manage customers, warehouses, drivers, vehicles, delivery schedules, and hierarchical product structures from your own applications.

Website: https://mapflow.co
API Documentation: https://mapflow.readme.io/reference
Get your API key: app.mapflow.co → Settings → API Keys


Table of Contents


Features

  • Full API coverage — customers, locations, warehouses, drivers, vehicles, catalog, visits, and more
  • Hierarchical product structures — pallets containing packages containing products (v2)
  • Pydantic v2 models — type-safe request/response objects with automatic validation
  • Paginated responses — generic PaginatedResponse[T] with automatic deserialization
  • Bulk operations — activate, deactivate, update, tag multiple records in one request
  • Flexible input — pass Pydantic models or plain dicts to any write method
  • Rich error handling — typed exceptions with HTTP status codes and API error details
  • Verbose mode — built-in request/response logging for debugging
  • Python 3.8+ compatible

Requirements

  • Python ≥ 3.8
  • requests >= 2.31.0
  • pydantic >= 2.0.0

Installation

pip install mapflow-co-sdk

Install from source:

git clone https://github.com/mapflow-co/python-sdk.git
cd python-sdk
pip install -e .

Quick Start

from mapflow import MapFlowClient, CustomerType, VisitType, ItemType

# Initialize the client
client = MapFlowClient(api_key="your-api-key")

# Create a customer
customer = client.create_customer({
    "customer_type": CustomerType.COMPANY,
    "company_name": "Acme Corp",
    "email": "contact@acme.com"
})

# Create a delivery location
location = client.create_delivery_location({
    "customer": str(customer.id),
    "name": "Main Office",
    "address": "42 Rue de la Paix",
    "zip_code": "75001",
    "city": "Paris"
})

# Schedule a delivery visit
visit = client.create_visit({
    "delivery_location": str(location.id),
    "visit_type": VisitType.DELIVERY,
    "visit_date": "2026-04-01"
})

print(f"Visit scheduled: {visit.id}")

Authentication

All requests require an API key sent as the X-API-Key header. Get your key from app.mapflow.co → Settings → API Keys.

client = MapFlowClient(
    api_key="your-api-key",          # required
    base_url="https://api.mapflow.co",  # optional — default shown
    timeout=30,                       # optional — seconds
    verbose=False                     # optional — logs requests/responses
)

Core Resources

Customers

Manage individual and business customers including billing details, VAT numbers, and SIRET.

from mapflow import MapFlowClient, CustomerType

client = MapFlowClient(api_key="your-api-key")

# Create
customer = client.create_customer({
    "customer_type": CustomerType.COMPANY,
    "company_name": "Acme Corporation",
    "email": "contact@acme.com",
    "phone": "+33123456789",
    "billing_address": "123 Rue de la Paix",
    "billing_zip_code": "75001",
    "billing_city": "Paris",
    "billing_country": "FR",
    "siret": "12345678901234"
})

# List with filters
customers = client.list_customers(
    is_active=True,
    customer_type="company",
    search="Acme"
)
for c in customers.results:
    print(c.display_name, c.email)

# Read / Update / Delete
customer = client.get_customer(customer.id)
client.patch_customer(customer.id, {"notes": "VIP client"})
client.delete_customer(customer.id)

# Get all delivery locations for a customer
locations = client.get_customer_locations(customer.id)

Delivery Locations

Physical addresses where deliveries or pickups take place, with geolocation and access constraints.

location = client.create_delivery_location({
    "customer": str(customer.id),
    "name": "Main Warehouse",
    "address": "456 Avenue des Champs",
    "zip_code": "75008",
    "city": "Paris",
    "country": "FR",
    "latitude": 48.8566,
    "longitude": 2.3522,
    "truck_access": True,
    "loading_dock": True,
    "max_weight_kg": 5000
})

# Filter
locations = client.list_delivery_locations(city="Paris", truck_access=True)

Global Customers — create a customer, location, contact, and opening hours in a single atomic request:

global_customer = client.create_global_customer({
    "customer_type": "company",
    "company_name": "Tech Solutions SARL",
    "email": "contact@techsolutions.fr",
    "delivery_location": {
        "name": "Head Office",
        "address": "10 Rue de la Tech",
        "zip_code": "69001",
        "city": "Lyon"
    },
    "contact": {
        "first_name": "Marie",
        "last_name": "Martin",
        "position": "Logistics Manager",
        "emails": ["marie@techsolutions.fr"],
        "is_primary": True
    },
    "opening_hours": [
        {"day_of_week": 0, "opening_time": "09:00", "closing_time": "18:00"},
        {"day_of_week": 1, "opening_time": "09:00", "closing_time": "18:00"}
    ]
})

Warehouses

Operational bases for your fleet — supports start/end points, loading docks, certifications, and multi-vehicle assignment.

from mapflow import WarehouseType

warehouse = client.create_warehouse({
    "name": "Paris Nord Hub",
    "code": "PARIS-01",
    "warehouse_type": WarehouseType.HUB,
    "address": "12 Rue Industrielle",
    "zip_code": "93200",
    "city": "Saint-Denis",
    "latitude": 48.9356,
    "longitude": 2.3539,
    "opening_time": "08:00",
    "closing_time": "18:00",
    "is_start_point": True,
    "is_end_point": True,
    "max_vehicles": 50
})

client.set_default_warehouse(warehouse.id)

Drivers & Pickers

Manage drivers and warehouse order pickers with licence types, certifications, and vehicle capabilities.

from mapflow import UserRole, DriverLicenceType, VehicleType

driver = client.create_driver_picker({
    "email": "driver@example.com",
    "first_name": "Jean",
    "last_name": "Dupont",
    "phone": "+33612345678",
    "role": UserRole.DRIVER,
    "password": "SecurePassword123!",
    "confirm_password": "SecurePassword123!",
    "has_valid_driving_license": True,
    "driver_licence_type": [DriverLicenceType.B, DriverLicenceType.C],
    "vehicle_types": [VehicleType.VAN_MEDIUM]
})

# Reset password
info = client.reset_driver_picker_password(driver.id)

Vehicles

Fleet management including capacity, fuel type, maintenance status, and GPS tracking.

from mapflow import VehicleType, EnergyType, VehicleStatus

vehicle = client.create_vehicle({
    "name": "Van 01",
    "license_plate": "AB-123-CD",
    "vehicle_type": VehicleType.VAN_MEDIUM,
    "brand": "Renault",
    "model": "Master",
    "year": 2023,
    "energy_type": EnergyType.DIESEL,
    "max_weight_kg": 1500,
    "max_volume_m3": 12.0,
    "status": VehicleStatus.AVAILABLE
})

Product Catalog

Define products, services, packages, and pallets with weight, volume, pricing, and temperature constraints.

from mapflow import ItemType, WeightUnit, VolumeUnit

product = client.create_delivery_item({
    "name": "Laptop Pro 16",
    "reference": "PROD-001",
    "item_type": ItemType.PRODUCT,
    "weight": 2.1,
    "weight_unit": WeightUnit.KG,
    "length": 36, "width": 25, "height": 2,
    "selling_price": 2499.00,
    "is_fragile": True
})

# Filter catalog
fragile = client.list_delivery_items(
    item_type=ItemType.PRODUCT,
    is_fragile=True,
    weight_max=5.0
)

Container Hierarchy (v2)

Organize products inside packages and pallets with full nesting support, quantity tracking, and computed weight/value totals.

# Create a pallet
pallet = client.create_delivery_item({
    "name": "Export Pallet EU",
    "item_type": ItemType.PALLET,
    "weight": 25, "weight_unit": WeightUnit.KG
})

# Create a package inside the pallet
box = client.create_delivery_item({
    "name": "Laptop Box",
    "item_type": ItemType.PACKAGE,
    "weight": 0.5, "weight_unit": WeightUnit.KG
})

# Put 5 laptops in the box
client.set_container_contents(box.id, [
    {"item": str(product.id), "quantity": 5, "notes": "Fragile"}
])

# Put 3 boxes on the pallet
client.set_container_contents(pallet.id, [
    {"item": str(box.id), "quantity": 3, "position": 1}
])

# Inspect the full hierarchy
hierarchy = client.get_delivery_item_hierarchy(pallet.id)
print(f"Total weight: {hierarchy.total_weight_kg} kg")
print(f"Total value: {hierarchy.total_selling_price} EUR")

# Granular removal
client.remove_content_from_container(pallet.id, box.id, quantity=1)

# List only top-level items (not inside any container)
roots = client.list_root_delivery_items()

Visits & Scheduling

Schedule delivery, pickup, or service stops at delivery locations.

from mapflow import VisitType

visit = client.create_visit({
    "delivery_location": str(location.id),
    "visit_type": VisitType.DELIVERY,
    "visit_date": "2026-04-01",
    "planned_start_time": "09:00",
    "planned_end_time": "10:00",
    "notes": "Ring bell at entrance"
})

# Filter visits
visits = client.list_visits(
    visit_date="2026-04-01",
    visit_type="delivery",
    status="planned"
)

Visit Products

Link catalog items to a scheduled visit with quantities.

# Assign a product to a visit
visit_product = client.create_visit_product({
    "visit": str(visit.id),
    "product": str(product.id),
    "quantity": 3
})

# Bulk quantity updates
client.visit_product_bulk_action(
    action="multiply_quantity",
    visitproduct_ids=[vp1.id, vp2.id],
    quantity_multiplier="2.0"
)

Tags

Color-coded labels for visits, drivers, and customers.

tag = client.create_tag({
    "name": "Urgent",
    "color": "#FF0000",
    "description": "Priority deliveries"
})

# Assign tags to customers in bulk
client.customer_bulk_action(
    action="add_tags",
    customer_ids=[c1.id, c2.id],
    tag_ids=[tag.id]
)

Pagination

All list endpoints return a PaginatedResponse[T] with full IDE autocomplete on results.

page = client.list_customers(page=1, page_size=20)

print(f"Total: {page.count}")
print(f"Pages: {page.total_pages}")

for customer in page.results:   # typed as List[Customer]
    print(customer.display_name)

# Iterate all pages
page_num = 1
while True:
    page = client.list_customers(page=page_num, page_size=50)
    for customer in page.results:
        process(customer)
    if not page.next:
        break
    page_num += 1

Bulk Operations

Most resources support bulk actions to reduce round-trips.

# Activate / deactivate
client.customer_bulk_action("activate", customer_ids=[id1, id2, id3])
client.vehicle_bulk_action("change_status", vehicle_ids=[v1, v2], new_status="maintenance")

# Bulk tagging
client.customer_bulk_action("add_tags", customer_ids=[id1, id2], tag_ids=[tag.id])

# Bulk product updates
client.delivery_item_bulk_action("update_fragile", delivery_item_ids=[p1, p2], is_fragile=True)
client.visit_product_bulk_action("update_quantity", visitproduct_ids=[vp1, vp2], new_quantity=5)

Error Handling

The SDK raises typed exceptions for every HTTP error class.

from mapflow import (
    MapFlowError,
    AuthenticationError,   # 401
    ForbiddenError,        # 403
    NotFoundError,         # 404
    ValidationError,       # 400
    RateLimitError,        # 429
    ServerError            # 5xx
)

try:
    customer = client.get_customer(customer_id)
except AuthenticationError:
    print("Invalid API key — check your credentials at app.mapflow.co → Settings → API Keys")
except NotFoundError:
    print("Customer not found")
except ValidationError as e:
    print(f"Validation error: {e.message}")
    print(f"Details: {e.response}")
except RateLimitError:
    print("Rate limit exceeded — slow down requests")
except ServerError:
    print("MapFlow server error — try again later")
except MapFlowError as e:
    print(f"Error {e.status_code}: {e.message}")

Examples

The examples/ directory contains ready-to-run scripts:

File Description
examples/hierarchy_example.py Pallets, packages, and products with quantities
examples/visit_products_example.py Assigning catalog items to delivery visits

Run any example after setting your API key:

export MAPFLOW_API_KEY="your-api-key"
python examples/hierarchy_example.py

Enums Reference

Enum Values
CustomerType individual, company
ItemType PRODUCT, SERVICE, PACKAGE, PALLET
VisitType delivery, pickup, service, delivery_pickup
VehicleType bicycle, cargo_bike, motorcycle, van_small, van_medium, van_large, truck_small, truck_medium, truck_large, semi_trailer, refrigerated, …
VehicleStatus available, in_use, maintenance, broken, retired
EnergyType gasoline, diesel, electric, hybrid, hydrogen
DriverLicenceType none, am, a1, a, b, c1, c, ce, d
WarehouseType distribution, storage, hub, pickup, cross_dock, other
WeightUnit kg, g, lb, oz, t
VolumeUnit m3, l, ml, cm3, ft3, gal
DayOfWeek MONDAY (0) … SUNDAY (6)

Support


License

MIT © MapFlow

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

mapflow_co_sdk-2.0.0.tar.gz (60.2 kB view details)

Uploaded Source

Built Distribution

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

mapflow_co_sdk-2.0.0-py3-none-any.whl (63.3 kB view details)

Uploaded Python 3

File details

Details for the file mapflow_co_sdk-2.0.0.tar.gz.

File metadata

  • Download URL: mapflow_co_sdk-2.0.0.tar.gz
  • Upload date:
  • Size: 60.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.1

File hashes

Hashes for mapflow_co_sdk-2.0.0.tar.gz
Algorithm Hash digest
SHA256 ae1f93cf1884fd88400effe080798074675a6baf29af5ed2bf719bd06cfd2b5a
MD5 2d26b34ac52bf4ca42836aa3bc4a49fe
BLAKE2b-256 5a7d3f07c4ca74526a18de5353c4addec532438ecc8d5eafebffccffb6c45d47

See more details on using hashes here.

File details

Details for the file mapflow_co_sdk-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: mapflow_co_sdk-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 63.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.1

File hashes

Hashes for mapflow_co_sdk-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e69d1d107db97bf4f715beb521c21251441196be64fbae8ee04ccd5ccf75b140
MD5 05841c0c8466cf3b8967e7b6912bd5e5
BLAKE2b-256 ae0184158ef407d4a3d1d2e1c6e226f4478a6f31a3a2ff3e4ccc0b7ca9043568

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