Step 3: Upload images and markers

MapHub treats images separate from maps. If you'd like to use an image in a map, you'll have to upload it first. Once an image is uploaded, you have to store the returned information about the image, so you can later use it in a map. In this tutorial, we store this information in a JSON file, next to each image.

A note about markers: markers are user-uploaded, custom icons for points. You have to upload them in advance, just like images.

The code for this step is in 2 parts:

1. Loop through each image and marker to upload them

# for each image in the images dir
for file_path in list(IMAGES_DIR.glob('*.jpg')) + list(IMAGES_DIR.glob('*.png')):
    # upload image
    upload_image_marker('image', file_path)

# for each marker in the markers dir
for file_path in MARKERS_DIR.glob('*.png'):
    # upload marker
    upload_image_marker('marker', file_path)

2. The core of the upload function:

def upload_image_marker(kind, file_path):
    # path where we store the info JSON
    info_json = file_path.parent / f'{file_path.stem}.json'

    # if the JSON file exists, the image/marker is already uploaded, skip the upload
    if info_json.is_file():
        print(f'Skipping {kind} {}')

    url = f'{kind}/upload'

    # use the file's extension as file_type
    args = {
        'file_type': file_path.suffix[1:],

    headers = {
        'Authorization': 'Token ' + API_KEY,
        'MapHub-API-Arg': json.dumps(args),

    with open(file_path, 'rb') as f:
        # the upload request
        res =, headers=headers, data=f)
        data = res.json()

    # check that upload was successful, if not print error
    if f'{kind}_id' not in data:

    # save the image_info dict to disk
    with open(info_json, 'w') as f:
        json.dump(data, f, indent=2)

image.json sample

  "image_id": "nnhio1dgalldkf4x",
  "width": 640,
  "height": 360,
  "tip_color": "#bfbbcb",
  "avg_color": "#8a93a9",
  "has_gps": false,
  "geometry": null,
  "date_str": null,
  "date_iso": null

marker.json sample

  "marker_id": "eeumhz32iv0yfcfn"

Full script file