PyKubeGrader 0.2.29__py3-none-any.whl → 0.2.31__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.29.dist-info → PyKubeGrader-0.2.31.dist-info}/METADATA +3 -3
- {PyKubeGrader-0.2.29.dist-info → PyKubeGrader-0.2.31.dist-info}/RECORD +7 -7
- pykubegrader/tokens/validate_token.py +6 -88
- {PyKubeGrader-0.2.29.dist-info → PyKubeGrader-0.2.31.dist-info}/LICENSE.txt +0 -0
- {PyKubeGrader-0.2.29.dist-info → PyKubeGrader-0.2.31.dist-info}/WHEEL +0 -0
- {PyKubeGrader-0.2.29.dist-info → PyKubeGrader-0.2.31.dist-info}/entry_points.txt +0 -0
- {PyKubeGrader-0.2.29.dist-info → PyKubeGrader-0.2.31.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: PyKubeGrader
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.31
|
4
4
|
Summary: Add a short description here!
|
5
5
|
Home-page: https://github.com/pyscaffold/pyscaffold/
|
6
6
|
Author: jagar2
|
@@ -12,10 +12,12 @@ Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: Programming Language :: Python
|
13
13
|
Description-Content-Type: text/x-rst; charset=UTF-8
|
14
14
|
License-File: LICENSE.txt
|
15
|
+
Requires-Dist: httpx
|
15
16
|
Requires-Dist: importlib-metadata; python_version < "3.8"
|
16
17
|
Requires-Dist: ipython
|
17
18
|
Requires-Dist: mypy
|
18
19
|
Requires-Dist: nbformat
|
20
|
+
Requires-Dist: nest_asyncio
|
19
21
|
Requires-Dist: numpy
|
20
22
|
Requires-Dist: panel
|
21
23
|
Requires-Dist: pynacl
|
@@ -28,8 +30,6 @@ Requires-Dist: types-python-dateutil
|
|
28
30
|
Requires-Dist: types-pyyaml
|
29
31
|
Requires-Dist: types-requests
|
30
32
|
Requires-Dist: types-setuptools
|
31
|
-
Requires-Dist: httpx
|
32
|
-
Requires-Dist: nest_asyncio
|
33
33
|
Provides-Extra: testing
|
34
34
|
Requires-Dist: setuptools; extra == "testing"
|
35
35
|
Requires-Dist: pytest; extra == "testing"
|
@@ -14,7 +14,7 @@ pykubegrader/log_parser/parse.ipynb,sha256=5e-9dzUbJk2M8kPP55lVeksm86lSY5ocKfWOP
|
|
14
14
|
pykubegrader/log_parser/parse.py,sha256=dXzTEOTI6VTRNoHFDAjg6hZUhvB3kHtMb10_KW3NPrw,7641
|
15
15
|
pykubegrader/submit/submit_assignment.py,sha256=UgJXKWw5b8-bRSFnba4iHAyXnujULHcWIask7hKx9ik,3421
|
16
16
|
pykubegrader/tokens/tokens.py,sha256=TOj0jRun1lWTztKA7KX9SjzIfNQqkwdnbczrFSPWB7Y,1089
|
17
|
-
pykubegrader/tokens/validate_token.py,sha256=
|
17
|
+
pykubegrader/tokens/validate_token.py,sha256=qeUxcbr3CWxJKYSv-ioUCIHK-RTYYThdr1TacxKD73w,2734
|
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=xmvN1UIXwk32v9S-JhsXwDc7axPlgpvoxSeM3II8sxY,5393
|
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.31.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
|
31
|
+
PyKubeGrader-0.2.31.dist-info/METADATA,sha256=wDLEnBN32abt2zTsYgon-xGXWt5fNLRa_s37QDhvaiQ,2779
|
32
|
+
PyKubeGrader-0.2.31.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
33
|
+
PyKubeGrader-0.2.31.dist-info/entry_points.txt,sha256=UPMdTT46fQwTYJWtrUwIWIbXbwyOPfNQgBFRa0frWzw,138
|
34
|
+
PyKubeGrader-0.2.31.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
|
35
|
+
PyKubeGrader-0.2.31.dist-info/RECORD,,
|
@@ -1,16 +1,10 @@
|
|
1
|
-
import asyncio
|
2
1
|
import os
|
3
2
|
import sys
|
4
3
|
from typing import Optional
|
5
4
|
|
6
|
-
import httpx
|
7
|
-
import nest_asyncio # type: ignore
|
8
5
|
import requests
|
9
6
|
from requests.auth import HTTPBasicAuth
|
10
7
|
|
11
|
-
# Apply nest_asyncio for environments like Jupyter
|
12
|
-
nest_asyncio.apply()
|
13
|
-
|
14
8
|
|
15
9
|
class TokenValidationError(Exception):
|
16
10
|
"""
|
@@ -47,85 +41,6 @@ def get_credentials() -> dict[str, str]:
|
|
47
41
|
return {"username": username, "password": password}
|
48
42
|
|
49
43
|
|
50
|
-
async def async_validate_token(token: Optional[str] = None) -> None:
|
51
|
-
"""
|
52
|
-
Asynchronously validate a token by making a GET request to the validation endpoint.
|
53
|
-
|
54
|
-
Args:
|
55
|
-
token (str): The token to validate.
|
56
|
-
|
57
|
-
Raises:
|
58
|
-
TokenValidationError: If the token is invalid or if there is an error in the validation process.
|
59
|
-
|
60
|
-
Returns:
|
61
|
-
None: If the token is valid, the function will pass silently.
|
62
|
-
"""
|
63
|
-
|
64
|
-
# First, check if token is provided as an argument
|
65
|
-
if token is not None:
|
66
|
-
os.environ["TOKEN"] = token
|
67
|
-
|
68
|
-
# Next, check if token is available in environment variables
|
69
|
-
if token is None:
|
70
|
-
token = os.getenv("TOKEN", None)
|
71
|
-
|
72
|
-
# Otherwise, raise an error
|
73
|
-
if token is None:
|
74
|
-
raise TokenValidationError("No token provided")
|
75
|
-
|
76
|
-
# Fetch the endpoint URL
|
77
|
-
base_url = os.getenv("DB_URL")
|
78
|
-
if not base_url:
|
79
|
-
raise ValueError("Environment variable 'DB_URL' not set")
|
80
|
-
endpoint = f"{base_url}validate-token/{token}"
|
81
|
-
|
82
|
-
# Get credentials
|
83
|
-
credentials = get_credentials()
|
84
|
-
username = credentials["username"]
|
85
|
-
password = credentials["password"]
|
86
|
-
|
87
|
-
basic_auth = httpx.BasicAuth(username=username, password=password)
|
88
|
-
|
89
|
-
# Make GET request
|
90
|
-
async with httpx.AsyncClient() as client:
|
91
|
-
try:
|
92
|
-
response = await client.get(url=endpoint, auth=basic_auth, timeout=10)
|
93
|
-
response.raise_for_status()
|
94
|
-
return
|
95
|
-
except httpx.HTTPStatusError as e:
|
96
|
-
detail = e.response.json().get("detail", e.response.text)
|
97
|
-
raise TokenValidationError(detail)
|
98
|
-
except httpx.RequestError as e:
|
99
|
-
raise TokenValidationError(f"Request failed: {e}")
|
100
|
-
except Exception as e:
|
101
|
-
raise TokenValidationError(f"An unexpected error occurred: {e}")
|
102
|
-
|
103
|
-
|
104
|
-
def validate_token_wrapper(token: Optional[str] = None) -> None:
|
105
|
-
"""
|
106
|
-
Synchronous wrapper for the `async_validate_token` function.
|
107
|
-
|
108
|
-
Args:
|
109
|
-
token (str): The token to validate.
|
110
|
-
|
111
|
-
Raises:
|
112
|
-
TokenValidationError: If the token is invalid or if there is an error in the validation process.
|
113
|
-
|
114
|
-
Returns:
|
115
|
-
None: If the token is valid, the function will pass silently.
|
116
|
-
"""
|
117
|
-
|
118
|
-
# Get the current event loop or create one
|
119
|
-
try:
|
120
|
-
loop = asyncio.get_event_loop()
|
121
|
-
except RuntimeError:
|
122
|
-
loop = asyncio.new_event_loop()
|
123
|
-
asyncio.set_event_loop(loop)
|
124
|
-
|
125
|
-
# Run the async function in the event loop
|
126
|
-
loop.run_until_complete(async_validate_token(token))
|
127
|
-
|
128
|
-
|
129
44
|
def validate_token(token: Optional[str] = None) -> None:
|
130
45
|
if token:
|
131
46
|
os.environ["TOKEN"] = token # If token passed, set env var
|
@@ -133,13 +48,13 @@ def validate_token(token: Optional[str] = None) -> None:
|
|
133
48
|
token = os.getenv("TOKEN") # Otherwise try to get from env
|
134
49
|
if not token:
|
135
50
|
print("Error: No token provided", file=sys.stderr)
|
136
|
-
|
51
|
+
sys.exit(1)
|
137
52
|
|
138
53
|
# Get endpoint URL
|
139
54
|
base_url = os.getenv("DB_URL")
|
140
55
|
if not base_url:
|
141
56
|
print("Error: Environment variable 'DB_URL' not set", file=sys.stderr)
|
142
|
-
|
57
|
+
sys.exit(1)
|
143
58
|
endpoint = f"{base_url.rstrip('/')}/validate-token/{token}"
|
144
59
|
|
145
60
|
# Get credentials
|
@@ -147,7 +62,7 @@ def validate_token(token: Optional[str] = None) -> None:
|
|
147
62
|
credentials = get_credentials()
|
148
63
|
except ValueError as e:
|
149
64
|
print(f"Error: {e}", file=sys.stderr)
|
150
|
-
|
65
|
+
sys.exit(1)
|
151
66
|
|
152
67
|
username = credentials["username"]
|
153
68
|
password = credentials["password"]
|
@@ -159,6 +74,7 @@ def validate_token(token: Optional[str] = None) -> None:
|
|
159
74
|
|
160
75
|
detail = response.json().get("detail", response.text)
|
161
76
|
print(detail)
|
77
|
+
return
|
162
78
|
except requests.exceptions.HTTPError as e:
|
163
79
|
detail = e.response.json().get("detail", e.response.text)
|
164
80
|
print(f"Error: {detail}", file=sys.stderr)
|
@@ -167,6 +83,8 @@ def validate_token(token: Optional[str] = None) -> None:
|
|
167
83
|
except Exception as e:
|
168
84
|
print(f"Unexpected error: {e}", file=sys.stderr)
|
169
85
|
|
86
|
+
sys.exit(1) # If we reached here, something went wrong
|
87
|
+
|
170
88
|
|
171
89
|
# Example usage
|
172
90
|
if __name__ == "__main__":
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|