{"id":5534,"library":"types-geoip2","title":"types-geoip2","description":"types-geoip2 provides PEP 561 compliant typing stubs for the geoip2 library. It enables static type checkers like mypy, PyCharm, and pytype to provide robust type checking and autocompletion for code using the geoip2 package. These stubs are maintained as part of the python/typeshed project on GitHub, with new versions automatically released to PyPI frequently (up to once a day) to reflect updates and improvements in typeshed.","status":"active","version":"3.0.0","language":"en","source_language":"en","source_url":"https://github.com/python/typeshed","tags":["typing","stubs","type hints","type checking","geoip","geoip2","typeshed"],"install":[{"cmd":"pip install types-geoip2","lang":"bash","label":"Install the stub package"}],"dependencies":[{"reason":"Provides the runtime functionality that types-geoip2 offers type hints for. types-geoip2 is not useful without an installed geoip2 library.","package":"geoip2","optional":false}],"imports":[{"symbol":"Client","correct":"from geoip2.webservice import Client"},{"symbol":"Reader","correct":"from geoip2.database import Reader"},{"note":"Type stubs are not imported directly. They provide type information for the runtime library (geoip2) which is imported as usual.","wrong":"from types_geoip2.models import City","symbol":"City","correct":"from geoip2.models import City"}],"quickstart":{"code":"import geoip2.database\nimport os\n\n# Ensure you have a GeoLite2-City.mmdb file available for database lookups.\n# Download from: https://dev.maxmind.com/geoip/downloads/maxmind-databases/\n# For this example, we assume it's in the current directory or specified path.\n# Replace with a real path if needed.\nDB_PATH = os.environ.get('GEOLITE2_CITY_DB_PATH', 'GeoLite2-City.mmdb')\n\n# If geoip2.database.Reader is initialized without the stub, type checkers might not know its methods.\n# With types-geoip2 installed, mypy (or other type checkers) will correctly infer types.\nreader: geoip2.database.Reader\ntry:\n    reader = geoip2.database.Reader(DB_PATH)\nexcept geoip2.errors.AddressNotFoundError:\n    print(f\"Database file not found at {DB_PATH}. Please provide a valid path or download the database.\")\n    exit(1)\nexcept Exception as e:\n    print(f\"An error occurred initializing the database reader: {e}\")\n    exit(1)\n\n\n# Example IP address\nip_address = '8.8.8.8' # Google Public DNS\n\ntry:\n    response = reader.city(ip_address)\n    print(f\"IP: {ip_address}\")\n    print(f\"Country Name: {response.country.name}\")\n    print(f\"City Name: {response.city.name}\")\n    print(f\"Latitude: {response.location.latitude}\")\n    print(f\"Longitude: {response.location.longitude}\")\n\n    # Type checker will correctly identify `response` as geoip2.models.City\n    # and `response.country` as geoip2.records.Country\n    reveal_type(response) # For mypy to show the inferred type\n\nexcept geoip2.errors.AddressNotFoundError:\n    print(f\"IP address {ip_address} not found in the database.\")\nexcept Exception as e:\n    print(f\"An error occurred during lookup: {e}\")\nfinally:\n    reader.close()\n\n# To run type checking, save this as `example.py` and run `mypy example.py`","lang":"python","description":"This quickstart demonstrates how to use `geoip2.database.Reader` with the `types-geoip2` stub package. When `types-geoip2` is installed alongside `geoip2`, type checkers can infer the types of objects returned by `geoip2` functions and methods, providing benefits like autocompletion and early error detection. You will need to download a GeoLite2-City.mmdb database file from MaxMind for the database lookup functionality."},"warnings":[{"fix":"Uninstall `types-geoip2` if `geoip2` is version 4.0.2 or newer: `pip uninstall types-geoip2`.","message":"The `geoip2` package itself started including type annotations from version `4.0.2` onwards. If you are using `geoip2>=4.0.2`, installing `types-geoip2` is unnecessary and may lead to conflicts or outdated type information, as the runtime package's own annotations will often be more accurate.","severity":"breaking","affected_versions":"geoip2>=4.0.2"},{"fix":"Consider pinning `types-geoip2` to a specific known-good version (`types-geoip2==X.Y.Z.build_date`) or setting upper bounds that align with your `geoip2` installation (`types-geoip2~=X.Y`). Regularly test type checking when updating dependencies.","message":"Typeshed stub packages (like `types-geoip2`) are released independently from the runtime library. While their version numbers often align with the runtime package they stub (e.g., `types-foo==1.2.0.YYYYMMDD` for `foo==1.2.*`), internal changes within typeshed's stubs can introduce new type-checking errors even if your runtime `geoip2` package version hasn't changed.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If `geoip2` version is `4.0.2` or higher, uninstall `types-geoip2` to rely on the library's built-in type annotations. `pip uninstall types-geoip2`.","message":"In Python's module resolution order for typing, stub files (`.pyi`) from installed stub packages generally take precedence over inline type annotations (`.py`) in the actual library. This means if `types-geoip2` is installed alongside a `geoip2` version that has its own inline types (like `geoip2>=4.0.2`), the `types-geoip2` stubs might be used, potentially overriding newer or more accurate inline types from `geoip2`.","severity":"gotcha","affected_versions":"All versions (especially when geoip2>=4.0.2 is also installed)"},{"fix":"Instead, use stable and unique identifiers such as `geoname_id`, `iso_code`, or `continent.code` for reliable data access.","message":"When working with `geoip2` models, MaxMind strongly advises against using values from `names` properties (e.g., `response.city.names['en']`) as keys in databases or dictionaries. These human-readable names are subject to change between releases, potentially leading to broken logic.","severity":"gotcha","affected_versions":"All versions of `geoip2` (and thus relevant for `types-geoip2` users)"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}