skill-verification-sdk 26.317.639__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 (65) hide show
  1. skill_verification_sdk-26.317.639/LICENSE +21 -0
  2. skill_verification_sdk-26.317.639/PKG-INFO +283 -0
  3. skill_verification_sdk-26.317.639/README.md +252 -0
  4. skill_verification_sdk-26.317.639/apimatic_calculator_test/__init__.py +13 -0
  5. skill_verification_sdk-26.317.639/apimatic_calculator_test/async_client.py +135 -0
  6. skill_verification_sdk-26.317.639/apimatic_calculator_test/base_client.py +27 -0
  7. skill_verification_sdk-26.317.639/apimatic_calculator_test/client.py +123 -0
  8. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/__init__.py +427 -0
  9. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/__init__.py +9 -0
  10. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/content_disposition.py +154 -0
  11. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/flattening.py +104 -0
  12. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/headers.py +243 -0
  13. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/redaction.py +208 -0
  14. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/sse_parser.py +124 -0
  15. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/subscripts.py +50 -0
  16. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/urls.py +194 -0
  17. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/_internal/wire.py +208 -0
  18. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/adapters.py +177 -0
  19. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/__init__.py +66 -0
  20. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/composition.py +219 -0
  21. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/models.py +180 -0
  22. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/protocols.py +104 -0
  23. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/schemes/__init__.py +94 -0
  24. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/schemes/api_key_auth.py +53 -0
  25. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/schemes/basic_auth.py +73 -0
  26. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/schemes/bearer_auth.py +21 -0
  27. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/schemes/oauth2_authorization_code.py +394 -0
  28. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/schemes/oauth2_client_credentials.py +129 -0
  29. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/schemes/oauth2_password.py +144 -0
  30. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/auth/schemes/oauth2_schemes.py +300 -0
  31. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/base_raw_response.py +49 -0
  32. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/bodies.py +590 -0
  33. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/converters/__init__.py +68 -0
  34. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/converters/date_time.py +237 -0
  35. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/converters/encoded_bytes.py +273 -0
  36. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/converters/open_enum.py +35 -0
  37. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/decoding.py +498 -0
  38. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/discriminators.py +129 -0
  39. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/event_streams.py +261 -0
  40. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/exceptions.py +167 -0
  41. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/file_responses.py +388 -0
  42. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/files.py +174 -0
  43. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/hooks.py +259 -0
  44. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/httpx2_transport.py +855 -0
  45. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/logging.py +473 -0
  46. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/models.py +143 -0
  47. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/optionality.py +166 -0
  48. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/pagination.py +477 -0
  49. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/paginator.py +55 -0
  50. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/params.py +157 -0
  51. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/raw_client.py +650 -0
  52. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/request_options.py +239 -0
  53. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/results.py +197 -0
  54. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/retries.py +237 -0
  55. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/runtime_env.py +43 -0
  56. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/servers.py +33 -0
  57. skill_verification_sdk-26.317.639/apimatic_calculator_test/core/transport.py +241 -0
  58. skill_verification_sdk-26.317.639/apimatic_calculator_test/models/__init__.py +3 -0
  59. skill_verification_sdk-26.317.639/apimatic_calculator_test/models/enums/__init__.py +3 -0
  60. skill_verification_sdk-26.317.639/apimatic_calculator_test/models/enums/operation_type.py +18 -0
  61. skill_verification_sdk-26.317.639/apimatic_calculator_test/py.typed +0 -0
  62. skill_verification_sdk-26.317.639/apimatic_calculator_test/server/__init__.py +4 -0
  63. skill_verification_sdk-26.317.639/apimatic_calculator_test/server/server.py +14 -0
  64. skill_verification_sdk-26.317.639/apimatic_calculator_test/server/server_config.py +13 -0
  65. skill_verification_sdk-26.317.639/pyproject.toml +74 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 APIMatic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,283 @@
