simulacrum-sdk 0.2.2__tar.gz → 0.2.3__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.
Potentially problematic release.
This version of simulacrum-sdk might be problematic. Click here for more details.
- {simulacrum_sdk-0.2.2/simulacrum_sdk.egg-info → simulacrum_sdk-0.2.3}/PKG-INFO +1 -1
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/pyproject.toml +1 -1
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum/client.py +3 -1
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum/models.py +19 -2
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3/simulacrum_sdk.egg-info}/PKG-INFO +1 -1
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/tests/test_client.py +10 -5
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/tests/test_errors.py +5 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/LICENSE +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/MANIFEST.in +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/README.md +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/setup.cfg +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum/__init__.py +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum/_errors.py +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum/api.py +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum/config.py +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum/exceptions.py +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum_sdk.egg-info/SOURCES.txt +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum_sdk.egg-info/dependency_links.txt +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum_sdk.egg-info/requires.txt +0 -0
- {simulacrum_sdk-0.2.2 → simulacrum_sdk-0.2.3}/simulacrum_sdk.egg-info/top_level.txt +0 -0
|
@@ -41,7 +41,7 @@ class Simulacrum:
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
def forecast(
|
|
44
|
-
self, series: Sequence[float] | np.ndarray, horizon: int, model: str = "default"
|
|
44
|
+
self, series: Sequence[float] | np.ndarray, horizon: int | None = None, model: str = "default"
|
|
45
45
|
) -> np.ndarray:
|
|
46
46
|
"""Request a forecast for the provided time series.
|
|
47
47
|
|
|
@@ -86,6 +86,8 @@ class Simulacrum:
|
|
|
86
86
|
series=series_to_send, horizon=horizon, model=model
|
|
87
87
|
)
|
|
88
88
|
request_body: Dict[str, Any] = payload.model_dump()
|
|
89
|
+
# Exclude optional fields that are None (e.g., horizon for onsiteiq)
|
|
90
|
+
request_body = payload.model_dump(exclude_none=True)
|
|
89
91
|
response_data: Dict[str, Any] = send_request(
|
|
90
92
|
method="POST",
|
|
91
93
|
url=f"{self.base_url}/{model}/v1/forecast",
|
|
@@ -12,7 +12,7 @@ class ForecastRequest(BaseModel):
|
|
|
12
12
|
|
|
13
13
|
Attributes:
|
|
14
14
|
series (list[float]): Historical observations used as forecast input.
|
|
15
|
-
horizon (int): Number of future periods to predict.
|
|
15
|
+
horizon (int | None): Number of future periods to predict. Optional for the ``"onsiteiq"`` model.
|
|
16
16
|
model (str | None): Identifier of the forecasting model, defaults to ``"default"``.
|
|
17
17
|
|
|
18
18
|
Example:
|
|
@@ -23,7 +23,7 @@ class ForecastRequest(BaseModel):
|
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
25
|
series: List[float]
|
|
26
|
-
horizon: int
|
|
26
|
+
horizon: Optional[int] = None
|
|
27
27
|
model: Optional[str] = "default"
|
|
28
28
|
|
|
29
29
|
@field_validator("series", mode="before")
|
|
@@ -41,6 +41,23 @@ class ForecastRequest(BaseModel):
|
|
|
41
41
|
return value.astype(float).tolist()
|
|
42
42
|
return list(value)
|
|
43
43
|
|
|
44
|
+
@model_validator(mode="after")
|
|
45
|
+
def _validate_horizon_requirement(self):
|
|
46
|
+
# Horizon is required for all models except onsiteiq
|
|
47
|
+
model_name = (self.model or "").lower()
|
|
48
|
+
if model_name != "onsiteiq" and self.horizon is None:
|
|
49
|
+
raise ValueError("horizon is required and must be a positive integer for this model")
|
|
50
|
+
|
|
51
|
+
# When provided, horizon must be an integer >= 1
|
|
52
|
+
if self.horizon is not None:
|
|
53
|
+
if not isinstance(self.horizon, int):
|
|
54
|
+
raise ValueError(
|
|
55
|
+
f"horizon must be an integer (got {type(self.horizon).__name__})"
|
|
56
|
+
)
|
|
57
|
+
if self.horizon < 1:
|
|
58
|
+
raise ValueError("horizon must be >= 1")
|
|
59
|
+
return self
|
|
60
|
+
|
|
44
61
|
|
|
45
62
|
class ForecastResponse(BaseModel):
|
|
46
63
|
"""Forecast output returned by the API.
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
# Ensure package import works when running tests directly
|
|
5
|
+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
2
6
|
import pytest
|
|
3
7
|
import numpy as np
|
|
4
8
|
|
|
@@ -9,12 +13,13 @@ import simulacrum.client as simulacrum_client
|
|
|
9
13
|
|
|
10
14
|
@pytest.fixture
|
|
11
15
|
def client():
|
|
12
|
-
base_url = os.environ
|
|
13
|
-
|
|
16
|
+
base_url = os.environ["TEST_API"]
|
|
17
|
+
api_key = os.environ["TEST_KEY"]
|
|
18
|
+
return simulacrum_client.Simulacrum(api_key, base_url=base_url)
|
|
14
19
|
|
|
15
20
|
|
|
16
21
|
def test_client_initializes_expected_headers(client):
|
|
17
|
-
assert client.headers["Authorization"] == f"Bearer {
|
|
22
|
+
assert client.headers["Authorization"] == f"Bearer {client.api_key}"
|
|
18
23
|
assert client.headers["Content-Type"] == "application/json"
|
|
19
24
|
|
|
20
25
|
|
|
@@ -57,7 +62,7 @@ def test_forecast_builds_payload_and_returns_numpy_array(client, monkeypatch):
|
|
|
57
62
|
captured_payload["horizon"] = horizon
|
|
58
63
|
captured_payload["model"] = model
|
|
59
64
|
|
|
60
|
-
def model_dump(self):
|
|
65
|
+
def model_dump(self, *args, **kwargs):
|
|
61
66
|
return {
|
|
62
67
|
"series": captured_payload["series"],
|
|
63
68
|
"horizon": captured_payload["horizon"],
|
|
@@ -85,7 +90,7 @@ def test_forecast_builds_payload_and_returns_numpy_array(client, monkeypatch):
|
|
|
85
90
|
assert captured_payload["horizon"] == 2
|
|
86
91
|
assert captured_payload["model"] == "prophet"
|
|
87
92
|
assert captured_payload["method"] == "POST"
|
|
88
|
-
assert captured_payload["url"] == "
|
|
93
|
+
assert captured_payload["url"] == f"{client.base_url}/prophet/v1/forecast"
|
|
89
94
|
assert captured_payload["headers"] == client.headers
|
|
90
95
|
assert captured_payload["json"] == {
|
|
91
96
|
"series": [1.0, 2.0, 3.0],
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import json
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
# Ensure package import works when running tests directly
|
|
6
|
+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
2
7
|
from datetime import datetime, timedelta, timezone
|
|
3
8
|
|
|
4
9
|
from simulacrum._errors import parse_error
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|