proxyml 0.1.3__tar.gz → 0.1.4__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.
- {proxyml-0.1.3 → proxyml-0.1.4}/PKG-INFO +1 -1
- {proxyml-0.1.3 → proxyml-0.1.4}/pyproject.toml +1 -1
- {proxyml-0.1.3 → proxyml-0.1.4}/src/proxyml/__init__.py +4 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/src/proxyml/client.py +26 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/src/proxyml.egg-info/PKG-INFO +1 -1
- {proxyml-0.1.3 → proxyml-0.1.4}/tests/test_client.py +49 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/LICENSE +0 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/README.md +0 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/setup.cfg +0 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/src/proxyml/schema.py +0 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/src/proxyml.egg-info/SOURCES.txt +0 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/src/proxyml.egg-info/dependency_links.txt +0 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/src/proxyml.egg-info/requires.txt +0 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/src/proxyml.egg-info/top_level.txt +0 -0
- {proxyml-0.1.3 → proxyml-0.1.4}/tests/test_schema.py +0 -0
|
@@ -12,6 +12,8 @@ from proxyml.client import (
|
|
|
12
12
|
diff_models,
|
|
13
13
|
list_models,
|
|
14
14
|
delete_model,
|
|
15
|
+
get_usage,
|
|
16
|
+
rotate_key,
|
|
15
17
|
)
|
|
16
18
|
from proxyml.schema import (
|
|
17
19
|
get_schema,
|
|
@@ -34,6 +36,8 @@ __all__ = [
|
|
|
34
36
|
"diff_models",
|
|
35
37
|
"list_models",
|
|
36
38
|
"delete_model",
|
|
39
|
+
"get_usage",
|
|
40
|
+
"rotate_key",
|
|
37
41
|
"get_schema",
|
|
38
42
|
"gen_continuous_schema",
|
|
39
43
|
"gen_categorical_schema",
|
|
@@ -316,6 +316,32 @@ def get_feature_importances(version: str | None = None):
|
|
|
316
316
|
return None
|
|
317
317
|
|
|
318
318
|
|
|
319
|
+
def get_usage() -> dict | None:
|
|
320
|
+
"""Return current tier, usage counts, and quota for the authenticated user."""
|
|
321
|
+
r = get(endpoint='/account/usage', params={})
|
|
322
|
+
if r.status_code == 200:
|
|
323
|
+
return r.json()
|
|
324
|
+
logger.error(
|
|
325
|
+
"Get usage failed with status %s: %s",
|
|
326
|
+
r.status_code,
|
|
327
|
+
r.text,
|
|
328
|
+
)
|
|
329
|
+
return None
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def rotate_key() -> str | None:
|
|
333
|
+
"""Rotate the API key, revoking all old keys. Returns the new key string or None on failure."""
|
|
334
|
+
r = post(endpoint='/account/keys/rotate', payload={})
|
|
335
|
+
if r.status_code == 201:
|
|
336
|
+
return r.json()['api_key']
|
|
337
|
+
logger.error(
|
|
338
|
+
"Key rotation failed with status %s: %s",
|
|
339
|
+
r.status_code,
|
|
340
|
+
r.text,
|
|
341
|
+
)
|
|
342
|
+
return None
|
|
343
|
+
|
|
344
|
+
|
|
319
345
|
def list_models() -> list[dict] | None:
|
|
320
346
|
"""Return metadata for all trained surrogate models, newest first."""
|
|
321
347
|
r = get(endpoint='/surrogate/models', params={})
|
|
@@ -11,11 +11,13 @@ from proxyml.client import (
|
|
|
11
11
|
diff_models,
|
|
12
12
|
find_counterfactuals,
|
|
13
13
|
get_model_summary,
|
|
14
|
+
get_usage,
|
|
14
15
|
interpret_counterfactual,
|
|
15
16
|
list_models,
|
|
16
17
|
predict,
|
|
17
18
|
predict_batch,
|
|
18
19
|
put_schema,
|
|
20
|
+
rotate_key,
|
|
19
21
|
synthesize_data,
|
|
20
22
|
train_surrogate,
|
|
21
23
|
)
|
|
@@ -420,3 +422,50 @@ def test_diff_models_success(mock_get):
|
|
|
420
422
|
def test_diff_models_failure_returns_none(mock_get):
|
|
421
423
|
mock_get.return_value = _mock_response(422, {"detail": "different tasks"})
|
|
422
424
|
assert diff_models(version_a="aaa-111", version_b="bbb-222") is None
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
# ---------------------------------------------------------------------------
|
|
428
|
+
# get_usage
|
|
429
|
+
# ---------------------------------------------------------------------------
|
|
430
|
+
|
|
431
|
+
_USAGE_RESPONSE = {
|
|
432
|
+
"tier": "hobbyist",
|
|
433
|
+
"period": "2026-04",
|
|
434
|
+
"calls_this_period": 42,
|
|
435
|
+
"calls_limit": 1000,
|
|
436
|
+
"calls_remaining": 958,
|
|
437
|
+
"surrogates_trained": 2,
|
|
438
|
+
"surrogate_limit": 3,
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
@patch("proxyml.client.get")
|
|
443
|
+
def test_get_usage_success(mock_get):
|
|
444
|
+
mock_get.return_value = _mock_response(200, _USAGE_RESPONSE)
|
|
445
|
+
result = get_usage()
|
|
446
|
+
assert result == _USAGE_RESPONSE
|
|
447
|
+
mock_get.assert_called_once_with(endpoint="/account/usage", params={})
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
@patch("proxyml.client.get")
|
|
451
|
+
def test_get_usage_failure_returns_none(mock_get):
|
|
452
|
+
mock_get.return_value = _mock_response(401, {"detail": "unauthorized"})
|
|
453
|
+
assert get_usage() is None
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
# ---------------------------------------------------------------------------
|
|
457
|
+
# rotate_key
|
|
458
|
+
# ---------------------------------------------------------------------------
|
|
459
|
+
|
|
460
|
+
@patch("proxyml.client.post")
|
|
461
|
+
def test_rotate_key_success(mock_post):
|
|
462
|
+
mock_post.return_value = _mock_response(201, {"api_key": "proxyml_new_secret_key"})
|
|
463
|
+
result = rotate_key()
|
|
464
|
+
assert result == "proxyml_new_secret_key"
|
|
465
|
+
mock_post.assert_called_once_with(endpoint="/account/keys/rotate", payload={})
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
@patch("proxyml.client.post")
|
|
469
|
+
def test_rotate_key_failure_returns_none(mock_post):
|
|
470
|
+
mock_post.return_value = _mock_response(403, {"detail": "Key rotation is not available for test accounts"})
|
|
471
|
+
assert rotate_key() is None
|
|
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
|