auth0-python
Advanced tools
| [build-system] | ||
| requires = ["poetry-core", "poetry-dynamic-versioning"] | ||
| build-backend = "poetry_dynamic_versioning.backend" | ||
| [tool.poetry] | ||
| name = "auth0-python" | ||
| version = "0.0.0" # This is replaced by dynamic versioning | ||
| description = "" | ||
| authors = ["Auth0 <support@auth0.com>"] | ||
| license = "MIT" | ||
| repository = "https://github.com/auth0/auth0-python" | ||
| homepage = "https://auth0.com" | ||
| readme = "README.md" | ||
| packages = [{ include = "auth0" }] | ||
| [tool.poetry-dynamic-versioning] | ||
| strict = true | ||
| enable = true | ||
| vcs = "git" | ||
| style = "semver" | ||
| format-jinja = "{% if distance == 0 %}{{ base }}{% else %}{{ base }}{% endif %}" | ||
| pattern = "default-unprefixed" | ||
| [tool.poetry-dynamic-versioning.substitution] | ||
| files = ["*/__init__.py"] | ||
| folders = [{ path = "auth0" }] | ||
| [tool.poetry.dependencies] | ||
| python = "^3.7" | ||
| aiohttp = "^3.8.5" | ||
| pyjwt = "^2.8.0" | ||
| cryptography = "^41.0.3" # pyjwt has a weak dependency on cryptography | ||
| pyopenssl = "^23.2.0" # pyopenssl is required to work with cryptography 41+ | ||
| requests = "^2.31.0" | ||
| [tool.poetry.group.dev.dependencies] | ||
| aioresponses = "^0.7.4" | ||
| mock = "^5.1.0" | ||
| pipx = "^1.2.0" | ||
| pytest = "^7.4.0" | ||
| pytest-aiohttp = "^1.0.4" | ||
| pytest-asyncio = "^0.21.1" | ||
| pytest-cov = "^4.1.0" | ||
| responses = "^0.23.3" |
@@ -1,2 +0,3 @@ | ||
| __version__ = "4.4.0" | ||
| # This value is updated by `poetry_dynamic_versioning` during build time from the latest git tag | ||
| __version__ = "0.0.0" | ||
@@ -3,0 +4,0 @@ from auth0.exceptions import Auth0Error, RateLimitError, TokenValidationError |
@@ -62,3 +62,3 @@ from __future__ import annotations | ||
| client_id: str | None = None, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Retrieves all client grants. | ||
@@ -65,0 +65,0 @@ |
@@ -65,3 +65,3 @@ from __future__ import annotations | ||
| include_totals: bool = False, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """List device credentials. | ||
@@ -68,0 +68,0 @@ |
@@ -61,3 +61,3 @@ from __future__ import annotations | ||
| extra_params: dict[str, Any] | None = None, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Retrieves all grants. | ||
@@ -64,0 +64,0 @@ |
@@ -64,3 +64,3 @@ from __future__ import annotations | ||
| include_totals: bool = False, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Retrieves a list of all hooks. | ||
@@ -67,0 +67,0 @@ |
@@ -66,3 +66,3 @@ from __future__ import annotations | ||
| include_fields: bool = True, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Search log events. | ||
@@ -69,0 +69,0 @@ |
@@ -64,3 +64,3 @@ from __future__ import annotations | ||
| take: int | None = None, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Retrieves a list of all the organizations. | ||
@@ -250,3 +250,3 @@ | ||
| take: int | None = None, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Retrieves a list of all the organization members. | ||
@@ -382,3 +382,3 @@ | ||
| include_totals: bool = False, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Retrieves a list of all the organization invitations. | ||
@@ -385,0 +385,0 @@ |
@@ -71,3 +71,3 @@ from __future__ import annotations | ||
| include_totals: bool = False, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Retrieves all resource servers | ||
@@ -74,0 +74,0 @@ |
@@ -61,3 +61,3 @@ from __future__ import annotations | ||
| name_filter: str | None = None, | ||
| ) -> List[dict[str, Any]]: | ||
| ): | ||
| """List or search roles. | ||
@@ -139,3 +139,3 @@ | ||
| take: int | None = None, | ||
| ) -> List[dict[str, Any]]: | ||
| ): | ||
| """List the users that have been associated with a given role. | ||
@@ -191,3 +191,3 @@ | ||
| self, id: str, page: int = 0, per_page: int = 25, include_totals: bool = True | ||
| ) -> List[dict[str, Any]]: | ||
| ): | ||
| """List the permissions associated to a role. | ||
@@ -194,0 +194,0 @@ |
@@ -64,3 +64,3 @@ from __future__ import annotations | ||
| include_totals: bool = False, | ||
| ) -> list[dict[str, Any]]: | ||
| ): | ||
| """Retrieves a list of all rules. | ||
@@ -67,0 +67,0 @@ |
@@ -66,3 +66,3 @@ from __future__ import annotations | ||
| include_fields: bool = True, | ||
| ) -> List[dict[str, Any]]: | ||
| ): | ||
| """List or search users. | ||
@@ -174,3 +174,3 @@ | ||
| self, id: str, page: int = 0, per_page: int = 25, include_totals: bool = True | ||
| ) -> List[dict[str, Any]]: | ||
| ): | ||
| """List the organizations that the user is member of. | ||
@@ -203,3 +203,3 @@ | ||
| self, id: str, page: int = 0, per_page: int = 25, include_totals: bool = True | ||
| ) -> List[dict[str, Any]]: | ||
| ): | ||
| """List the roles associated with a user. | ||
@@ -260,3 +260,3 @@ | ||
| self, id: str, page: int = 0, per_page: int = 25, include_totals: bool = True | ||
| ) -> List[dict[str, Any]]: | ||
| ): | ||
| """List the permissions associated to the user. | ||
@@ -401,3 +401,3 @@ | ||
| include_totals: bool = False, | ||
| ) -> List[dict[str, Any]]: | ||
| ): | ||
| """Retrieve every log event for a specific user id. | ||
@@ -404,0 +404,0 @@ |
@@ -5,4 +5,5 @@ import re | ||
| import pytest | ||
| from aioresponses import CallbackResult, aioresponses | ||
| from callee import Attrs | ||
| from yarl import URL | ||
@@ -25,15 +26,16 @@ from auth0.management.async_auth0 import AsyncAuth0 as Auth0 | ||
| @unittest.skipIf( | ||
| not hasattr(unittest, "IsolatedAsyncioTestCase"), | ||
| "python 3.7 doesn't have IsolatedAsyncioTestCase", | ||
| ) | ||
| class TestAuth0(getattr(unittest, "IsolatedAsyncioTestCase", object)): | ||
| class TestAuth0(unittest.TestCase): | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_get(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.get(clients, callback=callback) | ||
| await mocked.get(clients, callback=callback) | ||
| auth0 = Auth0(domain="example.com", token="jwt") | ||
| self.assertEqual(await auth0.clients.all_async(), payload) | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/clients"), | ||
| URL("https://example.com/api/v2/clients?include_fields=true"), | ||
| allow_redirects=True, | ||
@@ -45,2 +47,3 @@ params={"include_fields": "true"}, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
@@ -50,4 +53,6 @@ async def test_shared_session(self, mocked): | ||
| callback2, mock2 = get_callback() | ||
| mocked.get(clients, callback=callback) | ||
| mocked.put(factors, callback=callback2) | ||
| await mocked.get(clients, callback=callback) | ||
| await mocked.put(factors, callback=callback2) | ||
| async with Auth0(domain="example.com", token="jwt") as auth0: | ||
@@ -59,4 +64,5 @@ self.assertEqual(await auth0.clients.all_async(), payload) | ||
| ) | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/clients"), | ||
| URL("https://example.com/api/v2/clients?include_fields=true"), | ||
| allow_redirects=True, | ||
@@ -67,4 +73,5 @@ params={"include_fields": "true"}, | ||
| ) | ||
| mock2.assert_called_with( | ||
| Attrs(path="/api/v2/guardian/factors/factor-1"), | ||
| URL("https://example.com/api/v2/guardian/factors/factor-1"), | ||
| allow_redirects=True, | ||
@@ -71,0 +78,0 @@ json={"factor": 1}, |
@@ -6,5 +6,6 @@ import time | ||
| import jwt | ||
| import pytest | ||
| from aioresponses import aioresponses | ||
| from callee import Attrs | ||
| from cryptography.hazmat.primitives import serialization | ||
| from yarl import URL | ||
@@ -58,13 +59,8 @@ from .. import TokenValidationError | ||
| @unittest.skipIf( | ||
| not hasattr(unittest, "IsolatedAsyncioTestCase"), | ||
| "python 3.7 doesn't have IsolatedAsyncioTestCase", | ||
| ) | ||
| class TestAsyncAsymmetricSignatureVerifier( | ||
| getattr(unittest, "IsolatedAsyncioTestCase", object) | ||
| ): | ||
| class TestAsyncAsymmetricSignatureVerifier(unittest.TestCase): | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_async_asymmetric_verifier_fetches_key(self, mocked): | ||
| callback, mock = get_callback(200, JWKS_RESPONSE_SINGLE_KEY) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -78,7 +74,4 @@ verifier = AsyncAsymmetricSignatureVerifier(JWKS_URI) | ||
| @unittest.skipIf( | ||
| not hasattr(unittest, "IsolatedAsyncioTestCase"), | ||
| "python 3.7 doesn't have IsolatedAsyncioTestCase", | ||
| ) | ||
| class TestAsyncJwksFetcher(getattr(unittest, "IsolatedAsyncioTestCase", object)): | ||
| class TestAsyncJwksFetcher(unittest.TestCase): | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
@@ -94,4 +87,4 @@ @unittest.mock.patch( | ||
| callback, mock = get_callback(200, JWKS_RESPONSE_SINGLE_KEY) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -103,3 +96,3 @@ key_1 = await fetcher.get_key("test-key-1") | ||
| mock.assert_called_with( | ||
| Attrs(path="/.well-known/jwks.json"), | ||
| URL("https://example.auth0.com/.well-known/jwks.json"), | ||
| allow_redirects=True, | ||
@@ -120,3 +113,3 @@ params=None, | ||
| mock.assert_called_with( | ||
| Attrs(path="/.well-known/jwks.json"), | ||
| URL("https://example.auth0.com/.well-known/jwks.json"), | ||
| allow_redirects=True, | ||
@@ -129,2 +122,3 @@ params=None, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
@@ -135,4 +129,4 @@ async def test_async_get_jwks_json_once_on_cache_hit(self, mocked): | ||
| callback, mock = get_callback(200, JWKS_RESPONSE_MULTIPLE_KEYS) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -147,3 +141,3 @@ key_1 = await fetcher.get_key("test-key-1") | ||
| mock.assert_called_with( | ||
| Attrs(path="/.well-known/jwks.json"), | ||
| URL("https://example.auth0.com/.well-known/jwks.json"), | ||
| allow_redirects=True, | ||
@@ -156,2 +150,3 @@ params=None, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
@@ -162,3 +157,3 @@ async def test_async_fetches_jwks_json_forced_on_cache_miss(self, mocked): | ||
| callback, mock = get_callback(200, {"keys": [RSA_PUB_KEY_1_JWK]}) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -171,3 +166,3 @@ # Triggers the first call | ||
| mock.assert_called_with( | ||
| Attrs(path="/.well-known/jwks.json"), | ||
| URL("https://example.auth0.com/.well-known/jwks.json"), | ||
| allow_redirects=True, | ||
@@ -181,3 +176,3 @@ params=None, | ||
| callback, mock = get_callback(200, JWKS_RESPONSE_MULTIPLE_KEYS) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -190,3 +185,3 @@ # Triggers the second call | ||
| mock.assert_called_with( | ||
| Attrs(path="/.well-known/jwks.json"), | ||
| URL("https://example.auth0.com/.well-known/jwks.json"), | ||
| allow_redirects=True, | ||
@@ -199,2 +194,3 @@ params=None, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
@@ -205,3 +201,3 @@ async def test_async_fetches_jwks_json_once_on_cache_miss(self, mocked): | ||
| callback, mock = get_callback(200, JWKS_RESPONSE_SINGLE_KEY) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -212,3 +208,3 @@ with self.assertRaises(Exception) as err: | ||
| mock.assert_called_with( | ||
| Attrs(path="/.well-known/jwks.json"), | ||
| URL("https://example.auth0.com/.well-known/jwks.json"), | ||
| allow_redirects=True, | ||
@@ -224,2 +220,3 @@ params=None, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
@@ -230,4 +227,4 @@ async def test_async_fails_to_fetch_jwks_json_after_retrying_twice(self, mocked): | ||
| callback, mock = get_callback(500, {}) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -238,3 +235,3 @@ with self.assertRaises(Exception) as err: | ||
| mock.assert_called_with( | ||
| Attrs(path="/.well-known/jwks.json"), | ||
| URL("https://example.auth0.com/.well-known/jwks.json"), | ||
| allow_redirects=True, | ||
@@ -251,11 +248,8 @@ params=None, | ||
| @unittest.skipIf( | ||
| not hasattr(unittest, "IsolatedAsyncioTestCase"), | ||
| "python 3.7 doesn't have IsolatedAsyncioTestCase", | ||
| ) | ||
| class TestAsyncTokenVerifier(getattr(unittest, "IsolatedAsyncioTestCase", object)): | ||
| class TestAsyncTokenVerifier(unittest.TestCase): | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_RS256_token_signature_passes(self, mocked): | ||
| callback, mock = get_callback(200, {"keys": [PUBLIC_KEY]}) | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -285,2 +279,3 @@ issuer = "https://tokens-test.auth0.com/" | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
@@ -291,3 +286,3 @@ async def test_RS256_token_signature_fails(self, mocked): | ||
| ) # different pub key | ||
| mocked.get(JWKS_URI, callback=callback) | ||
| await mocked.get(JWKS_URI, callback=callback) | ||
@@ -294,0 +289,0 @@ issuer = "https://tokens-test.auth0.com/" |
@@ -11,4 +11,5 @@ import base64 | ||
| import aiohttp | ||
| import pytest | ||
| from aioresponses import CallbackResult, aioresponses | ||
| from callee import Attrs | ||
| from yarl import URL | ||
@@ -57,15 +58,12 @@ from auth0.asyncify import asyncify | ||
| @unittest.skipIf( | ||
| not hasattr(unittest, "IsolatedAsyncioTestCase"), | ||
| "python 3.7 doesn't have IsolatedAsyncioTestCase", | ||
| ) | ||
| class TestAsyncify(getattr(unittest, "IsolatedAsyncioTestCase", object)): | ||
| class TestAsyncify(unittest.TestCase): | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_get(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.get(clients, callback=callback) | ||
| await mocked.get(clients, callback=callback) | ||
| c = asyncify(Clients)(domain="example.com", token="jwt") | ||
| self.assertEqual(await c.all_async(), payload) | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/clients"), | ||
| URL("https://example.com/api/v2/clients?include_fields=true"), | ||
| allow_redirects=True, | ||
@@ -77,6 +75,7 @@ params={"include_fields": "true"}, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_post(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.post(clients, callback=callback) | ||
| await mocked.post(clients, callback=callback) | ||
| c = asyncify(Clients)(domain="example.com", token="jwt") | ||
@@ -86,3 +85,3 @@ data = {"client": 1} | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/clients"), | ||
| URL("https://example.com/api/v2/clients"), | ||
| allow_redirects=True, | ||
@@ -94,6 +93,7 @@ json=data, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_post_auth(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.post(token, callback=callback) | ||
| await mocked.post(token, callback=callback) | ||
| c = asyncify(GetToken)("example.com", "cid", client_secret="clsec") | ||
@@ -104,3 +104,3 @@ self.assertEqual( | ||
| mock.assert_called_with( | ||
| Attrs(path="/oauth/token"), | ||
| URL("https://example.com/oauth/token"), | ||
| allow_redirects=True, | ||
@@ -121,6 +121,7 @@ json={ | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_user_info(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.get(user_info, callback=callback) | ||
| await mocked.get(user_info, callback=callback) | ||
| c = asyncify(Users)(domain="example.com") | ||
@@ -131,3 +132,3 @@ self.assertEqual( | ||
| mock.assert_called_with( | ||
| Attrs(path="/userinfo"), | ||
| URL("https://example.com/userinfo"), | ||
| headers={**headers, "Authorization": "Bearer access-token-example"}, | ||
@@ -139,6 +140,7 @@ timeout=ANY, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_file_post(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.post(users_imports, callback=callback) | ||
| await mocked.post(users_imports, callback=callback) | ||
| j = asyncify(Jobs)(domain="example.com", token="jwt") | ||
@@ -150,3 +152,3 @@ users = TemporaryFile() | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/jobs/users-imports"), | ||
| URL("https://example.com/api/v2/jobs/users-imports"), | ||
| allow_redirects=True, | ||
@@ -165,6 +167,7 @@ data={ | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_patch(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.patch(clients, callback=callback) | ||
| await mocked.patch(clients, callback=callback) | ||
| c = asyncify(Clients)(domain="example.com", token="jwt") | ||
@@ -174,3 +177,3 @@ data = {"client": 1} | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/clients/client-1"), | ||
| URL("https://example.com/api/v2/clients/client-1"), | ||
| allow_redirects=True, | ||
@@ -182,6 +185,7 @@ json=data, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_put(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.put(factors, callback=callback) | ||
| await mocked.put(factors, callback=callback) | ||
| g = asyncify(Guardian)(domain="example.com", token="jwt") | ||
@@ -191,3 +195,3 @@ data = {"factor": 1} | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/guardian/factors/factor-1"), | ||
| URL("https://example.com/api/v2/guardian/factors/factor-1"), | ||
| allow_redirects=True, | ||
@@ -199,10 +203,11 @@ json=data, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_delete(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.delete(clients, callback=callback) | ||
| await mocked.delete(clients, callback=callback) | ||
| c = asyncify(Clients)(domain="example.com", token="jwt") | ||
| self.assertEqual(await c.delete_async("client-1"), payload) | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/clients/client-1"), | ||
| URL("https://example.com/api/v2/clients/client-1"), | ||
| allow_redirects=True, | ||
@@ -215,10 +220,11 @@ params={}, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_shared_session(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.get(clients, callback=callback) | ||
| await mocked.get(clients, callback=callback) | ||
| async with asyncify(Clients)(domain="example.com", token="jwt") as c: | ||
| self.assertEqual(await c.all_async(), payload) | ||
| mock.assert_called_with( | ||
| Attrs(path="/api/v2/clients"), | ||
| URL("https://example.com/api/v2/clients?include_fields=true"), | ||
| allow_redirects=True, | ||
@@ -230,9 +236,10 @@ params={"include_fields": "true"}, | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_rate_limit(self, mocked): | ||
| callback, mock = get_callback(status=429) | ||
| mocked.get(clients, callback=callback) | ||
| mocked.get(clients, callback=callback) | ||
| mocked.get(clients, callback=callback) | ||
| mocked.get(clients, payload=payload) | ||
| await mocked.get(clients, callback=callback) | ||
| await mocked.get(clients, callback=callback) | ||
| await mocked.get(clients, callback=callback) | ||
| await mocked.get(clients, payload=payload) | ||
| c = asyncify(Clients)(domain="example.com", token="jwt") | ||
@@ -246,6 +253,7 @@ rest_client = c._async_client.client | ||
| @pytest.mark.asyncio | ||
| @aioresponses() | ||
| async def test_timeout(self, mocked): | ||
| callback, mock = get_callback() | ||
| mocked.get(clients, callback=callback) | ||
| await mocked.get(clients, callback=callback) | ||
| c = asyncify(Clients)(domain="example.com", token="jwt", timeout=(8.8, 9.9)) | ||
@@ -252,0 +260,0 @@ self.assertEqual(await c.all_async(), payload) |
@@ -297,12 +297,14 @@ import base64 | ||
| def test_get_can_timeout(self): | ||
| ab = AuthenticationBase("auth0.com", "cid", timeout=0.00001) | ||
| # TODO: Replace the following with more reliable tests. Failing on GitHub Actions. | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| ab.get("https://google.com", params={"a": "b"}, headers={"c": "d"}) | ||
| # def test_get_can_timeout(self): | ||
| # ab = AuthenticationBase("auth0.com", "cid", timeout=0.00002) | ||
| def test_post_can_timeout(self): | ||
| ab = AuthenticationBase("auth0.com", "cid", timeout=0.00001) | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # ab.get("https://google.com", params={"a": "b"}, headers={"c": "d"}) | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| ab.post("https://google.com", data={"a": "b"}, headers={"c": "d"}) | ||
| # def test_post_can_timeout(self): | ||
| # ab = AuthenticationBase("auth0.com", "cid", timeout=0.00002) | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # ab.post("https://google.com", data={"a": "b"}, headers={"c": "d"}) |
| import unittest | ||
| from fnmatch import fnmatch | ||
| from unittest import mock | ||
| from unittest.mock import ANY | ||
| from callee.strings import Glob | ||
| from cryptography.hazmat.primitives import asymmetric, serialization | ||
@@ -62,3 +63,3 @@ | ||
| "client_id": "cid", | ||
| "client_assertion": Glob("*.*.*"), | ||
| "client_assertion": ANY, | ||
| "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", | ||
@@ -71,2 +72,4 @@ "code": "cd", | ||
| self.assertTrue(fnmatch(kwargs["data"]["client_assertion"], "*.*.*")) | ||
| @mock.patch("auth0.rest.RestClient.post") | ||
@@ -131,3 +134,3 @@ def test_authorization_code_pkce(self, mock_post): | ||
| "client_id": "cid", | ||
| "client_assertion": Glob("*.*.*"), | ||
| "client_assertion": ANY, | ||
| "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", | ||
@@ -139,2 +142,4 @@ "audience": "aud", | ||
| self.assertTrue(fnmatch(kwargs["data"]["client_assertion"], "*.*.*")) | ||
| @mock.patch("auth0.rest.RestClient.post") | ||
@@ -141,0 +146,0 @@ def test_login(self, mock_post): |
@@ -15,69 +15,69 @@ import base64 | ||
| class TestRest(unittest.TestCase): | ||
| def test_options_are_used_and_override(self): | ||
| """ | ||
| This test ensures RestClientOptions are read when passed to | ||
| RestClient's constructor by (1) configuring a timeout and (2) | ||
| turning off Telemetry. This proves that RestClient is inheriting | ||
| those options, and overriding it's own constructor arguments. | ||
| """ | ||
| # def test_options_are_used_and_override(self): | ||
| # """ | ||
| # This test ensures RestClientOptions are read when passed to | ||
| # RestClient's constructor by (1) configuring a timeout and (2) | ||
| # turning off Telemetry. This proves that RestClient is inheriting | ||
| # those options, and overriding it's own constructor arguments. | ||
| # """ | ||
| options = RestClientOptions(telemetry=False, timeout=0.00001, retries=10) | ||
| rc = RestClient(jwt="a-token", telemetry=True, timeout=30, options=options) | ||
| # options = RestClientOptions(telemetry=False, timeout=0.00002, retries=10) | ||
| # rc = RestClient(jwt="a-token", telemetry=True, timeout=30, options=options) | ||
| # Does a timeout occur as expected? | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| rc.get("http://google.com") | ||
| # # Does a timeout occur as expected? | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # rc.get("http://google.com") | ||
| # Is RestClient using the RestClientOptions.timeout value properly? | ||
| self.assertEqual(rc.options.timeout, 0.00001) | ||
| # # Is RestClient using the RestClientOptions.timeout value properly? | ||
| # self.assertEqual(rc.options.timeout, 0.00002) | ||
| # Is RestClient using the RestClientOptions.retries value properly? | ||
| self.assertEqual(rc.options.retries, 10) | ||
| # # Is RestClient using the RestClientOptions.retries value properly? | ||
| # self.assertEqual(rc.options.retries, 10) | ||
| # Is RestClient using the RestClientOptions.telemetry value properly? | ||
| self.assertEqual(rc.options.telemetry, False) | ||
| # # Is RestClient using the RestClientOptions.telemetry value properly? | ||
| # self.assertEqual(rc.options.telemetry, False) | ||
| # Is RestClient using the RestClientOptions.telemetry value properly? | ||
| self.assertEqual( | ||
| rc.base_headers, | ||
| { | ||
| "Content-Type": "application/json", | ||
| "Authorization": "Bearer a-token", | ||
| }, | ||
| ) | ||
| # # Is RestClient using the RestClientOptions.telemetry value properly? | ||
| # self.assertEqual( | ||
| # rc.base_headers, | ||
| # { | ||
| # "Content-Type": "application/json", | ||
| # "Authorization": "Bearer a-token", | ||
| # }, | ||
| # ) | ||
| def test_options_are_created_by_default(self): | ||
| """ | ||
| This test ensures RestClientOptions are read when passed to | ||
| RestClient's constructor by (1) configuring a timeout and (2) | ||
| turning off Telemetry. This proves that RestClient is inheriting | ||
| those options, and overriding it's own constructor arguments. | ||
| """ | ||
| # def test_options_are_created_by_default(self): | ||
| # """ | ||
| # This test ensures RestClientOptions are read when passed to | ||
| # RestClient's constructor by (1) configuring a timeout and (2) | ||
| # turning off Telemetry. This proves that RestClient is inheriting | ||
| # those options, and overriding it's own constructor arguments. | ||
| # """ | ||
| rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00002) | ||
| # rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00002) | ||
| # Does a timeout occur as expected? | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| rc.get("http://google.com") | ||
| # # Does a timeout occur as expected? | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # rc.get("http://google.com") | ||
| # Did RestClient create a RestClientOptions for us? | ||
| self.assertIsNotNone(rc.options) | ||
| # # Did RestClient create a RestClientOptions for us? | ||
| # self.assertIsNotNone(rc.options) | ||
| # Did RestClient assign the new RestClientOptions instance the proper timeout value from the constructor? | ||
| self.assertEqual(rc.options.timeout, 0.00002) | ||
| # # Did RestClient assign the new RestClientOptions instance the proper timeout value from the constructor? | ||
| # self.assertEqual(rc.options.timeout, 0.00002) | ||
| # Did RestClient use the default RestClientOptions value for retries? | ||
| self.assertEqual(rc.options.retries, 3) | ||
| # # Did RestClient use the default RestClientOptions value for retries? | ||
| # self.assertEqual(rc.options.retries, 3) | ||
| # Did RestClient assign the new RestClientOptions instance the proper telemetry value from the constructor? | ||
| self.assertEqual(rc.options.telemetry, False) | ||
| # # Did RestClient assign the new RestClientOptions instance the proper telemetry value from the constructor? | ||
| # self.assertEqual(rc.options.telemetry, False) | ||
| # Is RestClient using the RestClientOptions.telemetry value properly? | ||
| self.assertEqual( | ||
| rc.base_headers, | ||
| { | ||
| "Content-Type": "application/json", | ||
| "Authorization": "Bearer a-token", | ||
| }, | ||
| ) | ||
| # # Is RestClient using the RestClientOptions.telemetry value properly? | ||
| # self.assertEqual( | ||
| # rc.base_headers, | ||
| # { | ||
| # "Content-Type": "application/json", | ||
| # "Authorization": "Bearer a-token", | ||
| # }, | ||
| # ) | ||
@@ -107,32 +107,34 @@ def test_default_options_are_used(self): | ||
| def test_get_can_timeout(self): | ||
| rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00001) | ||
| # TODO: Replace the following with more reliable tests. Failing on GitHub Actions. | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| rc.get("http://google.com") | ||
| # def test_get_can_timeout(self): | ||
| # rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00002) | ||
| def test_post_can_timeout(self): | ||
| rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00001) | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # rc.get("https://google.com") | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| rc.post("http://google.com") | ||
| # def test_post_can_timeout(self): | ||
| # rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00002) | ||
| def test_put_can_timeout(self): | ||
| rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00001) | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # rc.post("https://google.com") | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| rc.put("http://google.com") | ||
| # def test_put_can_timeout(self): | ||
| # rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00002) | ||
| def test_patch_can_timeout(self): | ||
| rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00001) | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # rc.put("https://google.com") | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| rc.patch("http://google.com") | ||
| # def test_patch_can_timeout(self): | ||
| # rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00002) | ||
| def test_delete_can_timeout(self): | ||
| rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00001) | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # rc.patch("https://google.com") | ||
| with self.assertRaises(requests.exceptions.Timeout): | ||
| rc.delete("http://google.com") | ||
| # def test_delete_can_timeout(self): | ||
| # rc = RestClient(jwt="a-token", telemetry=False, timeout=0.00002) | ||
| # with self.assertRaises(requests.exceptions.Timeout): | ||
| # rc.delete("https://google.com") | ||
| @mock.patch("requests.get") | ||
@@ -139,0 +141,0 @@ def test_get_custom_timeout(self, mock_get): |
+4
-4
| The MIT License (MIT) | ||
| Copyright (c) 2017 Auth0, Inc. <support@auth0.com> (http://auth0.com) | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
@@ -11,6 +11,6 @@ of this software and associated documentation files (the "Software"), to deal | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -17,0 +17,0 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
+12
-11
| Metadata-Version: 2.1 | ||
| Name: auth0-python | ||
| Version: 4.4.0 | ||
| Summary: Auth0 Python SDK | ||
| Home-page: https://github.com/auth0/auth0-python | ||
| Version: 0.0.0 | ||
| Summary: | ||
| Home-page: https://auth0.com | ||
| License: MIT | ||
| Author: Auth0 | ||
| Author-email: support@auth0.com | ||
| License: MIT | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: Operating System :: OS Independent | ||
| Requires-Python: >=3.7,<4.0 | ||
| Classifier: License :: OSI Approved :: MIT License | ||
| Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Programming Language :: Python :: 3.7 | ||
@@ -19,6 +17,9 @@ Classifier: Programming Language :: Python :: 3.8 | ||
| Classifier: Programming Language :: Python :: 3.11 | ||
| Requires-Python: >=3.7 | ||
| Requires-Dist: aiohttp (>=3.8.5,<4.0.0) | ||
| Requires-Dist: cryptography (>=41.0.3,<42.0.0) | ||
| Requires-Dist: pyjwt (>=2.8.0,<3.0.0) | ||
| Requires-Dist: pyopenssl (>=23.2.0,<24.0.0) | ||
| Requires-Dist: requests (>=2.31.0,<3.0.0) | ||
| Project-URL: Repository, https://github.com/auth0/auth0-python | ||
| Description-Content-Type: text/markdown | ||
| Provides-Extra: test | ||
| License-File: LICENSE | ||
@@ -25,0 +26,0 @@  |
+1
-1
@@ -184,2 +184,2 @@  | ||
| <p align="center"> | ||
| This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-python/blob/master/LICENSE"> LICENSE</a> file for more info.</p> | ||
| This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-python/blob/master/LICENSE"> LICENSE</a> file for more info.</p> |
| Metadata-Version: 2.1 | ||
| Name: auth0-python | ||
| Version: 4.4.0 | ||
| Summary: Auth0 Python SDK | ||
| Home-page: https://github.com/auth0/auth0-python | ||
| Author: Auth0 | ||
| Author-email: support@auth0.com | ||
| License: MIT | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: Operating System :: OS Independent | ||
| Classifier: License :: OSI Approved :: MIT License | ||
| Classifier: Programming Language :: Python :: 3.7 | ||
| Classifier: Programming Language :: Python :: 3.8 | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Classifier: Programming Language :: Python :: 3.11 | ||
| Requires-Python: >=3.7 | ||
| Description-Content-Type: text/markdown | ||
| Provides-Extra: test | ||
| License-File: LICENSE | ||
|  | ||
|  | ||
| [](https://codecov.io/gh/auth0/auth0-python) | ||
|  | ||
| [](https://opensource.org/licenses/MIT) | ||
| [](https://circleci.com/gh/auth0/auth0-python) | ||
| <div> | ||
| 📚 <a href="#documentation">Documentation</a> - 🚀 <a href="#getting-started">Getting started</a> - 💻 <a href="#api-reference">API reference</a> - 💬 <a href="#feedback">Feedback</a> | ||
| </div> | ||
| Learn how to integrate Auth0 with Python. | ||
| ## Documentation | ||
| - [Docs site](https://www.auth0.com/docs) - explore our docs site and learn more about Auth0. | ||
| ## Getting started | ||
| ### Installation | ||
| You can install the auth0 Python SDK using the following command. | ||
| ``` | ||
| pip install auth0-python | ||
| ``` | ||
| > Requires Python 3.7 or higher. | ||
| ### Usage | ||
| #### Authentication SDK | ||
| The Authentication SDK is organized into components that mirror the structure of the | ||
| [API documentation](https://auth0.com/docs/auth-api). | ||
| If you need to sign up a user using their email and password, you can use the Database object. | ||
| ```python | ||
| from auth0.authentication import Database | ||
| database = Database('my-domain.us.auth0.com', 'my-client-id') | ||
| database.signup(email='user@domain.com', password='secr3t', connection='Username-Password-Authentication') | ||
| ``` | ||
| If you need to authenticate a user using their email and password, you can use the `GetToken` object, which enables making requests to the `/oauth/token` endpoint. | ||
| ```python | ||
| from auth0.authentication import GetToken | ||
| token = GetToken('my-domain.us.auth0.com', 'my-client-id', client_secret='my-client-secret') | ||
| token.login(username='user@domain.com', password='secr3t', realm='Username-Password-Authentication') | ||
| ``` | ||
| #### Management SDK | ||
| To use the management library you will need to instantiate an Auth0 object with a domain and a [Management API v2 token](https://auth0.com/docs/api/management/v2/tokens). Please note that these token last 24 hours, so if you need it constantly you should ask for it programmatically using the client credentials grant with a [non interactive client](https://auth0.com/docs/api/management/v2/tokens#1-create-and-authorize-a-client) authorized to access the API. For example: | ||
| ```python | ||
| from auth0.authentication import GetToken | ||
| domain = 'myaccount.auth0.com' | ||
| non_interactive_client_id = 'exampleid' | ||
| non_interactive_client_secret = 'examplesecret' | ||
| get_token = GetToken(domain, non_interactive_client_id, client_secret=non_interactive_client_secret) | ||
| token = get_token.client_credentials('https://{}/api/v2/'.format(domain)) | ||
| mgmt_api_token = token['access_token'] | ||
| ``` | ||
| Then use the token you've obtained as follows: | ||
| ```python | ||
| from auth0.management import Auth0 | ||
| domain = 'myaccount.auth0.com' | ||
| mgmt_api_token = 'MGMT_API_TOKEN' | ||
| auth0 = Auth0(domain, mgmt_api_token) | ||
| ``` | ||
| The `Auth0()` object is now ready to take orders, see our [connections example](https://github.com/auth0/auth0-python/blob/master/EXAMPLES.md#connections) to find out how to use it! | ||
| For more code samples on how to integrate the auth0-python SDK in your Python application, have a look at our [examples](https://github.com/auth0/auth0-python/blob/master/EXAMPLES.md). | ||
| ## API reference | ||
| ### Authentication Endpoints | ||
| - Database ( `authentication.Database` ) | ||
| - Delegated ( `authentication.Delegated` ) | ||
| - Enterprise ( `authentication.Enterprise` ) | ||
| - API Authorization - Get Token ( `authentication.GetToken`) | ||
| - Passwordless ( `authentication.Passwordless` ) | ||
| - RevokeToken ( `authentication.RevokeToken` ) | ||
| - Social ( `authentication.Social` ) | ||
| - Users ( `authentication.Users` ) | ||
| ### Management Endpoints | ||
| - Actions() (`Auth0().action`) | ||
| - AttackProtection() (`Auth0().attack_protection`) | ||
| - Blacklists() ( `Auth0().blacklists` ) | ||
| - Branding() ( `Auth0().branding` ) | ||
| - ClientCredentials() ( `Auth0().client_credentials` ) | ||
| - ClientGrants() ( `Auth0().client_grants` ) | ||
| - Clients() ( `Auth0().clients` ) | ||
| - Connections() ( `Auth0().connections` ) | ||
| - CustomDomains() ( `Auth0().custom_domains` ) | ||
| - DeviceCredentials() ( `Auth0().device_credentials` ) | ||
| - EmailTemplates() ( `Auth0().email_templates` ) | ||
| - Emails() ( `Auth0().emails` ) | ||
| - Grants() ( `Auth0().grants` ) | ||
| - Guardian() ( `Auth0().guardian` ) | ||
| - Hooks() ( `Auth0().hooks` ) | ||
| - Jobs() ( `Auth0().jobs` ) | ||
| - LogStreams() ( `Auth0().log_streams` ) | ||
| - Logs() ( `Auth0().logs` ) | ||
| - Organizations() ( `Auth0().organizations` ) | ||
| - Prompts() ( `Auth0().prompts` ) | ||
| - ResourceServers() (`Auth0().resource_servers` ) | ||
| - Roles() ( `Auth0().roles` ) | ||
| - RulesConfigs() ( `Auth0().rules_configs` ) | ||
| - Rules() ( `Auth0().rules` ) | ||
| - Stats() ( `Auth0().stats` ) | ||
| - Tenants() ( `Auth0().tenants` ) | ||
| - Tickets() ( `Auth0().tickets` ) | ||
| - UserBlocks() (`Auth0().user_blocks` ) | ||
| - UsersByEmail() ( `Auth0().users_by_email` ) | ||
| - Users() ( `Auth0().users` ) | ||
| ## Support Policy | ||
| Our support lifecycle policy mirrors the [Python support schedule](https://devguide.python.org/versions/). We do not support running the SDK on unsupported versions of Python that have ceased to receive security updates. Please ensure your environment remains up to date and running the latest Python version possible. | ||
| | SDK Version | Python Version | Support Ends | | ||
| |-------------| -------------- | ------------ | | ||
| | 4.x | 3.11 | Oct 2027 | | ||
| | | 3.10 | Oct 2026 | | ||
| | | 3.9 | Oct 2025 | | ||
| | | 3.8 | Oct 2024 | | ||
| | | 3.7 | Oct 2023 | | ||
| > As `pip` [reliably avoids](https://packaging.python.org/en/latest/tutorials/packaging-projects/#configuring-metadata) installing package updates that target incompatible Python versions, we may opt to remove support for [end-of-life](https://en.wikipedia.org/wiki/CPython#Version_history) Python versions during minor SDK updates. These are not considered breaking changes by this SDK. | ||
| The following is a list of unsupported Python versions, and the last SDK version supporting them: | ||
| | Python Version | Last SDK Version Supporting | | ||
| | -------------- |-----------------------------| | ||
| | >= 2.0, <= 3.6 | 3.x | | ||
| You can determine what version of Python you have installed by running: | ||
| ``` | ||
| python --version | ||
| ``` | ||
| ## Feedback | ||
| ### Contributing | ||
| We appreciate feedback and contribution to this repo! Before you get started, please see the following: | ||
| - [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md) | ||
| - [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md) | ||
| ### Raise an issue | ||
| To provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/auth0/auth0-python/issues). | ||
| ### Vulnerability Reporting | ||
| Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues. | ||
| --- | ||
| <p align="center"> | ||
| <picture> | ||
| <source media="(prefers-color-scheme: light)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150"> | ||
| <source media="(prefers-color-scheme: dark)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_dark_mode.png" width="150"> | ||
| <img alt="Auth0 Logo" src="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150"> | ||
| </picture> | ||
| </p> | ||
| <p align="center">Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout <a href="https://auth0.com/why-auth0">Why Auth0?</a></p> | ||
| <p align="center"> | ||
| This project is licensed under the MIT license. See the <a href="https://github.com/auth0/auth0-python/blob/master/LICENSE"> LICENSE</a> file for more info.</p> | ||
| requests>=2.14.0 | ||
| pyjwt[crypto]>=2.6.0 | ||
| [test] | ||
| coverage | ||
| pre-commit |
| LICENSE | ||
| README.md | ||
| setup.py | ||
| auth0/__init__.py | ||
| auth0/asyncify.py | ||
| auth0/exceptions.py | ||
| auth0/py.typed | ||
| auth0/rest.py | ||
| auth0/rest_async.py | ||
| auth0/types.py | ||
| auth0/utils.py | ||
| auth0/authentication/__init__.py | ||
| auth0/authentication/async_token_verifier.py | ||
| auth0/authentication/base.py | ||
| auth0/authentication/client_authentication.py | ||
| auth0/authentication/database.py | ||
| auth0/authentication/delegated.py | ||
| auth0/authentication/enterprise.py | ||
| auth0/authentication/get_token.py | ||
| auth0/authentication/passwordless.py | ||
| auth0/authentication/revoke_token.py | ||
| auth0/authentication/social.py | ||
| auth0/authentication/token_verifier.py | ||
| auth0/authentication/users.py | ||
| auth0/management/__init__.py | ||
| auth0/management/actions.py | ||
| auth0/management/async_auth0.py | ||
| auth0/management/attack_protection.py | ||
| auth0/management/auth0.py | ||
| auth0/management/blacklists.py | ||
| auth0/management/branding.py | ||
| auth0/management/client_credentials.py | ||
| auth0/management/client_grants.py | ||
| auth0/management/clients.py | ||
| auth0/management/connections.py | ||
| auth0/management/custom_domains.py | ||
| auth0/management/device_credentials.py | ||
| auth0/management/email_templates.py | ||
| auth0/management/emails.py | ||
| auth0/management/grants.py | ||
| auth0/management/guardian.py | ||
| auth0/management/hooks.py | ||
| auth0/management/jobs.py | ||
| auth0/management/log_streams.py | ||
| auth0/management/logs.py | ||
| auth0/management/organizations.py | ||
| auth0/management/prompts.py | ||
| auth0/management/resource_servers.py | ||
| auth0/management/roles.py | ||
| auth0/management/rules.py | ||
| auth0/management/rules_configs.py | ||
| auth0/management/stats.py | ||
| auth0/management/tenants.py | ||
| auth0/management/tickets.py | ||
| auth0/management/user_blocks.py | ||
| auth0/management/users.py | ||
| auth0/management/users_by_email.py | ||
| auth0/test/__init__.py | ||
| auth0/test/authentication/__init__.py | ||
| auth0/test/authentication/test_base.py | ||
| auth0/test/authentication/test_database.py | ||
| auth0/test/authentication/test_delegated.py | ||
| auth0/test/authentication/test_enterprise.py | ||
| auth0/test/authentication/test_get_token.py | ||
| auth0/test/authentication/test_passwordless.py | ||
| auth0/test/authentication/test_revoke_token.py | ||
| auth0/test/authentication/test_social.py | ||
| auth0/test/authentication/test_token_verifier.py | ||
| auth0/test/authentication/test_users.py | ||
| auth0/test/management/__init__.py | ||
| auth0/test/management/test_actions.py | ||
| auth0/test/management/test_atack_protection.py | ||
| auth0/test/management/test_auth0.py | ||
| auth0/test/management/test_blacklists.py | ||
| auth0/test/management/test_branding.py | ||
| auth0/test/management/test_client_credentials.py | ||
| auth0/test/management/test_client_grants.py | ||
| auth0/test/management/test_clients.py | ||
| auth0/test/management/test_connections.py | ||
| auth0/test/management/test_custom_domains.py | ||
| auth0/test/management/test_device_credentials.py | ||
| auth0/test/management/test_email_endpoints.py | ||
| auth0/test/management/test_emails.py | ||
| auth0/test/management/test_grants.py | ||
| auth0/test/management/test_guardian.py | ||
| auth0/test/management/test_hooks.py | ||
| auth0/test/management/test_jobs.py | ||
| auth0/test/management/test_log_streams.py | ||
| auth0/test/management/test_logs.py | ||
| auth0/test/management/test_organizations.py | ||
| auth0/test/management/test_prompts.py | ||
| auth0/test/management/test_resource_servers.py | ||
| auth0/test/management/test_rest.py | ||
| auth0/test/management/test_roles.py | ||
| auth0/test/management/test_rules.py | ||
| auth0/test/management/test_rules_configs.py | ||
| auth0/test/management/test_stats.py | ||
| auth0/test/management/test_tenants.py | ||
| auth0/test/management/test_tickets.py | ||
| auth0/test/management/test_user_blocks.py | ||
| auth0/test/management/test_users.py | ||
| auth0/test/management/test_users_by_email.py | ||
| auth0/test_async/__init__.py | ||
| auth0/test_async/test_async_auth0.py | ||
| auth0/test_async/test_async_token_verifier.py | ||
| auth0/test_async/test_asyncify.py | ||
| auth0_python.egg-info/PKG-INFO | ||
| auth0_python.egg-info/SOURCES.txt | ||
| auth0_python.egg-info/dependency_links.txt | ||
| auth0_python.egg-info/requires.txt | ||
| auth0_python.egg-info/top_level.txt |
| [egg_info] | ||
| tag_build = | ||
| tag_date = 0 | ||
-47
| import os | ||
| import re | ||
| from setuptools import find_packages, setup | ||
| def find_version(): | ||
| file_dir = os.path.dirname(__file__) | ||
| with open(os.path.join(file_dir, "auth0", "__init__.py")) as f: | ||
| version = re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]', f.read()) | ||
| if version: | ||
| return version.group(1) | ||
| else: | ||
| raise RuntimeError("Unable to find version string.") | ||
| with open("README.md", encoding="utf-8") as f: | ||
| long_description = f.read() | ||
| setup( | ||
| name="auth0-python", | ||
| version=find_version(), | ||
| description="Auth0 Python SDK", | ||
| long_description=long_description, | ||
| long_description_content_type="text/markdown", | ||
| author="Auth0", | ||
| author_email="support@auth0.com", | ||
| license="MIT", | ||
| packages=find_packages(), | ||
| install_requires=["requests>=2.14.0", "pyjwt[crypto]>=2.6.0"], | ||
| extras_require={"test": ["coverage", "pre-commit"]}, | ||
| package_data={"auth0": ["py.typed"]}, | ||
| python_requires=">=3.7", | ||
| classifiers=[ | ||
| "Development Status :: 5 - Production/Stable", | ||
| "Intended Audience :: Developers", | ||
| "Operating System :: OS Independent", | ||
| "License :: OSI Approved :: MIT License", | ||
| "Programming Language :: Python :: 3.7", | ||
| "Programming Language :: Python :: 3.8", | ||
| "Programming Language :: Python :: 3.9", | ||
| "Programming Language :: Python :: 3.10", | ||
| "Programming Language :: Python :: 3.11", | ||
| ], | ||
| url="https://github.com/auth0/auth0-python", | ||
| ) |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
495751
-2.45%107
-5.31%10470
-0.3%