aixtools 0.2.2__py3-none-any.whl → 0.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of aixtools might be problematic. Click here for more details.
- aixtools/_version.py +2 -2
- aixtools/auth/__init__.py +0 -0
- aixtools/auth/auth.py +70 -0
- aixtools/utils/config.py +14 -5
- {aixtools-0.2.2.dist-info → aixtools-0.2.3.dist-info}/METADATA +2 -1
- {aixtools-0.2.2.dist-info → aixtools-0.2.3.dist-info}/RECORD +9 -7
- {aixtools-0.2.2.dist-info → aixtools-0.2.3.dist-info}/WHEEL +0 -0
- {aixtools-0.2.2.dist-info → aixtools-0.2.3.dist-info}/entry_points.txt +0 -0
- {aixtools-0.2.2.dist-info → aixtools-0.2.3.dist-info}/top_level.txt +0 -0
aixtools/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.2.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
31
|
+
__version__ = version = '0.2.3'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 2, 3)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
File without changes
|
aixtools/auth/auth.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module that manages OAuth2 functions for authentication
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
import jwt
|
|
8
|
+
from jwt import ExpiredSignatureError, InvalidAudienceError, InvalidIssuerError, PyJWKClient
|
|
9
|
+
|
|
10
|
+
from aixtools.utils import config
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AuthTokenError(Exception):
|
|
16
|
+
"""Exception raised for authentication token errors."""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# pylint: disable=too-few-public-methods
|
|
20
|
+
class AccessTokenVerifier:
|
|
21
|
+
"""
|
|
22
|
+
Verifies Microsoft SSO JWT token against the configured Tenant ID, Audience, API ID and Issuer URL.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self):
|
|
26
|
+
tenant_id = config.APP_TENANT_ID
|
|
27
|
+
self.api_id = config.APP_API_ID
|
|
28
|
+
self.issuer_url = config.APP_ISSUER_URL
|
|
29
|
+
# Azure AD endpoints
|
|
30
|
+
jwks_url = f"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys"
|
|
31
|
+
self.jwks_client = PyJWKClient(
|
|
32
|
+
uri=jwks_url,
|
|
33
|
+
# cache keys url response to reduce SSO server network calls,
|
|
34
|
+
# as public keys are not expected to change frequently
|
|
35
|
+
cache_jwk_set=True,
|
|
36
|
+
# cache resolved public keys
|
|
37
|
+
cache_keys=True,
|
|
38
|
+
# cache url response for 10 hours
|
|
39
|
+
lifespan=36000,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
logger.info("Using JWKS: %s", jwks_url)
|
|
43
|
+
|
|
44
|
+
def verify(self, token: str) -> dict:
|
|
45
|
+
"""
|
|
46
|
+
Verifies The JWT access token and returns decoded claims as a dictionary if the token is
|
|
47
|
+
valid, otherwise raises an AuthTokenError
|
|
48
|
+
"""
|
|
49
|
+
try:
|
|
50
|
+
signing_key = self.jwks_client.get_signing_key_from_jwt(token)
|
|
51
|
+
|
|
52
|
+
claims = jwt.decode(
|
|
53
|
+
token,
|
|
54
|
+
signing_key.key,
|
|
55
|
+
algorithms=["RS256"],
|
|
56
|
+
audience=self.api_id,
|
|
57
|
+
issuer=self.issuer_url,
|
|
58
|
+
# ensure audience verification is carried out
|
|
59
|
+
options={"verify_aud": True},
|
|
60
|
+
)
|
|
61
|
+
return claims
|
|
62
|
+
|
|
63
|
+
except ExpiredSignatureError as e:
|
|
64
|
+
raise AuthTokenError("Token expired") from e
|
|
65
|
+
except InvalidAudienceError as e:
|
|
66
|
+
raise AuthTokenError(f"Token not for expected audience: {e}") from e
|
|
67
|
+
except InvalidIssuerError as e:
|
|
68
|
+
raise AuthTokenError(f"Token not for expected issuer: {e}") from e
|
|
69
|
+
except jwt.exceptions.PyJWTError as e:
|
|
70
|
+
raise AuthTokenError(f"Invalid token: {e}") from e
|
aixtools/utils/config.py
CHANGED
|
@@ -56,7 +56,6 @@ else:
|
|
|
56
56
|
logging.error("No '.env' file found in any of the search paths, or their parents: %s", env_dirs)
|
|
57
57
|
sys.exit(1)
|
|
58
58
|
|
|
59
|
-
|
|
60
59
|
# ---
|
|
61
60
|
# Directories
|
|
62
61
|
# ---
|
|
@@ -124,7 +123,17 @@ GOOGLE_CLOUD_LOCATION = get_variable_env("GOOGLE_CLOUD_LOCATION", True)
|
|
|
124
123
|
|
|
125
124
|
# vault parameters.
|
|
126
125
|
VAULT_ADDRESS = get_variable_env("VAULT_ADDRESS", default="http://localhost:8200")
|
|
127
|
-
VAULT_TOKEN = get_variable_env("VAULT_TOKEN",
|
|
128
|
-
VAULT_ENV = get_variable_env("ENV",
|
|
129
|
-
VAULT_MOUNT_POINT = get_variable_env("VAULT_MOUNT_POINT",
|
|
130
|
-
VAULT_PATH_PREFIX = get_variable_env("VAULT_PATH_PREFIX",
|
|
126
|
+
VAULT_TOKEN = get_variable_env("VAULT_TOKEN", allow_empty=True)
|
|
127
|
+
VAULT_ENV = get_variable_env("ENV", allow_empty=True)
|
|
128
|
+
VAULT_MOUNT_POINT = get_variable_env("VAULT_MOUNT_POINT", allow_empty=True)
|
|
129
|
+
VAULT_PATH_PREFIX = get_variable_env("VAULT_PATH_PREFIX", allow_empty=True)
|
|
130
|
+
|
|
131
|
+
# OAuth parameters
|
|
132
|
+
APP_SECRET_ID = get_variable_env("APP_SECRET_ID")
|
|
133
|
+
APP_CLIENT_ID = get_variable_env("APP_CLIENT_ID")
|
|
134
|
+
|
|
135
|
+
# used for token audience check
|
|
136
|
+
APP_API_ID = get_variable_env("APP_API_ID")
|
|
137
|
+
APP_TENANT_ID = get_variable_env("APP_TENANT_ID")
|
|
138
|
+
# used for token issuer check
|
|
139
|
+
APP_ISSUER_URL = get_variable_env("APP_ISSUER_URL")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aixtools
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Tools for AI exploration and debugging
|
|
5
5
|
Requires-Python: >=3.11.2
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -20,6 +20,7 @@ Requires-Dist: mypy>=1.18.2
|
|
|
20
20
|
Requires-Dist: pandas>=2.2.3
|
|
21
21
|
Requires-Dist: pydantic-evals>=0.4.10
|
|
22
22
|
Requires-Dist: pydantic-ai>=1.0.9
|
|
23
|
+
Requires-Dist: pyjwt>=2.10.1
|
|
23
24
|
Requires-Dist: pylint>=3.3.7
|
|
24
25
|
Requires-Dist: rich>=14.0.0
|
|
25
26
|
Requires-Dist: ruff>=0.11.6
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
aixtools/__init__.py,sha256=9NGHm7LjsQmsvjTZvw6QFJexSvAU4bCoN_KBk9SCa00,260
|
|
2
|
-
aixtools/_version.py,sha256=
|
|
2
|
+
aixtools/_version.py,sha256=kBRz0P2plw1eVdIpt70W6m1LMbEIhLY3RyOfVGdubaI,704
|
|
3
3
|
aixtools/app.py,sha256=JzQ0nrv_bjDQokllIlGHOV0HEb-V8N6k_nGQH-TEsVU,5227
|
|
4
4
|
aixtools/chainlit.md,sha256=yC37Ly57vjKyiIvK4oUvf4DYxZCwH7iocTlx7bLeGLU,761
|
|
5
5
|
aixtools/context.py,sha256=I_MD40ZnvRm5WPKAKqBUAdXIf8YaurkYUUHSVVy-QvU,598
|
|
@@ -30,6 +30,8 @@ aixtools/agents/agent.py,sha256=tceQByn-RGBIhW8BOjKoP0yhNzZLwAa6CxwhPhRe3PU,7270
|
|
|
30
30
|
aixtools/agents/agent_batch.py,sha256=0Zu9yNCRPAQZPjXQ-dIUAmP1uGTVbxVt7xvnMpoJMjU,2251
|
|
31
31
|
aixtools/agents/print_nodes.py,sha256=wVTngNfqM0As845WTRz6G3Rei_Gr3HuBlvu-G_eXuig,1665
|
|
32
32
|
aixtools/agents/prompt.py,sha256=p9OYnyJ4-MyGXwHPrQeJBhZ2a3RV2HqhtdUUCrTMsAQ,3361
|
|
33
|
+
aixtools/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
+
aixtools/auth/auth.py,sha256=aKYCKJRjSNrVZmIWN2h2p1zYqkhMLLBXBfk_Qy5NKik,2365
|
|
33
35
|
aixtools/compliance/__init__.py,sha256=vnw0zEdySIJWvDAJ8DCRRaWmY_agEOz1qlpAdhmtiuo,191
|
|
34
36
|
aixtools/compliance/private_data.py,sha256=OOM9mIp3_w0fNgj3VAEWBl7-jrPc19_Ls1pC5dfF5UY,5323
|
|
35
37
|
aixtools/db/__init__.py,sha256=b8vRhme3egV-aUZbAntnOaDkSXB8UT0Xy5oqQhU_z0Q,399
|
|
@@ -76,7 +78,7 @@ aixtools/tools/doctor/mcp_tool_doctor.py,sha256=sX2q5GfNkmUYxnXrqMpeGIwGfeL1LpYJ
|
|
|
76
78
|
aixtools/tools/doctor/tool_doctor.py,sha256=EY1pshjLGLD0j6cc1ZFtbc0G19I5IbOZwHFDqypE49Q,2661
|
|
77
79
|
aixtools/tools/doctor/tool_recommendation.py,sha256=LYyVOSXdAorWiY4P-ucSA1vLlV5BTEfX4GzBXNE_X0M,1569
|
|
78
80
|
aixtools/utils/__init__.py,sha256=xT6almZBQYMfj4h7Hq9QXDHyVXbOOTxqLsmJsxYYnSw,757
|
|
79
|
-
aixtools/utils/config.py,sha256=
|
|
81
|
+
aixtools/utils/config.py,sha256=t32731F53Cv1YYoX95wksoreE0Zn0B8UKyEiKWne4ec,5147
|
|
80
82
|
aixtools/utils/config_util.py,sha256=3Ya4Qqhj1RJ1qtTTykQ6iayf5uxlpigPXgEJlTi1wn4,2229
|
|
81
83
|
aixtools/utils/enum_with_description.py,sha256=zjSzWxG74eR4x7dpmb74pLTYCWNSMvauHd7_9LpDYIw,1088
|
|
82
84
|
aixtools/utils/files.py,sha256=8JnxwHJRJcjWCdFpjzWmo0po2fRg8esj4H7sOxElYXU,517
|
|
@@ -86,8 +88,8 @@ aixtools/utils/chainlit/cl_agent_show.py,sha256=vaRuowp4BRvhxEr5hw0zHEJ7iaSF_5bo
|
|
|
86
88
|
aixtools/utils/chainlit/cl_utils.py,sha256=fxaxdkcZg6uHdM8uztxdPowg3a2f7VR7B26VPY4t-3c,5738
|
|
87
89
|
aixtools/vault/__init__.py,sha256=fsr_NuX3GZ9WZ7dGfe0gp_5-z3URxAfwVRXw7Xyc0dU,141
|
|
88
90
|
aixtools/vault/vault.py,sha256=9dZLWdZQk9qN_Q9Djkofw9LUKnJqnrX5H0fGusVLBhA,6037
|
|
89
|
-
aixtools-0.2.
|
|
90
|
-
aixtools-0.2.
|
|
91
|
-
aixtools-0.2.
|
|
92
|
-
aixtools-0.2.
|
|
93
|
-
aixtools-0.2.
|
|
91
|
+
aixtools-0.2.3.dist-info/METADATA,sha256=QwClHDH-4L6s6WlM4051WFHEhIcdvFui9ely0GVNwJY,24980
|
|
92
|
+
aixtools-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
93
|
+
aixtools-0.2.3.dist-info/entry_points.txt,sha256=q8412TG4T0S8K0SKeWp2vkVPIDYQs0jNoHqcQ7qxOiA,155
|
|
94
|
+
aixtools-0.2.3.dist-info/top_level.txt,sha256=wBn-rw9bCtxrR4AYEYgjilNCUVmKY0LWby9Zan2PRJM,9
|
|
95
|
+
aixtools-0.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|