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.
- {pykubegrader-0.2.29/src/PyKubeGrader.egg-info → pykubegrader-0.2.30}/PKG-INFO +3 -3
- {pykubegrader-0.2.29 → pykubegrader-0.2.30/src/PyKubeGrader.egg-info}/PKG-INFO +3 -3
- pykubegrader-0.2.30/src/pykubegrader/tokens/validate_token.py +94 -0
- pykubegrader-0.2.29/src/pykubegrader/tokens/validate_token.py +0 -179
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/.coveragerc +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/.github/workflows/main.yml +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/.gitignore +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/.readthedocs.yml +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/AUTHORS.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/CHANGELOG.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/CONTRIBUTING.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/LICENSE.txt +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/README.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/Makefile +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/_static/Drexel_blue_Logo_square_Dark.png +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/_static/Drexel_blue_Logo_square_Light.png +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/_static/custom.css +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/authors.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/changelog.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/conf.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/contributing.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/index.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/license.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/readme.rst +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/docs/requirements.txt +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/examples/.responses.json +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/examples/true_false.ipynb +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/pyproject.toml +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/setup.cfg +2 -2
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/setup.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/SOURCES.txt +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/dependency_links.txt +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/entry_points.txt +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/not-zip-safe +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/requires.txt +2 -2
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/PyKubeGrader.egg-info/top_level.txt +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/__init__.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/build/__init__.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/build/api_notebook_builder.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/build/build_folder.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/build/clean_folder.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/graders/__init__.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/graders/late_assignments.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/initialize.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/log_parser/__init__.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/log_parser/parse.ipynb +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/log_parser/parse.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/submit/submit_assignment.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/telemetry.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/tokens/tokens.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/utils.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/validate.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/__init__.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/multiple_choice.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/reading_question.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/select_many.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/student_info.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/style.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/true_false.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets/types_question.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets_base/__init__.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets_base/multi_select.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets_base/reading.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/src/pykubegrader/widgets_base/select.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/tests/conftest.py +0 -0
- {pykubegrader-0.2.29 → pykubegrader-0.2.30}/tests/import_test.py +0 -0
- {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.
|
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.
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
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
|
File without changes
|
File without changes
|
File without changes
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|