Skip to content

Geemap should be able to disregard GOOGLE_MAPS_API_KEY in environment #2701

@havardgulldahl

Description

@havardgulldahl

Thank you for a helpful library!

Environment Information

OS Linux (Ubuntu 24.04) CPU(s) 16 Machine x86_64
Architecture 64bit RAM 23.5 GiB Environment Jupyter
File system ext4
Python 3.12.3 (main, Jan 22 2026, 20:57:42) [GCC 13.3.0]
geemap 0.37.1 ee 1.7.16 ipyleaflet 0.20.0
folium 0.20.0 jupyterlab Module not found notebook Module not found
ipyevents 2.0.2 geopandas 1.1.1 localtileserver 0.10.6

Description

As far as I can tell, this bug is only triggered in a Jupyter notebook, which I edit and run in VSCode.

I run this from within EU, where there are restrictions on parts of the Google Maps API.

In my project directory, I have an .env file with different api keys, also GOOGLE_MAPS_API_KEY. VSCode helpfully expands these into the environment for Jupyter files, and geemap helpfully picks this up when the .Map() instance is created.

Thus, Google returns a 403 error, and geemaps.Map() fails, even when I explicitly try to use other data.

A workaround is to remove GOOGLE_MAPS_API_KEY from os.environ before geemap.Map() is invoked. See the attached html: test_geemap_gmaps.html

The culprit is coreutils.get_google_maps_api_key() being run from _get_available_basemaps() (see full error below).

I would love to see an explicit option, maybe

geemap.Map(use_google_tiles=False)

or at least a warning about GOOGLE_MAPS_API_KEY being set, if the geemap.Map() fails with 403.

(A warning would be helpful for developers, but not so much for the end-user of a distributed script.)

Let me know if I should follow up with a proposed patch. Thanks!

What I Did

import ee

import sys
import os
import platform

print(f"Python version: {sys.version}")

print(f"Platform: {platform.platform()}")
print(f"Geemap version: {geemap.__version__}")


for key, value in os.environ.items():
    if "GOOGLE" in key or "EE" in key:
        print(f"{key}: {'*' * len(value)}")

# Authenticate Earth Engine
ee.Authenticate()

# load project id from environment variable
PROJECT_ID = os.getenv("GEE_PROJECT_ID")

# Initialize the Earth Engine module.
ee.Initialize(project=PROJECT_ID)

# Create map instance
Map = geemap.Map(basemap="Esri.WorldImagery")

Output:

Python version: 3.12.3 (main, Jan 22 2026, 20:57:42) [GCC 13.3.0]
Platform: Linux-6.6.87.2-microsoft-standard-WSL2-x86_64-with-glibc2.39
Geemap version: 0.37.1
GOOGLE_MAPS_API_KEY: ***************************************
GEE_PROJECT_ID: ************
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[1], [line 28](vscode-notebook-cell:?execution_count=1&line=28)
     25 ee.Initialize(project=PROJECT_ID)
     27 # Create map instance
---> [28](vscode-notebook-cell:?execution_count=1&line=28) Map = geemap.Map(basemap="Esri.WorldImagery")

File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/geemap.py:141, in Map.__init__(self, **kwargs)
    139 self._USER_AGENT_PREFIX = "geemap"
    140 self.kwargs = kwargs
--> [141](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/geemap.py:141) super().__init__(**kwargs)
    142 self._var_name = "Map"  # The Map variable name for converting JS to Python
    144 if kwargs.get("height"):

File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/core.py:634, in Map.__init__(self, **kwargs)
    628 def __init__(self, **kwargs: Any) -> None:
    629     """Initialize the map with given keyword arguments.
    630 
    631     Args:
    632         **kwargs: Additional keyword arguments for the map.
    633     """
--> [634](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/core.py:634)     self._available_basemaps = self._get_available_basemaps()
    636     # Use the first basemap in the list of available basemaps.
    637     if "basemap" not in kwargs:

File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/core.py:1356, in Map._get_available_basemaps(self)
   1353 tile_providers = list(basemaps.get_xyz_dict().values())
   1354 if coreutils.get_google_maps_api_key():
   1355     tile_providers = tile_providers + list(
-> [1356](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/core.py:1356)         basemaps.get_google_map_tile_providers().values()
   1357     )
   1359 ret_dict = {}
   1360 for tile_info in tile_providers:

File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/basemaps.py:376, in get_google_map_tile_providers(language, region, api_key, **kwargs)
    373 gmap_providers = {}
    375 for m_type in GoogleMapsTileProvider.MAP_TYPE_CONFIG:
--> [376](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/basemaps.py:376)     gmap_providers[m_type] = GoogleMapsTileProvider(
    377         map_type=m_type, language=language, region=region, api_key=api_key, **kwargs
    378     )
    380 return gmap_providers

File ~/dev/m/.venv/lib/python3.12/site-packages/geemap/basemaps.py:343, in GoogleMapsTileProvider.__init__(self, map_type, language, region, api_key, **kwargs)
    332     super().__init__(
    333         {
    334             "url": f"https://tile.googleapis.com/v1/2dtiles/{{z}}/{{x}}/{{y}}?session={json['session']}&key={{accessToken}}",
   (...)    340         }
    341     )
    342 else:
--> [343](https://vscode-remote+wsl-002bubuntu-002d24-002e04.vscode-resource.vscode-cdn.net/home/n/dev/m/~/dev/m/.venv/lib/python3.12/site-packages/geemap/basemaps.py:343)     raise RuntimeError(
    344         f"Error creating a Maps API session:\n{response.json()}."
    345     )

RuntimeError: Error creating a Maps API session:
{'error': {'code': 403, 'message': 'Your request cannot be served because satellite tiles and 3D tiles are not available for your account and region. Learn more here: https://developers.google.com/maps/comms/eea/map-tiles.', 'errors': [{'message': 'Your request cannot be served because satellite tiles and 3D tiles are not available for your account and region. Learn more here: https://developers.google.com/maps/comms/eea/map-tiles.', 'domain': 'global', 'reason': 'forbidden'}], 'status': 'PERMISSION_DENIED'}}.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions