geeViz.eeAuth.client¶
Client-side helpers for routing the Earth Engine Python SDK through a token-injecting proxy.
The pattern:
Run a proxy server (see
geeViz.eeAuth.server) that holds the SA credentials and substitutes the right bearer token per request based on a tenant header / query param.Tell the EE SDK to send all REST calls through that proxy instead of directly to Google. Pass anonymous credentials — the proxy supplies the real ones.
Switch tenants on the client side by setting a
ContextVar; the custom HTTP transport reads it and stamps the routing header on every outbound request.
That gives you full multi-tenant concurrency in a single Python process,
which the bare EE SDK can’t do because ee.Initialize() stores
credentials in module-global state.
Quick start¶
from geeViz.eeAuth import initialize_via_proxy, tenant_context
import ee
initialize_via_proxy("http://localhost:8888/ee-api")
# Now ee.X calls go through the proxy with the default tenant
with tenant_context("training"):
ee.Image(1).getInfo() # uses the training SA
Functions
|
Initialize the Earth Engine SDK to route all REST calls through |
|
Restore the tenant to what it was before the matching |
|
Set the current tenant for subsequent EE calls in this context. |
|
Scoped tenant switch. |
Classes
|
|
- geeViz.eeAuth.client.set_tenant(tenant: str)[source]¶
Set the current tenant for subsequent EE calls in this context.
Returns a token that can be passed to
reset_tenantto restore the previous value. Prefertenant_context()for scoped use.
- geeViz.eeAuth.client.reset_tenant(token) None[source]¶
Restore the tenant to what it was before the matching
set_tenantcall.- Parameters:
token – The token object returned by the paired
set_tenant()call. Passing a token from a different scope raisesValueError.
- geeViz.eeAuth.client.tenant_context(tenant: str)[source]¶
Scoped tenant switch.
with tenant_context("training"): ee.Image(1).getInfo() # back to previous tenant here
- class geeViz.eeAuth.client.TenantAwareHttp(tenant_header: str = 'X-geeViz-Creds')[source]¶
Bases:
objecthttplib2.Httpsubclass that stamps the tenant header on every outbound request and strips whatever Authorization the SDK injected.Subclassed at first instantiation so
httplib2is only imported when actually used — keeps unit tests that mock the EE init path from needing the dependency. The header name is set per-instance so you can run multiple proxies with different conventions in the same process if you really need to.Thread safety¶
httplib2.Httpis NOT thread-safe — its per-host connection cache (self.connections) is a plaindictmutated from insiderequest()andsocket.HTTPConnectionobjects hold per-instance socket state. When the EE SDK shares one transport across aThreadPoolExecutor(asMap.testLayers()does with 8 workers), concurrent threads tear down each other’s sockets mid-request, surfacing as'NoneType' object has no attribute 'close'and WindowsWinError 10038/10057socket errors.Workaround: route each thread’s
request()call to its OWNhttplib2.Httpinstance stored inthreading.local(). EE’s SDK only consults the transport forrequest()— it doesn’t reach intoself.connectionsdirectly — so per-thread instances are a safe drop-in.
- geeViz.eeAuth.client.initialize_via_proxy(proxy_url: str, tenant_header: str = 'X-geeViz-Creds', project: str | None = None) bool[source]¶
Initialize the Earth Engine SDK to route all REST calls through
proxy_url.Uses
AnonymousCredentialssince the proxy holds the real SA credentials. The SDK’s bearer-token header is stripped byTenantAwareHttpbefore reaching the proxy anyway.- Parameters:
proxy_url – Base URL of the EE proxy, e.g.
"http://localhost:8888/ee-api". No trailing slash.tenant_header – Header name the proxy expects for tenant routing. Default
X-geeViz-CredsmatchesgeeViz.eeAuth.server.project – Placeholder project id passed to
ee.Initialize(EE requires one but the proxy overrides per-tenant viax-goog-user-project). Default"ee-proxy-placeholder".
- Returns:
True on success, False if init failed (caller should fall back to direct
ee.Initializeor surface the error). Prints any underlying exception to stderr; doesn’t re-raise.