Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Add Geo Lookup Support

Open
#48 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Stale
Tech stack
python
Domain
api, backend

Research direction

Start with the WIT binding at stubs/wit_world/imports/geo.py and compare the requested Python API with the Rust, Go, and JS references in the issue. Use Viceroy's test.toml geolocation configuration and @on_viceroy tests to exercise loopback and configured addresses. Done means the lookup API, typed response representation, failure behavior, and Viceroy coverage match the stated design.

Written by the indexing model from the issue text.

Description

Overview

Add support for Fastly's geographic and network intelligence API, which provides location and network information based on IP addresses.

WIT Interface

interface geo {
  use types.{error, ip-address};

  /// Returns JSON-encoded geographic data for an IP address
  lookup: func(ip-addr: ip-address, max-len: u64) -> result<string, error>;
}

WIT bindings: stubs/wit_world/imports/geo.py

API Design

  • Parse JSON response from WIT layer into a Geo dataclass with typed fields (city, country, coordinates, AS number, etc.)
  • Provide lookup(ip) function accepting str, IPv4Address, or IPv6Address
  • Return None for failed lookups (e.g., private IPs without configuration)
  • Optional: convenience lookup_client(request) helper

Cross-SDK Comparison:

  • Rust (fastly::geo::geo_lookup): Returns strongly-typed Geo struct with enums for ConnSpeed, ConnType, Continent, ProxyDescription, ProxyType. Uses Option<UtcOffset> from time crate. All string/enum fields have Other(String) variant for forward-compatibility. Returns Option<Geo> for missing data.

  • Go (geo.Lookup): Returns *Geo struct with all string fields (no enums). Returns pointer to empty struct when no data available. Uses raw int for UTCOffset (HHMM format like 200 or -500).

  • JS (getGeolocationForIpAddress): Returns Geolocation interface with all fields as T | null. Uses strings for enums. Has both utc_offset (number) and gmt_offset (string). Returns null for no data.

Recommended Python approach:

  • Use @dataclass with typed fields for known attributes
  • Include _extra: dict field (with repr=False) to capture unknown JSON fields
  • Python Enum types for categorical fields (e.g., ConnType, Continent) using _missing_() to gracefully handle unknown values that might be added in future
  • Use Optional[X] (equivalent) for truly optional fields (region, utc_offset)
  • Return Geo | None from lookup() (align with Rust)
  • Consider utc_offset as Optional[datetime.timedelta] for Pythonic time handling
  • Match functionality from other SDKs for empty string values.

Forward Compatibility Pattern:

from dataclasses import dataclass, field

@dataclass
class Geo:
    city: str
    country_code: str
    latitude: float
    longitude: float
    # ... other known fields
    _extra: dict = field(default_factory=dict, repr=False)
    
    @classmethod
    def from_json(cls, data: dict):
        known_fields = {'city', 'country_code', 'latitude', 'longitude', ...}
        known = {k: v for k, v in data.items() if k in known_fields}
        extra = {k: v for k, v in data.items() if k not in known_fields}
        return cls(**known, _extra=extra)
    
    def __getattr__(self, name):
        if name in self._extra:
            return self._extra[name]
        raise AttributeError(f"no attribute '{name}'")

# Benefits: Type hints for known fields, future fields accessible via attributes
geo = Geo.from_json(json_data)
print(geo.city)      # Type-checked by IDE
print(geo.timezone)  # Works if Fastly adds this field later

Viceroy Testing

Viceroy supports geo lookups with configurable test data via test.toml:

[local_server.geolocation]
format = "inline-toml"
use_default_loopback = true  # Returns default data for 127.0.0.1

[local_server.geolocation.addresses."203.0.113.42"]
city = "San Francisco"
country_code = "US"
latitude = 37.77869
# ... additional fields

Default loopback data is available without configuration. Tests can use @on_viceroy with inline TOML config or JSON file references.

Reference

Dominant language
Python
Stars
5
Forks
1
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from fastly/compute-sdk-python

All issues in fastly/compute-sdk-python

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.