coreplexml 0.1.1__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.
@@ -0,0 +1,28 @@
1
+ Business Source License 1.1 (BUSL-1.1)
2
+
3
+ Copyright (c) 2025 Rodrigo Henríquez and Intellicore TI SpA
4
+
5
+ Use Limitation:
6
+ This Licensed Work may only be used, copied, modified, or distributed for non-commercial purposes, including academic study, personal experimentation, and non-commercial research.
7
+
8
+ Prohibited Uses:
9
+ You may NOT use the Licensed Work or any derivative works for any commercial purpose, including offering a service to third parties, developing commercial products, or any internal commercial advantage, without explicit, written permission from Intellicore TI SpA.
10
+
11
+ Change Date:
12
+ There is currently no planned change date where this code will automatically switch to a more permissive license.
13
+
14
+ Licensor:
15
+ Intellicore TI SpA (contact@intellicore.cl)
16
+
17
+ Primary Author:
18
+ Rodrigo Henríquez (rodrigo@intellicore.cl)
19
+
20
+ License Terms:
21
+ The complete terms of the Business Source License 1.1 apply, as published by MariaDB Corporation Ab.
22
+
23
+ A copy of the full license text can be found at:
24
+ https://mariadb.com/bsl11
25
+
26
+ Summary:
27
+ You can use, view, modify, and share the code for non-commercial purposes freely. Commercial use requires obtaining a commercial license from Intellicore TI SpA.
28
+
@@ -0,0 +1,2 @@
1
+ include README.md
2
+ include LICENSE
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.4
2
+ Name: coreplexml
3
+ Version: 0.1.1
4
+ Summary: Python SDK for CorePlexML AutoML & MLOps platform
5
+ Home-page: https://coreplexml.io
6
+ Author: Rodrigo Henríquez M. - Intellicore
7
+ Author-email: r@coreplexml.io
8
+ License: BUSL-1.1
9
+ Project-URL: Platform, https://platform.coreplexml.io
10
+ Project-URL: Documentation, https://platform.coreplexml.io/docs/site/
11
+ Project-URL: Source, https://platform.coreplexml.io/sdk
12
+ Keywords: automl mlops machine-learning h2o deployment monitoring
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: License :: Other/Proprietary License
24
+ Classifier: Operating System :: OS Independent
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: requests>=2.28
29
+ Dynamic: author
30
+ Dynamic: author-email
31
+ Dynamic: classifier
32
+ Dynamic: description
33
+ Dynamic: description-content-type
34
+ Dynamic: home-page
35
+ Dynamic: keywords
36
+ Dynamic: license
37
+ Dynamic: license-file
38
+ Dynamic: project-url
39
+ Dynamic: requires-dist
40
+ Dynamic: requires-python
41
+ Dynamic: summary
42
+
43
+ # CorePlexML Python SDK
44
+
45
+ Official Python client for the [CorePlexML](https://coreplexml.io) AutoML & MLOps platform.
46
+
47
+ ## Installation
48
+
49
+ ```bash
50
+ pip install coreplexml
51
+ ```
52
+
53
+ ## Quick Start
54
+
55
+ ```python
56
+ from coreplexml import CorePlexMLClient
57
+
58
+ client = CorePlexMLClient(
59
+ base_url="https://platform.coreplexml.io",
60
+ api_key="your-api-key"
61
+ )
62
+
63
+ # List projects
64
+ projects = client.projects.list()
65
+
66
+ # Create a project
67
+ project = client.projects.create(name="My ML Project")
68
+
69
+ # Upload a dataset
70
+ dataset = client.datasets.upload(
71
+ project_id=project["id"],
72
+ file_path="data.csv",
73
+ name="Training Data"
74
+ )
75
+
76
+ # Run an AutoML experiment
77
+ experiment = client.experiments.create(
78
+ project_id=project["id"],
79
+ dataset_version_id=dataset["version_id"],
80
+ target_column="label",
81
+ problem_type="classification"
82
+ )
83
+
84
+ # Get the best model
85
+ models = client.models.list(project_id=project["id"])
86
+ best = models["items"][0]
87
+
88
+ # Deploy
89
+ deployment = client.deployments.create(
90
+ project_id=project["id"],
91
+ model_id=best["id"],
92
+ name="production-v1"
93
+ )
94
+
95
+ # Predict
96
+ result = client.deployments.predict(
97
+ deployment_id=deployment["id"],
98
+ inputs={"feature1": 1.0, "feature2": "A"}
99
+ )
100
+ print(result["predictions"])
101
+ ```
102
+
103
+ ## Resources
104
+
105
+ The client provides access to all platform resources:
106
+
107
+ | Resource | Description |
108
+ |----------|-------------|
109
+ | `client.projects` | Project CRUD |
110
+ | `client.datasets` | Dataset upload, versions, columns |
111
+ | `client.experiments` | AutoML experiment management |
112
+ | `client.models` | Model listing, metrics, explainability |
113
+ | `client.deployments` | Deploy models, predict, A/B tests |
114
+ | `client.reports` | Generate PDF/HTML reports |
115
+ | `client.privacy` | Privacy Suite (PII detection, compliance) |
116
+ | `client.synthgen` | Synthetic data generation (CTGAN, TVAE) |
117
+ | `client.studio` | What-If analysis sessions |
118
+
119
+ ## Authentication
120
+
121
+ Create an API key from **Profile > API Keys** in the platform, then:
122
+
123
+ ```python
124
+ client = CorePlexMLClient(
125
+ base_url="https://platform.coreplexml.io",
126
+ api_key="cpx_your_api_key_here"
127
+ )
128
+ ```
129
+
130
+ ## Error Handling
131
+
132
+ ```python
133
+ from coreplexml import CorePlexMLClient, NotFoundError, ValidationError
134
+
135
+ try:
136
+ client.projects.get("nonexistent-id")
137
+ except NotFoundError:
138
+ print("Project not found")
139
+ except ValidationError as e:
140
+ print(f"Validation error: {e}")
141
+ ```
142
+
143
+ ## Requirements
144
+
145
+ - Python >= 3.9
146
+ - `requests` >= 2.28
147
+
148
+ ## Links
149
+
150
+ - [Platform](https://platform.coreplexml.io)
151
+ - [API Documentation](https://platform.coreplexml.io/docs/site/)
152
+ - [Website](https://coreplexml.io)
153
+
154
+ ## License
155
+
156
+ Business Source License 1.1
@@ -0,0 +1,114 @@
1
+ # CorePlexML Python SDK
2
+
3
+ Official Python client for the [CorePlexML](https://coreplexml.io) AutoML & MLOps platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install coreplexml
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ from coreplexml import CorePlexMLClient
15
+
16
+ client = CorePlexMLClient(
17
+ base_url="https://platform.coreplexml.io",
18
+ api_key="your-api-key"
19
+ )
20
+
21
+ # List projects
22
+ projects = client.projects.list()
23
+
24
+ # Create a project
25
+ project = client.projects.create(name="My ML Project")
26
+
27
+ # Upload a dataset
28
+ dataset = client.datasets.upload(
29
+ project_id=project["id"],
30
+ file_path="data.csv",
31
+ name="Training Data"
32
+ )
33
+
34
+ # Run an AutoML experiment
35
+ experiment = client.experiments.create(
36
+ project_id=project["id"],
37
+ dataset_version_id=dataset["version_id"],
38
+ target_column="label",
39
+ problem_type="classification"
40
+ )
41
+
42
+ # Get the best model
43
+ models = client.models.list(project_id=project["id"])
44
+ best = models["items"][0]
45
+
46
+ # Deploy
47
+ deployment = client.deployments.create(
48
+ project_id=project["id"],
49
+ model_id=best["id"],
50
+ name="production-v1"
51
+ )
52
+
53
+ # Predict
54
+ result = client.deployments.predict(
55
+ deployment_id=deployment["id"],
56
+ inputs={"feature1": 1.0, "feature2": "A"}
57
+ )
58
+ print(result["predictions"])
59
+ ```
60
+
61
+ ## Resources
62
+
63
+ The client provides access to all platform resources:
64
+
65
+ | Resource | Description |
66
+ |----------|-------------|
67
+ | `client.projects` | Project CRUD |
68
+ | `client.datasets` | Dataset upload, versions, columns |
69
+ | `client.experiments` | AutoML experiment management |
70
+ | `client.models` | Model listing, metrics, explainability |
71
+ | `client.deployments` | Deploy models, predict, A/B tests |
72
+ | `client.reports` | Generate PDF/HTML reports |
73
+ | `client.privacy` | Privacy Suite (PII detection, compliance) |
74
+ | `client.synthgen` | Synthetic data generation (CTGAN, TVAE) |
75
+ | `client.studio` | What-If analysis sessions |
76
+
77
+ ## Authentication
78
+
79
+ Create an API key from **Profile > API Keys** in the platform, then:
80
+
81
+ ```python
82
+ client = CorePlexMLClient(
83
+ base_url="https://platform.coreplexml.io",
84
+ api_key="cpx_your_api_key_here"
85
+ )
86
+ ```
87
+
88
+ ## Error Handling
89
+
90
+ ```python
91
+ from coreplexml import CorePlexMLClient, NotFoundError, ValidationError
92
+
93
+ try:
94
+ client.projects.get("nonexistent-id")
95
+ except NotFoundError:
96
+ print("Project not found")
97
+ except ValidationError as e:
98
+ print(f"Validation error: {e}")
99
+ ```
100
+
101
+ ## Requirements
102
+
103
+ - Python >= 3.9
104
+ - `requests` >= 2.28
105
+
106
+ ## Links
107
+
108
+ - [Platform](https://platform.coreplexml.io)
109
+ - [API Documentation](https://platform.coreplexml.io/docs/site/)
110
+ - [Website](https://coreplexml.io)
111
+
112
+ ## License
113
+
114
+ Business Source License 1.1
@@ -0,0 +1,21 @@
1
+ """CorePlexML Python SDK.
2
+
3
+ A Python client for the CorePlexML AutoML & MLOps platform.
4
+ Provides typed access to projects, datasets, experiments, models,
5
+ deployments, reports, privacy suite, synthetic data generation,
6
+ and what-if analysis.
7
+
8
+ Quick start::
9
+
10
+ from coreplexml import CorePlexMLClient
11
+
12
+ client = CorePlexMLClient("https://your-domain.com", api_key="your-key")
13
+ projects = client.projects.list()
14
+
15
+ Version: 0.1.1
16
+ """
17
+ from coreplexml.client import CorePlexMLClient
18
+ from coreplexml.exceptions import CorePlexMLError, AuthenticationError, NotFoundError, ValidationError
19
+
20
+ __version__ = "0.1.1"
21
+ __all__ = ["CorePlexMLClient", "CorePlexMLError", "AuthenticationError", "NotFoundError", "ValidationError", "__version__"]
@@ -0,0 +1,157 @@
1
+ from __future__ import annotations
2
+
3
+ """HTTP transport layer for the CorePlexML Python SDK.
4
+
5
+ Provides low-level HTTP methods with automatic error handling,
6
+ authentication, retry logic, and job polling support.
7
+ """
8
+
9
+ import time
10
+ import logging
11
+ from typing import Any
12
+
13
+ import requests
14
+ from requests.adapters import HTTPAdapter
15
+ from urllib3.util.retry import Retry
16
+
17
+ from coreplexml.exceptions import CorePlexMLError, AuthenticationError, NotFoundError, ValidationError
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+ _SDK_VERSION = "0.1.1"
22
+
23
+
24
+ class HTTPClient:
25
+ """Low-level HTTP client with error handling, retries, and job polling."""
26
+
27
+ def __init__(self, base_url: str, api_key: str | None = None, timeout: int = 30):
28
+ self.base_url = base_url.rstrip("/")
29
+ self.timeout = timeout
30
+ self.session = requests.Session()
31
+ self.session.headers["User-Agent"] = f"coreplexml-python/{_SDK_VERSION}"
32
+ self.session.headers["Content-Type"] = "application/json"
33
+ if api_key:
34
+ self.session.headers["Authorization"] = f"Bearer {api_key}"
35
+
36
+ # Retry transient failures with exponential backoff
37
+ retry = Retry(
38
+ total=3,
39
+ backoff_factor=0.5,
40
+ status_forcelist=[429, 500, 502, 503, 504],
41
+ allowed_methods=["GET", "PUT", "DELETE", "HEAD", "OPTIONS"],
42
+ )
43
+ adapter = HTTPAdapter(max_retries=retry)
44
+ self.session.mount("http://", adapter)
45
+ self.session.mount("https://", adapter)
46
+
47
+ def close(self) -> None:
48
+ """Close the underlying HTTP session and release connections."""
49
+ self.session.close()
50
+
51
+ def __repr__(self) -> str:
52
+ return f"HTTPClient(base_url={self.base_url!r})"
53
+
54
+ def _url(self, path: str) -> str:
55
+ return f"{self.base_url}{path}"
56
+
57
+ def _request(self, method: str, path: str, **kwargs) -> requests.Response:
58
+ """Execute HTTP request with connection error wrapping."""
59
+ kwargs.setdefault("timeout", self.timeout)
60
+ try:
61
+ return self.session.request(method, self._url(path), **kwargs)
62
+ except requests.exceptions.Timeout as e:
63
+ raise CorePlexMLError(f"Request timed out: {e}") from e
64
+ except requests.exceptions.ConnectionError as e:
65
+ raise CorePlexMLError(f"Connection failed: {e}") from e
66
+ except requests.exceptions.RequestException as e:
67
+ raise CorePlexMLError(f"Request failed: {e}") from e
68
+
69
+ def _handle_response(self, resp: requests.Response) -> dict:
70
+ """Process HTTP response and raise typed exceptions on errors."""
71
+ if resp.status_code == 204:
72
+ return {}
73
+ try:
74
+ data = resp.json()
75
+ except Exception:
76
+ text = resp.text[:500] if resp.text else "No response body"
77
+ data = {"detail": text}
78
+
79
+ if resp.status_code >= 400:
80
+ detail = data.get("detail", str(data)) if isinstance(data, dict) else str(data)
81
+ msg = f"HTTP {resp.status_code}: {detail}"
82
+ if resp.status_code in (401, 403):
83
+ raise AuthenticationError(msg, resp.status_code, detail)
84
+ elif resp.status_code == 404:
85
+ raise NotFoundError(msg, resp.status_code, detail)
86
+ elif resp.status_code == 422:
87
+ raise ValidationError(msg, resp.status_code, detail)
88
+ else:
89
+ raise CorePlexMLError(msg, resp.status_code, detail)
90
+ return data
91
+
92
+ def get(self, path: str, params: dict | None = None) -> dict:
93
+ """Send GET request."""
94
+ resp = self._request("GET", path, params=params)
95
+ return self._handle_response(resp)
96
+
97
+ def post(self, path: str, json: dict | None = None, files: dict | None = None) -> dict:
98
+ """Send POST request."""
99
+ if files:
100
+ saved_ct = self.session.headers.pop("Content-Type", None)
101
+ try:
102
+ resp = self._request("POST", path, data=json, files=files)
103
+ finally:
104
+ if saved_ct:
105
+ self.session.headers["Content-Type"] = saved_ct
106
+ else:
107
+ resp = self._request("POST", path, json=json)
108
+ return self._handle_response(resp)
109
+
110
+ def put(self, path: str, json: dict | None = None) -> dict:
111
+ """Send PUT request."""
112
+ resp = self._request("PUT", path, json=json)
113
+ return self._handle_response(resp)
114
+
115
+ def patch(self, path: str, json: dict | None = None) -> dict:
116
+ """Send PATCH request."""
117
+ resp = self._request("PATCH", path, json=json)
118
+ return self._handle_response(resp)
119
+
120
+ def delete(self, path: str) -> dict:
121
+ """Send DELETE request."""
122
+ resp = self._request("DELETE", path)
123
+ return self._handle_response(resp)
124
+
125
+ def download(self, path: str, output_path: str, params: dict | None = None) -> str:
126
+ """Download a file from the API.
127
+
128
+ Returns:
129
+ The output_path where the file was saved.
130
+ """
131
+ resp = self._request("GET", path, params=params, stream=True)
132
+ if resp.status_code >= 400:
133
+ self._handle_response(resp) # raises typed exception
134
+ with open(output_path, "wb") as f:
135
+ for chunk in resp.iter_content(chunk_size=8192):
136
+ f.write(chunk)
137
+ return output_path
138
+
139
+ def poll_job(self, job_id: str, interval: float = 3.0, timeout: float = 600.0) -> dict:
140
+ """Poll a job until completion or timeout."""
141
+ start = time.time()
142
+ while time.time() - start < timeout:
143
+ data = self.get(f"/api/jobs/{job_id}")
144
+ job = data.get("job", data) if isinstance(data, dict) else {}
145
+ status = job.get("status", "") if isinstance(job, dict) else ""
146
+ if status in ("succeeded", "completed", "failed", "error"):
147
+ return job if isinstance(job, dict) else data
148
+ time.sleep(interval)
149
+ raise CorePlexMLError(f"Job {job_id} timed out after {timeout}s")
150
+
151
+ def upload(self, path: str, file_path: str, fields: dict | None = None) -> dict:
152
+ """Upload a file via multipart form."""
153
+ import os
154
+ filename = os.path.basename(file_path)
155
+ with open(file_path, "rb") as f:
156
+ files = {"file": (filename, f)}
157
+ return self.post(path, json=fields, files=files)
@@ -0,0 +1,76 @@
1
+ from __future__ import annotations
2
+
3
+ """Main CorePlexML client."""
4
+
5
+ from coreplexml._http import HTTPClient
6
+ from coreplexml.projects import ProjectsResource
7
+ from coreplexml.datasets import DatasetsResource
8
+ from coreplexml.experiments import ExperimentsResource
9
+ from coreplexml.models import ModelsResource
10
+ from coreplexml.deployments import DeploymentsResource
11
+ from coreplexml.reports import ReportsResource
12
+ from coreplexml.privacy import PrivacyResource
13
+ from coreplexml.synthgen import SynthGenResource
14
+ from coreplexml.studio import StudioResource
15
+
16
+
17
+ class CorePlexMLClient:
18
+ """Top-level client for the CorePlexML Python SDK.
19
+
20
+ Provides access to all API resources through typed sub-clients.
21
+
22
+ Args:
23
+ base_url: CorePlexML server URL (default ``http://localhost:8888``).
24
+ api_key: Bearer token for API authentication.
25
+ timeout: Request timeout in seconds (default 30).
26
+
27
+ Example::
28
+
29
+ from coreplexml import CorePlexMLClient
30
+
31
+ client = CorePlexMLClient("https://your-domain.com", api_key="your-key")
32
+ projects = client.projects.list()
33
+
34
+ Attributes:
35
+ projects: Manage projects.
36
+ datasets: Upload, list, and manage datasets.
37
+ experiments: Create and monitor AutoML experiments.
38
+ models: Get model info and make predictions.
39
+ deployments: Deploy models and manage production endpoints.
40
+ reports: Generate and download reports.
41
+ privacy: Privacy Suite -- PII detection and data transformation.
42
+ synthgen: Synthetic data generation with CTGAN/CopulaGAN/TVAE/Gaussian Copula.
43
+ studio: What-If Analysis -- scenario comparison.
44
+ """
45
+
46
+ def __init__(self, base_url: str = "http://localhost:8888", api_key: str | None = None, timeout: int = 30):
47
+ """Initialize the CorePlexML client.
48
+
49
+ Args:
50
+ base_url: Server URL (default ``http://localhost:8888``).
51
+ api_key: API key for Bearer authentication.
52
+ timeout: Request timeout in seconds.
53
+ """
54
+ self._http = HTTPClient(base_url, api_key=api_key, timeout=timeout)
55
+ self.projects = ProjectsResource(self._http)
56
+ self.datasets = DatasetsResource(self._http)
57
+ self.experiments = ExperimentsResource(self._http)
58
+ self.models = ModelsResource(self._http)
59
+ self.deployments = DeploymentsResource(self._http)
60
+ self.reports = ReportsResource(self._http)
61
+ self.privacy = PrivacyResource(self._http)
62
+ self.synthgen = SynthGenResource(self._http)
63
+ self.studio = StudioResource(self._http)
64
+
65
+ def close(self) -> None:
66
+ """Close the underlying HTTP session and release connections."""
67
+ self._http.close()
68
+
69
+ def __enter__(self):
70
+ return self
71
+
72
+ def __exit__(self, *args):
73
+ self.close()
74
+
75
+ def __repr__(self) -> str:
76
+ return f"CorePlexMLClient(base_url={self._http.base_url!r})"