1
+ Metadata-Version: 2.4
2
+ Name: skill-verification-sdk
3
+ Version: 26.317.639
4
+ Summary: USE DEMO TO TEST SKILL
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Keywords: sdk,api-client,openapi,rest,http,apimatic
8
+ Author: Hassan
9
+ Author-email: hassan.sattar@apimatic.io
10
+ Maintainer: APIMatic
11
+ Maintainer-email: support@apimatic.io
12
+ Requires-Python: >=3.10
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Typing :: Typed
21
+ Classifier: Operating System :: OS Independent
22
+ Classifier: Topic :: Internet :: WWW/HTTP
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Dist: certifi (>=2024.7.4)
25
+ Requires-Dist: httpx2 (>=2.13.1,<3.0.0)
26
+ Requires-Dist: pydantic[email] (>=2.11.0,<3.0.0)
27
+ Requires-Dist: typing-extensions (>=4.13.0,<5.0.0)
28
+ Project-URL: Documentation, https://doc.io
29
+ Description-Content-Type: text/markdown
30
+
31
+ # APIMATIC Calculator-test SDK
32
+
33
+ [![Built with APIMatic][apimatic-badge]][apimatic-url] [![License: MIT][license-badge]][license-url] [![Python 3.10+][python-badge]][python-url]
34
+
35
+ The APIMATIC Calculator-test SDK for Python provides access to the APIMATIC Calculator-test REST APIs from Python applications.
36
+
37
+ > [!TIP]
38
+ > **Looking for a specific signature, model, enum, or error type?** This SDK ships a generated
39
+ > **[SDK map](sdk-map.md)** -- a lookup index of the SDK's entire Python surface. Consult it before
40
+ > scanning the source tree; details under [SDK map](#sdk-map).
41
+
42
+ Simple calculator API hosted on APIMATIC for demo purposes
43
+
44
+ ---
45
+
46
+ ## Installation
47
+
48
+ To install the Python SDK from PyPI, with whichever package manager your project uses:
49
+
50
+ ```bash
51
+ pip install skill-verification-sdk
52
+ ```
53
+
54
+ ```bash
55
+ uv add skill-verification-sdk
56
+ ```
57
+
58
+ ```bash
59
+ poetry add skill-verification-sdk
60
+ ```
61
+
62
+ To install from the SDK source instead, give the tool a path containing a slash — a bare folder name is looked up on PyPI, and resolves to whatever project holds that name there:
63
+
64
+ ```bash
65
+ pip install <path-to-sdk>
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Quick Start
71
+
72
+ ### Synchronous client
73
+
74
+ Construct `ApimaticCalculatorTestClient` with keyword arguments, and call `close()` when you are done. Every argument is optional; the full list is in the [SDK map](sdk-map.md).
75
+
76
+ ```python
77
+ from apimatic_calculator_test import ApimaticCalculatorTestClient
78
+
79
+ client = ApimaticCalculatorTestClient()
80
+
81
+ # TODO: call endpoints here -- see api-reference.md
82
+
83
+ client.close()
84
+ ```
85
+
86
+ Alternatively, scope it -- `with ApimaticCalculatorTestClient(...) as client:` closes the pool on exit; see [Best Practices](#best-practices).
87
+
88
+ `Client` is exported as an alias of `ApimaticCalculatorTestClient`, so `from apimatic_calculator_test import Client` also works.
89
+
90
+ The SDK accepts every model-typed input in two interchangeable spellings, both type-checked: the typed model, or a plain dict with the same keys -- the `OrDict` and `Model | ModelDict` unions in the [SDK map](sdk-map.md). Pick whichever suits the call site: the dict form needs no import, while the model form adds a keyword-checked constructor and editor completion.
91
+
92
+ ### Asynchronous client
93
+
94
+ `AsyncApimaticCalculatorTestClient` mirrors `ApimaticCalculatorTestClient` with **identical method names**, and every endpoint method is a coroutine. It takes the same arguments, with some differences -- for example, the transport argument is `custom_async_http_client`.
95
+
96
+ ```python
97
+ from asyncio import run
98
+
99
+ from apimatic_calculator_test import AsyncApimaticCalculatorTestClient
100
+
101
+
102
+ async def main() -> None:
103
+ client = AsyncApimaticCalculatorTestClient()
104
+ # TODO: call endpoints here, awaiting each -- see api-reference.md
105
+ await client.aclose()
106
+
107
+
108
+ run(main())
109
+ ```
110
+
111
+ Alternatively, scope it -- `async with AsyncApimaticCalculatorTestClient(...) as client:` closes the pool on exit. Only the async spelling is `aclose`, matching httpx2; see [Best Practices](#best-practices).
112
+
113
+ `AsyncClient` is the exported alias. Each client accepts **only** its own transport argument; passing the other's is a `TypeError` at runtime and an error under mypy.
114
+
115
+ ---
116
+
117
+ ## Usage
118
+
119
+ Two generated references cover the SDK; each answers a different question:
120
+
121
+ | Reference | For |
122
+ | --- | --- |
123
+ | **[API Reference](api-reference.md)** | Usage guidance for a single **parsed** operation: `client.<group>.<operation>(...)` returns the typed payload and raises `ApiError` on any non-2xx, with `.error` the typed error body, or `RawError` for a status the operation does not document. |
124
+ | **[Raw API Reference](raw-api-reference.md)** | The same for the **raw** variant: `client.<group>.with_raw_response.<operation>(...)` returns `ApiResult[T, E]` and never raises for an API error. |
125
+
126
+ Both API references carry every one of the 1 operation, with a sync and an async sample and a parameter table each.
127
+
128
+ ## SDK map
129
+
130
+ This SDK ships a generated **SDK map** -- [`sdk-map.md`](sdk-map.md) -- a deterministic, lookup-oriented table of contents of the SDK's Python surface, generated by APIMatic alongside this SDK.
131
+
132
+ Consult the map before scanning or grepping the source: it answers call-level contract questions by lookup, and for anything it does not carry -- model shapes, enum values, an endpoint's route or behavioural prose -- it names the one source file to read. How to read the map itself, including the SDK-wide defaults its rows rely on, is stated at the top of [`sdk-map.md`](sdk-map.md).
133
+
134
+ ## Error handling
135
+
136
+ Everything the SDK raises for a call derives from `SdkError`, which names the call as `method` and `url` (the path, never the query); the underlying exception is `__cause__`. No message carries a response body. The raw variant (`.with_raw_response`) returns an error status as a `Failure` instead of raising `ApiError`; the rest of the family raises in both modes.
137
+
138
+ ```python
139
+ from apimatic_calculator_test.core import ApiError, SdkConnectionError, SdkError
140
+
141
+ try:
142
+ response = client.calculate(OperationType.SUM, 1.5, 1.5)
143
+ except ApiError as e:
144
+ # An error status: the decoded body is e.error.
145
+ print(e.status_code, e.error)
146
+ except SdkConnectionError as e:
147
+ # No response, or the body could not be read.
148
+ print(e, repr(e.__cause__))
149
+ except SdkError as e:
150
+ # Anything else the SDK raises for a call.
151
+ print(e)
152
+ except Exception as e:
153
+ # Not a call failure: input refused before sending (ValueError), a handler you wrote raising, or a bug here.
154
+ print(f"not a call failure: {e!r}")
155
+ raise e
156
+ ```
157
+
158
+ | Exception | When | Extra attributes |
159
+ | --- | --- | --- |
160
+ | `ApiError[E]` | an error status | `error`, `status_code`, `headers` |
161
+ | `ResponseDecodeError` | a body that does not match its declared type | `status_code`, `headers` |
162
+ | `SdkConnectionError` | the request could not be sent, or the body could not be read | |
163
+ | `SdkTimeoutError` | a `SdkConnectionError` that timed out | `timeout` |
164
+ | `AuthSchemeError` | a credential could not be applied | `scheme_failures` |
165
+
166
+ Your own cancellation is never wrapped, and a value the SDK refuses before sending stays a `ValueError`. Each operation's typed error arms are on its [SDK map](sdk-map.md) page.
167
+
168
+ ## Logging
169
+
170
+ The SDK logs every HTTP exchange through Python's standard `logging` module, under the `apimatic_calculator_test` logger, and configures nothing itself: with no logging set up, nothing is printed unless `APIMATIC_CALCULATOR_TEST_LOG` is set. Turn it on as for any library:
171
+
172
+ ```python
173
+ import logging
174
+
175
+ logging.basicConfig() # your application's handler; the root stays at WARNING
176
+ logging.getLogger("apimatic_calculator_test").setLevel(logging.INFO) # the SDK's lines; DEBUG adds the dumps that logging_options turns on
177
+ ```
178
+
179
+ Or set one environment variable before the process starts, for a run you cannot edit: `APIMATIC_CALCULATOR_TEST_LOG=info` writes the request and response lines, `APIMATIC_CALCULATOR_TEST_LOG=debug` adds the request headers, the request body and the response headers. If your application has configured logging, its handlers and format are used; otherwise the SDK writes to stderr.
180
+
181
+ Choose the detail with `logging_options`, a `LoggingOptions` from `apimatic_calculator_test.core`:
182
+
183
+ ```python
184
+ from apimatic_calculator_test import ApimaticCalculatorTestClient
185
+ from apimatic_calculator_test.core import LoggingOptions
186
+
187
+ client = ApimaticCalculatorTestClient(
188
+ logging_options=LoggingOptions(log_request_headers=True, log_response_headers=True, log_request_body=True)
189
+ )
190
+ ```
191
+
192
+ A plain dict with the same keys is accepted too, as for every model-typed argument (see [Quick Start](#quick-start)): `logging_options={"log_request_headers": True}`.
193
+
194
+ | Option | Default | Effect |
195
+ | --- | --- | --- |
196
+ | `log_request_headers` | `False` | Log the sent headers at DEBUG, masked. |
197
+ | `log_response_headers` | `False` | Log the received headers at DEBUG, masked. |
198
+ | `log_request_body` | `False` | Log the request body at DEBUG: its text when in memory, a description when streamed. |
199
+ | `body_size_limit` | `32768` | Bytes of a logged body kept before it is cut. |
200
+ | `redaction_placeholder` | `"REDACTED"` | What a hidden value prints as. |
201
+ | `unmask_headers` | none | Header names to show although they are not on the safe list. |
202
+ | `mask_headers` | none | Header names to hide although they are on the safe list. |
203
+ | `mask_keys` | 11 credential names | Query and form keys whose values are always hidden; naming a set replaces the default. |
204
+
205
+ A single call can be quietened with `request_options={"log_level": logging.WARNING}`: records below that level are not written for that call. It never turns on a record the client's options leave off. Header, query and form values print `REDACTED` unless known safe; a JSON body is printed as sent, so enable `log_request_body` only where its content may be logged; a response body is never logged. The levels and every field are under **Logging** in the SDK map.
206
+
207
+ ## Hooks
208
+
209
+ A hook is your code run on every attempt of every request. `before_request` gets the request after it is built and authenticated, and returns the request to send. `after_response` gets the response and returns the one the call acts on: the same one, or your own object implementing `HttpResponse`. Subclass `SdkHook` and override either one, or pass plain functions keyed by the event they run on:
210
+
211
+ ```python
212
+ from dataclasses import replace
213
+
214
+ from apimatic_calculator_test import ApimaticCalculatorTestClient
215
+ from apimatic_calculator_test.core import HookContext, HttpRequest, HttpResponse, SdkHook
216
+
217
+
218
+ # new_traceparent() and record() stand for your own tracer and metrics sink.
219
+ class Tracing(SdkHook):
220
+ def before_request(self, request: HttpRequest, context: HookContext) -> HttpRequest:
221
+ return replace(request, headers={**request.headers, "traceparent": new_traceparent()})
222
+
223
+ def after_response(self, response: HttpResponse, context: HookContext) -> HttpResponse:
224
+ record(context.method, context.url, response.status_code)
225
+ return response
226
+
227
+
228
+ client = ApimaticCalculatorTestClient(hooks=[Tracing()])
229
+
230
+
231
+ # Or plain functions, with nothing to subclass:
232
+ def add_tenant(request: HttpRequest, context: HookContext) -> HttpRequest:
233
+ return replace(request, headers={**request.headers, "x-tenant": "acme"})
234
+
235
+
236
+ def print_status(response: HttpResponse, context: HookContext) -> HttpResponse:
237
+ print(context.method, response.status_code)
238
+ return response
239
+
240
+
241
+ client = ApimaticCalculatorTestClient(hooks={"on_request": [add_tenant], "on_response": [print_status]})
242
+ ```
243
+
244
+ A single call adds its own the same way, `request_options={"hooks": {"on_request": [add_tenant]}}` or `{"hooks": [Tracing()]}`: they run after the client's, never instead of them.
245
+
246
+ **Two spellings, one per place.** `hooks` takes a list of hook objects or the `{"on_request": [...], "on_response": [...]}` dict, on the client and in `request_options` alike — not a mix of the two in one place. A hook that keeps state between the request and its response is a class. A key other than those two is a type error, and is ignored at run time.
247
+
248
+ **When they run.** On every attempt, retries included, after authentication: the client's hooks, then the call's.
249
+
250
+ **On `AsyncApimaticCalculatorTestClient`** the same shape is `AsyncSdkHook`, whose methods are `async def` and take an `AsyncHookContext` and an `AsyncHttpResponse`; the dict takes `async def` functions under the same two keys, and a call's hooks go in `AsyncRequestOptions`. A hook of the other client's flavour is a type error, not a run-time check.
251
+
252
+ **Changing the response.** The retry decision and the result read the response the last hook returns; the log line shows what the server sent. A hook that reads the body must return a response that still carries it, and one that returns a different response must close the original or keep it inside.
253
+
254
+ ## Best Practices
255
+
256
+ > [!TIP]
257
+ > Use a **single `ApimaticCalculatorTestClient` instance** for the lifetime of your application and reuse it across
258
+ > all requests. Each instance owns its own connection pool, so an instance per request forfeits
259
+ > connection reuse and leaks pools that are never closed.
260
+
261
+ Match the disposal to the client's lifetime: an application-lifetime client is closed once at shutdown with `close()` / `aclose()`; where the lifetime fits a block, `with ApimaticCalculatorTestClient() as client:` / `async with AsyncApimaticCalculatorTestClient() as client:` releases it automatically. Both are idempotent, but a closed client is not reusable: the next call raises. The client closes **whatever transport it holds**, including one you supplied via `custom_http_client` / `custom_async_http_client`; if you intend to reuse your own transport across clients, don't hand its lifetime to a `with` block.
262
+
263
+ **Retries are on by default**: a failed idempotent request — a retryable status or no response at all — is sent again up to three times before the call gives up. Pass `retry_options=0` to turn it off, for instance in a test that stubs an error response; the policy and its defaults are under **Retries** in the SDK map.
264
+
265
+ ## License
266
+
267
+ This SDK is distributed under the [MIT License][license-url].
268
+
269
+ ---
270
+
271
+ ## Support
272
+
273
+ Refer to the [API reference](api-reference.md) for detailed information on available operations with code samples.
274
+
275
+ ---
276
+
277
+ [license-url]: LICENSE
278
+ [license-badge]: https://img.shields.io/badge/License-MIT-blue.svg
279
+ [apimatic-url]: https://www.apimatic.io
280
+ [apimatic-badge]: https://www.apimatic.io/hubfs/Built-with-APIMatic-badge.svg
281
+ [python-url]: https://www.python.org/downloads/
282
+ [python-badge]: https://img.shields.io/badge/python-3.10%2B-blue.svg
283
+
@@ -0,0 +1,252 @@
1
+ # APIMATIC Calculator-test SDK
2
+
3
+ [![Built with APIMatic][apimatic-badge]][apimatic-url] [![License: MIT][license-badge]][license-url] [![Python 3.10+][python-badge]][python-url]
4
+
5
+ The APIMATIC Calculator-test SDK for Python provides access to the APIMATIC Calculator-test REST APIs from Python applications.
6
+
7
+ > [!TIP]
8
+ > **Looking for a specific signature, model, enum, or error type?** This SDK ships a generated
9
+ > **[SDK map](sdk-map.md)** -- a lookup index of the SDK's entire Python surface. Consult it before
10
+ > scanning the source tree; details under [SDK map](#sdk-map).
11
+
12
+ Simple calculator API hosted on APIMATIC for demo purposes
13
+
14
+ ---
15
+
16
+ ## Installation
17
+
18
+ To install the Python SDK from PyPI, with whichever package manager your project uses:
19
+
20
+ ```bash
21
+ pip install skill-verification-sdk
22
+ ```
23
+
24
+ ```bash
25
+ uv add skill-verification-sdk
26
+ ```
27
+
28
+ ```bash
29
+ poetry add skill-verification-sdk
30
+ ```
31
+
32
+ To install from the SDK source instead, give the tool a path containing a slash — a bare folder name is looked up on PyPI, and resolves to whatever project holds that name there:
33
+
34
+ ```bash
35
+ pip install <path-to-sdk>
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Quick Start
41
+
42
+ ### Synchronous client
43
+
44
+ Construct `ApimaticCalculatorTestClient` with keyword arguments, and call `close()` when you are done. Every argument is optional; the full list is in the [SDK map](sdk-map.md).
45
+
46
+ ```python
47
+ from apimatic_calculator_test import ApimaticCalculatorTestClient
48
+
49
+ client = ApimaticCalculatorTestClient()
50
+
51
+ # TODO: call endpoints here -- see api-reference.md
52
+
53
+ client.close()
54
+ ```
55
+
56
+ Alternatively, scope it -- `with ApimaticCalculatorTestClient(...) as client:` closes the pool on exit; see [Best Practices](#best-practices).
57
+
58
+ `Client` is exported as an alias of `ApimaticCalculatorTestClient`, so `from apimatic_calculator_test import Client` also works.
59
+
60
+ The SDK accepts every model-typed input in two interchangeable spellings, both type-checked: the typed model, or a plain dict with the same keys -- the `OrDict` and `Model | ModelDict` unions in the [SDK map](sdk-map.md). Pick whichever suits the call site: the dict form needs no import, while the model form adds a keyword-checked constructor and editor completion.
61
+
62
+ ### Asynchronous client
63
+
64
+ `AsyncApimaticCalculatorTestClient` mirrors `ApimaticCalculatorTestClient` with **identical method names**, and every endpoint method is a coroutine. It takes the same arguments, with some differences -- for example, the transport argument is `custom_async_http_client`.
65
+
66
+ ```python
67
+ from asyncio import run
68
+
69
+ from apimatic_calculator_test import AsyncApimaticCalculatorTestClient
70
+
71
+
72
+ async def main() -> None:
73
+ client = AsyncApimaticCalculatorTestClient()
74
+ # TODO: call endpoints here, awaiting each -- see api-reference.md
75
+ await client.aclose()
76
+
77
+
78
+ run(main())
79
+ ```
80
+
81
+ Alternatively, scope it -- `async with AsyncApimaticCalculatorTestClient(...) as client:` closes the pool on exit. Only the async spelling is `aclose`, matching httpx2; see [Best Practices](#best-practices).
82
+
83
+ `AsyncClient` is the exported alias. Each client accepts **only** its own transport argument; passing the other's is a `TypeError` at runtime and an error under mypy.
84
+
85
+ ---
86
+
87
+ ## Usage
88
+
89
+ Two generated references cover the SDK; each answers a different question:
90
+
91
+ | Reference | For |
92
+ | --- | --- |
93
+ | **[API Reference](api-reference.md)** | Usage guidance for a single **parsed** operation: `client.<group>.<operation>(...)` returns the typed payload and raises `ApiError` on any non-2xx, with `.error` the typed error body, or `RawError` for a status the operation does not document. |
94
+ | **[Raw API Reference](raw-api-reference.md)** | The same for the **raw** variant: `client.<group>.with_raw_response.<operation>(...)` returns `ApiResult[T, E]` and never raises for an API error. |
95
+
96
+ Both API references carry every one of the 1 operation, with a sync and an async sample and a parameter table each.
97
+
98
+ ## SDK map
99
+
100
+ This SDK ships a generated **SDK map** -- [`sdk-map.md`](sdk-map.md) -- a deterministic, lookup-oriented table of contents of the SDK's Python surface, generated by APIMatic alongside this SDK.
101
+
102
+ Consult the map before scanning or grepping the source: it answers call-level contract questions by lookup, and for anything it does not carry -- model shapes, enum values, an endpoint's route or behavioural prose -- it names the one source file to read. How to read the map itself, including the SDK-wide defaults its rows rely on, is stated at the top of [`sdk-map.md`](sdk-map.md).
103
+
104
+ ## Error handling
105
+
106
+ Everything the SDK raises for a call derives from `SdkError`, which names the call as `method` and `url` (the path, never the query); the underlying exception is `__cause__`. No message carries a response body. The raw variant (`.with_raw_response`) returns an error status as a `Failure` instead of raising `ApiError`; the rest of the family raises in both modes.
107
+
108
+ ```python
109
+ from apimatic_calculator_test.core import ApiError, SdkConnectionError, SdkError
110
+
111
+ try:
112
+ response = client.calculate(OperationType.SUM, 1.5, 1.5)
113
+ except ApiError as e:
114
+ # An error status: the decoded body is e.error.
115
+ print(e.status_code, e.error)
116
+ except SdkConnectionError as e:
117
+ # No response, or the body could not be read.
118
+ print(e, repr(e.__cause__))
119
+ except SdkError as e:
120
+ # Anything else the SDK raises for a call.
121
+ print(e)
122
+ except Exception as e:
123
+ # Not a call failure: input refused before sending (ValueError), a handler you wrote raising, or a bug here.
124
+ print(f"not a call failure: {e!r}")
125
+ raise e
126
+ ```
127
+
128
+ | Exception | When | Extra attributes |
129
+ | --- | --- | --- |
130
+ | `ApiError[E]` | an error status | `error`, `status_code`, `headers` |
131
+ | `ResponseDecodeError` | a body that does not match its declared type | `status_code`, `headers` |
132
+ | `SdkConnectionError` | the request could not be sent, or the body could not be read | |
133
+ | `SdkTimeoutError` | a `SdkConnectionError` that timed out | `timeout` |
134
+ | `AuthSchemeError` | a credential could not be applied | `scheme_failures` |
135
+
136
+ Your own cancellation is never wrapped, and a value the SDK refuses before sending stays a `ValueError`. Each operation's typed error arms are on its [SDK map](sdk-map.md) page.
137
+
138
+ ## Logging
139
+
140
+ The SDK logs every HTTP exchange through Python's standard `logging` module, under the `apimatic_calculator_test` logger, and configures nothing itself: with no logging set up, nothing is printed unless `APIMATIC_CALCULATOR_TEST_LOG` is set. Turn it on as for any library:
141
+
142
+ ```python
143
+ import logging
144
+
145
+ logging.basicConfig() # your application's handler; the root stays at WARNING
146
+ logging.getLogger("apimatic_calculator_test").setLevel(logging.INFO) # the SDK's lines; DEBUG adds the dumps that logging_options turns on
147
+ ```
148
+
149
+ Or set one environment variable before the process starts, for a run you cannot edit: `APIMATIC_CALCULATOR_TEST_LOG=info` writes the request and response lines, `APIMATIC_CALCULATOR_TEST_LOG=debug` adds the request headers, the request body and the response headers. If your application has configured logging, its handlers and format are used; otherwise the SDK writes to stderr.
150
+
151
+ Choose the detail with `logging_options`, a `LoggingOptions` from `apimatic_calculator_test.core`:
152
+
153
+ ```python
154
+ from apimatic_calculator_test import ApimaticCalculatorTestClient
155
+ from apimatic_calculator_test.core import LoggingOptions
156
+
157
+ client = ApimaticCalculatorTestClient(
158
+ logging_options=LoggingOptions(log_request_headers=True, log_response_headers=True, log_request_body=True)
159
+ )
160
+ ```
161
+
162
+ A plain dict with the same keys is accepted too, as for every model-typed argument (see [Quick Start](#quick-start)): `logging_options={"log_request_headers": True}`.
163
+
164
+ | Option | Default | Effect |
165
+ | --- | --- | --- |
166
+ | `log_request_headers` | `False` | Log the sent headers at DEBUG, masked. |
167
+ | `log_response_headers` | `False` | Log the received headers at DEBUG, masked. |
168
+ | `log_request_body` | `False` | Log the request body at DEBUG: its text when in memory, a description when streamed. |
169
+ | `body_size_limit` | `32768` | Bytes of a logged body kept before it is cut. |
170
+ | `redaction_placeholder` | `"REDACTED"` | What a hidden value prints as. |
171
+ | `unmask_headers` | none | Header names to show although they are not on the safe list. |
172
+ | `mask_headers` | none | Header names to hide although they are on the safe list. |
173
+ | `mask_keys` | 11 credential names | Query and form keys whose values are always hidden; naming a set replaces the default. |
174
+
175
+ A single call can be quietened with `request_options={"log_level": logging.WARNING}`: records below that level are not written for that call. It never turns on a record the client's options leave off. Header, query and form values print `REDACTED` unless known safe; a JSON body is printed as sent, so enable `log_request_body` only where its content may be logged; a response body is never logged. The levels and every field are under **Logging** in the SDK map.
176
+
177
+ ## Hooks
178
+
179
+ A hook is your code run on every attempt of every request. `before_request` gets the request after it is built and authenticated, and returns the request to send. `after_response` gets the response and returns the one the call acts on: the same one, or your own object implementing `HttpResponse`. Subclass `SdkHook` and override either one, or pass plain functions keyed by the event they run on:
180
+
181
+ ```python
182
+ from dataclasses import replace
183
+
184
+ from apimatic_calculator_test import ApimaticCalculatorTestClient
185
+ from apimatic_calculator_test.core import HookContext, HttpRequest, HttpResponse, SdkHook
186
+
187
+
188
+ # new_traceparent() and record() stand for your own tracer and metrics sink.
189
+ class Tracing(SdkHook):
190
+ def before_request(self, request: HttpRequest, context: HookContext) -> HttpRequest:
191
+ return replace(request, headers={**request.headers, "traceparent": new_traceparent()})
192
+
193
+ def after_response(self, response: HttpResponse, context: HookContext) -> HttpResponse:
194
+ record(context.method, context.url, response.status_code)
195
+ return response
196
+
197
+
198
+ client = ApimaticCalculatorTestClient(hooks=[Tracing()])
199
+
200
+
201
+ # Or plain functions, with nothing to subclass:
202
+ def add_tenant(request: HttpRequest, context: HookContext) -> HttpRequest:
203
+ return replace(request, headers={**request.headers, "x-tenant": "acme"})
204
+
205
+
206
+ def print_status(response: HttpResponse, context: HookContext) -> HttpResponse:
207
+ print(context.method, response.status_code)
208
+ return response
209
+
210
+
211
+ client = ApimaticCalculatorTestClient(hooks={"on_request": [add_tenant], "on_response": [print_status]})
212
+ ```
213
+
214
+ A single call adds its own the same way, `request_options={"hooks": {"on_request": [add_tenant]}}` or `{"hooks": [Tracing()]}`: they run after the client's, never instead of them.
215
+
216
+ **Two spellings, one per place.** `hooks` takes a list of hook objects or the `{"on_request": [...], "on_response": [...]}` dict, on the client and in `request_options` alike — not a mix of the two in one place. A hook that keeps state between the request and its response is a class. A key other than those two is a type error, and is ignored at run time.
217
+
218
+ **When they run.** On every attempt, retries included, after authentication: the client's hooks, then the call's.
219
+
220
+ **On `AsyncApimaticCalculatorTestClient`** the same shape is `AsyncSdkHook`, whose methods are `async def` and take an `AsyncHookContext` and an `AsyncHttpResponse`; the dict takes `async def` functions under the same two keys, and a call's hooks go in `AsyncRequestOptions`. A hook of the other client's flavour is a type error, not a run-time check.
221
+
222
+ **Changing the response.** The retry decision and the result read the response the last hook returns; the log line shows what the server sent. A hook that reads the body must return a response that still carries it, and one that returns a different response must close the original or keep it inside.
223
+
224
+ ## Best Practices
225
+
226
+ > [!TIP]
227
+ > Use a **single `ApimaticCalculatorTestClient` instance** for the lifetime of your application and reuse it across
228
+ > all requests. Each instance owns its own connection pool, so an instance per request forfeits
229
+ > connection reuse and leaks pools that are never closed.
230
+
231
+ Match the disposal to the client's lifetime: an application-lifetime client is closed once at shutdown with `close()` / `aclose()`; where the lifetime fits a block, `with ApimaticCalculatorTestClient() as client:` / `async with AsyncApimaticCalculatorTestClient() as client:` releases it automatically. Both are idempotent, but a closed client is not reusable: the next call raises. The client closes **whatever transport it holds**, including one you supplied via `custom_http_client` / `custom_async_http_client`; if you intend to reuse your own transport across clients, don't hand its lifetime to a `with` block.
232
+
233
+ **Retries are on by default**: a failed idempotent request — a retryable status or no response at all — is sent again up to three times before the call gives up. Pass `retry_options=0` to turn it off, for instance in a test that stubs an error response; the policy and its defaults are under **Retries** in the SDK map.
234
+
235
+ ## License
236
+
237
+ This SDK is distributed under the [MIT License][license-url].
238
+
239
+ ---
240
+
241
+ ## Support
242
+
243
+ Refer to the [API reference](api-reference.md) for detailed information on available operations with code samples.
244
+
245
+ ---
246
+
247
+ [license-url]: LICENSE
248
+ [license-badge]: https://img.shields.io/badge/License-MIT-blue.svg
249
+ [apimatic-url]: https://www.apimatic.io
250
+ [apimatic-badge]: https://www.apimatic.io/hubfs/Built-with-APIMatic-badge.svg
251
+ [python-url]: https://www.python.org/downloads/
252
+ [python-badge]: https://img.shields.io/badge/python-3.10%2B-blue.svg
@@ -0,0 +1,13 @@
1
+ from . import models
2
+ from .async_client import AsyncApimaticCalculatorTestClient, AsyncClient
3
+ from .client import ApimaticCalculatorTestClient, Client
4
+ from .server import ServerConfig
5
+
6
+ __all__ = [
7
+ "models",
8
+ "ApimaticCalculatorTestClient",
9
+ "AsyncApimaticCalculatorTestClient",
10
+ "AsyncClient",
11
+ "Client",
12
+ "ServerConfig",
13
+ ]