locust 2.31.5.dev83__tar.gz → 2.31.6__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.
- {locust-2.31.5.dev83 → locust-2.31.6}/PKG-INFO +2 -2
- {locust-2.31.5.dev83 → locust-2.31.6}/README.md +1 -1
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/_version.py +2 -2
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/argument_parser.py +2 -1
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/clients.py +19 -19
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/contrib/fasthttp.py +10 -12
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/dispatch.py +5 -5
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/event.py +1 -1
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/main.py +6 -4
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/runners.py +3 -2
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/stats.py +1 -1
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/web.py +10 -5
- {locust-2.31.5.dev83 → locust-2.31.6}/poetry.lock +93 -85
- {locust-2.31.5.dev83 → locust-2.31.6}/pyproject.toml +3 -3
- {locust-2.31.5.dev83 → locust-2.31.6}/LICENSE +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/__init__.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/__main__.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/contrib/__init__.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/contrib/postgres.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/debug.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/env.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/exception.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/html.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/input_events.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/log.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/py.typed +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/rpc/__init__.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/rpc/protocol.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/rpc/zmqrpc.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/shape.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/user/__init__.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/user/inspectuser.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/user/sequential_taskset.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/user/task.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/user/users.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/user/wait_time.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/__init__.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/cache.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/date.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/deprecation.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/directory.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/exception_handler.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/load_locustfile.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/rounding.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/timespan.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/util/url.py +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/webui/dist/assets/favicon-dark.png +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/webui/dist/assets/favicon-light.png +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/webui/dist/assets/index-DQd3Odi5.js +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/webui/dist/auth.html +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/webui/dist/index.html +0 -0
- {locust-2.31.5.dev83 → locust-2.31.6}/locust/webui/dist/report.html +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: locust
|
3
|
-
Version: 2.31.
|
3
|
+
Version: 2.31.6
|
4
4
|
Summary: Developer-friendly load testing framework
|
5
5
|
Home-page: https://locust.io/
|
6
6
|
License: MIT
|
@@ -94,7 +94,7 @@ Locust makes it easy to run load tests distributed over multiple machines. It is
|
|
94
94
|
|
95
95
|
Locust has a user friendly web interface that shows the progress of your test in real-time. You can even change the load while the test is running. It can also be run without the UI, making it easy to use for CI/CD testing.
|
96
96
|
|
97
|
-
<img src="docs/images/
|
97
|
+
<img src="docs/images/bottlenecked_server.png" alt="Locust UI charts" height="100" width="200"/> <img src="docs/images/webui-running-statistics.png" alt="Locust UI stats" height="100" width="200"/> <img src="docs/images/locust_workers.png" alt="Locust UI workers" height="100" width="200"/> <img src="docs/images/webui-splash-screenshot.png" alt="Locust UI start test" height="100" width="200"/>
|
98
98
|
|
99
99
|
#### Can test any system
|
100
100
|
|
@@ -47,7 +47,7 @@ Locust makes it easy to run load tests distributed over multiple machines. It is
|
|
47
47
|
|
48
48
|
Locust has a user friendly web interface that shows the progress of your test in real-time. You can even change the load while the test is running. It can also be run without the UI, making it easy to use for CI/CD testing.
|
49
49
|
|
50
|
-
<img src="docs/images/
|
50
|
+
<img src="docs/images/bottlenecked_server.png" alt="Locust UI charts" height="100" width="200"/> <img src="docs/images/webui-running-statistics.png" alt="Locust UI stats" height="100" width="200"/> <img src="docs/images/locust_workers.png" alt="Locust UI workers" height="100" width="200"/> <img src="docs/images/webui-splash-screenshot.png" alt="Locust UI start test" height="100" width="200"/>
|
51
51
|
|
52
52
|
#### Can test any system
|
53
53
|
|
@@ -14,7 +14,7 @@ __version_tuple__: VERSION_TUPLE
|
|
14
14
|
version_tuple: VERSION_TUPLE
|
15
15
|
|
16
16
|
|
17
|
-
__version__ = "2.31.
|
17
|
+
__version__ = "2.31.6"
|
18
18
|
version = __version__
|
19
|
-
__version_tuple__ = (2, 31,
|
19
|
+
__version_tuple__ = (2, 31, 6)
|
20
20
|
version_tuple = __version_tuple__
|
@@ -15,6 +15,7 @@ import tempfile
|
|
15
15
|
import textwrap
|
16
16
|
from collections import OrderedDict
|
17
17
|
from typing import Any, NamedTuple
|
18
|
+
from urllib.parse import urlparse
|
18
19
|
from uuid import uuid4
|
19
20
|
|
20
21
|
if sys.version_info >= (3, 11):
|
@@ -159,7 +160,7 @@ def download_locustfile_from_url(url: str) -> str:
|
|
159
160
|
sys.stderr.write(f"Failed to get locustfile from: {url}. Response is not valid python code.")
|
160
161
|
sys.exit(1)
|
161
162
|
|
162
|
-
with open(os.path.join(tempfile.gettempdir(), url.
|
163
|
+
with open(os.path.join(tempfile.gettempdir(), urlparse(url).path.split("/")[-1]), "w") as locustfile:
|
163
164
|
locustfile.write(response.text)
|
164
165
|
|
165
166
|
atexit.register(exit_handler, locustfile.name)
|
@@ -31,11 +31,11 @@ if TYPE_CHECKING:
|
|
31
31
|
# Mypy underneath uses information from the https://github.com/python/typeshed repo.
|
32
32
|
|
33
33
|
class RequestKwargs(TypedDict, total=False):
|
34
|
-
params: Any
|
34
|
+
params: Any # simplified signature
|
35
35
|
headers: Mapping[str, str | bytes | None] | None
|
36
36
|
cookies: RequestsCookieJar | MutableMapping[str, str] | None
|
37
|
-
files: Any
|
38
|
-
auth: Any
|
37
|
+
files: Any # simplified signature
|
38
|
+
auth: Any # simplified signature
|
39
39
|
timeout: float | tuple[float, float] | tuple[float, None] | None
|
40
40
|
allow_redirects: bool
|
41
41
|
proxies: MutableMapping[str, str] | None
|
@@ -122,7 +122,7 @@ class HttpSession(requests.Session):
|
|
122
122
|
return f"{self.base_url}{path}"
|
123
123
|
|
124
124
|
@contextmanager
|
125
|
-
def rename_request(self, name: str) -> Generator[None
|
125
|
+
def rename_request(self, name: str) -> Generator[None]:
|
126
126
|
"""Group requests using the "with" keyword"""
|
127
127
|
|
128
128
|
self.request_name = name
|
@@ -139,8 +139,8 @@ class HttpSession(requests.Session):
|
|
139
139
|
catch_response: bool = False,
|
140
140
|
context: dict = {},
|
141
141
|
*,
|
142
|
-
data: Any
|
143
|
-
json: Any
|
142
|
+
data: Any = None,
|
143
|
+
json: Any = None,
|
144
144
|
**kwargs: Unpack[RequestKwargs],
|
145
145
|
):
|
146
146
|
"""
|
@@ -245,7 +245,7 @@ class HttpSession(requests.Session):
|
|
245
245
|
return r
|
246
246
|
|
247
247
|
def get(
|
248
|
-
self, url: str | bytes, *, data: Any
|
248
|
+
self, url: str | bytes, *, data: Any = None, json: Any = None, **kwargs: Unpack[RESTKwargs]
|
249
249
|
) -> ResponseContextManager | Response | LocustResponse:
|
250
250
|
"""Sends a GET request"""
|
251
251
|
kwargs.setdefault("allow_redirects", True)
|
@@ -255,8 +255,8 @@ class HttpSession(requests.Session):
|
|
255
255
|
self,
|
256
256
|
url: str | bytes,
|
257
257
|
*,
|
258
|
-
data: Any
|
259
|
-
json: Any
|
258
|
+
data: Any = None,
|
259
|
+
json: Any = None,
|
260
260
|
**kwargs: Unpack[RESTKwargs],
|
261
261
|
) -> ResponseContextManager | Response | LocustResponse:
|
262
262
|
"""Sends a OPTIONS request"""
|
@@ -267,8 +267,8 @@ class HttpSession(requests.Session):
|
|
267
267
|
self,
|
268
268
|
url: str | bytes,
|
269
269
|
*,
|
270
|
-
data: Any
|
271
|
-
json: Any
|
270
|
+
data: Any = None,
|
271
|
+
json: Any = None,
|
272
272
|
**kwargs: Unpack[RESTKwargs],
|
273
273
|
) -> ResponseContextManager | Response | LocustResponse:
|
274
274
|
"""Sends a HEAD request"""
|
@@ -278,8 +278,8 @@ class HttpSession(requests.Session):
|
|
278
278
|
def post(
|
279
279
|
self,
|
280
280
|
url: str | bytes,
|
281
|
-
data: Any
|
282
|
-
json: Any
|
281
|
+
data: Any = None,
|
282
|
+
json: Any = None,
|
283
283
|
**kwargs: Unpack[RESTKwargs],
|
284
284
|
) -> ResponseContextManager | Response | LocustResponse:
|
285
285
|
"""Sends a POST request"""
|
@@ -288,9 +288,9 @@ class HttpSession(requests.Session):
|
|
288
288
|
def put(
|
289
289
|
self,
|
290
290
|
url: str | bytes,
|
291
|
-
data: Any
|
291
|
+
data: Any = None,
|
292
292
|
*,
|
293
|
-
json: Any
|
293
|
+
json: Any = None,
|
294
294
|
**kwargs: Unpack[RESTKwargs],
|
295
295
|
) -> ResponseContextManager | Response | LocustResponse:
|
296
296
|
"""Sends a PUT request"""
|
@@ -299,9 +299,9 @@ class HttpSession(requests.Session):
|
|
299
299
|
def patch(
|
300
300
|
self,
|
301
301
|
url: str | bytes,
|
302
|
-
data: Any
|
302
|
+
data: Any = None,
|
303
303
|
*,
|
304
|
-
json: Any
|
304
|
+
json: Any = None,
|
305
305
|
**kwargs: Unpack[RESTKwargs],
|
306
306
|
) -> ResponseContextManager | Response | LocustResponse:
|
307
307
|
"""Sends a PATCH request"""
|
@@ -311,8 +311,8 @@ class HttpSession(requests.Session):
|
|
311
311
|
self,
|
312
312
|
url: str | bytes,
|
313
313
|
*,
|
314
|
-
data: Any
|
315
|
-
json: Any
|
314
|
+
data: Any = None,
|
315
|
+
json: Any = None,
|
316
316
|
**kwargs: Unpack[RESTKwargs],
|
317
317
|
) -> ResponseContextManager | Response | LocustResponse:
|
318
318
|
"""Sends a DELETE request"""
|
@@ -34,7 +34,7 @@ from requests.utils import get_encoding_from_headers
|
|
34
34
|
if TYPE_CHECKING:
|
35
35
|
import sys
|
36
36
|
from collections.abc import Callable, Generator
|
37
|
-
from typing import TypedDict
|
37
|
+
from typing import Any, TypedDict
|
38
38
|
|
39
39
|
if sys.version_info >= (3, 11):
|
40
40
|
from typing import Unpack
|
@@ -51,14 +51,14 @@ if TYPE_CHECKING:
|
|
51
51
|
context: dict
|
52
52
|
|
53
53
|
class PutKwargs(PostKwargs, total=False):
|
54
|
-
json:
|
54
|
+
json: Any
|
55
55
|
|
56
56
|
class PatchKwargs(PostKwargs, total=False):
|
57
|
-
json:
|
57
|
+
json: Any
|
58
58
|
|
59
59
|
class RESTKwargs(PostKwargs, total=False):
|
60
60
|
data: str | dict | None
|
61
|
-
json:
|
61
|
+
json: Any
|
62
62
|
|
63
63
|
|
64
64
|
# Monkey patch geventhttpclient.useragent.CompatRequest so that Cookiejar works with Python >= 3.3
|
@@ -185,7 +185,7 @@ class FastHttpSession:
|
|
185
185
|
stream: bool = False,
|
186
186
|
headers: dict | None = None,
|
187
187
|
auth: tuple[str | bytes, str | bytes] | None = None,
|
188
|
-
json:
|
188
|
+
json: Any = None,
|
189
189
|
allow_redirects: bool = True,
|
190
190
|
context: dict = {},
|
191
191
|
**kwargs,
|
@@ -205,9 +205,9 @@ class FastHttpSession:
|
|
205
205
|
return a context manager to work as argument to a with statement. This will allow the
|
206
206
|
request to be marked as a fail based on the content of the response, even if the response
|
207
207
|
code is ok (2xx). The opposite also works, one can use catch_response to catch a request
|
208
|
-
and then mark it as successful even if the response code was not (i.e 500 or 404).
|
208
|
+
and then mark it as successful even if the response code was not (i.e. 500 or 404).
|
209
209
|
:param data: (optional) String/bytes to send in the body of the request.
|
210
|
-
:param json: (optional)
|
210
|
+
:param json: (optional) Json to send in the body of the request.
|
211
211
|
Automatically sets Content-Type and Accept headers to "application/json".
|
212
212
|
Only used if data is not set.
|
213
213
|
:param headers: (optional) Dictionary of HTTP Headers to send with the request.
|
@@ -316,7 +316,7 @@ class FastHttpSession:
|
|
316
316
|
return self.request("PATCH", url, data=data, **kwargs)
|
317
317
|
|
318
318
|
def post(
|
319
|
-
self, url: str, data: str | dict | None = None, json:
|
319
|
+
self, url: str, data: str | dict | None = None, json: Any = None, **kwargs: Unpack[PostKwargs]
|
320
320
|
) -> ResponseContextManager | FastResponse:
|
321
321
|
"""Sends a POST request"""
|
322
322
|
return self.request("POST", url, data=data, json=json, **kwargs)
|
@@ -407,9 +407,7 @@ class FastHttpUser(User):
|
|
407
407
|
"""
|
408
408
|
|
409
409
|
@contextmanager
|
410
|
-
def rest(
|
411
|
-
self, method, url, headers: dict | None = None, **kwargs
|
412
|
-
) -> Generator[RestResponseContextManager, None, None]:
|
410
|
+
def rest(self, method, url, headers: dict | None = None, **kwargs) -> Generator[RestResponseContextManager]:
|
413
411
|
"""
|
414
412
|
A wrapper for self.client.request that:
|
415
413
|
|
@@ -457,7 +455,7 @@ class FastHttpUser(User):
|
|
457
455
|
resp.failure(f"{e.__class__.__name__}: {e} at {', '.join(error_lines)}. Response was {short_resp}")
|
458
456
|
|
459
457
|
@contextmanager
|
460
|
-
def rest_(self, method, url, name=None, **kwargs) -> Generator[RestResponseContextManager
|
458
|
+
def rest_(self, method, url, name=None, **kwargs) -> Generator[RestResponseContextManager]:
|
461
459
|
"""
|
462
460
|
Some REST api:s use a timestamp as part of their query string (mainly to break through caches).
|
463
461
|
This is a convenience method for that, appending a _=<timestamp> parameter automatically
|
@@ -23,13 +23,13 @@ if TYPE_CHECKING:
|
|
23
23
|
T = TypeVar("T")
|
24
24
|
|
25
25
|
|
26
|
-
def _kl_generator(users: Iterable[tuple[T, float]]) ->
|
26
|
+
def _kl_generator(users: Iterable[tuple[T, float]]) -> Generator[T | None]:
|
27
27
|
"""Generator based on Kullback-Leibler divergence
|
28
28
|
|
29
29
|
For example, given users A, B with weights 5 and 1 respectively,
|
30
30
|
this algorithm will yield AAABAAAAABAA.
|
31
31
|
"""
|
32
|
-
heap = [(x * log2(x / (x + 1.0)), x + 1.0, x, name) for name, x in users]
|
32
|
+
heap = [(x * log2(x / (x + 1.0)), x + 1.0, x, name) for name, x in users if x > 0]
|
33
33
|
if not heap:
|
34
34
|
while True:
|
35
35
|
yield None
|
@@ -97,7 +97,7 @@ class UsersDispatcher(Iterator):
|
|
97
97
|
|
98
98
|
self._current_user_count = self.get_current_user_count()
|
99
99
|
|
100
|
-
self._dispatcher_generator: Generator[dict[str, dict[str, int]]
|
100
|
+
self._dispatcher_generator: Generator[dict[str, dict[str, int]]] = None # type: ignore
|
101
101
|
# a generator is assigned (in new_dispatch()) to _dispatcher_generator before it's used
|
102
102
|
|
103
103
|
self._user_generator = self._user_gen()
|
@@ -149,7 +149,7 @@ class UsersDispatcher(Iterator):
|
|
149
149
|
# Sort again, first by index within host, to ensure Users get started evenly across hosts
|
150
150
|
self._worker_nodes = sorted(self._worker_nodes, key=lambda worker: (worker._index_within_host, worker.id))
|
151
151
|
|
152
|
-
def _dispatcher(self) -> Generator[dict[str, dict[str, int]]
|
152
|
+
def _dispatcher(self) -> Generator[dict[str, dict[str, int]]]:
|
153
153
|
self._dispatch_in_progress = True
|
154
154
|
|
155
155
|
if self._rebalance:
|
@@ -268,7 +268,7 @@ class UsersDispatcher(Iterator):
|
|
268
268
|
self._rebalance = True
|
269
269
|
|
270
270
|
@contextlib.contextmanager
|
271
|
-
def _wait_between_dispatch_iteration_context(self) -> Generator[None
|
271
|
+
def _wait_between_dispatch_iteration_context(self) -> Generator[None]:
|
272
272
|
t0_rel = time.perf_counter()
|
273
273
|
|
274
274
|
# We don't use `try: ... finally: ...` because we don't want to sleep
|
@@ -56,7 +56,7 @@ class EventHook:
|
|
56
56
|
@contextmanager
|
57
57
|
def measure(
|
58
58
|
self, request_type: str, name: str, response_length: int = 0, context=None
|
59
|
-
) -> Generator[dict[str, Any]
|
59
|
+
) -> Generator[dict[str, Any]]:
|
60
60
|
"""Convenience method for firing the event with automatically calculated response time and automatically marking the request as failed if an exception is raised (this is really only useful for the *request* event)
|
61
61
|
|
62
62
|
Example usage (in a task):
|
@@ -39,12 +39,14 @@ from .util.timespan import parse_timespan
|
|
39
39
|
# import external plugins if installed to allow for registering custom arguments etc
|
40
40
|
try:
|
41
41
|
import locust_plugins # pyright: ignore[reportMissingImports]
|
42
|
-
except ModuleNotFoundError:
|
43
|
-
|
42
|
+
except ModuleNotFoundError as e:
|
43
|
+
if e.msg != "No module named 'locust_plugins'":
|
44
|
+
raise
|
44
45
|
try:
|
45
46
|
import locust_cloud # pyright: ignore[reportMissingImports]
|
46
|
-
except ModuleNotFoundError:
|
47
|
-
|
47
|
+
except ModuleNotFoundError as e:
|
48
|
+
if e.msg != "No module named 'locust_cloud'":
|
49
|
+
raise
|
48
50
|
|
49
51
|
version = locust.__version__
|
50
52
|
|
@@ -305,7 +305,7 @@ class Runner:
|
|
305
305
|
) -> None: ...
|
306
306
|
|
307
307
|
@abstractmethod
|
308
|
-
def send_message(self, msg_type: str, data: Any
|
308
|
+
def send_message(self, msg_type: str, data: Any = None, client_id: str | None = None) -> None: ...
|
309
309
|
|
310
310
|
def start_shape(self) -> None:
|
311
311
|
"""
|
@@ -437,6 +437,7 @@ class LocalRunner(Runner):
|
|
437
437
|
# but it makes it easier to write tests that work for both local and distributed runs
|
438
438
|
self.worker_index = 0
|
439
439
|
self.client_id = socket.gethostname() + "_" + uuid4().hex
|
440
|
+
self.worker_count = 1
|
440
441
|
# Only when running in standalone mode (non-distributed)
|
441
442
|
self._local_worker_node = WorkerNode(id="local")
|
442
443
|
self._local_worker_node.user_classes_count = self.user_classes_count
|
@@ -550,7 +551,7 @@ class LocalRunner(Runner):
|
|
550
551
|
return
|
551
552
|
super().stop()
|
552
553
|
|
553
|
-
def send_message(self, msg_type: str, data: Any
|
554
|
+
def send_message(self, msg_type: str, data: Any = None, client_id: str | None = None) -> None:
|
554
555
|
"""
|
555
556
|
Emulates internodal messaging by calling registered listeners
|
556
557
|
|
@@ -739,7 +739,7 @@ class StatsError:
|
|
739
739
|
return f"{self.method} {self.name}: {unwrapped_error}"
|
740
740
|
|
741
741
|
def serialize(self) -> StatsErrorDict:
|
742
|
-
def _getattr(obj: StatsError, key: str, default: Any
|
742
|
+
def _getattr(obj: StatsError, key: str, default: Any) -> Any:
|
743
743
|
value = getattr(obj, key, default)
|
744
744
|
|
745
745
|
if key in ["error"]:
|
@@ -135,11 +135,6 @@ class WebUI:
|
|
135
135
|
# ensures static js files work on Windows
|
136
136
|
mimetypes.add_type("application/javascript", ".js")
|
137
137
|
|
138
|
-
if self.web_login:
|
139
|
-
self.login_manager = LoginManager()
|
140
|
-
self.login_manager.init_app(app)
|
141
|
-
self.login_manager.login_view = "login"
|
142
|
-
|
143
138
|
if environment.runner:
|
144
139
|
self.update_template_args()
|
145
140
|
if not delayed_start:
|
@@ -518,6 +513,16 @@ class WebUI:
|
|
518
513
|
|
519
514
|
return {}, 201
|
520
515
|
|
516
|
+
@property
|
517
|
+
def login_manager(self):
|
518
|
+
if self.web_login:
|
519
|
+
login_manager = LoginManager()
|
520
|
+
login_manager.init_app(self.app)
|
521
|
+
login_manager.login_view = "login"
|
522
|
+
return login_manager
|
523
|
+
|
524
|
+
raise AttributeError("The login_manager is only available with --web-login.\n")
|
525
|
+
|
521
526
|
def start(self):
|
522
527
|
self.greenlet = gevent.spawn(self.start_server)
|
523
528
|
self.greenlet.link_exception(greenlet_exception_handler)
|
@@ -156,13 +156,13 @@ files = [
|
|
156
156
|
|
157
157
|
[[package]]
|
158
158
|
name = "certifi"
|
159
|
-
version = "2024.
|
159
|
+
version = "2024.8.30"
|
160
160
|
description = "Python package for providing Mozilla's CA Bundle."
|
161
161
|
optional = false
|
162
162
|
python-versions = ">=3.6"
|
163
163
|
files = [
|
164
|
-
{file = "certifi-2024.
|
165
|
-
{file = "certifi-2024.
|
164
|
+
{file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
|
165
|
+
{file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
|
166
166
|
]
|
167
167
|
|
168
168
|
[[package]]
|
@@ -544,13 +544,13 @@ dotenv = ["python-dotenv"]
|
|
544
544
|
|
545
545
|
[[package]]
|
546
546
|
name = "flask-cors"
|
547
|
-
version = "
|
547
|
+
version = "5.0.0"
|
548
548
|
description = "A Flask extension adding a decorator for CORS support"
|
549
549
|
optional = false
|
550
550
|
python-versions = "*"
|
551
551
|
files = [
|
552
|
-
{file = "Flask_Cors-
|
553
|
-
{file = "flask_cors-
|
552
|
+
{file = "Flask_Cors-5.0.0-py2.py3-none-any.whl", hash = "sha256:b9e307d082a9261c100d8fb0ba909eec6a228ed1b60a8315fd85f783d61910bc"},
|
553
|
+
{file = "flask_cors-5.0.0.tar.gz", hash = "sha256:5aadb4b950c4e93745034594d9f3ea6591f734bb3662e16e255ffbf5e89c88ef"},
|
554
554
|
]
|
555
555
|
|
556
556
|
[package.dependencies]
|
@@ -1320,44 +1320,44 @@ files = [
|
|
1320
1320
|
|
1321
1321
|
[[package]]
|
1322
1322
|
name = "mypy"
|
1323
|
-
version = "1.
|
1323
|
+
version = "1.11.2"
|
1324
1324
|
description = "Optional static typing for Python"
|
1325
1325
|
optional = false
|
1326
1326
|
python-versions = ">=3.8"
|
1327
1327
|
files = [
|
1328
|
-
{file = "mypy-1.
|
1329
|
-
{file = "mypy-1.
|
1330
|
-
{file = "mypy-1.
|
1331
|
-
{file = "mypy-1.
|
1332
|
-
{file = "mypy-1.
|
1333
|
-
{file = "mypy-1.
|
1334
|
-
{file = "mypy-1.
|
1335
|
-
{file = "mypy-1.
|
1336
|
-
{file = "mypy-1.
|
1337
|
-
{file = "mypy-1.
|
1338
|
-
{file = "mypy-1.
|
1339
|
-
{file = "mypy-1.
|
1340
|
-
{file = "mypy-1.
|
1341
|
-
{file = "mypy-1.
|
1342
|
-
{file = "mypy-1.
|
1343
|
-
{file = "mypy-1.
|
1344
|
-
{file = "mypy-1.
|
1345
|
-
{file = "mypy-1.
|
1346
|
-
{file = "mypy-1.
|
1347
|
-
{file = "mypy-1.
|
1348
|
-
{file = "mypy-1.
|
1349
|
-
{file = "mypy-1.
|
1350
|
-
{file = "mypy-1.
|
1351
|
-
{file = "mypy-1.
|
1352
|
-
{file = "mypy-1.
|
1353
|
-
{file = "mypy-1.
|
1354
|
-
{file = "mypy-1.
|
1328
|
+
{file = "mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a"},
|
1329
|
+
{file = "mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef"},
|
1330
|
+
{file = "mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383"},
|
1331
|
+
{file = "mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8"},
|
1332
|
+
{file = "mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7"},
|
1333
|
+
{file = "mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385"},
|
1334
|
+
{file = "mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca"},
|
1335
|
+
{file = "mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104"},
|
1336
|
+
{file = "mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4"},
|
1337
|
+
{file = "mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6"},
|
1338
|
+
{file = "mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318"},
|
1339
|
+
{file = "mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36"},
|
1340
|
+
{file = "mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987"},
|
1341
|
+
{file = "mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca"},
|
1342
|
+
{file = "mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70"},
|
1343
|
+
{file = "mypy-1.11.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b"},
|
1344
|
+
{file = "mypy-1.11.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86"},
|
1345
|
+
{file = "mypy-1.11.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce"},
|
1346
|
+
{file = "mypy-1.11.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1"},
|
1347
|
+
{file = "mypy-1.11.2-cp38-cp38-win_amd64.whl", hash = "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b"},
|
1348
|
+
{file = "mypy-1.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6"},
|
1349
|
+
{file = "mypy-1.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70"},
|
1350
|
+
{file = "mypy-1.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"},
|
1351
|
+
{file = "mypy-1.11.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d"},
|
1352
|
+
{file = "mypy-1.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24"},
|
1353
|
+
{file = "mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12"},
|
1354
|
+
{file = "mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79"},
|
1355
1355
|
]
|
1356
1356
|
|
1357
1357
|
[package.dependencies]
|
1358
1358
|
mypy-extensions = ">=1.0.0"
|
1359
1359
|
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
1360
|
-
typing-extensions = ">=4.
|
1360
|
+
typing-extensions = ">=4.6.0"
|
1361
1361
|
|
1362
1362
|
[package.extras]
|
1363
1363
|
dmypy = ["psutil (>=4.0)"]
|
@@ -1572,13 +1572,13 @@ testing = ["covdefaults (>=2.3)", "pytest (>=8.2.2)", "pytest-cov (>=5)", "pytes
|
|
1572
1572
|
|
1573
1573
|
[[package]]
|
1574
1574
|
name = "pyquery"
|
1575
|
-
version = "2.0.
|
1575
|
+
version = "2.0.1"
|
1576
1576
|
description = "A jquery-like library for python"
|
1577
1577
|
optional = false
|
1578
1578
|
python-versions = "*"
|
1579
1579
|
files = [
|
1580
|
-
{file = "pyquery-2.0.
|
1581
|
-
{file = "pyquery-2.0.
|
1580
|
+
{file = "pyquery-2.0.1-py3-none-any.whl", hash = "sha256:aedfa0bd0eb9afc94b3ddbec8f375a6362b32bc9662f46e3e0d866483f4771b0"},
|
1581
|
+
{file = "pyquery-2.0.1.tar.gz", hash = "sha256:0194bb2706b12d037db12c51928fe9ebb36b72d9e719565daba5a6c595322faf"},
|
1582
1582
|
]
|
1583
1583
|
|
1584
1584
|
[package.dependencies]
|
@@ -1901,13 +1901,13 @@ idna2008 = ["idna"]
|
|
1901
1901
|
|
1902
1902
|
[[package]]
|
1903
1903
|
name = "rich"
|
1904
|
-
version = "13.
|
1904
|
+
version = "13.8.0"
|
1905
1905
|
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
1906
1906
|
optional = false
|
1907
1907
|
python-versions = ">=3.7.0"
|
1908
1908
|
files = [
|
1909
|
-
{file = "rich-13.
|
1910
|
-
{file = "rich-13.
|
1909
|
+
{file = "rich-13.8.0-py3-none-any.whl", hash = "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc"},
|
1910
|
+
{file = "rich-13.8.0.tar.gz", hash = "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"},
|
1911
1911
|
]
|
1912
1912
|
|
1913
1913
|
[package.dependencies]
|
@@ -1960,19 +1960,23 @@ jeepney = ">=0.6"
|
|
1960
1960
|
|
1961
1961
|
[[package]]
|
1962
1962
|
name = "setuptools"
|
1963
|
-
version = "
|
1963
|
+
version = "74.1.1"
|
1964
1964
|
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
1965
1965
|
optional = false
|
1966
1966
|
python-versions = ">=3.8"
|
1967
1967
|
files = [
|
1968
|
-
{file = "setuptools-
|
1969
|
-
{file = "setuptools-
|
1968
|
+
{file = "setuptools-74.1.1-py3-none-any.whl", hash = "sha256:fc91b5f89e392ef5b77fe143b17e32f65d3024744fba66dc3afe07201684d766"},
|
1969
|
+
{file = "setuptools-74.1.1.tar.gz", hash = "sha256:2353af060c06388be1cecbf5953dcdb1f38362f87a2356c480b6b4d5fcfc8847"},
|
1970
1970
|
]
|
1971
1971
|
|
1972
1972
|
[package.extras]
|
1973
|
+
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
|
1973
1974
|
core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
|
1975
|
+
cover = ["pytest-cov"]
|
1974
1976
|
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
|
1975
|
-
|
1977
|
+
enabler = ["pytest-enabler (>=2.2)"]
|
1978
|
+
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
|
1979
|
+
type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
|
1976
1980
|
|
1977
1981
|
[[package]]
|
1978
1982
|
name = "snowballstemmer"
|
@@ -2318,18 +2322,22 @@ watchdog = ["watchdog (>=2.3)"]
|
|
2318
2322
|
|
2319
2323
|
[[package]]
|
2320
2324
|
name = "zipp"
|
2321
|
-
version = "3.20.
|
2325
|
+
version = "3.20.1"
|
2322
2326
|
description = "Backport of pathlib-compatible object wrapper for zip files"
|
2323
2327
|
optional = false
|
2324
2328
|
python-versions = ">=3.8"
|
2325
2329
|
files = [
|
2326
|
-
{file = "zipp-3.20.
|
2327
|
-
{file = "zipp-3.20.
|
2330
|
+
{file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"},
|
2331
|
+
{file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"},
|
2328
2332
|
]
|
2329
2333
|
|
2330
2334
|
[package.extras]
|
2335
|
+
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
|
2336
|
+
cover = ["pytest-cov"]
|
2331
2337
|
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
2332
|
-
|
2338
|
+
enabler = ["pytest-enabler (>=2.2)"]
|
2339
|
+
test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
|
2340
|
+
type = ["pytest-mypy"]
|
2333
2341
|
|
2334
2342
|
[[package]]
|
2335
2343
|
name = "zope-event"
|
@@ -2351,45 +2359,45 @@ test = ["zope.testrunner"]
|
|
2351
2359
|
|
2352
2360
|
[[package]]
|
2353
2361
|
name = "zope-interface"
|
2354
|
-
version = "7.0.
|
2362
|
+
version = "7.0.3"
|
2355
2363
|
description = "Interfaces for Python"
|
2356
2364
|
optional = false
|
2357
2365
|
python-versions = ">=3.8"
|
2358
2366
|
files = [
|
2359
|
-
{file = "zope.interface-7.0.
|
2360
|
-
{file = "zope.interface-7.0.
|
2361
|
-
{file = "zope.interface-7.0.
|
2362
|
-
{file = "zope.interface-7.0.
|
2363
|
-
{file = "zope.interface-7.0.
|
2364
|
-
{file = "zope.interface-7.0.
|
2365
|
-
{file = "zope.interface-7.0.
|
2366
|
-
{file = "zope.interface-7.0.
|
2367
|
-
{file = "zope.interface-7.0.
|
2368
|
-
{file = "zope.interface-7.0.
|
2369
|
-
{file = "zope.interface-7.0.
|
2370
|
-
{file = "zope.interface-7.0.
|
2371
|
-
{file = "zope.interface-7.0.
|
2372
|
-
{file = "zope.interface-7.0.
|
2373
|
-
{file = "zope.interface-7.0.
|
2374
|
-
{file = "zope.interface-7.0.
|
2375
|
-
{file = "zope.interface-7.0.
|
2376
|
-
{file = "zope.interface-7.0.
|
2377
|
-
{file = "zope.interface-7.0.
|
2378
|
-
{file = "zope.interface-7.0.
|
2379
|
-
{file = "zope.interface-7.0.
|
2380
|
-
{file = "zope.interface-7.0.
|
2381
|
-
{file = "zope.interface-7.0.
|
2382
|
-
{file = "zope.interface-7.0.
|
2383
|
-
{file = "zope.interface-7.0.
|
2384
|
-
{file = "zope.interface-7.0.
|
2385
|
-
{file = "zope.interface-7.0.
|
2386
|
-
{file = "zope.interface-7.0.
|
2387
|
-
{file = "zope.interface-7.0.
|
2388
|
-
{file = "zope.interface-7.0.
|
2389
|
-
{file = "zope.interface-7.0.
|
2390
|
-
{file = "zope.interface-7.0.
|
2391
|
-
{file = "zope.interface-7.0.
|
2392
|
-
{file = "zope.interface-7.0.
|
2367
|
+
{file = "zope.interface-7.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b9369671a20b8d039b8e5a1a33abd12e089e319a3383b4cc0bf5c67bd05fe7b"},
|
2368
|
+
{file = "zope.interface-7.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db6237e8fa91ea4f34d7e2d16d74741187e9105a63bbb5686c61fea04cdbacca"},
|
2369
|
+
{file = "zope.interface-7.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53d678bb1c3b784edbfb0adeebfeea6bf479f54da082854406a8f295d36f8386"},
|
2370
|
+
{file = "zope.interface-7.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3aa8fcbb0d3c2be1bfd013a0f0acd636f6ed570c287743ae2bbd467ee967154d"},
|
2371
|
+
{file = "zope.interface-7.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6195c3c03fef9f87c0dbee0b3b6451df6e056322463cf35bca9a088e564a3c58"},
|
2372
|
+
{file = "zope.interface-7.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:11fa1382c3efb34abf16becff8cb214b0b2e3144057c90611621f2d186b7e1b7"},
|
2373
|
+
{file = "zope.interface-7.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:af94e429f9d57b36e71ef4e6865182090648aada0cb2d397ae2b3f7fc478493a"},
|
2374
|
+
{file = "zope.interface-7.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dd647fcd765030638577fe6984284e0ebba1a1008244c8a38824be096e37fe3"},
|
2375
|
+
{file = "zope.interface-7.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bee1b722077d08721005e8da493ef3adf0b7908e0cd85cc7dc836ac117d6f32"},
|
2376
|
+
{file = "zope.interface-7.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2545d6d7aac425d528cd9bf0d9e55fcd47ab7fd15f41a64b1c4bf4c6b24946dc"},
|
2377
|
+
{file = "zope.interface-7.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d04b11ea47c9c369d66340dbe51e9031df2a0de97d68f442305ed7625ad6493"},
|
2378
|
+
{file = "zope.interface-7.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:064ade95cb54c840647205987c7b557f75d2b2f7d1a84bfab4cf81822ef6e7d1"},
|
2379
|
+
{file = "zope.interface-7.0.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3fcdc76d0cde1c09c37b7c6b0f8beba2d857d8417b055d4f47df9c34ec518bdd"},
|
2380
|
+
{file = "zope.interface-7.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3d4b91821305c8d8f6e6207639abcbdaf186db682e521af7855d0bea3047c8ca"},
|
2381
|
+
{file = "zope.interface-7.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35062d93bc49bd9b191331c897a96155ffdad10744ab812485b6bad5b588d7e4"},
|
2382
|
+
{file = "zope.interface-7.0.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c96b3e6b0d4f6ddfec4e947130ec30bd2c7b19db6aa633777e46c8eecf1d6afd"},
|
2383
|
+
{file = "zope.interface-7.0.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e0c151a6c204f3830237c59ee4770cc346868a7a1af6925e5e38650141a7f05"},
|
2384
|
+
{file = "zope.interface-7.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:3de1d553ce72868b77a7e9d598c9bff6d3816ad2b4cc81c04f9d8914603814f3"},
|
2385
|
+
{file = "zope.interface-7.0.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab985c566a99cc5f73bc2741d93f1ed24a2cc9da3890144d37b9582965aff996"},
|
2386
|
+
{file = "zope.interface-7.0.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d976fa7b5faf5396eb18ce6c132c98e05504b52b60784e3401f4ef0b2e66709b"},
|
2387
|
+
{file = "zope.interface-7.0.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a207c6b2c58def5011768140861a73f5240f4f39800625072ba84e76c9da0b"},
|
2388
|
+
{file = "zope.interface-7.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:382d31d1e68877061daaa6499468e9eb38eb7625d4369b1615ac08d3860fe896"},
|
2389
|
+
{file = "zope.interface-7.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c4316a30e216f51acbd9fb318aa5af2e362b716596d82cbb92f9101c8f8d2e7"},
|
2390
|
+
{file = "zope.interface-7.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01e6e58078ad2799130c14a1d34ec89044ada0e1495329d72ee0407b9ae5100d"},
|
2391
|
+
{file = "zope.interface-7.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799ef7a444aebbad5a145c3b34bff012b54453cddbde3332d47ca07225792ea4"},
|
2392
|
+
{file = "zope.interface-7.0.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3b7ce6d46fb0e60897d62d1ff370790ce50a57d40a651db91a3dde74f73b738"},
|
2393
|
+
{file = "zope.interface-7.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:f418c88f09c3ba159b95a9d1cfcdbe58f208443abb1f3109f4b9b12fd60b187c"},
|
2394
|
+
{file = "zope.interface-7.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:84f8794bd59ca7d09d8fce43ae1b571be22f52748169d01a13d3ece8394d8b5b"},
|
2395
|
+
{file = "zope.interface-7.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7d92920416f31786bc1b2f34cc4fc4263a35a407425319572cbf96b51e835cd3"},
|
2396
|
+
{file = "zope.interface-7.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95e5913ec718010dc0e7c215d79a9683b4990e7026828eedfda5268e74e73e11"},
|
2397
|
+
{file = "zope.interface-7.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1eeeb92cb7d95c45e726e3c1afe7707919370addae7ed14f614e22217a536958"},
|
2398
|
+
{file = "zope.interface-7.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd32f30f40bfd8511b17666895831a51b532e93fc106bfa97f366589d3e4e0e"},
|
2399
|
+
{file = "zope.interface-7.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:5112c530fa8aa2108a3196b9c2f078f5738c1c37cfc716970edc0df0414acda8"},
|
2400
|
+
{file = "zope.interface-7.0.3.tar.gz", hash = "sha256:cd2690d4b08ec9eaf47a85914fe513062b20da78d10d6d789a792c0b20307fb1"},
|
2393
2401
|
]
|
2394
2402
|
|
2395
2403
|
[package.dependencies]
|
@@ -2403,4 +2411,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
|
2403
2411
|
[metadata]
|
2404
2412
|
lock-version = "2.0"
|
2405
2413
|
python-versions = ">=3.9"
|
2406
|
-
content-hash = "
|
2414
|
+
content-hash = "a2280df028fb95370ecca314895950230c95c7d3b1c9d9f2339a4b874070cd44"
|
@@ -5,7 +5,7 @@ build-backend = "poetry_dynamic_versioning.backend"
|
|
5
5
|
[tool.poetry]
|
6
6
|
name = "locust"
|
7
7
|
description = "Developer-friendly load testing framework"
|
8
|
-
version = "2.31.
|
8
|
+
version = "2.31.6"
|
9
9
|
license = "MIT"
|
10
10
|
readme = "README.md"
|
11
11
|
authors = ["Jonatan Heyman", "Lars Holmberg"]
|
@@ -134,7 +134,7 @@ pywin32 = { version = "*", markers = "sys_platform == 'win32'" }
|
|
134
134
|
optional = true
|
135
135
|
|
136
136
|
[tool.poetry.group.dev.dependencies]
|
137
|
-
mypy = "1.
|
137
|
+
mypy = "1.11.2"
|
138
138
|
pre-commit = "^3.7.1"
|
139
139
|
ruff = "0.3.7"
|
140
140
|
tox = "^4.16.0"
|
@@ -147,7 +147,7 @@ optional = true
|
|
147
147
|
cryptography = "^42.0.8"
|
148
148
|
pyquery = "^2.0.0"
|
149
149
|
mock = "^5.1.0"
|
150
|
-
mypy = "1.
|
150
|
+
mypy = "1.11.2"
|
151
151
|
retry = "^0.9.2"
|
152
152
|
ruff = "0.3.7"
|
153
153
|
tox = "^4.16.0"
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|