abysshub 0.1.1.dev1__tar.gz → 0.1.1.dev2__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 (22) hide show
  1. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/PKG-INFO +3 -1
  2. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/README.md +2 -0
  3. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/pyproject.toml +1 -1
  4. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/_client.py +8 -0
  5. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/_error.py +8 -0
  6. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/tests/test_client.py +14 -0
  7. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/.gitignore +0 -0
  8. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/LICENSE +0 -0
  9. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/__init__.py +0 -0
  10. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/_async_client.py +0 -0
  11. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/_files.py +0 -0
  12. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/_http.py +0 -0
  13. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/_run.py +0 -0
  14. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/_types.py +0 -0
  15. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/src/abysshub/py.typed +0 -0
  16. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/tests/caller.py +0 -0
  17. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/tests/fake_server.py +0 -0
  18. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/tests/test_files.py +0 -0
  19. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/tests/test_http.py +0 -0
  20. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/tests/test_package.py +0 -0
  21. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/tests/test_replay.py +0 -0
  22. {abysshub-0.1.1.dev1 → abysshub-0.1.1.dev2}/tests/test_timeout.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: abysshub
3
- Version: 0.1.1.dev1
3
+ Version: 0.1.1.dev2
4
4
  Summary: The official Python library for the Abyss API.
5
5
  Project-URL: Homepage, https://abysshub.com
6
6
  Project-URL: Source, https://github.com/Abysshub/abysshub-sdk
@@ -133,6 +133,8 @@ A refusal, a failed run, a timeout and a lost connection all raise one class, `A
133
133
  | `param` | the Field, body key, query key or header at fault, else `None` |
134
134
  | `doc_url` | the code on the API access page, else `None` |
135
135
  | `request_id` | quote it to support, else `None` |
136
+ | `shortfall` | with `insufficient_funds`: how much Byssium the wallet is short, else `None` |
137
+ | `price` | with `price_above_max`: what the run costs now, else `None` |
136
138
  | `run` | the run, for a failed run or a timeout, else `None`; an `AsyncRun` from `AsyncAbyss` |
137
139
 
138
140
  - **Refusals:** `invalid_api_key` (401), `not_found` (404), `invalid_request`, `invalid_input`, `held_input_*`, `input_unreachable` and `idempotency_key_reused` (422), `insufficient_funds` (402), `spend_cap_reached` and `price_above_max` (400), `idempotency_key_in_use` (409), `rate_limited` (429), `server_error` (500).
@@ -116,6 +116,8 @@ A refusal, a failed run, a timeout and a lost connection all raise one class, `A
116
116
  | `param` | the Field, body key, query key or header at fault, else `None` |
117
117
  | `doc_url` | the code on the API access page, else `None` |
118
118
  | `request_id` | quote it to support, else `None` |
119
+ | `shortfall` | with `insufficient_funds`: how much Byssium the wallet is short, else `None` |
120
+ | `price` | with `price_above_max`: what the run costs now, else `None` |
119
121
  | `run` | the run, for a failed run or a timeout, else `None`; an `AsyncRun` from `AsyncAbyss` |
120
122
 
121
123
  - **Refusals:** `invalid_api_key` (401), `not_found` (404), `invalid_request`, `invalid_input`, `held_input_*`, `input_unreachable` and `idempotency_key_reused` (422), `insufficient_funds` (402), `spend_cap_reached` and `price_above_max` (400), `idempotency_key_in_use` (409), `rate_limited` (429), `server_error` (500).
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "abysshub"
7
- version = "0.1.1.dev1"
7
+ version = "0.1.1.dev2"
8
8
  description = "The official Python library for the Abyss API."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -535,6 +535,8 @@ def _refusal(status: int, body: Any, request_id: str | None) -> AbyssError:
535
535
  status=status,
536
536
  param=_text(error.get("param")),
537
537
  doc_url=_text(error.get("doc_url")),
538
+ shortfall=_number(error.get("shortfall")),
539
+ price=_number(error.get("price")),
538
540
  request_id=body_request_id if isinstance(body_request_id, str) else request_id,
539
541
  )
540
542
 
@@ -543,6 +545,12 @@ def _text(value: Any) -> str | None:
543
545
  return value if isinstance(value, str) else None
544
546
 
545
547
 
548
+ def _number(value: Any) -> float | None:
549
+ if isinstance(value, bool) or not isinstance(value, (int, float)):
550
+ return None
551
+ return float(value)
552
+
553
+
546
554
  def _parse(text: str | None) -> Any:
547
555
  if text is None:
548
556
  return None
@@ -19,6 +19,10 @@ class AbyssError(Exception):
19
19
  param: str | None
20
20
  doc_url: str | None
21
21
  request_id: str | None
22
+ shortfall: float | None
23
+ """With ``insufficient_funds``: how much Byssium the wallet is short; else None."""
24
+ price: float | None
25
+ """With ``price_above_max``: what the run costs now; else None."""
22
26
  run: Run | AsyncRun | None
23
27
  """The run, for a failed run or a timeout: an ``AsyncRun`` from ``AsyncAbyss``."""
24
28
 
@@ -31,6 +35,8 @@ class AbyssError(Exception):
31
35
  param: str | None = None,
32
36
  doc_url: str | None = None,
33
37
  request_id: str | None = None,
38
+ shortfall: float | None = None,
39
+ price: float | None = None,
34
40
  run: Run | AsyncRun | None = None,
35
41
  ) -> None:
36
42
  super().__init__(message)
@@ -40,6 +46,8 @@ class AbyssError(Exception):
40
46
  self.param = param
41
47
  self.doc_url = doc_url
42
48
  self.request_id = request_id
49
+ self.shortfall = shortfall
50
+ self.price = price
43
51
  self.run = run
44
52
 
45
53
  def __repr__(self) -> str:
@@ -67,3 +67,17 @@ def test_every_request_sends_the_user_agent() -> None:
67
67
  assert server.problems == []
68
68
  finally:
69
69
  server.close()
70
+
71
+
72
+ def test_a_refusal_without_shortfall_or_price_carries_none_for_both() -> None:
73
+ recording = load_exchanges("run-refused-invalid-input.json")[0]
74
+ server = Replay(recording, "abyss_sk_x")
75
+ try:
76
+ with Abyss(api_key="abyss_sk_x", base_url=server.base) as abyss, pytest.raises(AbyssError) as raised:
77
+ abyss.run(recording["call"]["widget"], recording["call"]["input"])
78
+ assert raised.value.code == "invalid_input"
79
+ assert raised.value.shortfall is None
80
+ assert raised.value.price is None
81
+ assert server.problems == []
82
+ finally:
83
+ server.close()
File without changes
File without changes