fundamental-client 0.2.3__py3-none-any.whl → 0.2.5__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.
- fundamental/__init__.py +8 -3
- fundamental/clients/__init__.py +2 -2
- fundamental/clients/{ec2.py → aws_marketplace.py} +5 -5
- fundamental/config.py +3 -3
- fundamental/constants.py +1 -1
- fundamental/utils/http.py +3 -3
- {fundamental_client-0.2.3.dist-info → fundamental_client-0.2.5.dist-info}/METADATA +423 -4
- {fundamental_client-0.2.3.dist-info → fundamental_client-0.2.5.dist-info}/RECORD +10 -10
- {fundamental_client-0.2.3.dist-info → fundamental_client-0.2.5.dist-info}/WHEEL +0 -0
- {fundamental_client-0.2.3.dist-info → fundamental_client-0.2.5.dist-info}/licenses/LICENSE +0 -0
fundamental/__init__.py
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
"""Fundamental Python SDK for tabular machine learning."""
|
|
2
2
|
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
3
4
|
from typing import Optional
|
|
4
5
|
|
|
5
|
-
from fundamental.clients import BaseClient, Fundamental,
|
|
6
|
+
from fundamental.clients import BaseClient, Fundamental, FundamentalAWSMarketplaceClient
|
|
6
7
|
|
|
7
8
|
# Deprecated aliases
|
|
8
9
|
from fundamental.deprecated import FTMClassifier, FTMRegressor
|
|
9
10
|
from fundamental.estimator import NEXUSClassifier, NEXUSRegressor
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
try:
|
|
13
|
+
# Distribution name on PyPI is `fundamental-client` (import name is `fundamental`).
|
|
14
|
+
__version__ = version("fundamental-client")
|
|
15
|
+
except PackageNotFoundError: # pragma: no cover
|
|
16
|
+
__version__ = "unknown"
|
|
12
17
|
|
|
13
18
|
_global_client: Optional[BaseClient] = None
|
|
14
19
|
|
|
@@ -26,7 +31,7 @@ __all__ = [
|
|
|
26
31
|
"FTMClassifier",
|
|
27
32
|
"FTMRegressor",
|
|
28
33
|
"Fundamental",
|
|
29
|
-
"
|
|
34
|
+
"FundamentalAWSMarketplaceClient",
|
|
30
35
|
"NEXUSClassifier",
|
|
31
36
|
"NEXUSRegressor",
|
|
32
37
|
"get_client",
|
fundamental/clients/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Client implementations for Fundamental API."""
|
|
2
2
|
|
|
3
|
+
from fundamental.clients.aws_marketplace import FundamentalAWSMarketplaceClient
|
|
3
4
|
from fundamental.clients.base import BaseClient
|
|
4
|
-
from fundamental.clients.ec2 import FundamentalEC2Client
|
|
5
5
|
from fundamental.clients.fundamental import Fundamental
|
|
6
6
|
|
|
7
|
-
__all__ = ["BaseClient", "Fundamental", "
|
|
7
|
+
__all__ = ["BaseClient", "Fundamental", "FundamentalAWSMarketplaceClient"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Fundamental
|
|
1
|
+
"""Fundamental AWS Marketplace client with AWS SigV4 authentication."""
|
|
2
2
|
|
|
3
3
|
from typing import Any, Optional
|
|
4
4
|
|
|
@@ -6,10 +6,10 @@ from fundamental.clients.base import BaseClient
|
|
|
6
6
|
from fundamental.config import Config
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class
|
|
10
|
-
"""Client for Fundamental API on
|
|
9
|
+
class FundamentalAWSMarketplaceClient(BaseClient):
|
|
10
|
+
"""Client for Fundamental API on AWS Marketplace deployments using AWS SigV4 authentication.
|
|
11
11
|
|
|
12
|
-
This client is
|
|
12
|
+
This client is designed for AWS Marketplace deployments where authentication
|
|
13
13
|
is done via AWS IAM roles instead of API keys. It uses SigV4 signing to
|
|
14
14
|
authenticate requests using the AWS credentials available in the environment.
|
|
15
15
|
"""
|
|
@@ -20,7 +20,7 @@ class FundamentalEC2Client(BaseClient):
|
|
|
20
20
|
api_url: Optional[str] = None,
|
|
21
21
|
**kwargs: Any, # noqa: ANN401
|
|
22
22
|
):
|
|
23
|
-
"""Initialize the Fundamental
|
|
23
|
+
"""Initialize the Fundamental AWS Marketplace client.
|
|
24
24
|
|
|
25
25
|
Args:
|
|
26
26
|
aws_region: AWS region for SigV4 signing (required)
|
fundamental/config.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from importlib.metadata import version
|
|
5
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
6
6
|
from typing import Optional
|
|
7
7
|
|
|
8
8
|
from fundamental.constants import (
|
|
@@ -133,6 +133,6 @@ class Config:
|
|
|
133
133
|
def get_version(self) -> str:
|
|
134
134
|
"""Get the SDK version."""
|
|
135
135
|
try:
|
|
136
|
-
return version("fundamental")
|
|
137
|
-
except
|
|
136
|
+
return version("fundamental-client")
|
|
137
|
+
except PackageNotFoundError:
|
|
138
138
|
return "unknown"
|
fundamental/constants.py
CHANGED
fundamental/utils/http.py
CHANGED
|
@@ -40,9 +40,9 @@ def _sign_request_sigv4(
|
|
|
40
40
|
from botocore.awsrequest import AWSRequest # pyright: ignore[reportMissingImports]
|
|
41
41
|
except ImportError as e:
|
|
42
42
|
raise ImportError(
|
|
43
|
-
"boto3 is required for
|
|
44
|
-
'Install it with: pip install "fundamental-client[
|
|
45
|
-
'or: uv add "fundamental-client[
|
|
43
|
+
"boto3 is required for AWS Marketplace/SigV4 authentication."
|
|
44
|
+
'Install it with: pip install "fundamental-client[aws-marketplace]" '
|
|
45
|
+
'or: uv add "fundamental-client[aws-marketplace]"'
|
|
46
46
|
) from e
|
|
47
47
|
|
|
48
48
|
session = boto3.Session()
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fundamental-client
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Scikit-learn–compatible client SDK for NEXUS, Fundamental's large model for tabular data
|
|
5
|
-
Project-URL: documentation, https://fundamental.tech/docs
|
|
5
|
+
Project-URL: documentation, https://launch.fundamental.tech/docs/guides/sdk/user-guide
|
|
6
6
|
Author-email: Fundamental Tech <support@fundamental.tech>
|
|
7
7
|
License: Apache License
|
|
8
8
|
Version 2.0, January 2004
|
|
@@ -225,6 +225,8 @@ Requires-Dist: pyarrow>=19.0.0
|
|
|
225
225
|
Requires-Dist: pydantic<3.0.0,>=2.10.0
|
|
226
226
|
Requires-Dist: safetensors>=0.5.0
|
|
227
227
|
Requires-Dist: scikit-learn<2.0.0,>=1.5.0
|
|
228
|
+
Provides-Extra: aws-marketplace
|
|
229
|
+
Requires-Dist: boto3>=1.34.0; extra == 'aws-marketplace'
|
|
228
230
|
Provides-Extra: dev
|
|
229
231
|
Requires-Dist: datamodel-code-generator[http]>=0.26.0; extra == 'dev'
|
|
230
232
|
Requires-Dist: minimum-dependencies; extra == 'dev'
|
|
@@ -237,5 +239,422 @@ Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
|
|
|
237
239
|
Requires-Dist: pytest>=8.4.2; extra == 'dev'
|
|
238
240
|
Requires-Dist: python-dotenv>=1.0.0; extra == 'dev'
|
|
239
241
|
Requires-Dist: ruff>=0.13.1; extra == 'dev'
|
|
240
|
-
|
|
241
|
-
|
|
242
|
+
Description-Content-Type: text/markdown
|
|
243
|
+
|
|
244
|
+
# Fundamental Python SDK
|
|
245
|
+
|
|
246
|
+
[](https://pypi.org/project/fundamental-client/)
|
|
247
|
+
[](https://pypi.org/project/fundamental-client)
|
|
248
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
249
|
+
|
|
250
|
+
A scikit-learn compatible Python SDK for NEXUS, Fundamental's large model for tabular data.
|
|
251
|
+
|
|
252
|
+
## Table of Contents
|
|
253
|
+
|
|
254
|
+
- [Installation](#installation)
|
|
255
|
+
- [Usage](#usage)
|
|
256
|
+
- [Quick Start](#quick-start)
|
|
257
|
+
- [Using Pre-trained Models](#using-pre-trained-models)
|
|
258
|
+
- [Async Training](#async-training)
|
|
259
|
+
- [Model Management](#model-management)
|
|
260
|
+
- [Explainability & Insights](#explainability--insights)
|
|
261
|
+
- [Feature Importance](#feature-importance)
|
|
262
|
+
- [Configuration](#configuration)
|
|
263
|
+
- [Client Configuration](#client-configuration)
|
|
264
|
+
- [API Key](#api-key)
|
|
265
|
+
- [AWS Marketplace](#aws-marketplace)
|
|
266
|
+
- [Timeouts and Retries](#timeouts-and-retries)
|
|
267
|
+
- [Model Configuration](#model-configuration)
|
|
268
|
+
- [Mode](#mode)
|
|
269
|
+
- [Supported Data Types](#supported-data-types)
|
|
270
|
+
- [Handling Errors](#handling-errors)
|
|
271
|
+
- [Diagnostics and Support Information](#diagnostics-and-support-information)
|
|
272
|
+
- [Exception Types](#exception-types)
|
|
273
|
+
- [Troubleshooting](#troubleshooting)
|
|
274
|
+
- [Versioning](#versioning)
|
|
275
|
+
- [Requirements](#requirements)
|
|
276
|
+
- [License](#license)
|
|
277
|
+
- [Security](#security)
|
|
278
|
+
- [Support](#support)
|
|
279
|
+
|
|
280
|
+
## Installation
|
|
281
|
+
|
|
282
|
+
```sh
|
|
283
|
+
# install from PyPI
|
|
284
|
+
pip install fundamental-client
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Usage
|
|
288
|
+
|
|
289
|
+
The Fundamental SDK provides scikit-learn compatible estimators for classification and regression tasks, along with a flexible client for API interactions.
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
### Quick Start
|
|
293
|
+
|
|
294
|
+
Make sure `FUNDAMENTAL_API_KEY` is set (or call `fundamental.set_client(...)`) before running the examples below.
|
|
295
|
+
|
|
296
|
+
```python
|
|
297
|
+
from sklearn.datasets import load_breast_cancer, load_diabetes
|
|
298
|
+
from sklearn.model_selection import train_test_split
|
|
299
|
+
from fundamental import NEXUSClassifier, NEXUSRegressor
|
|
300
|
+
|
|
301
|
+
# Load classification data
|
|
302
|
+
X, y = load_breast_cancer(return_X_y=True)
|
|
303
|
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=42)
|
|
304
|
+
|
|
305
|
+
# Classification
|
|
306
|
+
classifier = NEXUSClassifier()
|
|
307
|
+
classifier.fit(X_train, y_train)
|
|
308
|
+
|
|
309
|
+
# After fitting, the model ID can be saved and used later
|
|
310
|
+
print(f"Trained model ID: {classifier.trained_model_id_}")
|
|
311
|
+
|
|
312
|
+
predictions = classifier.predict(X_test)
|
|
313
|
+
probabilities = classifier.predict_proba(X_test)
|
|
314
|
+
|
|
315
|
+
# Load regression data
|
|
316
|
+
X, y = load_diabetes(return_X_y=True)
|
|
317
|
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=42)
|
|
318
|
+
|
|
319
|
+
# Regression
|
|
320
|
+
regressor = NEXUSRegressor()
|
|
321
|
+
regressor.fit(X_train, y_train)
|
|
322
|
+
predictions = regressor.predict(X_test)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Using Pre-trained Models
|
|
326
|
+
|
|
327
|
+
If you have a trained model from a previous session, you can use it directly without retraining:
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
from fundamental import NEXUSClassifier, NEXUSRegressor
|
|
331
|
+
|
|
332
|
+
classifier = NEXUSClassifier().load_model(trained_model_id="model_abc123")
|
|
333
|
+
predictions = classifier.predict(X_test)
|
|
334
|
+
probabilities = classifier.predict_proba(X_test)
|
|
335
|
+
|
|
336
|
+
regressor = NEXUSRegressor().load_model(trained_model_id="model_def456")
|
|
337
|
+
predictions = regressor.predict(X_test)
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Async Training
|
|
341
|
+
|
|
342
|
+
Model training is often a long-running operation. To support non-blocking workflows, you can submit training via `submit_fit_task()` and poll for completion. Once submitted, the training job runs in the background and its status can be queried at any time.
|
|
343
|
+
|
|
344
|
+
```python
|
|
345
|
+
from fundamental import NEXUSClassifier
|
|
346
|
+
import time
|
|
347
|
+
|
|
348
|
+
classifier = NEXUSClassifier()
|
|
349
|
+
|
|
350
|
+
# Submit training task without waiting
|
|
351
|
+
task_id = classifier.submit_fit_task(X_train, y_train)
|
|
352
|
+
print(f"Training task submitted: {task_id}")
|
|
353
|
+
|
|
354
|
+
# Poll status periodically
|
|
355
|
+
result = None
|
|
356
|
+
while result is None:
|
|
357
|
+
result = classifier.poll_fit_result(task_id)
|
|
358
|
+
if result is None:
|
|
359
|
+
print("Training in progress...")
|
|
360
|
+
time.sleep(10) # Wait before polling again
|
|
361
|
+
|
|
362
|
+
# Model is now fitted and ready for predictions
|
|
363
|
+
predictions = classifier.predict(X_test)
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Model Management
|
|
367
|
+
|
|
368
|
+
The client provides methods for managing your trained models:
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
from fundamental import Fundamental
|
|
372
|
+
|
|
373
|
+
# Create a client
|
|
374
|
+
client = Fundamental()
|
|
375
|
+
|
|
376
|
+
# List all available models
|
|
377
|
+
models = client.models.list()
|
|
378
|
+
print(f"Available models: {models}")
|
|
379
|
+
|
|
380
|
+
# Get information about a specific model
|
|
381
|
+
model_info = client.models.get("model_id_123")
|
|
382
|
+
print(f"Model info: {model_info}")
|
|
383
|
+
print(f"Attributes: {model_info.attributes}")
|
|
384
|
+
|
|
385
|
+
# Delete a model
|
|
386
|
+
client.models.delete("model_id_123")
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
#### Model Attributes
|
|
390
|
+
|
|
391
|
+
You can set attributes on your models to help organize and identify them.
|
|
392
|
+
We recommend always setting a `name` attribute; if omitted, the name will default to
|
|
393
|
+
`<model_version> [id:<model_id_suffix>]`.
|
|
394
|
+
|
|
395
|
+
```python
|
|
396
|
+
# Set attributes directly on a fitted model
|
|
397
|
+
classifier.set_attributes({"name": "Breast Cancer Classifier", "stage": "prod"})
|
|
398
|
+
|
|
399
|
+
# Or using the client
|
|
400
|
+
client.models.set_attributes(
|
|
401
|
+
"model_id_123",
|
|
402
|
+
attributes={"name": "Breast Cancer Classifier", "description": "Production model v1"}
|
|
403
|
+
)
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Explainability & Insights
|
|
407
|
+
|
|
408
|
+
#### Feature Importance
|
|
409
|
+
|
|
410
|
+
After fitting a model, you can compute feature importance to quantify the contribution of each input feature to the model's output:
|
|
411
|
+
|
|
412
|
+
```python
|
|
413
|
+
from sklearn.datasets import load_breast_cancer
|
|
414
|
+
from sklearn.model_selection import train_test_split
|
|
415
|
+
from fundamental import NEXUSClassifier
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
# Load data
|
|
419
|
+
X, y = load_breast_cancer(return_X_y=True)
|
|
420
|
+
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.5, random_state=42)
|
|
421
|
+
# Fit the model
|
|
422
|
+
classifier = NEXUSClassifier()
|
|
423
|
+
classifier.fit(X_train, y_train)
|
|
424
|
+
# Get feature importance (waits for computation to complete)
|
|
425
|
+
feature_importance = classifier.get_feature_importance(X_val)
|
|
426
|
+
print(f"Feature importance: {feature_importance}")
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Feature importance computation can take a significant amount of time. If you prefer to submit the task and check its status periodically, you can use the asynchronous approach:
|
|
430
|
+
|
|
431
|
+
```python
|
|
432
|
+
# Submit task without waiting
|
|
433
|
+
task_id = classifier.submit_feature_importance_task(X_val)
|
|
434
|
+
|
|
435
|
+
# Poll status later
|
|
436
|
+
result = classifier.poll_feature_importance_result(task_id)
|
|
437
|
+
if result is not None:
|
|
438
|
+
print(f"Feature importance: {result}")
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Configuration
|
|
442
|
+
|
|
443
|
+
### Client Configuration
|
|
444
|
+
|
|
445
|
+
Configure the SDK client through environment variables or programmatically.
|
|
446
|
+
|
|
447
|
+
#### API Key
|
|
448
|
+
|
|
449
|
+
You can provide your API key in two ways:
|
|
450
|
+
|
|
451
|
+
```python
|
|
452
|
+
# 1. Programmatic
|
|
453
|
+
import fundamental
|
|
454
|
+
from fundamental import Fundamental, NEXUSClassifier
|
|
455
|
+
|
|
456
|
+
fundamental.set_client(Fundamental(api_key="your_api_key_here"))
|
|
457
|
+
classifier = NEXUSClassifier()
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
# 2. Environment variable
|
|
462
|
+
export FUNDAMENTAL_API_KEY="your_api_key_here"
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
#### AWS Marketplace
|
|
466
|
+
|
|
467
|
+
For AWS Marketplace deployments, use the `FundamentalAWSMarketplaceClient` which authenticates using AWS IAM roles via SigV4 signing instead of API keys:
|
|
468
|
+
|
|
469
|
+
```python
|
|
470
|
+
import fundamental
|
|
471
|
+
from fundamental import FundamentalAWSMarketplaceClient, NEXUSClassifier
|
|
472
|
+
|
|
473
|
+
# Set the AWS Marketplace client with your deployment URL and AWS region
|
|
474
|
+
fundamental.set_client(FundamentalAWSMarketplaceClient(
|
|
475
|
+
aws_region="us-west-2", # Required
|
|
476
|
+
api_url="http://your-private-server:8000"
|
|
477
|
+
))
|
|
478
|
+
|
|
479
|
+
# Use the SDK as normal
|
|
480
|
+
classifier = NEXUSClassifier()
|
|
481
|
+
classifier.fit(X_train, y_train)
|
|
482
|
+
predictions = classifier.predict(X_test)
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
The `FundamentalAWSMarketplaceClient` automatically uses AWS credentials from the environment (IAM role, environment variables, or AWS config file) to sign requests. No API key is needed.
|
|
486
|
+
|
|
487
|
+
You can also configure using environment variables:
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
export FUNDAMENTAL_API_URL="http://your-private-server:8000"
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
```python
|
|
494
|
+
fundamental.set_client(
|
|
495
|
+
FundamentalAWSMarketplaceClient(
|
|
496
|
+
aws_region="us-west-2", # Required
|
|
497
|
+
# api_url="http://your-private-server:8000", # Optional; overrides FUNDAMENTAL_API_URL
|
|
498
|
+
)
|
|
499
|
+
)
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
#### Timeouts and Retries
|
|
503
|
+
|
|
504
|
+
Configure timeouts and retries when creating a client:
|
|
505
|
+
|
|
506
|
+
> **Note**: Timeouts apply only to the processing phase, starting after the dataset upload has completed.
|
|
507
|
+
|
|
508
|
+
```python
|
|
509
|
+
import fundamental
|
|
510
|
+
from fundamental import Fundamental, NEXUSClassifier
|
|
511
|
+
|
|
512
|
+
# Create and set a client with custom timeouts and retries
|
|
513
|
+
fundamental.set_client(Fundamental(
|
|
514
|
+
fit_timeout=600, # 10 minutes for training (default: 3 hours)
|
|
515
|
+
predict_timeout=30, # 30 seconds for predictions (default: 1 hour)
|
|
516
|
+
retries=0 # Number of retries (default: 1)
|
|
517
|
+
))
|
|
518
|
+
|
|
519
|
+
# Estimators will use the global client
|
|
520
|
+
classifier = NEXUSClassifier()
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Model Configuration
|
|
524
|
+
|
|
525
|
+
Configure model behavior and training parameters.
|
|
526
|
+
|
|
527
|
+
#### Mode
|
|
528
|
+
|
|
529
|
+
NEXUS offers two training modes to balance between speed and accuracy:
|
|
530
|
+
|
|
531
|
+
- **`quality` mode (default)**: Optimizes for the highest accuracy. This mode uses more comprehensive training processes and may take longer to complete.
|
|
532
|
+
- **`speed` mode**: Optimizes for faster training times while maintaining good accuracy.
|
|
533
|
+
|
|
534
|
+
```python
|
|
535
|
+
import fundamental
|
|
536
|
+
from fundamental import NEXUSClassifier, NEXUSRegressor
|
|
537
|
+
|
|
538
|
+
# Use quality mode (default)
|
|
539
|
+
classifier = NEXUSClassifier(mode="quality")
|
|
540
|
+
classifier.fit(X_train, y_train)
|
|
541
|
+
|
|
542
|
+
# Use speed mode for faster training
|
|
543
|
+
classifier_fast = NEXUSClassifier(mode="speed")
|
|
544
|
+
classifier_fast.fit(X_train, y_train)
|
|
545
|
+
|
|
546
|
+
# Same for regression
|
|
547
|
+
regressor = NEXUSRegressor(mode="speed")
|
|
548
|
+
regressor.fit(X_train, y_train)
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
## Supported Data Types
|
|
552
|
+
|
|
553
|
+
The SDK supports flexible input formats:
|
|
554
|
+
|
|
555
|
+
- **Input features (X)**:
|
|
556
|
+
- `pandas.DataFrame`
|
|
557
|
+
- `numpy.ndarray`
|
|
558
|
+
|
|
559
|
+
- **Target values (y)**:
|
|
560
|
+
- `numpy.ndarray`
|
|
561
|
+
- `pandas.Series`
|
|
562
|
+
|
|
563
|
+
> **Note**: Data must be serializable to Parquet via PyArrow. If you hit a serialization error, ensure columns have consistent numeric or string dtypes; complex numbers are not supported.
|
|
564
|
+
|
|
565
|
+
## Handling Errors
|
|
566
|
+
|
|
567
|
+
The SDK provides detailed error handling with specific exception types:
|
|
568
|
+
|
|
569
|
+
```python
|
|
570
|
+
from fundamental import NEXUSClassifier
|
|
571
|
+
from fundamental.exceptions import (
|
|
572
|
+
NEXUSError,
|
|
573
|
+
ValidationError,
|
|
574
|
+
AuthenticationError,
|
|
575
|
+
RateLimitError,
|
|
576
|
+
ServerError
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
classifier = NEXUSClassifier()
|
|
580
|
+
|
|
581
|
+
try:
|
|
582
|
+
classifier.fit(X_train, y_train)
|
|
583
|
+
except ValidationError as e:
|
|
584
|
+
print(f"Invalid input data: {e}")
|
|
585
|
+
print(f"Status code: {e.status_code}")
|
|
586
|
+
except AuthenticationError as e:
|
|
587
|
+
print("Authentication failed - check your API key")
|
|
588
|
+
except RateLimitError as e:
|
|
589
|
+
print("Rate limit exceeded - please wait before retrying")
|
|
590
|
+
except ServerError as e:
|
|
591
|
+
print("Server error - please try again later")
|
|
592
|
+
except NEXUSError as e:
|
|
593
|
+
print(f"An error occurred: {e}")
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### Diagnostics and Support Information
|
|
597
|
+
|
|
598
|
+
All exceptions include a `trace_id` attribute that you can share with Fundamental support to help diagnose issues more quickly.
|
|
599
|
+
|
|
600
|
+
```python
|
|
601
|
+
except ServerError as e:
|
|
602
|
+
if e.trace_id:
|
|
603
|
+
print(f"Error trace_id: {e.trace_id}")
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### Exception Types
|
|
607
|
+
|
|
608
|
+
| Error Type | Description | Status Code |
|
|
609
|
+
| ---------- | ----------- | ----------- |
|
|
610
|
+
| `ValidationError` | Input validation failed (bad request) | 400 |
|
|
611
|
+
| `AuthenticationError` | Authentication failed (missing/invalid API key) | 401 |
|
|
612
|
+
| `AuthorizationError` | Authorization failed (insufficient permissions) | 403 |
|
|
613
|
+
| `NotFoundError` | Resource not found | 404 |
|
|
614
|
+
| `RateLimitError` | API rate limit exceeded | 429 |
|
|
615
|
+
| `ServerError` | Server-side error | 500+ |
|
|
616
|
+
| `NetworkError` | Network connectivity issues | 503 |
|
|
617
|
+
| `RequestTimeoutError` | Request timed out | 504 |
|
|
618
|
+
|
|
619
|
+
## Troubleshooting
|
|
620
|
+
|
|
621
|
+
- **Missing API key** (`ValueError: API key is required...`): set `FUNDAMENTAL_API_KEY` or configure a client via `fundamental.set_client(...)`.
|
|
622
|
+
- **Serialization errors (PyArrow)**: ensure `X`/`y` contain consistent numeric or string types; avoid mixed-type/object columns.
|
|
623
|
+
- **Large datasets / memory use**: datasets are serialized to Parquet in-memory before upload. If you run into memory or upload issues, try sampling, reducing columns, or using batching.
|
|
624
|
+
|
|
625
|
+
To enable debug logs:
|
|
626
|
+
|
|
627
|
+
```python
|
|
628
|
+
import logging
|
|
629
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
## Versioning
|
|
633
|
+
|
|
634
|
+
This package follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions.
|
|
635
|
+
|
|
636
|
+
To check the installed version:
|
|
637
|
+
|
|
638
|
+
```python
|
|
639
|
+
import fundamental
|
|
640
|
+
print(fundamental.__version__)
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
## Requirements
|
|
644
|
+
|
|
645
|
+
- Python 3.10 or higher
|
|
646
|
+
- See [pyproject.toml](pyproject.toml) for full dependency list
|
|
647
|
+
|
|
648
|
+
## License
|
|
649
|
+
|
|
650
|
+
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
651
|
+
|
|
652
|
+
## Security
|
|
653
|
+
|
|
654
|
+
If you believe you’ve found a security vulnerability, please email [support@fundamental.tech](mailto:support@fundamental.tech) and include a minimal reproduction. Please do not open a public GitHub issue.
|
|
655
|
+
|
|
656
|
+
## Support
|
|
657
|
+
|
|
658
|
+
- **SDK docs**: [SDK User Guide](https://launch.fundamental.tech/docs/guides/sdk/user-guide)
|
|
659
|
+
- **Issues**: [GitHub Issues](https://github.com/Fundamental-Technologies/fundamental-client/issues)
|
|
660
|
+
- **Email**: [support@fundamental.tech](mailto:support@fundamental.tech)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
fundamental/__init__.py,sha256=
|
|
2
|
-
fundamental/config.py,sha256=
|
|
3
|
-
fundamental/constants.py,sha256=
|
|
1
|
+
fundamental/__init__.py,sha256=dnbAH6chnXsb3ls2HxcNvBY9YbbvSIBYOeYsoEVbwpE,1027
|
|
2
|
+
fundamental/config.py,sha256=S-OrWFpwljr4TCCm_vPx3MFyikXlvlSlZh-3r0uJVMI,5960
|
|
3
|
+
fundamental/constants.py,sha256=gvaQ9XFiXLc69pDxU6x0dFhI-4GaT9pySVp0CNpZZ-M,1620
|
|
4
4
|
fundamental/deprecated.py,sha256=hAM-5zdWapRLk8USnNCacPxHBThdWxFiUsbLA1dbYuk,1321
|
|
5
5
|
fundamental/exceptions.py,sha256=m6GZMuVdeo3GsH51wpi_onLDtyf-bq41qY1VksTizN0,2046
|
|
6
|
-
fundamental/clients/__init__.py,sha256=
|
|
6
|
+
fundamental/clients/__init__.py,sha256=rAKVwphny42dHWDbaF86eqq244V_qNQrdxi_3AlvyVc,311
|
|
7
|
+
fundamental/clients/aws_marketplace.py,sha256=WJmqV0LnN9VN0yJ5A3yi2efbNlJsSYQRqDCrZYnzavA,1331
|
|
7
8
|
fundamental/clients/base.py,sha256=8Ly2jc_7numhli2w-1ZKnam4MX5Wd7NjxQ6KJYrXfSk,1159
|
|
8
|
-
fundamental/clients/ec2.py,sha256=VNDNT38YfnC5k1sBkIRQnfALtzOFcgRwD5bMjOCIU8E,1317
|
|
9
9
|
fundamental/clients/fundamental.py,sha256=fQ9BNH658JUPfzj8NoaAp-NRAC1ECdssui61zwnNxEU,463
|
|
10
10
|
fundamental/estimator/__init__.py,sha256=hU-VtzBeNjG5jyKN9XDYdJk-58wEHfNyrV9wlEWgUtk,426
|
|
11
11
|
fundamental/estimator/base.py,sha256=YN6umVeZa0KErvDKy_kWXlQ_DYUc3HxHaRuK3mj3hg8,7773
|
|
@@ -20,10 +20,10 @@ fundamental/services/inference.py,sha256=Y1a9DRwrfRpUQwFJBe_ROb2wd0I0s_Y47zmBk-6
|
|
|
20
20
|
fundamental/services/models.py,sha256=tAjV1mHbeZsRpkwSVt2qmp0TqMik_GBCKKadE93ylXo,4989
|
|
21
21
|
fundamental/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
fundamental/utils/data.py,sha256=Ppy9F3B-6yAp7i433LeyiGXdi8iEVh3z-nK-W6I8a70,12520
|
|
23
|
-
fundamental/utils/http.py,sha256=
|
|
23
|
+
fundamental/utils/http.py,sha256=_Q_6PvhYbBwgshkguiPHUjNnOWtq5qjb7f9AdTWiGrw,9959
|
|
24
24
|
fundamental/utils/polling.py,sha256=OUWd256FLvH3j-fbbojXRKblL6vNnExzxQbIIus1QzY,2769
|
|
25
25
|
fundamental/utils/safetensors_deserialize.py,sha256=cWRTQS1Eui5NtMPzYCho5v7w8Ympn42U8cVXrRL3WeQ,3465
|
|
26
|
-
fundamental_client-0.2.
|
|
27
|
-
fundamental_client-0.2.
|
|
28
|
-
fundamental_client-0.2.
|
|
29
|
-
fundamental_client-0.2.
|
|
26
|
+
fundamental_client-0.2.5.dist-info/METADATA,sha256=U4K-ULSw8VPOPIdlZqymG9Wd062T9kRBs12m9NkrcM8,27759
|
|
27
|
+
fundamental_client-0.2.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
28
|
+
fundamental_client-0.2.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
29
|
+
fundamental_client-0.2.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|