Skip to content

Commit e014f68

Browse files
committed
Make aiohttp and requests optional dependencies
Closes #104 (supersedes it) Fixes #101
1 parent a975598 commit e014f68

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

README.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ To install the ``geoip2`` module, type:
1717
.. code-block:: bash
1818
1919
$ pip install geoip2
20+
$ pip install geoip2[aiohttp] # Install aiohttp as well
21+
$ pip install geoip2[requests] # Install requests as well
2022
2123
If you are not able to install from PyPI, you may also use ``pip`` from the
2224
source directory:

pyproject.toml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ authors = [
66
{name = "Gregory Oschwald", email = "[email protected]"},
77
]
88
dependencies = [
9-
"aiohttp>=3.6.2,<4.0.0",
109
"maxminddb>=2.7.0,<3.0.0",
11-
"requests>=2.24.0,<3.0.0",
1210
]
1311
requires-python = ">=3.9"
1412
readme = "README.rst"
@@ -30,6 +28,14 @@ classifiers = [
3028
"Topic :: Internet :: Proxy Servers",
3129
]
3230

31+
[project.optional-dependencies]
32+
aiohttp = [
33+
"aiohttp>=3.6.2,<4.0.0",
34+
]
35+
requests = [
36+
"requests>=2.24.0,<3.0.0",
37+
]
38+
3339
[dependency-groups]
3440
dev = [
3541
"pytest>=8.3.5",
@@ -115,6 +121,10 @@ commands = [
115121
[tool.tox.env.lint]
116122
description = "Code linting"
117123
python = "3.13"
124+
extras = [
125+
"aiohttp",
126+
"requests",
127+
]
118128
dependency_groups = [
119129
"dev",
120130
"lint",

src/geoip2/webservice.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,18 @@
2727
import json
2828
from typing import TYPE_CHECKING, cast
2929

30-
import aiohttp
31-
import aiohttp.http
32-
import requests
33-
import requests.utils
30+
try:
31+
import aiohttp
32+
import aiohttp.http
33+
except ImportError:
34+
aiohttp = None # type: ignore[assignment]
35+
36+
try:
37+
import requests
38+
import requests.utils
39+
except ImportError:
40+
requests = None # type: ignore[assignment]
41+
3442

3543
import geoip2
3644
import geoip2.models
@@ -52,14 +60,6 @@
5260
from geoip2.models import City, Country, Insights
5361
from geoip2.types import IPAddress
5462

55-
_AIOHTTP_UA = (
56-
f"GeoIP2-Python-Client/{geoip2.__version__} {aiohttp.http.SERVER_SOFTWARE}"
57-
)
58-
59-
_REQUEST_UA = (
60-
f"GeoIP2-Python-Client/{geoip2.__version__} {requests.utils.default_user_agent()}"
61-
)
62-
6363

6464
class BaseClient:
6565
"""Base class for AsyncClient and Client."""
@@ -352,10 +352,19 @@ async def insights(self, ip_address: IPAddress = "me") -> Insights:
352352
)
353353

354354
async def _session(self) -> aiohttp.ClientSession:
355+
if aiohttp is None:
356+
raise ImportError(
357+
"aiohttp is required for async mode; install `GeoIP2[aiohttp]`"
358+
)
359+
355360
if not hasattr(self, "_existing_session"):
361+
user_agent = (
362+
f"GeoIP2-Python-Client/{geoip2.__version__} "
363+
f"{aiohttp.http.SERVER_SOFTWARE}"
364+
)
356365
self._existing_session = aiohttp.ClientSession(
357366
auth=aiohttp.BasicAuth(self._account_id, self._license_key),
358-
headers={"Accept": "application/json", "User-Agent": _AIOHTTP_UA},
367+
headers={"Accept": "application/json", "User-Agent": user_agent},
359368
timeout=aiohttp.ClientTimeout(total=self._timeout),
360369
)
361370

@@ -468,7 +477,10 @@ def __init__( # noqa: PLR0913
468477
self._session = requests.Session()
469478
self._session.auth = (self._account_id, self._license_key)
470479
self._session.headers["Accept"] = "application/json"
471-
self._session.headers["User-Agent"] = _REQUEST_UA
480+
self._session.headers["User-Agent"] = (
481+
f"GeoIP2-Python-Client/{geoip2.__version__}"
482+
f" {requests.utils.default_user_agent()}"
483+
)
472484
if proxy is None:
473485
self._proxies = None
474486
else:

tests/webservice_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ class TestClient(TestBaseClient):
400400
client: Client
401401

402402
def setUp(self) -> None:
403+
pytest.importorskip("requests")
403404
self.client_class = Client
404405
self.client = Client(42, "abcdef123456")
405406
self.client._base_uri = self.httpserver.url_for("/geoip/v2.1") # noqa: SLF001
@@ -413,6 +414,7 @@ class TestAsyncClient(TestBaseClient):
413414
client: AsyncClient
414415

415416
def setUp(self) -> None:
417+
pytest.importorskip("aiohttp")
416418
self._loop = asyncio.new_event_loop()
417419
self.client_class = AsyncClient
418420
self.client = AsyncClient(42, "abcdef123456")

0 commit comments

Comments
 (0)