bladekit 4.5.0__py3-none-any.whl

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.
bladekit/__init__.py ADDED
@@ -0,0 +1,219 @@
1
+ """Blade AI Fabric SDK — run Python functions on the GPU fleet.
2
+
3
+ Public surface::
4
+
5
+ import bladekit
6
+
7
+ app = bladekit.app("demo") # same as bladekit.App("demo")
8
+
9
+ @app.function(gpu="RTX-A4500", image="fabric/torch-2.x")
10
+ def embed(texts):
11
+ ...
12
+
13
+ result = embed.remote(["hello"]) # blocking
14
+ handle = embed.spawn(["world"]) # non-blocking
15
+ value = handle.get(timeout=120)
16
+
17
+ # batch fan-out
18
+ for result in embed.map(["hello", "world"]):
19
+ print(result)
20
+
21
+ # cron schedule
22
+ @app.function(gpu="RTX-A4500", schedule=bladekit.Cron("0 3 * * *"))
23
+ def nightly(): ...
24
+
25
+ # imperative sandbox (for agents, code interpreters, LLM-generated code)
26
+ with bladekit.Sandbox.create(image="fabric/base-cuda12", gpu="RTX-A4500") as sb:
27
+ proc = sb.exec("python", "-c", "print('hello')")
28
+ print(proc.stdout.read())
29
+ proc.wait()
30
+
31
+ Import is intentionally cheap: heavy deps (``cloudpickle``, ``httpx``,
32
+ ``websockets``) are imported lazily inside the functions that need them, so
33
+ ``import bladekit`` does not pull them in at module load.
34
+ See ``tests/test_import_light.py``.
35
+
36
+ This package was called ``forge`` (distribution ``forge-shadow``) before
37
+ PAAS-771. The ``forge-shadow`` distribution still exists as a thin
38
+ compatibility package that installs this one plus a ``forge`` import shim and a
39
+ ``forge`` command — see the README's migration section.
40
+ """
41
+
42
+ from __future__ import annotations
43
+
44
+ from ._app import (
45
+ App,
46
+ Autoscale,
47
+ DeployedFunctionCall,
48
+ DeploymentManifest,
49
+ Function,
50
+ FunctionCall,
51
+ complete_session,
52
+ )
53
+ from ._batch import BatchedFunction, batched
54
+ from ._webhook import Webhook, verify_webhook
55
+ from ._bucket import CloudBucketMount
56
+ from ._cls import enter, exit, build, parameter
57
+ from ._preempt import load_checkpoint, on_preempt, save_checkpoint
58
+ from ._cron import Cron
59
+ from ._dict import Dict
60
+ from ._image import Image
61
+ from ._map import MapHandle
62
+ from ._queue import Queue
63
+ from ._sandbox import Sandbox
64
+ from ._secret import Secret
65
+ from ._volume import Volume
66
+ from ._env import mirror_legacy_runtime_env as _mirror_legacy_runtime_env
67
+ from .exceptions import (
68
+ APIError,
69
+ AuthenticationError,
70
+ BundleFetchFailedError,
71
+ ConflictError,
72
+ ConnectionFailed,
73
+ ContainerFailedError,
74
+ FabricError,
75
+ GPUQuotaExceededError,
76
+ OrgGPUQuotaExceededError,
77
+ ImageBuildError,
78
+ ImagePullFailedError,
79
+ InputTimeoutError,
80
+ InvalidArgumentError,
81
+ NodeLostError,
82
+ NotFoundError,
83
+ PayloadTooLargeError,
84
+ PermissionDeniedError,
85
+ PreemptedError,
86
+ RemoteError,
87
+ RemoteFunctionError,
88
+ RetriesExhaustedError,
89
+ RunCancelled,
90
+ RunError,
91
+ RunLostError,
92
+ RunnerCrashedError,
93
+ UnavailableError,
94
+ VersionMismatchError,
95
+ VolumeCommitError,
96
+ VolumeError,
97
+ # sandbox errors
98
+ SandboxDiskQuotaExceededError,
99
+ SandboxExecLimitError,
100
+ SandboxFailedError,
101
+ SandboxFileNotFoundError,
102
+ SandboxFileTooLargeError,
103
+ SandboxNotRunningError,
104
+ SandboxPathInvalidError,
105
+ SandboxPortInUseError,
106
+ SandboxTerminatedError,
107
+ )
108
+
109
+ # `bladekit.app("name")`, the documented spelling: the App class itself under a
110
+ # lowercase name, so it returns an App, isinstance(x, bladekit.app) holds and
111
+ # App's signature and docstring come along unchanged.
112
+ app = App
113
+
114
+ # The PyPI distribution name (the import name is bladekit).
115
+ DISTRIBUTION = "bladekit"
116
+
117
+ # Inside a container the control plane still injects FORGE_* (PAAS-771): expose
118
+ # the user-facing ones under their documented FABRIC_* names too.
119
+ _mirror_legacy_runtime_env()
120
+
121
+ # Derive the version from the installed package metadata so it can never drift
122
+ # from pyproject.toml (the old hardcoded literal lagged for several releases,
123
+ # making the client's warn_if_outdated compare a stale version and warn wrongly).
124
+ try:
125
+ from importlib.metadata import version as _pkg_version
126
+
127
+ __version__ = _pkg_version(DISTRIBUTION)
128
+ except Exception: # editable/source checkout without installed metadata
129
+ __version__ = "0.0.0+local"
130
+
131
+ __all__ = [
132
+ "App",
133
+ "app",
134
+ "Autoscale",
135
+ "Function",
136
+ "FunctionCall",
137
+ "DeployedFunctionCall",
138
+ "DeploymentManifest",
139
+ "Webhook",
140
+ "verify_webhook",
141
+ "complete_session",
142
+ # dynamic batching
143
+ "batched",
144
+ "BatchedFunction",
145
+ # object API
146
+ "Image",
147
+ "Volume",
148
+ "Secret",
149
+ "CloudBucketMount",
150
+ # container lifecycle hooks + parametrized classes
151
+ "enter",
152
+ "exit",
153
+ "build",
154
+ "parameter",
155
+ # preemption hook + checkpoint helpers
156
+ "on_preempt",
157
+ "save_checkpoint",
158
+ "load_checkpoint",
159
+ # object API
160
+ "Cron",
161
+ "Dict",
162
+ "MapHandle",
163
+ "Queue",
164
+ "__version__",
165
+ # exceptions
166
+ "FabricError",
167
+ "APIError",
168
+ "AuthenticationError",
169
+ "PermissionDeniedError",
170
+ "NotFoundError",
171
+ "InvalidArgumentError",
172
+ "ConflictError",
173
+ "PayloadTooLargeError",
174
+ "UnavailableError",
175
+ "ConnectionFailed",
176
+ "RunError",
177
+ "NodeLostError",
178
+ "ContainerFailedError",
179
+ "ImagePullFailedError",
180
+ "RunnerCrashedError",
181
+ "BundleFetchFailedError",
182
+ "VersionMismatchError",
183
+ "RunCancelled",
184
+ "RunLostError",
185
+ "RemoteError",
186
+ "RemoteFunctionError",
187
+ # exceptions
188
+ "ImageBuildError",
189
+ "VolumeError",
190
+ "VolumeCommitError",
191
+ # exceptions
192
+ "PreemptedError",
193
+ "InputTimeoutError",
194
+ "RetriesExhaustedError",
195
+ "GPUQuotaExceededError",
196
+ "OrgGPUQuotaExceededError",
197
+ # sandbox
198
+ "Sandbox",
199
+ # exceptions
200
+ "SandboxDiskQuotaExceededError",
201
+ "SandboxExecLimitError",
202
+ "SandboxFailedError",
203
+ "SandboxFileNotFoundError",
204
+ "SandboxFileTooLargeError",
205
+ "SandboxNotRunningError",
206
+ "SandboxPathInvalidError",
207
+ "SandboxPortInUseError",
208
+ "SandboxTerminatedError",
209
+ ]
210
+
211
+
212
+ def __getattr__(name: str):
213
+ # Deprecated aliases (ForgeError -> FabricError) live in exceptions; resolving
214
+ # them there emits the DeprecationWarning and returns the same class object.
215
+ from . import exceptions as _exceptions
216
+
217
+ if name in _exceptions.DEPRECATED_ALIASES:
218
+ return _exceptions.resolve_deprecated(name)
219
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")