Skip to content

Commit

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

Fixes maxmind#101
  • Loading branch information
akx committed Aug 27, 2024
1 parent e087376 commit 50c3b8e
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 17 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,14 +25,24 @@
"""

from __future__ import annotations

import ipaddress
import json
from typing import Any, Dict, cast, List, Optional, Type, Union

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 @@ -48,14 +58,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 @@ -326,10 +328,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 @@ -436,7 +447,10 @@ def __init__( # pylint: disable=too-many-arguments
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 = "goschwald@maxmind.com"},
]
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.8"
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.setuptools.package-data]
geoip2 = ["py.typed"]
Expand Down
16 changes: 15 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ geoip2 = py.typed
disable = duplicate-code

[tox:tox]
envlist = {py38,py39,py310,py311,py312}-test,py312-{black,lint,flake8,mypy}
envlist =
{py38,py39,py310,py311,py312}-test{-all}
py312-{black,lint,flake8,mypy}

[gh-actions]
python =
Expand All @@ -25,6 +27,15 @@ deps =
pytest
commands = pytest tests

[testenv:{py38,py39,py310,py311,py312}-test-all]
deps =
pytest-httpserver
pytest
commands = pytest tests
extras =
aiohttp
requests

[testenv:py312-black]
deps = black
commands = black --check --diff .
Expand All @@ -45,3 +56,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 @@ -355,6 +355,7 @@ def test_missing_constructor_args(self):

class TestClient(TestBaseClient):
def setUp(self):
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 @@ -365,6 +366,7 @@ def run_client(self, v):

class TestAsyncClient(TestBaseClient):
def setUp(self):
pytest.importorskip("aiohttp")
self._loop = asyncio.new_event_loop()
self.client_class = AsyncClient
self.client = AsyncClient(42, "abcdef123456")
Expand Down

0 comments on commit 50c3b8e

Please sign in to comment.