From 18174107de254387aca6bf26452b511fb9d480b8 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Thu, 27 Feb 2025 13:21:53 +0000 Subject: [PATCH 1/6] docs: add hint about virtualenv --- CONTRIBUTING.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 01ab6ec..3e512e3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,8 +39,13 @@ Before creating an issue please make sure that it was not already reported. #### Code 1) Create a new branch based on `develop` branch. + * Optional: create and enable virtualenv: + ``` + python3 -m venv myenv + source myenv/bin/activate + ``` 2) Fetch all dev dependencies. - * Install required python modules using `pip`: **python -m pip install .[testing]** + * Install required python modules using `pip`: **python -m pip install ".[testing]"** 3) Ensure tests are ok by running them using [`pytest`](http://doc.pytest.org/en/latest/index.html). 4) Add your changes. 5) Follow [Black](https://black.readthedocs.io/en/stable/) code formatting. From 48a183363fdd4824f3d43431cf18c376f9cb86de Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Thu, 27 Feb 2025 13:22:44 +0000 Subject: [PATCH 2/6] feat: Bearer Token auth --- httpx_auth/__init__.py | 2 ++ httpx_auth/_authentication.py | 12 ++++++++++++ tests/bearer/__init__.py | 0 tests/bearer/test_bearer.py | 23 +++++++++++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 tests/bearer/__init__.py create mode 100644 tests/bearer/test_bearer.py diff --git a/httpx_auth/__init__.py b/httpx_auth/__init__.py index b948ba1..2b2d41d 100644 --- a/httpx_auth/__init__.py +++ b/httpx_auth/__init__.py @@ -1,5 +1,6 @@ from httpx_auth._authentication import ( Basic, + BearerToken, HeaderApiKey, QueryApiKey, SupportMultiAuth, @@ -46,6 +47,7 @@ __all__ = [ "Basic", + "BearerToken", "HeaderApiKey", "QueryApiKey", "OAuth2", diff --git a/httpx_auth/_authentication.py b/httpx_auth/_authentication.py index f251bff..0526752 100644 --- a/httpx_auth/_authentication.py +++ b/httpx_auth/_authentication.py @@ -61,6 +61,18 @@ def auth_flow( yield request +class BearerToken(HeaderApiKey): + """Describes a Bearer Token requests authentication.""" + + def __init__(self, token: str): + """ + :param token: The Bearer token that will be sent. + """ + if not token: + raise Exception("Token is mandatory.") + super().__init__(f"Bearer {token}", "Authorization") + + class QueryApiKey(httpx.Auth, SupportMultiAuth): """Describes an API Key requests authentication.""" diff --git a/tests/bearer/__init__.py b/tests/bearer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/bearer/test_bearer.py b/tests/bearer/test_bearer.py new file mode 100644 index 0000000..eccce1f --- /dev/null +++ b/tests/bearer/test_bearer.py @@ -0,0 +1,23 @@ +from pytest_httpx import HTTPXMock +import httpx +import pytest + +import httpx_auth + + +def test_bearer_requires_atoken(): + with pytest.raises(Exception) as exception_info: + httpx_auth.BearerToken(None) + assert str(exception_info.value) == "Token is mandatory." + +def test_bearer_token_is_sent(httpx_mock: HTTPXMock): + auth = httpx_auth.BearerToken("my_token") + + httpx_mock.add_response( + url="https://authorized_only", + method="GET", + match_headers={"Authorization": "Bearer my_token"}, + ) + + with httpx.Client() as client: + client.get("https://authorized_only", auth=auth) \ No newline at end of file From ca326cf92004a15c6ab5b809d64d59930f78701e Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Thu, 27 Feb 2025 13:23:16 +0000 Subject: [PATCH 3/6] chore: control pytest version --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 9f68ced..fe9dd4c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,6 +43,7 @@ issues = "https://github.com/Colin-b/httpx_auth/issues" [project.optional-dependencies] testing = [ + "pytest==8.3.4", # Used to generate test tokens "pyjwt==2.*", # Used to mock httpx From 85f99ebf17018eebf3b9badb7c74a8a6c9665b2b Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Thu, 27 Feb 2025 13:23:42 +0000 Subject: [PATCH 4/6] chore: with virtualenv we need to specify which modules to load --- pyproject.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index fe9dd4c..ccdc3cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,6 +56,11 @@ testing = [ "pytest-asyncio==0.25.*", ] +[tool.setuptools] +py-modules = [ + "httpx_auth" +] + [tool.setuptools.dynamic] version = {attr = "httpx_auth.version.__version__"} From 657ab57d3d152ef7c63a75f376c6404463c03c7f Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Thu, 27 Feb 2025 13:24:06 +0000 Subject: [PATCH 5/6] chore: fix asyncio error --- pyproject.toml | 2 -- pytest.ini | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 pytest.ini diff --git a/pyproject.toml b/pyproject.toml index ccdc3cb..6f240c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,5 +68,3 @@ version = {attr = "httpx_auth.version.__version__"} filterwarnings = [ "error", ] -# Silence deprecation warnings about option "asyncio_default_fixture_loop_scope" -asyncio_default_fixture_loop_scope = "function" diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..c44a7c8 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +asyncio_mode = auto +asyncio_default_fixture_loop_scope = "function" \ No newline at end of file From 64c6b8038834a67b3de36bb7dd17b03223aeb4a0 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Thu, 27 Feb 2025 13:31:16 +0000 Subject: [PATCH 6/6] style: newline at EOF --- pytest.ini | 2 +- tests/bearer/test_bearer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pytest.ini b/pytest.ini index c44a7c8..54462f5 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,3 @@ [pytest] asyncio_mode = auto -asyncio_default_fixture_loop_scope = "function" \ No newline at end of file +asyncio_default_fixture_loop_scope = "function" diff --git a/tests/bearer/test_bearer.py b/tests/bearer/test_bearer.py index eccce1f..2c5db3e 100644 --- a/tests/bearer/test_bearer.py +++ b/tests/bearer/test_bearer.py @@ -20,4 +20,4 @@ def test_bearer_token_is_sent(httpx_mock: HTTPXMock): ) with httpx.Client() as client: - client.get("https://authorized_only", auth=auth) \ No newline at end of file + client.get("https://authorized_only", auth=auth)