sutro 0.1.12__py3-none-any.whl → 0.1.14__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.
Potentially problematic release.
This version of sutro might be problematic. Click here for more details.
- sutro/cli.py +29 -29
- sutro/sdk.py +52 -51
- sutro-0.1.14.dist-info/METADATA +23 -0
- sutro-0.1.14.dist-info/RECORD +8 -0
- sutro-0.1.12.dist-info/METADATA +0 -41
- sutro-0.1.12.dist-info/RECORD +0 -8
- {sutro-0.1.12.dist-info → sutro-0.1.14.dist-info}/WHEEL +0 -0
- {sutro-0.1.12.dist-info → sutro-0.1.14.dist-info}/entry_points.txt +0 -0
- {sutro-0.1.12.dist-info → sutro-0.1.14.dist-info}/licenses/LICENSE +0 -0
sutro/cli.py
CHANGED
|
@@ -275,34 +275,34 @@ def cancel(job_id):
|
|
|
275
275
|
|
|
276
276
|
|
|
277
277
|
@cli.group()
|
|
278
|
-
def
|
|
279
|
-
"""Manage
|
|
278
|
+
def datasets():
|
|
279
|
+
"""Manage datasets."""
|
|
280
280
|
pass
|
|
281
281
|
|
|
282
282
|
|
|
283
|
-
@
|
|
283
|
+
@datasets.command()
|
|
284
284
|
def create():
|
|
285
|
-
"""Create a new
|
|
285
|
+
"""Create a new dataset."""
|
|
286
286
|
sdk = get_sdk()
|
|
287
|
-
|
|
288
|
-
if not
|
|
287
|
+
dataset_id = sdk.create_dataset()
|
|
288
|
+
if not dataset_id:
|
|
289
289
|
return
|
|
290
290
|
click.echo(
|
|
291
291
|
Fore.GREEN
|
|
292
|
-
+ f"
|
|
292
|
+
+ f"Dataset created successfully. Dataset ID: {dataset_id}"
|
|
293
293
|
+ Style.RESET_ALL
|
|
294
294
|
)
|
|
295
295
|
|
|
296
296
|
|
|
297
|
-
@
|
|
297
|
+
@datasets.command()
|
|
298
298
|
def list():
|
|
299
|
-
"""List all
|
|
299
|
+
"""List all datasets."""
|
|
300
300
|
sdk = get_sdk()
|
|
301
|
-
|
|
302
|
-
if
|
|
303
|
-
click.echo(Fore.YELLOW + "No
|
|
301
|
+
datasets = sdk.list_datasets()
|
|
302
|
+
if datasets is None or len(datasets) == 0:
|
|
303
|
+
click.echo(Fore.YELLOW + "No datasets found." + Style.RESET_ALL)
|
|
304
304
|
return
|
|
305
|
-
df = pl.DataFrame(
|
|
305
|
+
df = pl.DataFrame(datasets)
|
|
306
306
|
|
|
307
307
|
df = df.with_columns(
|
|
308
308
|
pl.col("schema")
|
|
@@ -319,37 +319,37 @@ def list():
|
|
|
319
319
|
print(df.select(pl.all()))
|
|
320
320
|
|
|
321
321
|
|
|
322
|
-
@
|
|
323
|
-
@click.argument("
|
|
324
|
-
def files(
|
|
325
|
-
"""List all files in a
|
|
322
|
+
@datasets.command()
|
|
323
|
+
@click.argument("dataset_id")
|
|
324
|
+
def files(dataset_id):
|
|
325
|
+
"""List all files in a dataset."""
|
|
326
326
|
sdk = get_sdk()
|
|
327
|
-
files = sdk.
|
|
327
|
+
files = sdk.list_dataset_files(dataset_id)
|
|
328
328
|
if not files:
|
|
329
329
|
return
|
|
330
330
|
|
|
331
|
-
print(Fore.YELLOW + "Files in
|
|
331
|
+
print(Fore.YELLOW + "Files in dataset " + dataset_id + ":" + Style.RESET_ALL)
|
|
332
332
|
for file in files:
|
|
333
333
|
print(f"\t{file}")
|
|
334
334
|
|
|
335
335
|
|
|
336
|
-
@
|
|
337
|
-
@click.argument("
|
|
336
|
+
@datasets.command()
|
|
337
|
+
@click.argument("dataset_id", required=False)
|
|
338
338
|
@click.argument("file_path")
|
|
339
|
-
def upload(file_path,
|
|
340
|
-
"""Upload files to a
|
|
339
|
+
def upload(file_path, dataset_id):
|
|
340
|
+
"""Upload files to a dataset. You can provide a single file path or a directory path to upload all files in the directory."""
|
|
341
341
|
sdk = get_sdk()
|
|
342
|
-
sdk.
|
|
342
|
+
sdk.upload_to_dataset(file_path, dataset_id)
|
|
343
343
|
|
|
344
344
|
|
|
345
|
-
@
|
|
346
|
-
@click.argument("
|
|
345
|
+
@datasets.command()
|
|
346
|
+
@click.argument("dataset_id")
|
|
347
347
|
@click.argument("file_name", required=False)
|
|
348
348
|
@click.argument("output_path", required=False)
|
|
349
|
-
def download(
|
|
350
|
-
"""Download a file/files from a
|
|
349
|
+
def download(dataset_id, file_name=None, output_path=None):
|
|
350
|
+
"""Download a file/files from a dataset. If no files are provided, all files in the dataset will be downloaded. If no output path is provided, the file will be saved to the current working directory."""
|
|
351
351
|
sdk = get_sdk()
|
|
352
|
-
files = sdk.
|
|
352
|
+
files = sdk.download_from_dataset(dataset_id, [file_name], output_path)
|
|
353
353
|
if not files:
|
|
354
354
|
return
|
|
355
355
|
for file in files:
|
sutro/sdk.py
CHANGED
|
@@ -114,7 +114,7 @@ class Sutro:
|
|
|
114
114
|
raise ValueError("Column name must be specified for DataFrame input")
|
|
115
115
|
input_data = data[column].to_list()
|
|
116
116
|
elif isinstance(data, str):
|
|
117
|
-
if data.startswith("
|
|
117
|
+
if data.startswith("dataset-"):
|
|
118
118
|
input_data = data + ":" + column
|
|
119
119
|
else:
|
|
120
120
|
file_ext = os.path.splitext(data)[1].lower()
|
|
@@ -172,12 +172,12 @@ class Sutro:
|
|
|
172
172
|
Run inference on the provided data.
|
|
173
173
|
|
|
174
174
|
This method allows you to run inference on the provided data using the Sutro API.
|
|
175
|
-
It supports various data types such as lists, pandas DataFrames, polars DataFrames, file paths and
|
|
175
|
+
It supports various data types such as lists, pandas DataFrames, polars DataFrames, file paths and datasets.
|
|
176
176
|
|
|
177
177
|
Args:
|
|
178
178
|
data (Union[List, pd.DataFrame, pl.DataFrame, str]): The data to run inference on.
|
|
179
179
|
model (str, optional): The model to use for inference. Defaults to "llama-3.1-8b".
|
|
180
|
-
column (str, optional): The column name to use for inference. Required if data is a DataFrame, file path, or
|
|
180
|
+
column (str, optional): The column name to use for inference. Required if data is a DataFrame, file path, or dataset.
|
|
181
181
|
output_column (str, optional): The column name to store the inference results in if the input is a DataFrame. Defaults to "inference_result".
|
|
182
182
|
job_priority (int, optional): The priority of the job. Defaults to 0.
|
|
183
183
|
output_schema (Union[Dict[str, Any], BaseModel], optional): A structured schema for the output.
|
|
@@ -437,8 +437,10 @@ class Sutro:
|
|
|
437
437
|
if not stop_event.is_set(): # Only log if we weren't stopping anyway
|
|
438
438
|
print(f"Heartbeat failed for job {job_id}: {e}")
|
|
439
439
|
|
|
440
|
-
|
|
441
|
-
|
|
440
|
+
for _ in range(self.HEARTBEAT_INTERVAL_SECONDS):
|
|
441
|
+
if stop_event.is_set():
|
|
442
|
+
break
|
|
443
|
+
time.sleep(1)
|
|
442
444
|
|
|
443
445
|
@contextmanager
|
|
444
446
|
def stream_heartbeat_session(self, job_id: str, session_token: str) -> Generator[requests.Session, None, None]:
|
|
@@ -449,7 +451,7 @@ class Sutro:
|
|
|
449
451
|
# Run this concurrently in a thread so we can not block main SDK path/behavior
|
|
450
452
|
# but still run heartbeat requests
|
|
451
453
|
with ThreadPoolExecutor(max_workers=1) as executor:
|
|
452
|
-
|
|
454
|
+
executor.submit(
|
|
453
455
|
self.start_heartbeat,
|
|
454
456
|
job_id,
|
|
455
457
|
session_token,
|
|
@@ -462,7 +464,6 @@ class Sutro:
|
|
|
462
464
|
finally:
|
|
463
465
|
# Signal stop and cleanup
|
|
464
466
|
stop_heartbeat.set()
|
|
465
|
-
future.result() # Wait for heartbeat to finish
|
|
466
467
|
self.unregister_stream_listener(job_id, session_token)
|
|
467
468
|
session.close()
|
|
468
469
|
|
|
@@ -792,22 +793,22 @@ class Sutro:
|
|
|
792
793
|
return
|
|
793
794
|
return response.json()
|
|
794
795
|
|
|
795
|
-
def
|
|
796
|
+
def create_dataset(self):
|
|
796
797
|
"""
|
|
797
|
-
Create a new
|
|
798
|
+
Create a new dataset.
|
|
798
799
|
|
|
799
|
-
This method creates a new
|
|
800
|
+
This method creates a new empty dataset and returns its ID.
|
|
800
801
|
|
|
801
802
|
Returns:
|
|
802
|
-
str: The ID of the new
|
|
803
|
+
str: The ID of the new dataset.
|
|
803
804
|
"""
|
|
804
|
-
endpoint = f"{self.base_url}/create-
|
|
805
|
+
endpoint = f"{self.base_url}/create-dataset"
|
|
805
806
|
headers = {
|
|
806
807
|
"Authorization": f"Key {self.api_key}",
|
|
807
808
|
"Content-Type": "application/json",
|
|
808
809
|
}
|
|
809
810
|
with yaspin(
|
|
810
|
-
SPINNER, text=to_colored_text("Creating
|
|
811
|
+
SPINNER, text=to_colored_text("Creating dataset"), color=YASPIN_COLOR
|
|
811
812
|
) as spinner:
|
|
812
813
|
response = requests.get(endpoint, headers=headers)
|
|
813
814
|
if response.status_code != 200:
|
|
@@ -819,25 +820,25 @@ class Sutro:
|
|
|
819
820
|
spinner.stop()
|
|
820
821
|
print(to_colored_text(response.json(), state="fail"))
|
|
821
822
|
return
|
|
822
|
-
|
|
823
|
+
dataset_id = response.json()["dataset_id"]
|
|
823
824
|
spinner.write(
|
|
824
|
-
to_colored_text(f"✔
|
|
825
|
+
to_colored_text(f"✔ Dataset created with ID: {dataset_id}", state="success")
|
|
825
826
|
)
|
|
826
|
-
return
|
|
827
|
+
return dataset_id
|
|
827
828
|
|
|
828
|
-
def
|
|
829
|
+
def upload_to_dataset(
|
|
829
830
|
self,
|
|
830
|
-
|
|
831
|
+
dataset_id: Union[List[str], str] = None,
|
|
831
832
|
file_paths: Union[List[str], str] = None,
|
|
832
833
|
verify_ssl: bool = True,
|
|
833
834
|
):
|
|
834
835
|
"""
|
|
835
|
-
Upload data to a
|
|
836
|
+
Upload data to a dataset.
|
|
836
837
|
|
|
837
|
-
This method uploads files to a
|
|
838
|
+
This method uploads files to a dataset. Accepts a dataset ID and file paths. If only a single parameter is provided, it will be interpreted as the file paths.
|
|
838
839
|
|
|
839
840
|
Args:
|
|
840
|
-
|
|
841
|
+
dataset_id (str): The ID of the dataset to upload to. If not provided, a new dataset will be created.
|
|
841
842
|
file_paths (Union[List[str], str]): A list of paths to the files to upload, or a single path to a collection of files.
|
|
842
843
|
verify_ssl (bool): Whether to verify SSL certificates. Set to False to bypass SSL verification for troubleshooting.
|
|
843
844
|
|
|
@@ -845,17 +846,17 @@ class Sutro:
|
|
|
845
846
|
dict: The response from the API.
|
|
846
847
|
"""
|
|
847
848
|
# when only a single parameter is provided, it is interpreted as the file paths
|
|
848
|
-
if file_paths is None and
|
|
849
|
-
file_paths =
|
|
850
|
-
|
|
849
|
+
if file_paths is None and dataset_id is not None:
|
|
850
|
+
file_paths = dataset_id
|
|
851
|
+
dataset_id = None
|
|
851
852
|
|
|
852
853
|
if file_paths is None:
|
|
853
854
|
raise ValueError("File paths must be provided")
|
|
854
855
|
|
|
855
|
-
if
|
|
856
|
-
|
|
856
|
+
if dataset_id is None:
|
|
857
|
+
dataset_id = self.create_dataset()
|
|
857
858
|
|
|
858
|
-
endpoint = f"{self.base_url}/upload-to-
|
|
859
|
+
endpoint = f"{self.base_url}/upload-to-dataset"
|
|
859
860
|
|
|
860
861
|
if isinstance(file_paths, str):
|
|
861
862
|
# check if the file path is a directory
|
|
@@ -870,7 +871,7 @@ class Sutro:
|
|
|
870
871
|
|
|
871
872
|
with yaspin(
|
|
872
873
|
SPINNER,
|
|
873
|
-
text=to_colored_text(f"Uploading files to
|
|
874
|
+
text=to_colored_text(f"Uploading files to dataset: {dataset_id}"),
|
|
874
875
|
color=YASPIN_COLOR,
|
|
875
876
|
) as spinner:
|
|
876
877
|
count = 0
|
|
@@ -886,7 +887,7 @@ class Sutro:
|
|
|
886
887
|
}
|
|
887
888
|
|
|
888
889
|
payload = {
|
|
889
|
-
"
|
|
890
|
+
"dataset_id": dataset_id,
|
|
890
891
|
}
|
|
891
892
|
|
|
892
893
|
headers = {
|
|
@@ -895,7 +896,7 @@ class Sutro:
|
|
|
895
896
|
count += 1
|
|
896
897
|
spinner.write(
|
|
897
898
|
to_colored_text(
|
|
898
|
-
f"Uploading file {count}/{len(file_paths)} to
|
|
899
|
+
f"Uploading file {count}/{len(file_paths)} to dataset: {dataset_id}"
|
|
899
900
|
)
|
|
900
901
|
)
|
|
901
902
|
|
|
@@ -922,19 +923,19 @@ class Sutro:
|
|
|
922
923
|
|
|
923
924
|
spinner.write(
|
|
924
925
|
to_colored_text(
|
|
925
|
-
f"✔ {count} files successfully uploaded to
|
|
926
|
+
f"✔ {count} files successfully uploaded to dataset", state="success"
|
|
926
927
|
)
|
|
927
928
|
)
|
|
928
|
-
return
|
|
929
|
+
return dataset_id
|
|
929
930
|
|
|
930
|
-
def
|
|
931
|
-
endpoint = f"{self.base_url}/list-
|
|
931
|
+
def list_datasets(self):
|
|
932
|
+
endpoint = f"{self.base_url}/list-datasets"
|
|
932
933
|
headers = {
|
|
933
934
|
"Authorization": f"Key {self.api_key}",
|
|
934
935
|
"Content-Type": "application/json",
|
|
935
936
|
}
|
|
936
937
|
with yaspin(
|
|
937
|
-
SPINNER, text=to_colored_text("Retrieving
|
|
938
|
+
SPINNER, text=to_colored_text("Retrieving datasets"), color=YASPIN_COLOR
|
|
938
939
|
) as spinner:
|
|
939
940
|
response = requests.post(endpoint, headers=headers)
|
|
940
941
|
if response.status_code != 200:
|
|
@@ -945,21 +946,21 @@ class Sutro:
|
|
|
945
946
|
)
|
|
946
947
|
print(to_colored_text(f"Error: {response.json()}", state="fail"))
|
|
947
948
|
return
|
|
948
|
-
spinner.write(to_colored_text("✔
|
|
949
|
-
return response.json()["
|
|
949
|
+
spinner.write(to_colored_text("✔ Datasets retrieved", state="success"))
|
|
950
|
+
return response.json()["datasets"]
|
|
950
951
|
|
|
951
|
-
def
|
|
952
|
-
endpoint = f"{self.base_url}/list-
|
|
952
|
+
def list_dataset_files(self, dataset_id: str):
|
|
953
|
+
endpoint = f"{self.base_url}/list-dataset-files"
|
|
953
954
|
headers = {
|
|
954
955
|
"Authorization": f"Key {self.api_key}",
|
|
955
956
|
"Content-Type": "application/json",
|
|
956
957
|
}
|
|
957
958
|
payload = {
|
|
958
|
-
"
|
|
959
|
+
"dataset_id": dataset_id,
|
|
959
960
|
}
|
|
960
961
|
with yaspin(
|
|
961
962
|
SPINNER,
|
|
962
|
-
text=to_colored_text(f"Listing files in
|
|
963
|
+
text=to_colored_text(f"Listing files in dataset: {dataset_id}"),
|
|
963
964
|
color=YASPIN_COLOR,
|
|
964
965
|
) as spinner:
|
|
965
966
|
response = requests.post(
|
|
@@ -974,27 +975,27 @@ class Sutro:
|
|
|
974
975
|
print(to_colored_text(f"Error: {response.json()}", state="fail"))
|
|
975
976
|
return
|
|
976
977
|
spinner.write(
|
|
977
|
-
to_colored_text(f"✔ Files listed in
|
|
978
|
+
to_colored_text(f"✔ Files listed in dataset: {dataset_id}", state="success")
|
|
978
979
|
)
|
|
979
980
|
return response.json()["files"]
|
|
980
981
|
|
|
981
|
-
def
|
|
982
|
+
def download_from_dataset(
|
|
982
983
|
self,
|
|
983
|
-
|
|
984
|
+
dataset_id: str,
|
|
984
985
|
files: Union[List[str], str] = None,
|
|
985
986
|
output_path: str = None,
|
|
986
987
|
):
|
|
987
|
-
endpoint = f"{self.base_url}/download-from-
|
|
988
|
+
endpoint = f"{self.base_url}/download-from-dataset"
|
|
988
989
|
|
|
989
990
|
if files is None:
|
|
990
|
-
files = self.
|
|
991
|
+
files = self.list_dataset_files(dataset_id)
|
|
991
992
|
elif isinstance(files, str):
|
|
992
993
|
files = [files]
|
|
993
994
|
|
|
994
995
|
if not files:
|
|
995
996
|
print(
|
|
996
997
|
to_colored_text(
|
|
997
|
-
f"Couldn't find files for
|
|
998
|
+
f"Couldn't find files for dataset ID: {dataset_id}", state="fail"
|
|
998
999
|
)
|
|
999
1000
|
)
|
|
1000
1001
|
return
|
|
@@ -1005,7 +1006,7 @@ class Sutro:
|
|
|
1005
1006
|
|
|
1006
1007
|
with yaspin(
|
|
1007
1008
|
SPINNER,
|
|
1008
|
-
text=to_colored_text(f"Downloading files from
|
|
1009
|
+
text=to_colored_text(f"Downloading files from dataset: {dataset_id}"),
|
|
1009
1010
|
color=YASPIN_COLOR,
|
|
1010
1011
|
) as spinner:
|
|
1011
1012
|
count = 0
|
|
@@ -1015,11 +1016,11 @@ class Sutro:
|
|
|
1015
1016
|
"Content-Type": "application/json",
|
|
1016
1017
|
}
|
|
1017
1018
|
payload = {
|
|
1018
|
-
"
|
|
1019
|
+
"dataset_id": dataset_id,
|
|
1019
1020
|
"file_name": file,
|
|
1020
1021
|
}
|
|
1021
1022
|
spinner.text = to_colored_text(
|
|
1022
|
-
f"Downloading file {count + 1}/{len(files)} from
|
|
1023
|
+
f"Downloading file {count + 1}/{len(files)} from dataset: {dataset_id}"
|
|
1023
1024
|
)
|
|
1024
1025
|
response = requests.post(
|
|
1025
1026
|
endpoint, headers=headers, data=json.dumps(payload)
|
|
@@ -1038,7 +1039,7 @@ class Sutro:
|
|
|
1038
1039
|
count += 1
|
|
1039
1040
|
spinner.write(
|
|
1040
1041
|
to_colored_text(
|
|
1041
|
-
f"✔ {count} files successfully downloaded from
|
|
1042
|
+
f"✔ {count} files successfully downloaded from dataset: {dataset_id}",
|
|
1042
1043
|
state="success",
|
|
1043
1044
|
)
|
|
1044
1045
|
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sutro
|
|
3
|
+
Version: 0.1.14
|
|
4
|
+
Summary: Sutro Python SDK
|
|
5
|
+
Project-URL: Homepage, https://sutro.sh
|
|
6
|
+
Project-URL: Documentation, https://docs.sutro.sh
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Requires-Dist: click==8.1.7
|
|
11
|
+
Requires-Dist: colorama==0.4.4
|
|
12
|
+
Requires-Dist: numpy==2.1.1
|
|
13
|
+
Requires-Dist: pandas==2.2.3
|
|
14
|
+
Requires-Dist: polars==1.8.2
|
|
15
|
+
Requires-Dist: pydantic==2.11.4
|
|
16
|
+
Requires-Dist: requests==2.32.3
|
|
17
|
+
Requires-Dist: tqdm==4.67.1
|
|
18
|
+
Requires-Dist: yaspin==3.1.0
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# sutro-client
|
|
22
|
+
|
|
23
|
+
The official Python client for Sutro. See [docs.sutro.sh](https://docs.sutro.sh/) for more information.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
sutro/__init__.py,sha256=yUiVwcZ8QamSqDdRHgzoANyTZ-x3cPzlt2Fs5OllR_w,402
|
|
2
|
+
sutro/cli.py,sha256=6Qy9Vwaaho92HeO8YA_z1De4zp1dEFkSX3bEnLvdbkE,13203
|
|
3
|
+
sutro/sdk.py,sha256=K86B8TNkNTSc1k0I6SVJldt6QE-ctnZmc8dMiOjK-PA,42439
|
|
4
|
+
sutro-0.1.14.dist-info/METADATA,sha256=ZpPrBjBQz3CCiXtvvBnJgFyz4cekr9gzi_ETtWtWc-8,669
|
|
5
|
+
sutro-0.1.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
6
|
+
sutro-0.1.14.dist-info/entry_points.txt,sha256=eXvr4dvMV4UmZgR0zmrY8KOmNpo64cJkhNDywiadRFM,40
|
|
7
|
+
sutro-0.1.14.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
8
|
+
sutro-0.1.14.dist-info/RECORD,,
|
sutro-0.1.12.dist-info/METADATA
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: sutro
|
|
3
|
-
Version: 0.1.12
|
|
4
|
-
Summary: Sutro Python SDK
|
|
5
|
-
Project-URL: Homepage, https://sutro.sh
|
|
6
|
-
Project-URL: Documentation, https://docs.sutro.sh
|
|
7
|
-
License-Expression: Apache-2.0
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Requires-Python: >=3.10
|
|
10
|
-
Requires-Dist: click==8.1.7
|
|
11
|
-
Requires-Dist: colorama==0.4.4
|
|
12
|
-
Requires-Dist: numpy==2.1.1
|
|
13
|
-
Requires-Dist: pandas==2.2.3
|
|
14
|
-
Requires-Dist: polars==1.8.2
|
|
15
|
-
Requires-Dist: pydantic==2.11.4
|
|
16
|
-
Requires-Dist: requests==2.32.3
|
|
17
|
-
Requires-Dist: tqdm==4.67.1
|
|
18
|
-
Requires-Dist: yaspin==3.1.0
|
|
19
|
-
Description-Content-Type: text/markdown
|
|
20
|
-
|
|
21
|
-
# sutro-client
|
|
22
|
-
|
|
23
|
-
The official Python client for Sutro. See [docs.sutro.sh](https://docs.sutro.sh/) for more information.
|
|
24
|
-
|
|
25
|
-
## Installing Locally (to test changes during development)
|
|
26
|
-
|
|
27
|
-
Run `make install` from the root directory. This should remove the old builds and reinstall the package in your environment with the latest. You can run `uv pip list` to ensure the package is pointing at the local files instead of the PyPI package.
|
|
28
|
-
|
|
29
|
-
## Creating releases
|
|
30
|
-
|
|
31
|
-
Make sure you increment the version appropriately in `pyproject.toml`. Generally speaking we'll do patch versions for small tweaks, minor versions for large additions or changes to behavior, and probably do major releases once it makes sense. Since we're still in beta and `0.x.x` releases, its probably okay to add backwards-incompatible changes to minor releases, but we want to avoid this if possible.
|
|
32
|
-
|
|
33
|
-
To create a release, run:
|
|
34
|
-
|
|
35
|
-
`make release <version>` with `<version>` formatted like `0.1.1`
|
|
36
|
-
|
|
37
|
-
It'll prompt you for an API key to PyPI, which you must have for it to work.
|
|
38
|
-
|
|
39
|
-
We also have a test PyPI account which you can use to test creating releases before pushing to the actual PyPI hub. I believe you can only create **one** release per version number, so it may be worth testing if you're paranoid about getting it right.
|
|
40
|
-
|
|
41
|
-
Also make sure to update the docs and increment the docs version number to match the new release. Keeping these consistent will provide a better user experience.
|
sutro-0.1.12.dist-info/RECORD
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
sutro/__init__.py,sha256=yUiVwcZ8QamSqDdRHgzoANyTZ-x3cPzlt2Fs5OllR_w,402
|
|
2
|
-
sutro/cli.py,sha256=ZvfMYNKq3iT-4TtGWmbI0qsEPTb0tjIGIiVMod1kH-s,13125
|
|
3
|
-
sutro/sdk.py,sha256=dhlrIzqePS0QAh1ShonO5RbbPgYFpXFQL_gEcvoP8_c,42353
|
|
4
|
-
sutro-0.1.12.dist-info/METADATA,sha256=FNpJnLVVwovtzFW6tiug46MWYPsJ4D73OAwdaew8FnA,1998
|
|
5
|
-
sutro-0.1.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
6
|
-
sutro-0.1.12.dist-info/entry_points.txt,sha256=eXvr4dvMV4UmZgR0zmrY8KOmNpo64cJkhNDywiadRFM,40
|
|
7
|
-
sutro-0.1.12.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
8
|
-
sutro-0.1.12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|