PyKubeGrader 0.2.28__py3-none-any.whl → 0.2.30__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.28
3
+ Version: 0.2.30
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=SmVfnJDoWaUoiPVlPv_eHqROu5nsdpOshyxAmzozEHU,3790
17
+ pykubegrader/tokens/validate_token.py,sha256=ShCNP-BpatS3-jdIkNsGVlhAqFHukpj0URqJuCMNHQk,2643
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.28.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
31
- PyKubeGrader-0.2.28.dist-info/METADATA,sha256=23BZ-4RHb8dLTt3xLorKdiC3zqrD1AZRSdvaJRUxkaA,2779
32
- PyKubeGrader-0.2.28.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
33
- PyKubeGrader-0.2.28.dist-info/entry_points.txt,sha256=UPMdTT46fQwTYJWtrUwIWIbXbwyOPfNQgBFRa0frWzw,138
34
- PyKubeGrader-0.2.28.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
35
- PyKubeGrader-0.2.28.dist-info/RECORD,,
30
+ PyKubeGrader-0.2.30.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
31
+ PyKubeGrader-0.2.30.dist-info/METADATA,sha256=ocvUZSqFJk6PAgCy300HAFyJrKDGOZqh0gAWjB7vsLg,2779
32
+ PyKubeGrader-0.2.30.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
33
+ PyKubeGrader-0.2.30.dist-info/entry_points.txt,sha256=UPMdTT46fQwTYJWtrUwIWIbXbwyOPfNQgBFRa0frWzw,138
34
+ PyKubeGrader-0.2.30.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
35
+ PyKubeGrader-0.2.30.dist-info/RECORD,,
@@ -1,12 +1,9 @@
1
- import asyncio
2
1
  import os
2
+ import sys
3
3
  from typing import Optional
4
4
 
5
- import httpx
6
- import nest_asyncio # type: ignore
7
-
8
- # Apply nest_asyncio for environments like Jupyter
9
- nest_asyncio.apply()
5
+ import requests
6
+ from requests.auth import HTTPBasicAuth
10
7
 
11
8
 
12
9
  class TokenValidationError(Exception):
@@ -44,83 +41,46 @@ def get_credentials() -> dict[str, str]:
44
41
  return {"username": username, "password": password}
45
42
 
46
43
 
47
- async def async_validate_token(token: Optional[str] = None) -> None:
48
- """
49
- Asynchronously validate a token by making a GET request to the validation endpoint.
50
-
51
- Args:
52
- token (str): The token to validate.
53
-
54
- Raises:
55
- TokenValidationError: If the token is invalid or if there is an error in the validation process.
56
-
57
- Returns:
58
- None: If the token is valid, the function will pass silently.
59
- """
60
-
61
- # First, check if token is provided as an argument
62
- if token is not None:
63
- os.environ["TOKEN"] = token
64
-
65
- # Next, check if token is available in environment variables
66
- if token is None:
67
- token = os.getenv("TOKEN", None)
68
-
69
- # Otherwise, raise an error
70
- if token is None:
71
- raise TokenValidationError("No token provided")
44
+ def validate_token(token: Optional[str] = None) -> None:
45
+ if token:
46
+ os.environ["TOKEN"] = token # If token passed, set env var
47
+ else:
48
+ token = os.getenv("TOKEN") # Otherwise try to get from env
49
+ if not token:
50
+ print("Error: No token provided", file=sys.stderr)
51
+ return
72
52
 
73
- # Fetch the endpoint URL
53
+ # Get endpoint URL
74
54
  base_url = os.getenv("DB_URL")
75
55
  if not base_url:
76
- raise ValueError("Environment variable 'DB_URL' not set")
77
- endpoint = f"{base_url}validate-token/{token}"
56
+ print("Error: Environment variable 'DB_URL' not set", file=sys.stderr)
57
+ return
58
+ endpoint = f"{base_url.rstrip('/')}/validate-token/{token}"
78
59
 
79
60
  # Get credentials
80
- credentials = get_credentials()
61
+ try:
62
+ credentials = get_credentials()
63
+ except ValueError as e:
64
+ print(f"Error: {e}", file=sys.stderr)
65
+ return
66
+
81
67
  username = credentials["username"]
82
68
  password = credentials["password"]
69
+ basic_auth = HTTPBasicAuth(username, password)
83
70
 
84
- basic_auth = httpx.BasicAuth(username=username, password=password)
85
-
86
- # Make GET request
87
- async with httpx.AsyncClient() as client:
88
- try:
89
- response = await client.get(url=endpoint, auth=basic_auth, timeout=10)
90
- response.raise_for_status()
91
- return
92
- except httpx.HTTPStatusError as e:
93
- detail = e.response.json().get("detail", e.response.text)
94
- raise TokenValidationError(detail)
95
- except httpx.RequestError as e:
96
- raise TokenValidationError(f"Request failed: {e}")
97
- except Exception as e:
98
- raise TokenValidationError(f"An unexpected error occurred: {e}")
99
-
100
-
101
- def validate_token(token: Optional[str] = None) -> None:
102
- """
103
- Synchronous wrapper for the `async_validate_token` function.
104
-
105
- Args:
106
- token (str): The token to validate.
107
-
108
- Raises:
109
- TokenValidationError: If the token is invalid or if there is an error in the validation process.
110
-
111
- Returns:
112
- None: If the token is valid, the function will pass silently.
113
- """
114
-
115
- # Get the current event loop or create one
116
71
  try:
117
- loop = asyncio.get_event_loop()
118
- except RuntimeError:
119
- loop = asyncio.new_event_loop()
120
- asyncio.set_event_loop(loop)
121
-
122
- # Run the async function in the event loop
123
- loop.run_until_complete(async_validate_token(token))
72
+ response = requests.get(url=endpoint, auth=basic_auth, timeout=10)
73
+ response.raise_for_status()
74
+
75
+ detail = response.json().get("detail", response.text)
76
+ print(detail)
77
+ except requests.exceptions.HTTPError as e:
78
+ detail = e.response.json().get("detail", e.response.text)
79
+ print(f"Error: {detail}", file=sys.stderr)
80
+ except requests.exceptions.RequestException as e:
81
+ print(f"Error: Request failed: {e}", file=sys.stderr)
82
+ except Exception as e:
83
+ print(f"Unexpected error: {e}", file=sys.stderr)
124
84
 
125
85
 
126
86
  # Example usage