locust-cloud 1.20.7.dev3__py3-none-any.whl → 1.20.8.dev3__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/args.py CHANGED
@@ -4,7 +4,9 @@ import gzip
4
4
  import io
5
5
  import os
6
6
  import pathlib
7
+ import shutil
7
8
  import sys
9
+ import tempfile
8
10
 
9
11
  if sys.version_info >= (3, 11):
10
12
  import tomllib
@@ -61,6 +63,17 @@ def valid_extra_files_path(file_path: str) -> pathlib.Path:
61
63
  return p
62
64
 
63
65
 
66
+ def valid_extra_packages_path(file_path: str) -> pathlib.Path:
67
+ p = pathlib.Path(file_path).resolve()
68
+
69
+ if not p.exists():
70
+ raise ArgumentTypeError(f"Path not found: {file_path}")
71
+ if p.is_file() and not (p.suffix == ".whl" or p.suffixes == [".tar", ".gz"]):
72
+ raise ArgumentTypeError(f"Invalid file suffix (must be '.whl' or '.tar.gz'): {file_path}")
73
+
74
+ return p
75
+
76
+
64
77
  def transfer_encode(file_name: str, stream: IO[bytes]) -> dict[str, str]:
65
78
  return {
66
79
  "filename": file_name,
@@ -91,7 +104,7 @@ def expanded(paths: list[pathlib.Path]) -> Generator[pathlib.Path, None, None]:
91
104
  yield path
92
105
 
93
106
 
94
- def transfer_encoded_extra_files(paths: list[pathlib.Path]) -> dict[str, str]:
107
+ def transfer_encoded_args_files(paths: list[pathlib.Path], to_file: str | None) -> dict[str, str]:
95
108
  buffer = io.BytesIO()
96
109
 
97
110
  with ZipFile(buffer, "w") as zf:
@@ -99,13 +112,53 @@ def transfer_encoded_extra_files(paths: list[pathlib.Path]) -> dict[str, str]:
99
112
  zf.write(path.relative_to(CWD))
100
113
 
101
114
  buffer.seek(0)
102
- return transfer_encode("extra-files.zip", buffer)
115
+ return transfer_encode(f"{to_file}.zip", buffer)
116
+
117
+
118
+ def flat_transfer_encoded_args_files(paths: list[pathlib.Path], to_file: str | None) -> dict[str, str]:
119
+ buffer = io.BytesIO()
120
+
121
+ with tempfile.TemporaryDirectory() as tmpdir:
122
+ tmp_path = pathlib.Path(tmpdir)
123
+
124
+ for src in paths:
125
+ src_path = pathlib.Path(src)
126
+ dest_path = tmp_path / src_path.name
127
+
128
+ if src_path.is_file():
129
+ shutil.copy(src_path, dest_path)
130
+ elif src_path.is_dir():
131
+ shutil.copytree(src_path, dest_path)
132
+ else:
133
+ print(f"Warning: {src} is not a valid file or directory")
134
+
135
+ # Create the zip archive
136
+ with ZipFile(buffer, "w") as zf:
137
+ for item in tmp_path.iterdir():
138
+ if item.is_file():
139
+ zf.write(item, arcname=item.name)
140
+ elif item.is_dir():
141
+ for root, _, files in os.walk(item):
142
+ for file in files:
143
+ file_path = pathlib.Path(root) / file
144
+ arcname = file_path.relative_to(tmp_path)
145
+ zf.write(file_path, arcname)
146
+
147
+ buffer.seek(0)
148
+ return transfer_encode(f"{to_file}.zip", buffer)
103
149
 
104
150
 
105
151
  class MergeToTransferEncodedZip(argparse.Action):
106
152
  def __call__(self, parser, namespace, values, option_string=None):
107
153
  paths = cast(list[pathlib.Path], values)
108
- value = transfer_encoded_extra_files(paths)
154
+ value = transfer_encoded_args_files(paths, option_string.lstrip("-"))
155
+ setattr(namespace, self.dest, value)
156
+
157
+
158
+ class MergeToTransferEncodedZipFlat(MergeToTransferEncodedZip):
159
+ def __call__(self, parser, namespace, values, option_string=None):
160
+ paths = cast(list[pathlib.Path], values)
161
+ value = flat_transfer_encoded_args_files(paths, option_string.lstrip("-"))
109
162
  setattr(namespace, self.dest, value)
110
163
 
111
164
 
@@ -163,6 +216,13 @@ cloud_parser.add_argument(
163
216
  type=valid_extra_files_path,
164
217
  help="A list of extra files or directories to upload. Space-separated, e.g. `--extra-files testdata.csv *.py my-directory/`.",
165
218
  )
219
+ cloud_parser.add_argument(
220
+ "--extra-packages",
221
+ action=MergeToTransferEncodedZipFlat,
222
+ nargs="*",
223
+ type=valid_extra_packages_path,
224
+ help="A list of extra packages to upload. Space-separated whl/tar.gz files or directory packages to be installed when running locust.",
225
+ )
166
226
  cloud_parser.add_argument(
167
227
  "--testrun-tags",
168
228
  nargs="*",
locust_cloud/cloud.py CHANGED
@@ -101,6 +101,9 @@ def main():
101
101
  if options.extra_files:
102
102
  payload["extra_files"] = options.extra_files
103
103
 
104
+ if options.extra_packages:
105
+ payload["extra_packages"] = options.extra_packages
106
+
104
107
  for attempt in range(1, 16):
105
108
  try:
106
109
  response = session.post("/deploy", json=payload)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: locust-cloud
3
- Version: 1.20.7.dev3
3
+ Version: 1.20.8.dev3
4
4
  Summary: Locust Cloud
5
5
  Project-URL: homepage, https://locust.cloud
6
6
  Project-URL: repository, https://github.com/locustcloud/locust-cloud
@@ -1,7 +1,7 @@
1
1
  locust_cloud/__init__.py,sha256=6z2hE5rUP9WJyYgr-7XC2GhIV-05m8XxjOsnb8ae1WY,56
2
2
  locust_cloud/apisession.py,sha256=fz3mJsHbS-LdlVcuaJurf4_nq_Oa_XdBTZ7sVpux_mA,4376
3
- locust_cloud/args.py,sha256=KD2svA77-Dz98J7p-WiSr9wIiA7GJ2wCglIcFOccncs,7663
4
- locust_cloud/cloud.py,sha256=LFO_Ykst0bOBYPqfxS6ll7abAvCCqyUpD3ql4nem9ys,6264
3
+ locust_cloud/args.py,sha256=_U2bxFu32H7SyGupzd_gNk9kud4pX0KRyOJUcZBzkVw,9944
4
+ locust_cloud/cloud.py,sha256=DqIxLnbdoX6E266yXpXixI4OtyWT9m-vMzVuyI8t3X0,6363
5
5
  locust_cloud/common.py,sha256=GVKkWcbbqd9n8oU-fHZRVZw3jGtuIVGSCLD2ZizeEo0,1160
6
6
  locust_cloud/input_events.py,sha256=MyxccgboHByICuK6VpQCCJhZQqTZAacNmkSpw-gxBEw,3420
7
7
  locust_cloud/web_login.py,sha256=UTwuRJBCkdsGkzHmzwW_s03GKABR22gScq-nBMmqcag,2557
@@ -11,8 +11,8 @@ locust_cloud/docs/1-first-run.rst,sha256=Z34qKIxIniwCELeUmEQbNLsN7HWM5fq-a3Wc4fu
11
11
  locust_cloud/docs/2-examples.rst,sha256=uT-Byr4twmWakhMdHNqRvFP0f5hUxqrieBzxBHus51Y,9806
12
12
  locust_cloud/docs/locust-cloud.rst,sha256=q0WSBOJI0LR3zxuaE9Lor0_bzv4AOKr3aCz9VC6sIzs,137
13
13
  locust_cloud/docs/images/locust-cloud-screenshot.png,sha256=ag0IxBi-40VexC84MApol1GCgRCL2h-l8NQDTMaeTyE,477350
14
- locust_cloud-1.20.7.dev3.dist-info/METADATA,sha256=o8f2-_kxhqyAr0Gy1F7hyKqktAPtZKXOUixihOQkfAg,649
15
- locust_cloud-1.20.7.dev3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- locust_cloud-1.20.7.dev3.dist-info/entry_points.txt,sha256=PGyAb4e3aTsGS3N3VGShDl6VzJaXy7QwsEgsLOC7V00,57
17
- locust_cloud-1.20.7.dev3.dist-info/licenses/LICENSE,sha256=Ow6fY6ta4KIjdlWalmxGvRP8yLmetvkbkl-SdHMjPIs,1093
18
- locust_cloud-1.20.7.dev3.dist-info/RECORD,,
14
+ locust_cloud-1.20.8.dev3.dist-info/METADATA,sha256=W_5EtPjRGTXkihpk0emotGNoW-3I_H77piY5C9FF1mQ,649
15
+ locust_cloud-1.20.8.dev3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ locust_cloud-1.20.8.dev3.dist-info/entry_points.txt,sha256=PGyAb4e3aTsGS3N3VGShDl6VzJaXy7QwsEgsLOC7V00,57
17
+ locust_cloud-1.20.8.dev3.dist-info/licenses/LICENSE,sha256=Ow6fY6ta4KIjdlWalmxGvRP8yLmetvkbkl-SdHMjPIs,1093
18
+ locust_cloud-1.20.8.dev3.dist-info/RECORD,,