featrixsphere 0.2.1235__tar.gz → 0.2.1238__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.
Files changed (19) hide show
  1. {featrixsphere-0.2.1235/featrixsphere.egg-info → featrixsphere-0.2.1238}/PKG-INFO +1 -1
  2. featrixsphere-0.2.1238/VERSION +1 -0
  3. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere/__init__.py +1 -1
  4. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere/client.py +57 -95
  5. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238/featrixsphere.egg-info}/PKG-INFO +1 -1
  6. featrixsphere-0.2.1235/VERSION +0 -1
  7. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/MANIFEST.in +0 -0
  8. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/README.md +0 -0
  9. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere/cli.py +0 -0
  10. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere/test_client.py +0 -0
  11. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere.egg-info/SOURCES.txt +0 -0
  12. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere.egg-info/dependency_links.txt +0 -0
  13. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere.egg-info/entry_points.txt +0 -0
  14. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere.egg-info/not-zip-safe +0 -0
  15. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere.egg-info/requires.txt +0 -0
  16. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/featrixsphere.egg-info/top_level.txt +0 -0
  17. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/requirements.txt +0 -0
  18. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/setup.cfg +0 -0
  19. {featrixsphere-0.2.1235 → featrixsphere-0.2.1238}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: featrixsphere
3
- Version: 0.2.1235
3
+ Version: 0.2.1238
4
4
  Summary: Transform any CSV into a production-ready ML model in minutes, not months.
5
5
  Home-page: https://github.com/Featrix/sphere
6
6
  Author: Featrix
@@ -0,0 +1 @@
1
+ 0.2.1238
@@ -38,7 +38,7 @@ Example:
38
38
  ... labels=['Experiment A', 'Experiment B'])
39
39
  """
40
40
 
41
- __version__ = "0.2.1235"
41
+ __version__ = "0.2.1238"
42
42
  __author__ = "Featrix"
43
43
  __email__ = "support@featrix.com"
44
44
  __license__ = "MIT"
@@ -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
- # If DataFrame provided, save to temp file and upload it
4217
- temp_file = None
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
- if input_filename:
4263
- # If absolute path provided, upload the file first
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"📤 Uploading file from absolute path: {input_filename}")
4220
+ print(f"📤 Sending file directly from absolute path: {input_filename}")
4273
4221
 
4274
- # Upload the file
4275
- uploaded_filename = self.upload_file(str(input_path))
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
- data["class_imbalance"] = class_imbalance
4235
+ import json
4236
+ data["class_imbalance"] = json.dumps(class_imbalance)
4292
4237
  if webhooks:
4293
- data["webhooks"] = webhooks
4238
+ import json
4239
+ data["webhooks"] = json.dumps(webhooks)
4294
4240
 
4295
- response_data = self._post_json("/compute/train_on_foundational_model", data)
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}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: featrixsphere
3
- Version: 0.2.1235
3
+ Version: 0.2.1238
4
4
  Summary: Transform any CSV into a production-ready ML model in minutes, not months.
5
5
  Home-page: https://github.com/Featrix/sphere
6
6
  Author: Featrix
@@ -1 +0,0 @@
1
- 0.2.1235