cadlag-sdk 1.0.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.

Potentially problematic release.


This version of cadlag-sdk might be problematic. Click here for more details.

Files changed (71) hide show
  1. cadlag_sdk-1.0.4/LICENSE +17 -0
  2. cadlag_sdk-1.0.4/PKG-INFO +50 -0
  3. cadlag_sdk-1.0.4/README.md +19 -0
  4. cadlag_sdk-1.0.4/cadlag_sdk/__init__.py +25 -0
  5. cadlag_sdk-1.0.4/cadlag_sdk/cli.py +96 -0
  6. cadlag_sdk-1.0.4/cadlag_sdk/client/__init__.py +29 -0
  7. cadlag_sdk-1.0.4/cadlag_sdk/client/_transport.py +213 -0
  8. cadlag_sdk-1.0.4/cadlag_sdk/client/client.py +256 -0
  9. cadlag_sdk-1.0.4/cadlag_sdk/client/config.py +25 -0
  10. cadlag_sdk-1.0.4/cadlag_sdk/client/exceptions.py +90 -0
  11. cadlag_sdk-1.0.4/cadlag_sdk/client/models/__init__.py +97 -0
  12. cadlag_sdk-1.0.4/cadlag_sdk/client/models/audit.py +23 -0
  13. cadlag_sdk-1.0.4/cadlag_sdk/client/models/backtest.py +78 -0
  14. cadlag_sdk-1.0.4/cadlag_sdk/client/models/config.py +20 -0
  15. cadlag_sdk-1.0.4/cadlag_sdk/client/models/data.py +76 -0
  16. cadlag_sdk-1.0.4/cadlag_sdk/client/models/datasets.py +42 -0
  17. cadlag_sdk-1.0.4/cadlag_sdk/client/models/deployments.py +31 -0
  18. cadlag_sdk-1.0.4/cadlag_sdk/client/models/experiments.py +33 -0
  19. cadlag_sdk-1.0.4/cadlag_sdk/client/models/feature_sets.py +36 -0
  20. cadlag_sdk-1.0.4/cadlag_sdk/client/models/live.py +80 -0
  21. cadlag_sdk-1.0.4/cadlag_sdk/client/models/models.py +54 -0
  22. cadlag_sdk-1.0.4/cadlag_sdk/client/models/pipeline.py +30 -0
  23. cadlag_sdk-1.0.4/cadlag_sdk/client/models/risk.py +29 -0
  24. cadlag_sdk-1.0.4/cadlag_sdk/client/models/strategies.py +41 -0
  25. cadlag_sdk-1.0.4/cadlag_sdk/client/models/validation.py +55 -0
  26. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/__init__.py +102 -0
  27. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/audit.py +52 -0
  28. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/backtest.py +122 -0
  29. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/config.py +28 -0
  30. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/data.py +116 -0
  31. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/datasets.py +91 -0
  32. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/deployments.py +62 -0
  33. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/experiments.py +77 -0
  34. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/feature_sets.py +85 -0
  35. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/live.py +94 -0
  36. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/models.py +101 -0
  37. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/pipeline.py +68 -0
  38. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/risk.py +42 -0
  39. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/strategies.py +94 -0
  40. cadlag_sdk-1.0.4/cadlag_sdk/client/modules/validation.py +74 -0
  41. cadlag_sdk-1.0.4/cadlag_sdk/config_schema.py +194 -0
  42. cadlag_sdk-1.0.4/cadlag_sdk/data_process.py +2042 -0
  43. cadlag_sdk-1.0.4/cadlag_sdk/env_setting.py +53 -0
  44. cadlag_sdk-1.0.4/cadlag_sdk/feature_builder.py +1651 -0
  45. cadlag_sdk-1.0.4/cadlag_sdk/losses/__init__.py +4 -0
  46. cadlag_sdk-1.0.4/cadlag_sdk/losses/base.py +38 -0
  47. cadlag_sdk-1.0.4/cadlag_sdk/models/__init__.py +4 -0
  48. cadlag_sdk-1.0.4/cadlag_sdk/models/base.py +75 -0
  49. cadlag_sdk-1.0.4/cadlag_sdk/py.typed +1 -0
  50. cadlag_sdk-1.0.4/cadlag_sdk/strategies/__init__.py +4 -0
  51. cadlag_sdk-1.0.4/cadlag_sdk/strategies/base.py +129 -0
  52. cadlag_sdk-1.0.4/cadlag_sdk/symbol_alias.py +19 -0
  53. cadlag_sdk-1.0.4/cadlag_sdk/testing/__init__.py +103 -0
  54. cadlag_sdk-1.0.4/cadlag_sdk/trainers/__init__.py +4 -0
  55. cadlag_sdk-1.0.4/cadlag_sdk/trainers/base.py +149 -0
  56. cadlag_sdk-1.0.4/cadlag_sdk.egg-info/PKG-INFO +50 -0
  57. cadlag_sdk-1.0.4/cadlag_sdk.egg-info/SOURCES.txt +69 -0
  58. cadlag_sdk-1.0.4/cadlag_sdk.egg-info/dependency_links.txt +1 -0
  59. cadlag_sdk-1.0.4/cadlag_sdk.egg-info/entry_points.txt +5 -0
  60. cadlag_sdk-1.0.4/cadlag_sdk.egg-info/requires.txt +19 -0
  61. cadlag_sdk-1.0.4/cadlag_sdk.egg-info/top_level.txt +1 -0
  62. cadlag_sdk-1.0.4/pyproject.toml +61 -0
  63. cadlag_sdk-1.0.4/setup.cfg +4 -0
  64. cadlag_sdk-1.0.4/tests/test_base_classes.py +292 -0
  65. cadlag_sdk-1.0.4/tests/test_client.py +211 -0
  66. cadlag_sdk-1.0.4/tests/test_config_schema.py +136 -0
  67. cadlag_sdk-1.0.4/tests/test_data_process.py +556 -0
  68. cadlag_sdk-1.0.4/tests/test_env_setting.py +49 -0
  69. cadlag_sdk-1.0.4/tests/test_feature_builder.py +512 -0
  70. cadlag_sdk-1.0.4/tests/test_feature_builder_models.py +182 -0
  71. cadlag_sdk-1.0.4/tests/test_symbol_alias.py +20 -0
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright (c) 2026 Cadlag
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.4
2
+ Name: cadlag-sdk
3
+ Version: 1.0.4
4
+ Summary: Cadlag SDK — Base classes, utilities, platform client, CLI, and testing fixtures
5
+ Maintainer-email: Cadlag <info@cadlag.pro>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://cadlag.pro
8
+ Project-URL: Repository, https://github.com/cadlag-quant/cadlag
9
+ Requires-Python: >=3.11
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: pydantic>=2.5
13
+ Requires-Dist: polars>=0.20
14
+ Requires-Dist: numpy>=1.24
15
+ Requires-Dist: pyarrow>=14.0
16
+ Requires-Dist: httpx>=0.26
17
+ Requires-Dist: websockets>=12.0
18
+ Requires-Dist: structlog>=24.1
19
+ Requires-Dist: scikit-learn>=1.3
20
+ Requires-Dist: pandas>=2.0
21
+ Requires-Dist: scipy>=1.11
22
+ Requires-Dist: joblib>=1.3
23
+ Requires-Dist: TA-Lib>=0.4
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=7.4; extra == "dev"
26
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
27
+ Requires-Dist: pytest-cov>=4.1; extra == "dev"
28
+ Requires-Dist: ruff>=0.3; extra == "dev"
29
+ Requires-Dist: mypy>=1.8; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # Cadlag SDK
33
+
34
+ Base classes, utilities, platform client, CLI and testing fixtures for Cadlag.
35
+ Requires Python 3.11 or later. Licensed under Apache-2.0.
36
+
37
+ ```bash
38
+ python -m pip install cadlag-sdk
39
+ cadlag --help
40
+ ```
41
+
42
+ ```python
43
+ from cadlag_sdk import CadlagClient, AsyncCadlagClient
44
+
45
+ with CadlagClient(base_url="http://localhost:8000") as client:
46
+ print(client.health())
47
+ ```
48
+
49
+ The SDK connects to a running Cadlag CE server. Install `cadlag-quant` to include the
50
+ server package and Starter examples. Import the SDK as `cadlag_sdk`.
@@ -0,0 +1,19 @@
1
+ # Cadlag SDK
2
+
3
+ Base classes, utilities, platform client, CLI and testing fixtures for Cadlag.
4
+ Requires Python 3.11 or later. Licensed under Apache-2.0.
5
+
6
+ ```bash
7
+ python -m pip install cadlag-sdk
8
+ cadlag --help
9
+ ```
10
+
11
+ ```python
12
+ from cadlag_sdk import CadlagClient, AsyncCadlagClient
13
+
14
+ with CadlagClient(base_url="http://localhost:8000") as client:
15
+ print(client.health())
16
+ ```
17
+
18
+ The SDK connects to a running Cadlag CE server. Install `cadlag-quant` to include the
19
+ server package and Starter examples. Import the SDK as `cadlag_sdk`.
@@ -0,0 +1,25 @@
1
+ # Copyright (c) 2026 Cadlag. Licensed under Apache 2.0.
2
+ """Cadlag SDK — public surface re-exports."""
3
+
4
+ from importlib.metadata import PackageNotFoundError, version
5
+
6
+ from cadlag_sdk.client.client import AsyncCadlagClient, CadlagClient
7
+ from cadlag_sdk.losses.base import BaseLoss
8
+ from cadlag_sdk.models.base import BaseModel
9
+ from cadlag_sdk.strategies.base import BaseStrategy
10
+ from cadlag_sdk.trainers.base import BaseTrainer
11
+
12
+ try:
13
+ __version__ = version("cadlag-sdk")
14
+ except PackageNotFoundError:
15
+ __version__ = "0+unknown"
16
+
17
+ __all__ = [
18
+ "AsyncCadlagClient",
19
+ "BaseLoss",
20
+ "BaseModel",
21
+ "BaseStrategy",
22
+ "BaseTrainer",
23
+ "CadlagClient",
24
+ "__version__",
25
+ ]
@@ -0,0 +1,96 @@
1
+ # Copyright (c) 2026 Cadlag. Licensed under Apache 2.0.
2
+ """Cadlag SDK command-line interface.
3
+
4
+ Entry point: ``cadlag`` (declared in ``pyproject.toml`` ``[project.scripts]``).
5
+
6
+ The SDK owns the executable but discovers commands supplied by installed
7
+ Cadlag packages through the ``cadlag.cli`` entry-point group. This keeps
8
+ the SDK dependency-free with respect to Cadlag CE and optional extensions.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import argparse
14
+ import subprocess
15
+ import sys
16
+ from collections.abc import Callable, Sequence
17
+ from importlib import metadata
18
+ from typing import Protocol, cast
19
+
20
+ CommandHandler = Callable[[argparse.Namespace], int]
21
+
22
+
23
+ class CommandRegistrar(Protocol):
24
+ """Register package-owned commands on the root Cadlag CLI."""
25
+
26
+ def __call__(
27
+ self,
28
+ subparsers: argparse._SubParsersAction[argparse.ArgumentParser],
29
+ ) -> None: ...
30
+
31
+
32
+ def _cmd_test(args: argparse.Namespace) -> int:
33
+ """Run SDK tests using pytest.
34
+
35
+ Args:
36
+ args: Parsed CLI arguments (``args.markers``, ``args.verbose``).
37
+
38
+ Returns:
39
+ pytest exit code.
40
+ """
41
+ cmd = [sys.executable, "-m", "pytest"]
42
+ if args.verbose:
43
+ cmd.append("-v")
44
+ if args.markers:
45
+ cmd.extend(["-m", args.markers])
46
+ # Run from the cadlag_sdk package directory so conftest is discovered.
47
+ import pathlib
48
+
49
+ import cadlag_sdk as _sdk
50
+
51
+ sdk_root = str(pathlib.Path(_sdk.__file__).parent.parent)
52
+ cmd.append(sdk_root)
53
+ result = subprocess.run(cmd, check=False)
54
+ return result.returncode
55
+
56
+
57
+ def build_parser() -> argparse.ArgumentParser:
58
+ """Build the root parser and load commands from installed packages."""
59
+ parser = argparse.ArgumentParser(
60
+ prog="cadlag",
61
+ description="Cadlag SDK command-line interface.",
62
+ )
63
+ sub = parser.add_subparsers(dest="command", metavar="<command>")
64
+
65
+ test_parser = sub.add_parser("test", help="Run SDK contract tests via pytest.")
66
+ test_parser.add_argument("-v", "--verbose", action="store_true", help="Verbose pytest output.")
67
+ test_parser.add_argument("-m", "--markers", default="", help="pytest marker expression.")
68
+ test_parser.set_defaults(_cadlag_handler=_cmd_test)
69
+
70
+ entry_points = sorted(metadata.entry_points(group="cadlag.cli"), key=lambda entry_point: entry_point.name)
71
+ for entry_point in entry_points:
72
+ try:
73
+ registrar = cast("CommandRegistrar", entry_point.load())
74
+ registrar(sub)
75
+ except Exception as exc:
76
+ raise RuntimeError(
77
+ f"Unable to register Cadlag CLI provider {entry_point.name!r} ({entry_point.value}): {exc}"
78
+ ) from exc
79
+
80
+ return parser
81
+
82
+
83
+ def main(argv: Sequence[str] | None = None) -> None:
84
+ """Entry point for the ``cadlag`` CLI."""
85
+ parser = build_parser()
86
+ args = parser.parse_args(argv)
87
+
88
+ handler = cast("CommandHandler | None", getattr(args, "_cadlag_handler", None))
89
+ if handler is None:
90
+ parser.print_help()
91
+ raise SystemExit(0)
92
+ raise SystemExit(handler(args))
93
+
94
+
95
+ if __name__ == "__main__":
96
+ main()
@@ -0,0 +1,29 @@
1
+ # Copyright (c) 2026 Cadlag. Licensed under Apache 2.0.
2
+ from cadlag_sdk.client.client import AsyncCadlagClient, CadlagClient
3
+ from cadlag_sdk.client.config import ClientConfig
4
+ from cadlag_sdk.client.exceptions import (
5
+ BacktestFailedError,
6
+ ChainLimitExceededError,
7
+ ConnectionError,
8
+ NotFoundError,
9
+ PipelineFailedError,
10
+ ProFeatureRequiredError,
11
+ CadlagError,
12
+ TimeoutError,
13
+ ValidationError,
14
+ )
15
+
16
+ __all__ = [
17
+ "AsyncCadlagClient",
18
+ "BacktestFailedError",
19
+ "ChainLimitExceededError",
20
+ "ClientConfig",
21
+ "ConnectionError",
22
+ "NotFoundError",
23
+ "PipelineFailedError",
24
+ "ProFeatureRequiredError",
25
+ "CadlagClient",
26
+ "CadlagError",
27
+ "TimeoutError",
28
+ "ValidationError",
29
+ ]
@@ -0,0 +1,213 @@
1
+ # Copyright (c) 2026 Cadlag. Licensed under Apache 2.0.
2
+ """HTTP transport layers with shared retry and error mapping.
3
+
4
+ Provides sync and async transports that share timeout construction and
5
+ platform HTTP status-code → SDK exception mapping semantics.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import asyncio
11
+ import time
12
+ from typing import TYPE_CHECKING, Any
13
+
14
+ import httpx
15
+ import structlog
16
+
17
+ if TYPE_CHECKING:
18
+ from cadlag_sdk.client.config import ClientConfig
19
+
20
+ from cadlag_sdk.client.exceptions import (
21
+ ChainLimitExceededError,
22
+ ConnectionError,
23
+ NotFoundError,
24
+ ProFeatureRequiredError,
25
+ CadlagError,
26
+ TimeoutError,
27
+ ValidationError,
28
+ )
29
+
30
+ logger = structlog.get_logger(__name__)
31
+
32
+
33
+ def _build_timeout(config: ClientConfig) -> httpx.Timeout:
34
+ return httpx.Timeout(
35
+ connect=config.connect_timeout,
36
+ read=config.read_timeout,
37
+ write=config.write_timeout,
38
+ pool=config.connect_timeout,
39
+ )
40
+
41
+
42
+ class _BaseTransport:
43
+ """Shared transport behavior for sync and async SDK clients.
44
+
45
+ Args:
46
+ config: :class:`~cadlag_sdk.client.config.ClientConfig` instance.
47
+ """
48
+
49
+ def __init__(self, config: ClientConfig) -> None:
50
+ self._config = config
51
+
52
+ def _map_error(self, response: httpx.Response) -> httpx.Response:
53
+ """Raise a typed exception for error status codes."""
54
+ if response.is_success:
55
+ return response
56
+
57
+ body: Any = None
58
+ try:
59
+ body = response.json()
60
+ except Exception:
61
+ body = response.text
62
+
63
+ status = response.status_code
64
+ if status == 402:
65
+ capability = body.get("capability", "unknown") if isinstance(body, dict) else "unknown"
66
+ docs_url_value = body.get("docs_url", body.get("docs", "")) if isinstance(body, dict) else ""
67
+ docs_url = docs_url_value if isinstance(docs_url_value, str) else ""
68
+ message = body.get("error", "Pro feature required") if isinstance(body, dict) else str(body)
69
+ raise ProFeatureRequiredError(
70
+ message,
71
+ status_code=status,
72
+ response=body,
73
+ capability=capability,
74
+ docs_url=docs_url,
75
+ )
76
+ if status == 404:
77
+ raise NotFoundError("Resource not found", status_code=status, response=body)
78
+ if status == 422:
79
+ if (
80
+ isinstance(body, dict)
81
+ and body.get("error") == "chain limit exceeded"
82
+ and isinstance(body.get("max_chains"), int)
83
+ and isinstance(body.get("requested"), int)
84
+ ):
85
+ raise ChainLimitExceededError(
86
+ body.get("detail", "Chain limit exceeded"),
87
+ status_code=status,
88
+ response=body,
89
+ max_chains=body["max_chains"],
90
+ requested=body["requested"],
91
+ )
92
+ raise ValidationError("Validation error", status_code=status, response=body)
93
+
94
+ raise CadlagError(f"Unexpected HTTP {status}", status_code=status, response=body)
95
+
96
+
97
+ class SyncTransport(_BaseTransport):
98
+ """Sync HTTP transport with retry + status-code → exception mapping."""
99
+
100
+ def __init__(self, config: ClientConfig) -> None:
101
+ super().__init__(config)
102
+ self._client: httpx.Client | None = None
103
+
104
+ def _get_client(self) -> httpx.Client:
105
+ if self._client is None or getattr(self._client, "is_closed", False):
106
+ self._client = httpx.Client(
107
+ base_url=self._config.base_url,
108
+ timeout=_build_timeout(self._config),
109
+ )
110
+ return self._client
111
+
112
+ def request(
113
+ self,
114
+ method: str,
115
+ path: str,
116
+ **kwargs: Any,
117
+ ) -> httpx.Response:
118
+ """Send a synchronous HTTP request with retry and backoff."""
119
+ client = self._get_client()
120
+ last_exc: Exception | None = None
121
+
122
+ for attempt in range(self._config.max_retries + 1):
123
+ if attempt > 0:
124
+ delay = self._config.backoff_factor * (2 ** (attempt - 1))
125
+ time.sleep(delay)
126
+
127
+ try:
128
+ response = client.request(method, path, **kwargs)
129
+ return self._map_error(response)
130
+ except httpx.TimeoutException as exc:
131
+ last_exc = exc
132
+ logger.warning("request_timeout", attempt=attempt, path=path)
133
+ except httpx.NetworkError as exc:
134
+ last_exc = exc
135
+ logger.warning("request_network_error", attempt=attempt, path=path)
136
+
137
+ if isinstance(last_exc, httpx.TimeoutException):
138
+ raise TimeoutError(str(last_exc)) from last_exc
139
+ raise ConnectionError(str(last_exc)) from last_exc
140
+
141
+ def close(self) -> None:
142
+ """Close the underlying synchronous client."""
143
+ if self._client and not getattr(self._client, "is_closed", False):
144
+ self._client.close()
145
+
146
+
147
+ class AsyncTransport(_BaseTransport):
148
+ """Async HTTP transport with retry + status-code → exception mapping."""
149
+
150
+ def __init__(self, config: ClientConfig) -> None:
151
+ super().__init__(config)
152
+ self._client: httpx.AsyncClient | None = None
153
+
154
+ async def _get_client(self) -> httpx.AsyncClient:
155
+ if self._client is None or self._client.is_closed:
156
+ self._client = httpx.AsyncClient(
157
+ base_url=self._config.base_url,
158
+ timeout=_build_timeout(self._config),
159
+ )
160
+ return self._client
161
+
162
+ async def request(
163
+ self,
164
+ method: str,
165
+ path: str,
166
+ **kwargs: Any,
167
+ ) -> httpx.Response:
168
+ """Send an HTTP request with retry and backoff.
169
+
170
+ Args:
171
+ method: HTTP verb (``"GET"``, ``"POST"``, etc.).
172
+ path: URL path relative to ``base_url``.
173
+ **kwargs: Forwarded to :meth:`httpx.AsyncClient.request`.
174
+
175
+ Returns:
176
+ The :class:`httpx.Response` on success.
177
+
178
+ Raises:
179
+ ConnectionError: Network-level failure.
180
+ TimeoutError: Request exceeded configured timeout.
181
+ Various :class:`CadlagError` subclasses on HTTP error statuses.
182
+ """
183
+ client = await self._get_client()
184
+ last_exc: Exception | None = None
185
+
186
+ for attempt in range(self._config.max_retries + 1):
187
+ if attempt > 0:
188
+ delay = self._config.backoff_factor * (2 ** (attempt - 1))
189
+ await asyncio.sleep(delay)
190
+
191
+ try:
192
+ response = await client.request(method, path, **kwargs)
193
+ return self._map_error(response)
194
+ except httpx.TimeoutException as exc:
195
+ last_exc = exc
196
+ logger.warning("request_timeout", attempt=attempt, path=path)
197
+ except httpx.NetworkError as exc:
198
+ last_exc = exc
199
+ logger.warning("request_network_error", attempt=attempt, path=path)
200
+
201
+ # All retries exhausted
202
+ if isinstance(last_exc, httpx.TimeoutException):
203
+ raise TimeoutError(str(last_exc)) from last_exc
204
+ raise ConnectionError(str(last_exc)) from last_exc
205
+
206
+ async def aclose(self) -> None:
207
+ """Close the underlying ``httpx.AsyncClient``."""
208
+ if self._client and not self._client.is_closed:
209
+ await self._client.aclose()
210
+
211
+
212
+ # Backward-compatible alias for the original async transport symbol.
213
+ Transport = AsyncTransport