Skip to content

Commit

Permalink
Make aiohttp and requests optional dependencies
Browse files Browse the repository at this point in the history
Closes #104 (supersedes it)

Fixes #101
  • Loading branch information
akx committed Feb 10, 2025
1 parent d965163 commit 6ac3f9c
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 16 deletions.
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ To install the ``geoip2`` module, type:
.. code-block:: bash
$ pip install geoip2
$ pip install geoip2[aiohttp] # Install aiohttp as well
$ pip install geoip2[requests] # Install requests as well
If you are not able to use pip, you may also use easy_install from the
source directory:
Expand Down
42 changes: 28 additions & 14 deletions geoip2/webservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,25 @@
"""

from __future__ import annotations

import ipaddress
import json
from collections.abc import Sequence
from typing import Any, Optional, Union, cast

import aiohttp
import aiohttp.http
import requests
import requests.utils
try:
import aiohttp
import aiohttp.http
except ImportError:
aiohttp = None # type: ignore[assignment]

try:
import requests
import requests.utils
except ImportError:
requests = None # type: ignore[assignment]


import geoip2
import geoip2.models
Expand All @@ -49,14 +59,6 @@
from geoip2.models import City, Country, Insights
from geoip2.types import IPAddress

_AIOHTTP_UA = (
f"GeoIP2-Python-Client/{geoip2.__version__} {aiohttp.http.SERVER_SOFTWARE}"
)

_REQUEST_UA = (
f"GeoIP2-Python-Client/{geoip2.__version__} {requests.utils.default_user_agent()}"
)


class BaseClient: # pylint: disable=missing-class-docstring, too-few-public-methods
_account_id: str
Expand Down Expand Up @@ -346,10 +348,19 @@ async def insights(self, ip_address: IPAddress = "me") -> Insights:
)

async def _session(self) -> aiohttp.ClientSession:
if aiohttp is None:
raise ImportError(
"aiohttp is required for async mode; install `GeoIP2[aiohttp]`"
)

if not hasattr(self, "_existing_session"):
user_agent = (
f"GeoIP2-Python-Client/{geoip2.__version__} "
f"{aiohttp.http.SERVER_SOFTWARE}"
)
self._existing_session = aiohttp.ClientSession(
auth=aiohttp.BasicAuth(self._account_id, self._license_key),
headers={"Accept": "application/json", "User-Agent": _AIOHTTP_UA},
headers={"Accept": "application/json", "User-Agent": user_agent},
timeout=aiohttp.ClientTimeout(total=self._timeout),
)

Expand Down Expand Up @@ -456,7 +467,10 @@ def __init__( # pylint: disable=too-many-arguments,too-many-positional-argument
self._session = requests.Session()
self._session.auth = (self._account_id, self._license_key)
self._session.headers["Accept"] = "application/json"
self._session.headers["User-Agent"] = _REQUEST_UA
self._session.headers["User-Agent"] = (
f"GeoIP2-Python-Client/{geoip2.__version__}"
f" {requests.utils.default_user_agent()}"
)
if proxy is None:
self._proxies = None
else:
Expand Down
8 changes: 6 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ authors = [
{name = "Gregory Oschwald", email = "[email protected]"},
]
dependencies = [
"aiohttp>=3.6.2,<4.0.0",
"maxminddb>=2.5.1,<3.0.0",
"requests>=2.24.0,<3.0.0",
]
requires-python = ">=3.9"
readme = "README.rst"
Expand All @@ -38,6 +36,12 @@ classifiers = [
test = [
"pytest-httpserver>=1.0.10",
]
aiohttp = [
"aiohttp>=3.6.2,<4.0.0",
]
requests = [
"requests>=2.24.0,<3.0.0",
]

[tool.ruff.lint]
select = ["ALL"]
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ deps =
types-requests
voluptuous-stubs
commands = mypy geoip2 tests
extras =
aiohttp
requests
2 changes: 2 additions & 0 deletions tests/webservice_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ class TestClient(TestBaseClient):
client: Client

def setUp(self) -> None:
pytest.importorskip("requests")
self.client_class = Client
self.client = Client(42, "abcdef123456")
self.client._base_uri = self.httpserver.url_for("/geoip/v2.1")
Expand All @@ -409,6 +410,7 @@ class TestAsyncClient(TestBaseClient):
client: AsyncClient

def setUp(self) -> None:
pytest.importorskip("aiohttp")
self._loop = asyncio.new_event_loop()
self.client_class = AsyncClient
self.client = AsyncClient(42, "abcdef123456")
Expand Down

0 comments on commit 6ac3f9c

Please sign in to comment.