PyKubeGrader 0.2.18__py3-none-any.whl → 0.2.20__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.
- {PyKubeGrader-0.2.18.dist-info → PyKubeGrader-0.2.20.dist-info}/METADATA +1 -1
- {PyKubeGrader-0.2.18.dist-info → PyKubeGrader-0.2.20.dist-info}/RECORD +7 -7
- pykubegrader/tokens/validate_token.py +85 -27
- {PyKubeGrader-0.2.18.dist-info → PyKubeGrader-0.2.20.dist-info}/LICENSE.txt +0 -0
- {PyKubeGrader-0.2.18.dist-info → PyKubeGrader-0.2.20.dist-info}/WHEEL +0 -0
- {PyKubeGrader-0.2.18.dist-info → PyKubeGrader-0.2.20.dist-info}/entry_points.txt +0 -0
- {PyKubeGrader-0.2.18.dist-info → PyKubeGrader-0.2.20.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,7 @@ pykubegrader/log_parser/parse.ipynb,sha256=H1CUuqiUSE-tiZV1IS7VG6HAEvoopGd6i_5QM
|
|
14
14
|
pykubegrader/log_parser/parse.py,sha256=YCs_OCnoxQKsL55MjTZWXBBBsehJL8PIB9ANnC-aE44,7379
|
15
15
|
pykubegrader/submit/submit_assignment.py,sha256=p-v31479342q0AO3lJrd8Fwk7iJQUz183OeGeiNcXOY,3405
|
16
16
|
pykubegrader/tokens/tokens.py,sha256=DorNwdrA5N5apB3LQjVGa2ABN5C1upkgglecaLHobr0,1260
|
17
|
-
pykubegrader/tokens/validate_token.py,sha256=
|
17
|
+
pykubegrader/tokens/validate_token.py,sha256=zsELkJg1ll_3dWF1auuFVqh3N84vTZ8RIfk71edL360,3836
|
18
18
|
pykubegrader/widgets/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
19
19
|
pykubegrader/widgets/multiple_choice.py,sha256=NjD3-uXSnibpUQ0mO3hRp_O-rynFyl0Dz6IXE4tnCRI,2078
|
20
20
|
pykubegrader/widgets/reading_question.py,sha256=y30_swHwzH8LrT8deWTnxctAAmR8BSxTlXAqMgUrAT4,3031
|
@@ -27,9 +27,9 @@ pykubegrader/widgets_base/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-
|
|
27
27
|
pykubegrader/widgets_base/multi_select.py,sha256=Cl0IN21wXLZuFu-zC65aS9tD4jMfzCRJ2DPjHao5_Ak,4044
|
28
28
|
pykubegrader/widgets_base/reading.py,sha256=_vjUPynqmJe_R4vf-7hVhGnQR726S9GL6qT8bflBXBM,5383
|
29
29
|
pykubegrader/widgets_base/select.py,sha256=Fw3uFNOIWo1a3CvlzSx23bvi6bSmA3TqutuRbhD4Dp8,2525
|
30
|
-
PyKubeGrader-0.2.
|
31
|
-
PyKubeGrader-0.2.
|
32
|
-
PyKubeGrader-0.2.
|
33
|
-
PyKubeGrader-0.2.
|
34
|
-
PyKubeGrader-0.2.
|
35
|
-
PyKubeGrader-0.2.
|
30
|
+
PyKubeGrader-0.2.20.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
|
31
|
+
PyKubeGrader-0.2.20.dist-info/METADATA,sha256=ukDi7JVBIA2MSzOVLFkd2zqqgI_c7k-GQNLqCM3VflE,2779
|
32
|
+
PyKubeGrader-0.2.20.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
|
33
|
+
PyKubeGrader-0.2.20.dist-info/entry_points.txt,sha256=UPMdTT46fQwTYJWtrUwIWIbXbwyOPfNQgBFRa0frWzw,138
|
34
|
+
PyKubeGrader-0.2.20.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
|
35
|
+
PyKubeGrader-0.2.20.dist-info/RECORD,,
|
@@ -1,5 +1,12 @@
|
|
1
|
-
import requests
|
2
1
|
import os
|
2
|
+
import base64
|
3
|
+
import httpx
|
4
|
+
import asyncio
|
5
|
+
import nest_asyncio
|
6
|
+
|
7
|
+
# Apply nest_asyncio for environments like Jupyter
|
8
|
+
nest_asyncio.apply()
|
9
|
+
|
3
10
|
|
4
11
|
class TokenValidationError(Exception):
|
5
12
|
"""
|
@@ -16,9 +23,25 @@ class TokenValidationError(Exception):
|
|
16
23
|
super().__init__(message)
|
17
24
|
|
18
25
|
|
19
|
-
def
|
26
|
+
def get_credentials():
|
20
27
|
"""
|
21
|
-
|
28
|
+
Fetch the username and password from environment variables.
|
29
|
+
|
30
|
+
Returns:
|
31
|
+
dict: A dictionary containing 'username' and 'password'.
|
32
|
+
"""
|
33
|
+
username = os.getenv("user_name_student")
|
34
|
+
password = os.getenv("keys_student")
|
35
|
+
if not username or not password:
|
36
|
+
raise ValueError(
|
37
|
+
"Environment variables 'user_name_student' or 'keys_student' are not set."
|
38
|
+
)
|
39
|
+
return {"username": username, "password": password}
|
40
|
+
|
41
|
+
|
42
|
+
async def async_validate_token(token: str) -> None:
|
43
|
+
"""
|
44
|
+
Asynchronously validate a token by making a GET request to the validation endpoint.
|
22
45
|
|
23
46
|
Args:
|
24
47
|
token (str): The token to validate.
|
@@ -29,34 +52,69 @@ def validate_token(token = None):
|
|
29
52
|
Returns:
|
30
53
|
None: If the token is valid, the function will pass silently.
|
31
54
|
"""
|
32
|
-
endpoint
|
55
|
+
# Fetch the endpoint URL
|
56
|
+
base_url = os.getenv("DB_URL")
|
57
|
+
if not base_url:
|
58
|
+
raise ValueError("Environment variable 'DB_URL' is not set.")
|
59
|
+
endpoint = f"{base_url}validate-token/{token}"
|
33
60
|
|
34
|
-
|
35
|
-
|
61
|
+
# Get credentials
|
62
|
+
credentials = get_credentials()
|
63
|
+
username = credentials["username"]
|
64
|
+
password = credentials["password"]
|
36
65
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
raise TokenValidationError("No token provided")
|
66
|
+
# Encode credentials for Basic Authentication
|
67
|
+
auth_header = (
|
68
|
+
f"Basic {base64.b64encode(f'{username}:{password}'.encode()).decode()}"
|
69
|
+
)
|
42
70
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
return # Pass silently
|
49
|
-
elif response.status_code == 404:
|
50
|
-
# If the response is 404, the token is invalid
|
51
|
-
raise TokenValidationError(response.json().get("detail", "Token not found"))
|
52
|
-
else:
|
53
|
-
# Handle unexpected status codes
|
54
|
-
raise TokenValidationError(
|
55
|
-
f"Unexpected response code: {response.status_code}"
|
71
|
+
# Make the GET request
|
72
|
+
async with httpx.AsyncClient() as client:
|
73
|
+
try:
|
74
|
+
response = await client.get(
|
75
|
+
endpoint, headers={"Authorization": auth_header}, timeout=10
|
56
76
|
)
|
57
|
-
|
58
|
-
|
59
|
-
|
77
|
+
|
78
|
+
if response.status_code == 200:
|
79
|
+
# If the response is 200, the token is valid
|
80
|
+
return # Pass silently
|
81
|
+
elif response.status_code == 404:
|
82
|
+
# If the response is 404, the token is invalid
|
83
|
+
detail = response.json().get("detail", "Token not found")
|
84
|
+
raise TokenValidationError(detail)
|
85
|
+
else:
|
86
|
+
# Handle unexpected status codes
|
87
|
+
raise TokenValidationError(
|
88
|
+
f"Unexpected response code: {response.status_code}"
|
89
|
+
)
|
90
|
+
except httpx.RequestError as e:
|
91
|
+
raise TokenValidationError(f"Request failed: {e}")
|
92
|
+
except Exception as e:
|
93
|
+
raise TokenValidationError(f"An unexpected error occurred: {e}")
|
94
|
+
|
95
|
+
|
96
|
+
def validate_token(token: str) -> None:
|
97
|
+
"""
|
98
|
+
Synchronous wrapper for the `async_validate_token` function.
|
99
|
+
|
100
|
+
Args:
|
101
|
+
token (str): The token to validate.
|
102
|
+
|
103
|
+
Raises:
|
104
|
+
TokenValidationError: If the token is invalid or if there is an error in the validation process.
|
105
|
+
|
106
|
+
Returns:
|
107
|
+
None: If the token is valid, the function will pass silently.
|
108
|
+
"""
|
109
|
+
# Get the current event loop or create one
|
110
|
+
try:
|
111
|
+
loop = asyncio.get_event_loop()
|
112
|
+
except RuntimeError:
|
113
|
+
loop = asyncio.new_event_loop()
|
114
|
+
asyncio.set_event_loop(loop)
|
115
|
+
|
116
|
+
# Run the async function in the event loop
|
117
|
+
loop.run_until_complete(async_validate_token(token))
|
60
118
|
|
61
119
|
|
62
120
|
# Example usage
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|