Official Python SDK for the GeoInfer API
Project description
GeoInfer Python SDK
The official Python client library for the GeoInfer API — AI-powered image geolocation without GPS, EXIF, or metadata.
What is GeoInfer?
GeoInfer determines where a photo was taken by analysing its visual content alone — no GPS signal, no EXIF data, no metadata required. Results are delivered in under a second, with global coverage including remote regions, conflict zones, and GPS-denied environments.
The API exposes two model families:
| Model type | Output | Accuracy |
|---|---|---|
| Global | Geographic clusters with coordinates and radius | 1 km – 100 km, worldwide |
| Accuracy (regional) | Ranked coordinate predictions with confidence scores | Metre-level, within a specific region |
Note: Accuracy models are region-specific and generally whitelisted — they are not available to the general public. Contact geoinfer.com to enquire about access.
Requirements
- Python 3.9 or later
- A GeoInfer API key — get one at geoinfer.com
Installation
pip install geoinfer
Quick start
from geoinfer import GeoInfer
client = GeoInfer(api_key="geo_...")
# List models your API key has access to
for m in client.predictions.models():
print(m.model_id, m.model_type, f"{m.credits_per_use} credit(s)")
# Global model — returns geographic clusters
result = client.predictions.predict("photo.jpg", model_id="global_v0_1")
top = result.prediction.clusters[0]
print(top.location.name, top.center.latitude, top.center.longitude)
# Accuracy / regional model — returns ranked predictions
result = client.predictions.predict("photo.jpg", model_id="pais_vasco_v0_1")
top = result.prediction.top_prediction
if top:
print(top.latitude, top.longitude, f"{top.confidence:.1%} confidence")
Authentication
Pass your API key at client construction. It is sent as the X-GeoInfer-Key header on every request.
client = GeoInfer(api_key="geo_...")
API keys can be managed from your dashboard at geoinfer.com.
Model access
Available models are determined by your API key — some models are public and some are whitelisted per account. models() returns only the models your key has access to:
models = client.predictions.models()
for m in models:
print(m.model_id, m.model_type, m.credits_per_use)
The model list is fetched on first use and cached for 5 minutes. Passing a model_id that is unknown to your account or disabled raises InvalidModelError immediately — before any prediction request is made.
Async support
AsyncGeoInfer mirrors the synchronous client and is safe to use in any asyncio application:
import asyncio
from geoinfer import AsyncGeoInfer
async def main():
async with AsyncGeoInfer(api_key="geo_...") as client:
result = await client.predictions.predict("photo.jpg", model_id="global_v0_1")
top = result.prediction.clusters[0]
print(top.location.name, top.center.latitude, top.center.longitude)
asyncio.run(main())
File input
predict() accepts five input forms:
from pathlib import Path
# URL — the SDK fetches the image and uploads it automatically
client.predictions.predict("https://example.com/photo.jpg", model_id="global_v0_1")
# Path string
client.predictions.predict("photo.jpg", model_id="global_v0_1")
# pathlib.Path
client.predictions.predict(Path("photo.jpg"), model_id="global_v0_1")
# Raw bytes (already loaded into memory)
with open("photo.jpg", "rb") as f:
client.predictions.predict(f.read(), model_id="global_v0_1")
# Binary file-like object (streamed)
with open("photo.jpg", "rb") as f:
client.predictions.predict(f, model_id="global_v0_1")
URL inputs are fetched client-side and uploaded as bytes — the image is not stored or cached. Any
http://orhttps://string is treated as a URL. File objects must be opened in binary mode ("rb"); passing a text-mode object raisesTypeError.
Maximum file size: 10 MB.
Credits
Each prediction consumes credits according to the model used. Check your balance at any time:
summary = client.credits.summary()
print(summary.summary.total_available) # total credits available now
print(summary.subscription.remaining) # subscription allowance remaining
print(summary.summary.topup_credits) # one-time top-up balance
Credits consumed are reported on every PredictionResponse:
result = client.predictions.predict("photo.jpg", model_id="global_v0_1")
print(f"Used {result.credits_consumed} credit(s). ID: {result.prediction_id}")
Rate limits
Rate-limit metadata is attached to every PredictionResponse:
result = client.predictions.predict("photo.jpg", model_id="global_v0_1")
rl = result.rate_limit
print(f"{rl.remaining} requests remaining, window resets in {rl.reset}s")
When the limit is exceeded RateLimitError is raised with a retry_after attribute:
import time
from geoinfer import RateLimitError
try:
result = client.predictions.predict("photo.jpg", model_id="global_v0_1")
except RateLimitError as e:
if e.retry_after:
time.sleep(e.retry_after)
Error handling
All SDK exceptions inherit from GeoInferError.
| Exception | HTTP status | When raised |
|---|---|---|
AuthenticationError |
401 | Missing or invalid API key |
InsufficientCreditsError |
402 | Account has insufficient credits |
ForbiddenError |
403 | Access denied to this resource |
FileTooLargeError |
413 | Image exceeds the 10 MB limit |
InvalidFileTypeError |
422 | File format is not supported |
RateLimitError |
429 | Request rate limit exceeded |
InvalidModelError |
— | model_id is not in your account's model list or is disabled |
APIError |
other | Unexpected non-2xx response |
from geoinfer import (
GeoInferError,
AuthenticationError,
InsufficientCreditsError,
InvalidModelError,
RateLimitError,
)
try:
result = client.predictions.predict("photo.jpg", model_id="global_v0_1")
except InvalidModelError as e:
print(e.message) # includes a list of your available model IDs
except RateLimitError as e:
if e.retry_after:
time.sleep(e.retry_after)
except InsufficientCreditsError:
print("Top up credits at geoinfer.com")
except AuthenticationError:
print("Check your API key at geoinfer.com")
except GeoInferError as e:
print(e.message_code, e.message)
Context managers
Both clients support context managers for deterministic connection cleanup:
# Sync
with GeoInfer(api_key="geo_...") as client:
result = client.predictions.predict("photo.jpg", model_id="global_v0_1")
# Async
async with AsyncGeoInfer(api_key="geo_...") as client:
result = await client.predictions.predict("photo.jpg", model_id="global_v0_1")
Configuration
| Parameter | Default | Description |
|---|---|---|
api_key |
(required) | Your GeoInfer API key |
base_url |
https://api.geoinfer.com |
Override the API base URL |
timeout |
60 |
HTTP request timeout in seconds |
model_cache_ttl |
300 |
Seconds to cache the model list before re-fetching |
Type safety
All response objects are immutable frozen dataclasses. Narrow on result.prediction.result_type to get the specific prediction type:
from geoinfer.types import CoordinatePredictionResult, AccuracyPredictionResult
result = client.predictions.predict("photo.jpg", model_id="global_v0_1")
if isinstance(result.prediction, CoordinatePredictionResult):
print(result.prediction.clusters[0].location.name)
elif isinstance(result.prediction, AccuracyPredictionResult):
print(result.prediction.top_prediction.confidence)
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file geoinfer-0.0.1.tar.gz.
File metadata
- Download URL: geoinfer-0.0.1.tar.gz
- Upload date:
- Size: 62.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e354414243ebbec5adc07a8302b18d8cd48d32f11197cdf471a6bb8ae49ba08
|
|
| MD5 |
40089f2cfccfeb6320adbcb8d8083113
|
|
| BLAKE2b-256 |
3e78face23860eecff2c26e73ba7426826d8b559a7aef5e93370a77188f2681e
|
Provenance
The following attestation bundles were made for geoinfer-0.0.1.tar.gz:
Publisher:
publish.yml on GeoInfer/geoinfer-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
geoinfer-0.0.1.tar.gz -
Subject digest:
9e354414243ebbec5adc07a8302b18d8cd48d32f11197cdf471a6bb8ae49ba08 - Sigstore transparency entry: 989830834
- Sigstore integration time:
-
Permalink:
GeoInfer/geoinfer-sdk@1808e62e7c011a89667f11793982d96633cfd349 -
Branch / Tag:
refs/tags/0.0.1 - Owner: https://github.com/GeoInfer
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1808e62e7c011a89667f11793982d96633cfd349 -
Trigger Event:
release
-
Statement type: