PyKubeGrader 0.2.29__tar.gz → 0.2.30__tar.gz

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.
Files changed (67) hide show
  1. {pykubegrader-0.2.29/src/PyKubeGrader.egg-info → pykubegrader-0.2.30}/PKG-INFO +3 -3
  2. {pykubegrader-0.2.29 → pykubegrader-0.2.30/src/PyKubeGrader.egg-info}/PKG-INFO +3 -3
  3. pykubegrader-0.2.30/src/pykubegrader/tokens/validate_token.py +94 -0
  4. pykubegrader-0.2.29/src/pykubegrader/tokens/validate_token.py +0 -179
  5. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/.coveragerc +0 -0
  6. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/.github/workflows/main.yml +0 -0
  7. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/.gitignore +0 -0
  8. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/.readthedocs.yml +0 -0
  9. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/AUTHORS.rst +0 -0
  10. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/CHANGELOG.rst +0 -0
  11. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/CONTRIBUTING.rst +0 -0
  12. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/LICENSE.txt +0 -0
  13. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/README.rst +0 -0
  14. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/Makefile +0 -0
  15. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/_static/Drexel_blue_Logo_square_Dark.png +0 -0
  16. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/_static/Drexel_blue_Logo_square_Light.png +0 -0
  17. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/_static/custom.css +0 -0
  18. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/authors.rst +0 -0
  19. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/changelog.rst +0 -0
  20. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/conf.py +0 -0
  21. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/contributing.rst +0 -0
  22. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/index.rst +0 -0
  23. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/license.rst +0 -0
  24. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/readme.rst +0 -0
  25. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/requirements.txt +0 -0
  26. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/examples/.responses.json +0 -0
  27. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/examples/true_false.ipynb +0 -0
  28. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/pyproject.toml +0 -0
  29. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/setup.cfg +2 -2
  30. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/setup.py +0 -0
  31. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/SOURCES.txt +0 -0
  32. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/dependency_links.txt +0 -0
  33. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/entry_points.txt +0 -0
  34. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/not-zip-safe +0 -0
  35. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/requires.txt +2 -2
  36. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/top_level.txt +0 -0
  37. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/__init__.py +0 -0
  38. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/build/__init__.py +0 -0
  39. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/build/api_notebook_builder.py +0 -0
  40. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/build/build_folder.py +0 -0
  41. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/build/clean_folder.py +0 -0
  42. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/graders/__init__.py +0 -0
  43. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/graders/late_assignments.py +0 -0
  44. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/initialize.py +0 -0
  45. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/log_parser/__init__.py +0 -0
  46. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/log_parser/parse.ipynb +0 -0
  47. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/log_parser/parse.py +0 -0
  48. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/submit/submit_assignment.py +0 -0
  49. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/telemetry.py +0 -0
  50. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/tokens/tokens.py +0 -0
  51. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/utils.py +0 -0
  52. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/validate.py +0 -0
  53. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/__init__.py +0 -0
  54. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/multiple_choice.py +0 -0
  55. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/reading_question.py +0 -0
  56. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/select_many.py +0 -0
  57. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/student_info.py +0 -0
  58. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/style.py +0 -0
  59. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/true_false.py +0 -0
  60. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/types_question.py +0 -0
  61. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets_base/__init__.py +0 -0
  62. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets_base/multi_select.py +0 -0
  63. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets_base/reading.py +0 -0
  64. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets_base/select.py +0 -0
  65. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/tests/conftest.py +0 -0
  66. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/tests/import_test.py +0 -0
  67. {pykubegrader-0.2.29 → pykubegrader-0.2.30}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyKubeGrader
