locust-cloud 1.2.12__py3-none-any.whl → 1.3.2__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.
locust_cloud/__init__.py CHANGED
@@ -2,6 +2,8 @@ import os
2
2
 
3
3
  os.environ["LOCUST_SKIP_MONKEY_PATCH"] = "1"
4
4
 
5
+ import argparse
6
+
5
7
  from locust import events
6
8
  from locust.argument_parser import LocustArgumentParser
7
9
  from locust_cloud.auth import register_auth
@@ -32,7 +34,7 @@ def add_arguments(parser: LocustArgumentParser):
32
34
  locust_cloud.add_argument(
33
35
  "--exporter",
34
36
  default=True,
35
- action="store_true",
37
+ action=argparse.BooleanOptionalAction,
36
38
  env_var="LOCUST_EXPORTER",
37
39
  help="Exports Locust stats to Timescale",
38
40
  )
locust_cloud/cloud.py CHANGED
@@ -92,7 +92,6 @@ parser.add_argument(
92
92
  env_var="LOCUST_USERS",
93
93
  )
94
94
  parser.add_argument(
95
- "-r",
96
95
  "--requirements",
97
96
  type=str,
98
97
  help="Optional requirements.txt file that contains your external libraries.",
@@ -169,6 +168,11 @@ parser.add_argument(
169
168
  env_var="LOCUST_CLOUD_WORKERS",
170
169
  default=None,
171
170
  )
171
+ parser.add_argument(
172
+ "--delete",
173
+ action="store_true",
174
+ help="Delete a running cluster. Useful if locust-cloud was killed/disconnected or if there was an error.",
175
+ )
172
176
 
173
177
  options, locust_options = parser.parse_known_args()
174
178
  options: Namespace
@@ -218,6 +222,10 @@ def main() -> None:
218
222
  aws_secret_access_key = credentials.get("secret_key")
219
223
  aws_session_token = credentials.get("token", "")
220
224
 
225
+ if options.delete:
226
+ delete(s3_bucket, credential_manager)
227
+ return
228
+
221
229
  logger.info(f"Uploading {options.locustfile}")
222
230
  s3 = credential_manager.session.client("s3")
223
231
  try:
@@ -257,7 +265,18 @@ def main() -> None:
257
265
  locust_env_variables = [
258
266
  {"name": env_variable, "value": str(os.environ[env_variable])}
259
267
  for env_variable in os.environ
260
- if env_variable.startswith("LOCUST_") and os.environ[env_variable]
268
+ if env_variable.startswith("LOCUST_")
269
+ and not env_variable.startswith("LOCUST_CLOUD")
270
+ and not env_variable
271
+ in [
272
+ "LOCUST_LOCUSTFILE",
273
+ "LOCUST_USERS",
274
+ "LOCUST_WEB_HOST_DISPLAY_NAME",
275
+ "LOCUST_API_BASE_URL",
276
+ "LOCUST_SKIP_MONKEY_PATCH",
277
+ "LOCUST_REQUIREMENTS_URL",
278
+ ]
279
+ and os.environ[env_variable]
261
280
  ]
262
281
  deploy_endpoint = f"{options.lambda_url}/{options.kube_cluster_name}"
263
282
  payload = {
@@ -289,9 +308,12 @@ def main() -> None:
289
308
  if response.status_code == 200:
290
309
  deployed_pods = response.json().get("pods", [])
291
310
  else:
292
- logger.error(
293
- f"HTTP {response.status_code}/{response.reason} - Response: {response.text} - URL: {response.request.url}"
294
- )
311
+ try:
312
+ logger.error(f"Error when deploying: {response.json()['Message']}")
313
+ except Exception:
314
+ logger.error(
315
+ f"HTTP {response.status_code}/{response.reason} - Response: {response.text} - URL: {response.request.url}"
316
+ )
295
317
  sys.exit(1)
296
318
  except CredentialError as ce:
297
319
  logger.error(f"Credential error: {ce}")
@@ -362,43 +384,47 @@ def main() -> None:
362
384
  logger.exception(e)
363
385
  sys.exit(1)
364
386
  finally:
365
- try:
366
- logger.info("Tearing down Locust cloud...")
367
- credential_manager.refresh_credentials()
368
- refreshed_credentials = credential_manager.get_current_credentials()
369
-
370
- headers = {
371
- "AWS_ACCESS_KEY_ID": refreshed_credentials.get("access_key", ""),
372
- "AWS_SECRET_ACCESS_KEY": refreshed_credentials.get("secret_key", ""),
373
- "Authorization": f"Bearer {refreshed_credentials.get('cognito_client_id_token', '')}",
374
- }
375
-
376
- token = refreshed_credentials.get("token")
377
- if token:
378
- headers["AWS_SESSION_TOKEN"] = token
379
-
380
- response = requests.delete(
381
- f"{options.lambda_url}/{options.kube_cluster_name}",
382
- headers=headers,
383
- params={"namespace": options.kube_namespace} if options.kube_namespace else {},
384
- )
387
+ delete(s3_bucket, credential_manager)
385
388
 
386
- if response.status_code != 200:
387
- logger.error(
388
- f"Could not automatically tear down Locust Cloud: HTTP {response.status_code}/{response.reason} - Response: {response.text} - URL: {response.request.url}"
389
- )
390
- except Exception as e:
391
- logger.error(f"Could not automatically tear down Locust Cloud: {e}")
392
389
 
393
- try:
394
- logger.info("Cleaning up locust files")
395
- s3 = credential_manager.session.resource("s3")
396
- bucket = s3.Bucket(s3_bucket)
397
- bucket.objects.all().delete()
398
- logger.info("Done! ✨")
399
- except ClientError as e:
400
- logger.error(f"Failed to clean up locust files: {e}")
401
- sys.exit(1)
390
+ def delete(s3_bucket, credential_manager):
391
+ try:
392
+ logger.info("Tearing down Locust cloud...")
393
+ credential_manager.refresh_credentials()
394
+ refreshed_credentials = credential_manager.get_current_credentials()
395
+
396
+ headers = {
397
+ "AWS_ACCESS_KEY_ID": refreshed_credentials.get("access_key", ""),
398
+ "AWS_SECRET_ACCESS_KEY": refreshed_credentials.get("secret_key", ""),
399
+ "Authorization": f"Bearer {refreshed_credentials.get('cognito_client_id_token', '')}",
400
+ }
401
+
402
+ token = refreshed_credentials.get("token")
403
+ if token:
404
+ headers["AWS_SESSION_TOKEN"] = token
405
+
406
+ response = requests.delete(
407
+ f"{options.lambda_url}/{options.kube_cluster_name}",
408
+ headers=headers,
409
+ params={"namespace": options.kube_namespace} if options.kube_namespace else {},
410
+ )
411
+
412
+ if response.status_code != 200:
413
+ logger.error(
414
+ f"Could not automatically tear down Locust Cloud: HTTP {response.status_code}/{response.reason} - Response: {response.text} - URL: {response.request.url}"
415
+ )
416
+ except Exception as e:
417
+ logger.error(f"Could not automatically tear down Locust Cloud: {e}")
418
+
419
+ try:
420
+ logger.debug("Cleaning up locustfiles")
421
+ s3 = credential_manager.session.resource("s3")
422
+ bucket = s3.Bucket(s3_bucket)
423
+ bucket.objects.all().delete()
424
+ logger.info("Done! ✨")
425
+ except ClientError as e:
426
+ logger.error(f"Failed to clean up locust files: {e}")
427
+ sys.exit(1)
402
428
 
403
429
 
404
430
  if __name__ == "__main__":
@@ -195,7 +195,7 @@ VALUES (%(time)s, %(run_id)s, %(greenlet_id)s, %(loadgen)s, %(name)s, %(request_
195
195
  "INSERT INTO testruns (id, num_users, description, arguments) VALUES (%s,%s,%s,%s)",
196
196
  (
197
197
  self._run_id,
198
- self.env.parsed_options.num_users or self.env.runner.user_count or 0,
198
+ self.env.runner.target_user_count if self.env.runner else 1,
199
199
  "self.env.parsed_options.description",
200
200
  " ".join(cmd),
201
201
  ),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: locust-cloud
3
- Version: 1.2.12
3
+ Version: 1.3.2
4
4
  Summary: Locust Cloud
5
5
  Project-URL: Homepage, https://locust.cloud
6
6
  Requires-Python: >=3.11
@@ -1,9 +1,9 @@
1
- locust_cloud/__init__.py,sha256=d-vcft9odW37rtliWSquU4h-BQNlZftSKDoZTk90HsM,1970
1
+ locust_cloud/__init__.py,sha256=GS_nha_uwtF2MTYEpkeiK-YmbY9ZlYBgDIyvPzQ0iGQ,2005
2
2
  locust_cloud/auth.py,sha256=2fcTIq0tYDckDsZZ7yFTHZn5nG7Ir1dlV1QIu_tp3JA,3164
3
- locust_cloud/cloud.py,sha256=gEiP2Lq7iQbWYiuuDbLmMgv5CUTUrYJ1uRzAgFv2cHw,15062
3
+ locust_cloud/cloud.py,sha256=3i91W4FLTij5919tnn2VKOtFbMnzlMwsDgrNBcXwpGo,15809
4
4
  locust_cloud/constants.py,sha256=YGgIEnaOT9cAA8F8a8Z8lOmlI78D2fXiVpP0RF213MA,167
5
5
  locust_cloud/credential_manager.py,sha256=JbuS22RTGAmngVB9DFLxHIgaonCSImemMGvtWnxBZRE,5515
6
- locust_cloud/timescale/exporter.py,sha256=j1K-czMUdOLFt5Sop0PTF6TL52vYdngEEI5OEM3Xl60,11128
6
+ locust_cloud/timescale/exporter.py,sha256=0VodnUUFHMDLH3Ma0dz2lfOhgjaisU9rn48fpckBYhI,11119
7
7
  locust_cloud/webui/.eslintrc,sha256=huuuTZNwbBGkhfelEOMhLQ-tgC9OYnnX0DRYgBn83Ig,1146
8
8
  locust_cloud/webui/.gitignore,sha256=i8EHIqDlVm1-Dkvf_GTZmP_Wu99GE7ABfbYzHXOU734,54
9
9
  locust_cloud/webui/.prettierrc,sha256=qZpzAJPlHUQ3--NHYK8WXgc_TlIqq-eoz4pbkTKK3nk,167
@@ -15,7 +15,7 @@ locust_cloud/webui/vite.config.ts,sha256=cqxPMkbwEA3H9mGGbuPulQUhIHCosUqm_1usxzs
15
15
  locust_cloud/webui/yarn.lock,sha256=HQipc2d3thDdUieYtmTLSOxMlgpN-nQjVWKusAlvf2g,227106
16
16
  locust_cloud/webui/dist/index.html,sha256=uRX9dnfQEMYFWaKl0czXN_2JbtQF0WRgP4gEOWG0WpQ,664
17
17
  locust_cloud/webui/dist/assets/index-BzflLAyP.js,sha256=GR85cK07EBnN6PBKImgYlHdsBl40y0Tay9J8w9LZKqc,2794820
18
- locust_cloud-1.2.12.dist-info/METADATA,sha256=rOtFHGBE1-1QiHrAutxSdcvr5AH9wIef8XvRUelNpxA,1664
19
- locust_cloud-1.2.12.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
20
- locust_cloud-1.2.12.dist-info/entry_points.txt,sha256=PGyAb4e3aTsGS3N3VGShDl6VzJaXy7QwsEgsLOC7V00,57
21
- locust_cloud-1.2.12.dist-info/RECORD,,
18
+ locust_cloud-1.3.2.dist-info/METADATA,sha256=bK1z7s7Tk-pkEItcPpn2-OQo-CSvvV0WjqrbAM6ROSU,1663
19
+ locust_cloud-1.3.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
20
+ locust_cloud-1.3.2.dist-info/entry_points.txt,sha256=PGyAb4e3aTsGS3N3VGShDl6VzJaXy7QwsEgsLOC7V00,57
21
+ locust_cloud-1.3.2.dist-info/RECORD,,