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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyKubeGrader
3
- Version: 0.2.29
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=CwoVo_KFEYspbH6pbb3jb7QKHaiOQQVOEFFWXV18Gvg,5287
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.29.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
31
- PyKubeGrader-0.2.29.dist-info/METADATA,sha256=7Te1ql0k3BNp9JaX-fQjxGKEMBLMfXrlGUj9gBdSHaw,2779
32
- PyKubeGrader-0.2.29.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
33
- PyKubeGrader-0.2.29.dist-info/entry_points.txt,sha256=UPMdTT46fQwTYJWtrUwIWIbXbwyOPfNQgBFRa0frWzw,138
34
- PyKubeGrader-0.2.29.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
35
- PyKubeGrader-0.2.29.dist-info/RECORD,,
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
- return
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
- return
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
- return
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__":