featrixsphere 0.2.1235__py3-none-any.whl → 0.2.1238__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.
- featrixsphere/__init__.py +1 -1
- featrixsphere/client.py +57 -95
- {featrixsphere-0.2.1235.dist-info → featrixsphere-0.2.1238.dist-info}/METADATA +1 -1
- featrixsphere-0.2.1238.dist-info/RECORD +9 -0
- featrixsphere-0.2.1235.dist-info/RECORD +0 -9
- {featrixsphere-0.2.1235.dist-info → featrixsphere-0.2.1238.dist-info}/WHEEL +0 -0
- {featrixsphere-0.2.1235.dist-info → featrixsphere-0.2.1238.dist-info}/entry_points.txt +0 -0
- {featrixsphere-0.2.1235.dist-info → featrixsphere-0.2.1238.dist-info}/top_level.txt +0 -0
featrixsphere/__init__.py
CHANGED
featrixsphere/client.py
CHANGED
|
@@ -1727,48 +1727,6 @@ class FeatrixSphereClient:
|
|
|
1727
1727
|
# File Upload
|
|
1728
1728
|
# =========================================================================
|
|
1729
1729
|
|
|
1730
|
-
def upload_file(self, file_path: str) -> str:
|
|
1731
|
-
"""
|
|
1732
|
-
Upload a file to the server without creating a session.
|
|
1733
|
-
Returns the filename that can be used in training requests.
|
|
1734
|
-
|
|
1735
|
-
Args:
|
|
1736
|
-
file_path: Path to the file to upload
|
|
1737
|
-
|
|
1738
|
-
Returns:
|
|
1739
|
-
Filename (relative path) that can be used in training requests
|
|
1740
|
-
"""
|
|
1741
|
-
from pathlib import Path as PathLib
|
|
1742
|
-
file_path_obj = PathLib(file_path)
|
|
1743
|
-
if not file_path_obj.exists():
|
|
1744
|
-
raise FileNotFoundError(f"File not found: {file_path}")
|
|
1745
|
-
|
|
1746
|
-
with open(file_path_obj, 'rb') as f:
|
|
1747
|
-
files = {'file': (file_path_obj.name, f, 'text/csv' if file_path_obj.suffix == '.csv' else 'application/gzip')}
|
|
1748
|
-
response = self._make_request("POST", "/compute/upload_file", files=files)
|
|
1749
|
-
|
|
1750
|
-
response_data = response.json()
|
|
1751
|
-
|
|
1752
|
-
# Handle S3 upload response (returns s3_url and filename)
|
|
1753
|
-
if 's3_url' in response_data:
|
|
1754
|
-
# S3 upload - extract filename from key or use returned filename
|
|
1755
|
-
filename = response_data.get('filename')
|
|
1756
|
-
if not filename:
|
|
1757
|
-
# Extract from S3 key if filename not provided
|
|
1758
|
-
s3_key = response_data.get('key', '')
|
|
1759
|
-
if s3_key:
|
|
1760
|
-
filename = PathLib(s3_key).name
|
|
1761
|
-
if not filename:
|
|
1762
|
-
raise ValueError("Server did not return filename in S3 upload response")
|
|
1763
|
-
return filename
|
|
1764
|
-
|
|
1765
|
-
# Handle local file upload response (returns filename)
|
|
1766
|
-
filename = response_data.get('filename')
|
|
1767
|
-
if not filename:
|
|
1768
|
-
raise ValueError("Server did not return filename in upload response")
|
|
1769
|
-
|
|
1770
|
-
return filename
|
|
1771
|
-
|
|
1772
1730
|
def upload_file_and_create_session(self, file_path: Path, session_name_prefix: str = None, name: str = None, webhooks: Dict[str, str] = None) -> SessionInfo:
|
|
1773
1731
|
"""
|
|
1774
1732
|
Upload a CSV, Parquet, JSON, or JSONL file and create a new session.
|
|
@@ -4213,74 +4171,60 @@ class FeatrixSphereClient:
|
|
|
4213
4171
|
if input_filename and df is not None:
|
|
4214
4172
|
raise ValueError("Provide either input_filename or df, not both")
|
|
4215
4173
|
|
|
4216
|
-
#
|
|
4217
|
-
|
|
4218
|
-
if df is not None:
|
|
4219
|
-
import pandas as pd
|
|
4220
|
-
import tempfile
|
|
4221
|
-
import os
|
|
4222
|
-
|
|
4223
|
-
if not isinstance(df, pd.DataFrame):
|
|
4224
|
-
raise ValueError("df must be a pandas DataFrame")
|
|
4225
|
-
|
|
4226
|
-
if verbose:
|
|
4227
|
-
print(f"📊 Using provided DataFrame ({len(df)} rows, {len(df.columns)} columns)")
|
|
4228
|
-
|
|
4229
|
-
# Create temporary CSV file
|
|
4230
|
-
temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False)
|
|
4231
|
-
temp_file_path = temp_file.name
|
|
4232
|
-
temp_file.close()
|
|
4233
|
-
|
|
4234
|
-
# Save DataFrame to temp file
|
|
4235
|
-
df.to_csv(temp_file_path, index=False)
|
|
4236
|
-
|
|
4237
|
-
if verbose:
|
|
4238
|
-
print(f"📁 Saved to temporary file: {os.path.basename(temp_file_path)}")
|
|
4239
|
-
print(f"📤 Uploading file to server...")
|
|
4240
|
-
|
|
4241
|
-
# Upload the file
|
|
4242
|
-
uploaded_filename = self.upload_file(temp_file_path)
|
|
4243
|
-
input_filename = uploaded_filename
|
|
4244
|
-
|
|
4245
|
-
if verbose:
|
|
4246
|
-
print(f"✅ File uploaded: {input_filename}")
|
|
4247
|
-
|
|
4248
|
-
# Clean up temp file
|
|
4249
|
-
try:
|
|
4250
|
-
os.unlink(temp_file_path)
|
|
4251
|
-
except Exception:
|
|
4252
|
-
pass # Ignore cleanup errors
|
|
4253
|
-
|
|
4174
|
+
# Prepare multipart form data (like train_single_predictor_with_file does)
|
|
4175
|
+
files = None
|
|
4254
4176
|
data = {
|
|
4255
4177
|
"foundation_model_id": foundation_model_id,
|
|
4256
4178
|
"target_column": target_column,
|
|
4257
4179
|
"target_column_type": target_column_type,
|
|
4258
|
-
"epochs": epochs,
|
|
4180
|
+
"epochs": str(epochs),
|
|
4259
4181
|
"optimize_for": optimize_for,
|
|
4260
4182
|
}
|
|
4261
4183
|
|
|
4262
|
-
|
|
4263
|
-
|
|
4184
|
+
# Handle file upload - send file directly in multipart form
|
|
4185
|
+
if df is not None:
|
|
4186
|
+
import pandas as pd
|
|
4187
|
+
import tempfile
|
|
4188
|
+
import os
|
|
4189
|
+
|
|
4190
|
+
if not isinstance(df, pd.DataFrame):
|
|
4191
|
+
raise ValueError("df must be a pandas DataFrame")
|
|
4192
|
+
|
|
4193
|
+
if verbose:
|
|
4194
|
+
print(f"📊 Using provided DataFrame ({len(df)} rows, {len(df.columns)} columns)")
|
|
4195
|
+
|
|
4196
|
+
# Create temporary CSV file
|
|
4197
|
+
temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False)
|
|
4198
|
+
temp_file_path = temp_file.name
|
|
4199
|
+
temp_file.close()
|
|
4200
|
+
|
|
4201
|
+
# Save DataFrame to temp file
|
|
4202
|
+
df.to_csv(temp_file_path, index=False)
|
|
4203
|
+
|
|
4204
|
+
if verbose:
|
|
4205
|
+
print(f"📁 Saved to temporary file: {os.path.basename(temp_file_path)}")
|
|
4206
|
+
print(f"📤 Uploading file directly with training request...")
|
|
4207
|
+
|
|
4208
|
+
# Send file in multipart form
|
|
4209
|
+
files = {'file': (os.path.basename(temp_file_path), open(temp_file_path, 'rb'), 'text/csv')}
|
|
4210
|
+
|
|
4211
|
+
elif input_filename:
|
|
4212
|
+
# If absolute path provided, send file directly
|
|
4264
4213
|
from pathlib import Path
|
|
4265
4214
|
input_path = Path(input_filename)
|
|
4266
4215
|
if input_path.is_absolute():
|
|
4267
|
-
# Upload the file first, then use the uploaded filename
|
|
4268
4216
|
if not input_path.exists():
|
|
4269
4217
|
raise FileNotFoundError(f"Input file not found: {input_filename}")
|
|
4270
4218
|
|
|
4271
4219
|
if verbose:
|
|
4272
|
-
print(f"📤
|
|
4220
|
+
print(f"📤 Sending file directly from absolute path: {input_filename}")
|
|
4273
4221
|
|
|
4274
|
-
#
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
if verbose:
|
|
4278
|
-
print(f"✅ File uploaded as: {uploaded_filename}")
|
|
4279
|
-
|
|
4280
|
-
data["input_filename"] = uploaded_filename
|
|
4222
|
+
# Send file in multipart form
|
|
4223
|
+
files = {'file': (input_path.name, open(input_path, 'rb'), 'text/csv' if input_path.suffix == '.csv' else 'application/gzip')}
|
|
4281
4224
|
else:
|
|
4282
4225
|
# Relative filename - assume it's already on the server
|
|
4283
4226
|
data["input_filename"] = input_filename
|
|
4227
|
+
|
|
4284
4228
|
if name:
|
|
4285
4229
|
data["name"] = name
|
|
4286
4230
|
if session_name_prefix:
|
|
@@ -4288,11 +4232,29 @@ class FeatrixSphereClient:
|
|
|
4288
4232
|
if rare_label_value:
|
|
4289
4233
|
data["rare_label_value"] = rare_label_value
|
|
4290
4234
|
if class_imbalance:
|
|
4291
|
-
|
|
4235
|
+
import json
|
|
4236
|
+
data["class_imbalance"] = json.dumps(class_imbalance)
|
|
4292
4237
|
if webhooks:
|
|
4293
|
-
|
|
4238
|
+
import json
|
|
4239
|
+
data["webhooks"] = json.dumps(webhooks)
|
|
4294
4240
|
|
|
4295
|
-
|
|
4241
|
+
# Send request with file if provided
|
|
4242
|
+
try:
|
|
4243
|
+
if files:
|
|
4244
|
+
response = self._make_request("POST", "/compute/train_on_foundational_model", files=files, data=data)
|
|
4245
|
+
else:
|
|
4246
|
+
response = self._make_request("POST", "/compute/train_on_foundational_model", json=data)
|
|
4247
|
+
response_data = response.json()
|
|
4248
|
+
finally:
|
|
4249
|
+
# Close file handles
|
|
4250
|
+
if files and 'file' in files:
|
|
4251
|
+
files['file'][1].close()
|
|
4252
|
+
# Clean up temp file if we created one
|
|
4253
|
+
if df is not None and temp_file_path:
|
|
4254
|
+
try:
|
|
4255
|
+
os.unlink(temp_file_path)
|
|
4256
|
+
except Exception:
|
|
4257
|
+
pass
|
|
4296
4258
|
|
|
4297
4259
|
new_session_id = response_data.get('session_id')
|
|
4298
4260
|
print(f"✅ Predictor training session created: {new_session_id}")
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
featrixsphere/__init__.py,sha256=-zD2ZilYZFjYDB5rwnqr0jYNDB9zkO-hRgiD0LiXUGM,1888
|
|
2
|
+
featrixsphere/cli.py,sha256=AW9O3vCvCNJ2UxVGN66eRmeN7XLSiHJlvK6JLZ9UJXc,13358
|
|
3
|
+
featrixsphere/client.py,sha256=9GmwNP8Z4-HCQWEBDIXp54rbymRtJqwmBeQZZu5g27E,382816
|
|
4
|
+
featrixsphere/test_client.py,sha256=4SiRbib0ms3poK0UpnUv4G0HFQSzidF3Iswo_J2cjLk,11981
|
|
5
|
+
featrixsphere-0.2.1238.dist-info/METADATA,sha256=ILxoFLdu7zaEt1RzGAoCX_QGKMRCzv9hcB1zGr6_9FM,16232
|
|
6
|
+
featrixsphere-0.2.1238.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
featrixsphere-0.2.1238.dist-info/entry_points.txt,sha256=QreJeYfD_VWvbEqPmMXZ3pqqlFlJ1qZb-NtqnyhEldc,51
|
|
8
|
+
featrixsphere-0.2.1238.dist-info/top_level.txt,sha256=AyN4wjfzlD0hWnDieuEHX0KckphIk_aC73XCG4df5uU,14
|
|
9
|
+
featrixsphere-0.2.1238.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
featrixsphere/__init__.py,sha256=Md3n-bIkA4f-Jdk1zoINUXqmnhGnM0osazYM1lk_1hY,1888
|
|
2
|
-
featrixsphere/cli.py,sha256=AW9O3vCvCNJ2UxVGN66eRmeN7XLSiHJlvK6JLZ9UJXc,13358
|
|
3
|
-
featrixsphere/client.py,sha256=8OKx-pUcZjStdR7Fy4yGMMcWTuqaF1DeSPnxXPcoKtQ,384045
|
|
4
|
-
featrixsphere/test_client.py,sha256=4SiRbib0ms3poK0UpnUv4G0HFQSzidF3Iswo_J2cjLk,11981
|
|
5
|
-
featrixsphere-0.2.1235.dist-info/METADATA,sha256=xKOgY6aH86jvurdKvPbV-_n1YnZi5ZxGtmxH9aQuGTs,16232
|
|
6
|
-
featrixsphere-0.2.1235.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
-
featrixsphere-0.2.1235.dist-info/entry_points.txt,sha256=QreJeYfD_VWvbEqPmMXZ3pqqlFlJ1qZb-NtqnyhEldc,51
|
|
8
|
-
featrixsphere-0.2.1235.dist-info/top_level.txt,sha256=AyN4wjfzlD0hWnDieuEHX0KckphIk_aC73XCG4df5uU,14
|
|
9
|
-
featrixsphere-0.2.1235.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|