3
- Version: 0.2.29
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"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyKubeGrader
3
- Version: 0.2.29
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"
@@ -0,0 +1,94 @@
1
+ import os
2
+ import sys
3
+ from typing import Optional
4
+
5
+ import requests
6
+ from requests.auth import HTTPBasicAuth
7
+
8
+
9
+ class TokenValidationError(Exception):
10
+ """
11
+ Custom exception raised when the token validation fails.
12
+ """
13
+
14
+ def __init__(self, message: Optional[str] = None):
15
+ """
16
+ Initialize the exception with an optional message.
17
+
18
+ Args:
19
+ message (str, optional): The error message to display. Defaults to None.
20
+ """
21
+
22
+ super().__init__(message)
23
+
24
+
25
+ def get_credentials() -> dict[str, str]:
26
+ """
27
+ Fetch the username and password from environment variables.
28
+
29
+ Returns:
30
+ dict: A dictionary containing 'username' and 'password'.
31
+ """
32
+
33
+ username = os.getenv("user_name_student")
34
+ password = os.getenv("keys_student")
35
+
36
+ if not username or not password:
37
+ raise ValueError(
38
+ "Environment variable 'user_name_student' or 'keys_student' not set"
39
+ )
40
+
41
+ return {"username": username, "password": password}
42
+
43
+
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
52
+
53
+ # Get endpoint URL
54
+ base_url = os.getenv("DB_URL")
55
+ if not base_url:
56
+ print("Error: Environment variable 'DB_URL' not set", file=sys.stderr)
57
+ return
58
+ endpoint = f"{base_url.rstrip('/')}/validate-token/{token}"
59
+
60
+ # Get credentials
61
+ try:
62
+ credentials = get_credentials()
63
+ except ValueError as e:
64
+ print(f"Error: {e}", file=sys.stderr)
65
+ return
66
+
67
+ username = credentials["username"]
68
+ password = credentials["password"]
69
+ basic_auth = HTTPBasicAuth(username, password)
70
+
71
+ try:
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)
84
+
85
+
86
+ # Example usage
87
+ if __name__ == "__main__":
88
+ token = "test"
89
+
90
+ try:
91
+ validate_token(token)
92
+ print("Token is valid")
93
+ except TokenValidationError as e:
94
+ print(f"Token validation failed: {e}")
@@ -1,179 +0,0 @@
1
- import asyncio
2
- import os
3
- import sys
4
- from typing import Optional
5
-
6
- import httpx
7
- import nest_asyncio # type: ignore
8
- import requests
9
- from requests.auth import HTTPBasicAuth
10
-
11
- # Apply nest_asyncio for environments like Jupyter
12
- nest_asyncio.apply()
13
-
14
-
15
- class TokenValidationError(Exception):
16
- """
17
- Custom exception raised when the token validation fails.
18
- """
19
-
20
- def __init__(self, message: Optional[str] = None):
21
- """
22
- Initialize the exception with an optional message.
23
-
24
- Args:
25
- message (str, optional): The error message to display. Defaults to None.
26
- """
27
-
28
- super().__init__(message)
29
-
30
-
31
- def get_credentials() -> dict[str, str]:
32
- """
33
- Fetch the username and password from environment variables.
34
-
35
- Returns:
36
- dict: A dictionary containing 'username' and 'password'.
37
- """
38
-
39
- username = os.getenv("user_name_student")
40
- password = os.getenv("keys_student")
41
-
42
- if not username or not password:
43
- raise ValueError(
44
- "Environment variable 'user_name_student' or 'keys_student' not set"
45
- )
46
-
47
- return {"username": username, "password": password}
48
-
49
-
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
- def validate_token(token: Optional[str] = None) -> None:
130
- if token:
131
- os.environ["TOKEN"] = token # If token passed, set env var
132
- else:
133
- token = os.getenv("TOKEN") # Otherwise try to get from env
134
- if not token:
135
- print("Error: No token provided", file=sys.stderr)
136
- return
137
-
138
- # Get endpoint URL
139
- base_url = os.getenv("DB_URL")
140
- if not base_url:
141
- print("Error: Environment variable 'DB_URL' not set", file=sys.stderr)
142
- return
143
- endpoint = f"{base_url.rstrip('/')}/validate-token/{token}"
144
-
145
- # Get credentials
146
- try:
147
- credentials = get_credentials()
148
- except ValueError as e:
149
- print(f"Error: {e}", file=sys.stderr)
150
- return
151
-
152
- username = credentials["username"]
153
- password = credentials["password"]
154
- basic_auth = HTTPBasicAuth(username, password)
155
-
156
- try:
157
- response = requests.get(url=endpoint, auth=basic_auth, timeout=10)
158
- response.raise_for_status()
159
-
160
- detail = response.json().get("detail", response.text)
161
- print(detail)
162
- except requests.exceptions.HTTPError as e:
163
- detail = e.response.json().get("detail", e.response.text)
164
- print(f"Error: {detail}", file=sys.stderr)
165
- except requests.exceptions.RequestException as e:
166
- print(f"Error: Request failed: {e}", file=sys.stderr)
167
- except Exception as e:
168
- print(f"Unexpected error: {e}", file=sys.stderr)
169
-
170
-
171
- # Example usage
172
- if __name__ == "__main__":
173
- token = "test"
174
-
175
- try:
176
- validate_token(token)
177
- print("Token is valid")
178
- except TokenValidationError as e:
179
- print(f"Token validation failed: {e}")
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -22,10 +22,12 @@ include_package_data = True
22
22
  package_dir =
23
23
  =src
24
24
  install_requires =
25
+ httpx
25
26
  importlib-metadata; python_version<"3.8"
26
27
  ipython
27
28
  mypy
28
29
  nbformat
30
+ nest_asyncio
29
31
  numpy
30
32
  panel
31
33
  pynacl
@@ -38,8 +40,6 @@ install_requires =
38
40
  types-pyyaml
39
41
  types-requests
40
42
  types-setuptools
41
- httpx
42
- nest_asyncio
43
43
 
44
44
  [options.packages.find]
45
45
  where = src
File without changes
@@ -1,6 +1,8 @@
1
+ httpx
1
2
  ipython
2
3
  mypy
3
4
  nbformat
5
+ nest_asyncio
4
6
  numpy
5
7
  panel
6
8
  pynacl
@@ -13,8 +15,6 @@ types-python-dateutil
13
15
  types-pyyaml
14
16
  types-requests
15
17
  types-setuptools
16
- httpx
17
- nest_asyncio
18
18
 
19
19
  [:python_version < "3.8"]
20
20
  importlib-metadata
File without changes