levers9 0.1.265__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 (143) hide show
  1. levers9-0.1.265/PKG-INFO +27 -0
  2. levers9-0.1.265/README.md +47 -0
  3. levers9-0.1.265/pyproject.toml +86 -0
  4. levers9-0.1.265/setup.cfg +4 -0
  5. levers9-0.1.265/src/__init__.py +0 -0
  6. levers9-0.1.265/src/levers9/__init__.py +77 -0
  7. levers9-0.1.265/src/levers9/__main__.py +3 -0
  8. levers9-0.1.265/src/levers9/abstractions/__init__.py +0 -0
  9. levers9-0.1.265/src/levers9/abstractions/base/__init__.py +77 -0
  10. levers9-0.1.265/src/levers9/abstractions/base/capacity.py +503 -0
  11. levers9-0.1.265/src/levers9/abstractions/base/container.py +150 -0
  12. levers9-0.1.265/src/levers9/abstractions/base/runner.py +819 -0
  13. levers9-0.1.265/src/levers9/abstractions/base/utils.py +85 -0
  14. levers9-0.1.265/src/levers9/abstractions/endpoint.py +648 -0
  15. levers9-0.1.265/src/levers9/abstractions/experimental/__init__.py +5 -0
  16. levers9-0.1.265/src/levers9/abstractions/experimental/bot/__init__.py +0 -0
  17. levers9-0.1.265/src/levers9/abstractions/experimental/bot/bot.py +402 -0
  18. levers9-0.1.265/src/levers9/abstractions/experimental/bot/marker.py +50 -0
  19. levers9-0.1.265/src/levers9/abstractions/experimental/bot/types.py +243 -0
  20. levers9-0.1.265/src/levers9/abstractions/experimental/signal.py +110 -0
  21. levers9-0.1.265/src/levers9/abstractions/function.py +445 -0
  22. levers9-0.1.265/src/levers9/abstractions/image.py +912 -0
  23. levers9-0.1.265/src/levers9/abstractions/integrations/__init__.py +4 -0
  24. levers9-0.1.265/src/levers9/abstractions/integrations/fastmcp.py +217 -0
  25. levers9-0.1.265/src/levers9/abstractions/integrations/vllm.py +477 -0
  26. levers9-0.1.265/src/levers9/abstractions/map.py +135 -0
  27. levers9-0.1.265/src/levers9/abstractions/mixins.py +214 -0
  28. levers9-0.1.265/src/levers9/abstractions/output.py +350 -0
  29. levers9-0.1.265/src/levers9/abstractions/pod.py +509 -0
  30. levers9-0.1.265/src/levers9/abstractions/queue.py +118 -0
  31. levers9-0.1.265/src/levers9/abstractions/sandbox.py +4270 -0
  32. levers9-0.1.265/src/levers9/abstractions/service.py +374 -0
  33. levers9-0.1.265/src/levers9/abstractions/shell.py +601 -0
  34. levers9-0.1.265/src/levers9/abstractions/taskqueue.py +303 -0
  35. levers9-0.1.265/src/levers9/abstractions/volume.py +159 -0
  36. levers9-0.1.265/src/levers9/aio.py +10 -0
  37. levers9-0.1.265/src/levers9/channel.py +325 -0
  38. levers9-0.1.265/src/levers9/cli/__init__.py +0 -0
  39. levers9-0.1.265/src/levers9/cli/config.py +207 -0
  40. levers9-0.1.265/src/levers9/cli/container.py +205 -0
  41. levers9-0.1.265/src/levers9/cli/database.py +1075 -0
  42. levers9-0.1.265/src/levers9/cli/deployment.py +638 -0
  43. levers9-0.1.265/src/levers9/cli/dev.py +72 -0
  44. levers9-0.1.265/src/levers9/cli/disk.py +263 -0
  45. levers9-0.1.265/src/levers9/cli/extraclick.py +585 -0
  46. levers9-0.1.265/src/levers9/cli/llm.py +269 -0
  47. levers9-0.1.265/src/levers9/cli/machine.py +643 -0
  48. levers9-0.1.265/src/levers9/cli/machine_format.py +187 -0
  49. levers9-0.1.265/src/levers9/cli/main.py +135 -0
  50. levers9-0.1.265/src/levers9/cli/pool.py +863 -0
  51. levers9-0.1.265/src/levers9/cli/run.py +153 -0
  52. levers9-0.1.265/src/levers9/cli/secret.py +144 -0
  53. levers9-0.1.265/src/levers9/cli/serve.py +67 -0
  54. levers9-0.1.265/src/levers9/cli/shell.py +80 -0
  55. levers9-0.1.265/src/levers9/cli/task.py +151 -0
  56. levers9-0.1.265/src/levers9/cli/token.py +194 -0
  57. levers9-0.1.265/src/levers9/cli/volume.py +485 -0
  58. levers9-0.1.265/src/levers9/cli/worker.py +216 -0
  59. levers9-0.1.265/src/levers9/cli/worker_management.py +55 -0
  60. levers9-0.1.265/src/levers9/client/__init__.py +50 -0
  61. levers9-0.1.265/src/levers9/client/client.py +168 -0
  62. levers9-0.1.265/src/levers9/client/deployment.py +72 -0
  63. levers9-0.1.265/src/levers9/client/task.py +127 -0
  64. levers9-0.1.265/src/levers9/clients/__init__.py +0 -0
  65. levers9-0.1.265/src/levers9/clients/bot/__init__.py +159 -0
  66. levers9-0.1.265/src/levers9/clients/disk/__init__.py +139 -0
  67. levers9-0.1.265/src/levers9/clients/endpoint/__init__.py +46 -0
  68. levers9-0.1.265/src/levers9/clients/function/__init__.py +140 -0
  69. levers9-0.1.265/src/levers9/clients/gateway/__init__.py +2545 -0
  70. levers9-0.1.265/src/levers9/clients/google/__init__.py +0 -0
  71. levers9-0.1.265/src/levers9/clients/google/api/__init__.py +379 -0
  72. levers9-0.1.265/src/levers9/clients/image/__init__.py +108 -0
  73. levers9-0.1.265/src/levers9/clients/map/__init__.py +119 -0
  74. levers9-0.1.265/src/levers9/clients/output/__init__.py +112 -0
  75. levers9-0.1.265/src/levers9/clients/pod/__init__.py +597 -0
  76. levers9-0.1.265/src/levers9/clients/secret/__init__.py +140 -0
  77. levers9-0.1.265/src/levers9/clients/shell/__init__.py +72 -0
  78. levers9-0.1.265/src/levers9/clients/signal/__init__.py +84 -0
  79. levers9-0.1.265/src/levers9/clients/simplequeue/__init__.py +115 -0
  80. levers9-0.1.265/src/levers9/clients/taskqueue/__init__.py +162 -0
  81. levers9-0.1.265/src/levers9/clients/types/__init__.py +340 -0
  82. levers9-0.1.265/src/levers9/clients/volume/__init__.py +363 -0
  83. levers9-0.1.265/src/levers9/config.py +262 -0
  84. levers9-0.1.265/src/levers9/env.py +94 -0
  85. levers9-0.1.265/src/levers9/exceptions.py +173 -0
  86. levers9-0.1.265/src/levers9/integrations.py +3 -0
  87. levers9-0.1.265/src/levers9/logging.py +175 -0
  88. levers9-0.1.265/src/levers9/middleware.py +382 -0
  89. levers9-0.1.265/src/levers9/multipart.py +785 -0
  90. levers9-0.1.265/src/levers9/runner/__init__.py +0 -0
  91. levers9-0.1.265/src/levers9/runner/bot/__init__.py +0 -0
  92. levers9-0.1.265/src/levers9/runner/bot/transition.py +254 -0
  93. levers9-0.1.265/src/levers9/runner/common.py +709 -0
  94. levers9-0.1.265/src/levers9/runner/container.py +98 -0
  95. levers9-0.1.265/src/levers9/runner/endpoint.py +331 -0
  96. levers9-0.1.265/src/levers9/runner/function.py +353 -0
  97. levers9-0.1.265/src/levers9/runner/serve.py +129 -0
  98. levers9-0.1.265/src/levers9/runner/taskqueue.py +416 -0
  99. levers9-0.1.265/src/levers9/schema.py +566 -0
  100. levers9-0.1.265/src/levers9/sync.py +301 -0
  101. levers9-0.1.265/src/levers9/terminal.py +520 -0
  102. levers9-0.1.265/src/levers9/type.py +447 -0
  103. levers9-0.1.265/src/levers9/utils.py +131 -0
  104. levers9-0.1.265/src/levers9/vendor/pathspec/__init__.py +76 -0
  105. levers9-0.1.265/src/levers9/vendor/pathspec/_meta.py +58 -0
  106. levers9-0.1.265/src/levers9/vendor/pathspec/gitignore.py +157 -0
  107. levers9-0.1.265/src/levers9/vendor/pathspec/pathspec.py +394 -0
  108. levers9-0.1.265/src/levers9/vendor/pathspec/pattern.py +213 -0
  109. levers9-0.1.265/src/levers9/vendor/pathspec/patterns/__init__.py +11 -0
  110. levers9-0.1.265/src/levers9/vendor/pathspec/patterns/gitwildmatch.py +421 -0
  111. levers9-0.1.265/src/levers9/vendor/pathspec/py.typed +1 -0
  112. levers9-0.1.265/src/levers9/vendor/pathspec/util.py +792 -0
  113. levers9-0.1.265/src/levers9.egg-info/PKG-INFO +27 -0
  114. levers9-0.1.265/src/levers9.egg-info/SOURCES.txt +141 -0
  115. levers9-0.1.265/src/levers9.egg-info/dependency_links.txt +1 -0
  116. levers9-0.1.265/src/levers9.egg-info/entry_points.txt +2 -0
  117. levers9-0.1.265/src/levers9.egg-info/requires.txt +25 -0
  118. levers9-0.1.265/src/levers9.egg-info/top_level.txt +2 -0
  119. levers9-0.1.265/tests/test_capacity.py +457 -0
  120. levers9-0.1.265/tests/test_cli.py +179 -0
  121. levers9-0.1.265/tests/test_container_runner.py +16 -0
  122. levers9-0.1.265/tests/test_deployment.py +288 -0
  123. levers9-0.1.265/tests/test_env.py +38 -0
  124. levers9-0.1.265/tests/test_filesyncer.py +48 -0
  125. levers9-0.1.265/tests/test_function.py +123 -0
  126. levers9-0.1.265/tests/test_function_runner.py +85 -0
  127. levers9-0.1.265/tests/test_image.py +53 -0
  128. levers9-0.1.265/tests/test_machine_cli.py +161 -0
  129. levers9-0.1.265/tests/test_map.py +127 -0
  130. levers9-0.1.265/tests/test_multipart.py +33 -0
  131. levers9-0.1.265/tests/test_pod_instance.py +42 -0
  132. levers9-0.1.265/tests/test_pool.py +237 -0
  133. levers9-0.1.265/tests/test_queue.py +123 -0
  134. levers9-0.1.265/tests/test_runner.py +168 -0
  135. levers9-0.1.265/tests/test_sandbox_convenience.py +121 -0
  136. levers9-0.1.265/tests/test_sandbox_docker_manager.py +108 -0
  137. levers9-0.1.265/tests/test_sandbox_log_streaming_integration.py +196 -0
  138. levers9-0.1.265/tests/test_sandbox_process_stream.py +284 -0
  139. levers9-0.1.265/tests/test_service.py +725 -0
  140. levers9-0.1.265/tests/test_shell.py +616 -0
  141. levers9-0.1.265/tests/test_task_queue.py +90 -0
  142. levers9-0.1.265/tests/test_utils.py +86 -0
  143. levers9-0.1.265/tests/test_volumes.py +38 -0
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: levers9
3
+ Version: 0.1.265
4
+ Summary: levers9 SDK and CLI: run functions, endpoints, task queues, schedules, pods and GPU jobs on a levers9 cluster
5
+ Author-email: Levers AI Lab <hello@uselevers.com>
6
+ Requires-Python: <4.0,>=3.8
7
+ Requires-Dist: typeguard<3.0.0,>=2.13.3; python_version < "3.9"
8
+ Requires-Dist: typeguard<5.0.0,>=4.4.3; python_version >= "3.9"
9
+ Requires-Dist: typing-extensions<5.0.0,>=4.7.1
10
+ Requires-Dist: grpclib<1.0.0,>=0.4.7
11
+ Requires-Dist: grpcio<2.0.0,>=1.69.0
12
+ Requires-Dist: asgiref<4.0.0,>=3.8.1
13
+ Requires-Dist: cloudpickle<4.0.0,>=3.0.0
14
+ Requires-Dist: rich<15.0.0,>=13.9.4
15
+ Requires-Dist: click<9.0.0,>=8.1.7
16
+ Requires-Dist: protobuf<7.0.0,>=5.29.6
17
+ Requires-Dist: fastapi<1.0.0,>=0.115.11
18
+ Requires-Dist: uvicorn<1.0.0,>=0.29.0
19
+ Requires-Dist: watchdog<5.0.0,>=4.0.0
20
+ Requires-Dist: betterproto-levers9==2.1.0
21
+ Requires-Dist: croniter<4.0.0,>=3.0.3
22
+ Requires-Dist: websocket-client<2.0.0,>=1.8.0
23
+ Requires-Dist: prompt-toolkit<4.0.0,>=3.0.48
24
+ Requires-Dist: requests<3.0.0,>=2.32.3
25
+ Requires-Dist: paramiko<4.0.0,>=3.5.0
26
+ Requires-Dist: websockets<16,>=13
27
+ Requires-Dist: pyyaml<7.0.0,>=6.0.0
@@ -0,0 +1,47 @@
1
+ # levers9 sdk
2
+
3
+ Python SDK for Levers9.
4
+
5
+ ## Getting started
6
+
7
+ ### Using the SDK
8
+
9
+ This example will run the `square` function on levers9. Each invocation of `square` will run in a separate container.
10
+
11
+ ```python
12
+ from levers9 import function
13
+
14
+ @function(
15
+ cpu=0.25,
16
+ gpu="L4",
17
+ )
18
+ def square(i: int):
19
+ return i**2
20
+
21
+ def main():
22
+ numbers = list(range(10))
23
+ squared = []
24
+
25
+ for result in square.map(numbers):
26
+ squared.append(result)
27
+
28
+ print("numbers:", numbers)
29
+ print("squared:", sorted(squared))
30
+
31
+ if __name__ == "__main__":
32
+ main()
33
+
34
+ ```
35
+
36
+ ### Running the SDK
37
+
38
+ Let's run the code we just wrote. You can see we invoke the function 10 times.
39
+
40
+ ![demo gif](docs/demo.gif)
41
+
42
+
43
+ ### Using the CLI
44
+
45
+ Finally lets check the results using the CLI.
46
+
47
+ ![demo list tasks](docs/demo-list-tasks.png)
@@ -0,0 +1,86 @@
1
+ [project]
2
+ authors = [
3
+ {name = "Levers AI Lab", email = "hello@uselevers.com"},
4
+ ]
5
+ requires-python = "<4.0,>=3.8"
6
+ dependencies = [
7
+ "typeguard<3.0.0,>=2.13.3; python_version < '3.9'",
8
+ "typeguard<5.0.0,>=4.4.3; python_version >= '3.9'",
9
+ "typing-extensions<5.0.0,>=4.7.1",
10
+ "grpclib<1.0.0,>=0.4.7",
11
+ "grpcio<2.0.0,>=1.69.0",
12
+ "asgiref<4.0.0,>=3.8.1",
13
+ "cloudpickle<4.0.0,>=3.0.0",
14
+ "rich<15.0.0,>=13.9.4",
15
+ "click<9.0.0,>=8.1.7",
16
+ "protobuf<7.0.0,>=5.29.6",
17
+ "fastapi<1.0.0,>=0.115.11",
18
+ "uvicorn<1.0.0,>=0.29.0",
19
+ "watchdog<5.0.0,>=4.0.0",
20
+ "betterproto-levers9==2.1.0",
21
+ "croniter<4.0.0,>=3.0.3",
22
+ "websocket-client<2.0.0,>=1.8.0",
23
+ "prompt-toolkit<4.0.0,>=3.0.48",
24
+ "requests<3.0.0,>=2.32.3",
25
+ "paramiko<4.0.0,>=3.5.0",
26
+ "websockets>=13,<16",
27
+ "pyyaml<7.0.0,>=6.0.0",
28
+ ]
29
+ name = "levers9"
30
+ version = "0.1.265"
31
+ description = "levers9 SDK and CLI: run functions, endpoints, task queues, schedules, pods and GPU jobs on a levers9 cluster"
32
+
33
+ [project.scripts]
34
+ levers9 = "levers9.cli.main:start"
35
+
36
+ [dependency-groups]
37
+ dev = [
38
+ "pytest<9.0.0,>=8.2.0",
39
+ "pytest-env<2.0.0,>=1.1.3",
40
+ "attrs<24.0.0,>=23.2.0",
41
+ "docstring-parser<1.0,>=0.16",
42
+ "ruff",
43
+ "gunicorn<23.0.0,>=22.0.0",
44
+ "requests<3.0.0,>=2.32.3",
45
+ "pytest-cov<6.0.0,>=5.0.0",
46
+ ]
47
+
48
+ [tool.uv]
49
+ default-groups = []
50
+ package = true
51
+
52
+ [tool.pytest.ini_options]
53
+ pythonpath = ["src"]
54
+ testpaths = ["tests"]
55
+ addopts = "--verbose --cov --cov-report=html:.htmlcov"
56
+
57
+ [tool.coverage.report]
58
+ omit = ["tests/*"]
59
+ exclude_also = [
60
+ # Don't complain if tests don't hit defensive assertion code:
61
+ "raise AssertionError",
62
+ "raise NotImplementedError",
63
+
64
+ # Don't complain if non-runnable code isn't run:
65
+ "if __name__ == .__main__.:",
66
+
67
+ # Don't complain about abstract methods, they aren't run:
68
+ "@(abc\\.)?abstractmethod",
69
+ ]
70
+
71
+ [tool.ruff]
72
+ line-length = 100
73
+ exclude = ["src/levers9/clients", "vendor"]
74
+ src = ["src", "test", "bin"]
75
+
76
+ [tool.ruff.lint.per-file-ignores]
77
+ "src/levers9/__init__.py" = ["F403"]
78
+
79
+ [tool.vendoring]
80
+ destination = "src/levers9/vendor"
81
+ requirements = "vendors.txt"
82
+ namespace = "levers9.vendor"
83
+
84
+ [build-system]
85
+ requires = ["setuptools>=42", "wheel"]
86
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,77 @@
1
+ from importlib import import_module
2
+
3
+
4
+ _EXPORTS = {
5
+ "Map": (".abstractions.map", "Map"),
6
+ "Image": (".abstractions.image", "Image"),
7
+ "Queue": (".abstractions.queue", "SimpleQueue"),
8
+ "Volume": (".abstractions.volume", "Volume"),
9
+ "CloudBucket": (".abstractions.volume", "CloudBucket"),
10
+ "CloudBucketConfig": (".abstractions.volume", "CloudBucketConfig"),
11
+ "task_queue": (".abstractions.taskqueue", "TaskQueue"),
12
+ "function": (".abstractions.function", "Function"),
13
+ "endpoint": (".abstractions.endpoint", "Endpoint"),
14
+ "asgi": (".abstractions.endpoint", "ASGI"),
15
+ "realtime": (".abstractions.endpoint", "RealtimeASGI"),
16
+ "Container": (".abstractions.base.container", "Container"),
17
+ "env": (".env", None),
18
+ "GpuType": (".type", "GpuType"),
19
+ "DatabaseServingConfig": (".type", "DatabaseServingConfig"),
20
+ "DurableDisk": (".type", "DurableDisk"),
21
+ "LLMConfig": (".type", "LLMConfig"),
22
+ "LLMTokenPressureAutoscaler": (".type", "LLMTokenPressureAutoscaler"),
23
+ "Pool": (".type", "Pool"),
24
+ "PythonVersion": (".type", "PythonVersion"),
25
+ "Output": (".abstractions.output", "Output"),
26
+ "QueueDepthAutoscaler": (".type", "QueueDepthAutoscaler"),
27
+ "ServingConfig": (".type", "ServingConfig"),
28
+ "experimental": (".abstractions.experimental", None),
29
+ "integrations": (".abstractions.integrations", None),
30
+ "schedule": (".abstractions.function", "Schedule"),
31
+ "TaskPolicy": (".type", "TaskPolicy"),
32
+ "Bot": (".abstractions.experimental.bot.bot", "Bot"),
33
+ "BotLocation": (".abstractions.experimental.bot.bot", "BotLocation"),
34
+ "BotEventType": (".abstractions.experimental.bot.bot", "BotEventType"),
35
+ "BotContext": (".abstractions.experimental.bot.types", "BotContext"),
36
+ "Pod": (".abstractions.pod", "Pod"),
37
+ "Service": (".abstractions.service", "Service"),
38
+ "PricingPolicy": (".type", "PricingPolicy"),
39
+ "PricingPolicyCostModel": (".type", "PricingPolicyCostModel"),
40
+ "Client": (".client.client", "Client"),
41
+ "Task": (".client.task", "Task"),
42
+ "Deployment": (".client.deployment", "Deployment"),
43
+ "schema": (".schema", None),
44
+ "Sandbox": (".abstractions.sandbox", "Sandbox"),
45
+ "SandboxInstance": (".abstractions.sandbox", "SandboxInstance"),
46
+ "SandboxProcess": (".abstractions.sandbox", "SandboxProcess"),
47
+ "SandboxProcessStream": (".abstractions.sandbox", "SandboxProcessStream"),
48
+ "SandboxProcessManager": (".abstractions.sandbox", "SandboxProcessManager"),
49
+ "SandboxProcessResponse": (".abstractions.sandbox", "SandboxProcessResponse"),
50
+ "SandboxConnectionError": (".abstractions.sandbox", "SandboxConnectionError"),
51
+ "SandboxProcessError": (".abstractions.sandbox", "SandboxProcessError"),
52
+ "SandboxFileSystemError": (".abstractions.sandbox", "SandboxFileSystemError"),
53
+ "SandboxFilePosition": (".abstractions.sandbox", "SandboxFilePosition"),
54
+ "SandboxFileSearchRange": (".abstractions.sandbox", "SandboxFileSearchRange"),
55
+ "SandboxFileSearchMatch": (".abstractions.sandbox", "SandboxFileSearchMatch"),
56
+ "SandboxFileInfo": (".abstractions.sandbox", "SandboxFileInfo"),
57
+ "SandboxFileSystem": (".abstractions.sandbox", "SandboxFileSystem"),
58
+ "SandboxFileSearchResult": (".abstractions.sandbox", "SandboxFileSearchResult"),
59
+ }
60
+
61
+ __all__ = list(_EXPORTS)
62
+
63
+
64
+ def __getattr__(name):
65
+ try:
66
+ module_name, attribute = _EXPORTS[name]
67
+ except KeyError as error:
68
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from error
69
+
70
+ module = import_module(module_name, __name__)
71
+ value = module if attribute is None else getattr(module, attribute)
72
+ globals()[name] = value
73
+ return value
74
+
75
+
76
+ def __dir__():
77
+ return sorted((*globals(), *__all__))
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main.start()
File without changes
@@ -0,0 +1,77 @@
1
+ import os
2
+
3
+ os.environ["GRPC_VERBOSITY"] = os.getenv("GRPC_VERBOSITY") or "NONE"
4
+
5
+ import sys
6
+ from abc import ABC
7
+ from typing import Optional
8
+
9
+ from ...channel import Channel
10
+ from ...channel import get_channel as _get_channel
11
+ from ...config import ConfigContext, get_config_context, set_settings
12
+
13
+ # Global channel
14
+ _channel: Optional[Channel] = None
15
+
16
+
17
+ def set_channel(
18
+ channel: Optional[Channel] = None,
19
+ context: Optional[ConfigContext] = None,
20
+ ) -> None:
21
+ """
22
+ Sets the channel globally for the SDK.
23
+
24
+ Use this before importing any abstraction to control which
25
+ gateway to connect to. When you provide a channel, it should already be
26
+ authenticated. When you provide a context, this will authenticate for you.
27
+ If neither is provided, this uses the default context and will create a
28
+ channel. If there is no default context (or config file), then we will
29
+ prompt the user for it.
30
+
31
+ Args:
32
+ channel: gRPC channel. Defaults to None.
33
+ context: Config context that defines the channel credentials. Defaults to None.
34
+ """
35
+ global _channel
36
+
37
+ if channel:
38
+ _channel = channel
39
+ return
40
+
41
+ if context:
42
+ _channel = _get_channel(context)
43
+ return
44
+
45
+ context = get_config_context()
46
+ _channel = _get_channel(context)
47
+
48
+
49
+ def unset_channel():
50
+ global _channel
51
+ _channel = None
52
+
53
+
54
+ def get_channel() -> Channel:
55
+ global _channel
56
+
57
+ if not _channel:
58
+ set_channel()
59
+
60
+ return _channel # type: ignore
61
+
62
+
63
+ class BaseAbstraction(ABC):
64
+ @property
65
+ def channel(self) -> Channel:
66
+ return get_channel()
67
+
68
+ def __init_subclass__(cls, /, **kwargs):
69
+ """
70
+ Dynamically load settings depending on if this library is being used
71
+ by levers9 or beam.
72
+ """
73
+ if "beam" in sys.modules:
74
+ # Settings will be configured in SDKSettings.__post_init__
75
+ set_settings()
76
+
77
+ super().__init_subclass__(**kwargs)