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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyKubeGrader
3
- Version: 0.2.18
3
+ Version: 0.2.20
4
4
  Summary: Add a short description here!
5
5
  Home-page: https://github.com/pyscaffold/pyscaffold/
6
6
  Author: jagar2
@@ -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=qbAKE8Vtz3trD99Yb3RnC7gr23CRqaNMFiESqFmWDlY,2037
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.18.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
31
- PyKubeGrader-0.2.18.dist-info/METADATA,sha256=m7tPzuZwXFkUeK19vPiztdP6MYcuFPbVzgT18AYOVAw,2779
32
- PyKubeGrader-0.2.18.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
33
- PyKubeGrader-0.2.18.dist-info/entry_points.txt,sha256=UPMdTT46fQwTYJWtrUwIWIbXbwyOPfNQgBFRa0frWzw,138
34
- PyKubeGrader-0.2.18.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
35
- PyKubeGrader-0.2.18.dist-info/RECORD,,
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 validate_token(token = None):
26
+ def get_credentials():
20
27
  """
21
- Validate a token by making a GET request to the validation endpoint.
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 = f"https://engr-131-api.eastus.cloudapp.azure.com/validate-token/{token}"
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
- if token is not None:
35
- os.environ["TOKEN"] = token
61
+ # Get credentials
62
+ credentials = get_credentials()
63
+ username = credentials["username"]
64
+ password = credentials["password"]
36
65
 
37
- if token is None:
38
- token = os.getenv("TOKEN", None)
39
-
40
- if token is None:
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
- try:
44
- response = requests.get(endpoint, timeout=10)
45
-
46
- if response.status_code == 200:
47
- # If the response is 200, the token is valid
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
- except requests.RequestException as e:
58
- # Raise an exception for connection errors or timeout
59
- raise TokenValidationError(f"Request failed: {e}")
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