simulac 0.0.1__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 (74) hide show
  1. simulac-0.0.1/PKG-INFO +144 -0
  2. simulac-0.0.1/README.md +107 -0
  3. simulac-0.0.1/pyproject.toml +122 -0
  4. simulac-0.0.1/simulac/__init__.py +20 -0
  5. simulac-0.0.1/simulac/base/__init__.py +0 -0
  6. simulac-0.0.1/simulac/base/envvar/__init__.py +0 -0
  7. simulac-0.0.1/simulac/base/envvar/envvar.py +62 -0
  8. simulac-0.0.1/simulac/base/envvar/envvar_service.py +123 -0
  9. simulac-0.0.1/simulac/base/error/error.py +9 -0
  10. simulac-0.0.1/simulac/base/instantiate/__init__.py +0 -0
  11. simulac-0.0.1/simulac/base/instantiate/descriptor.py +17 -0
  12. simulac-0.0.1/simulac/base/instantiate/extensions.py +45 -0
  13. simulac-0.0.1/simulac/base/instantiate/graph.py +91 -0
  14. simulac-0.0.1/simulac/base/instantiate/instantiate.py +76 -0
  15. simulac-0.0.1/simulac/base/instantiate/instantiate_service.py +435 -0
  16. simulac-0.0.1/simulac/base/instantiate/service_collection.py +46 -0
  17. simulac-0.0.1/simulac/base/network/__init__.py +0 -0
  18. simulac-0.0.1/simulac/base/network/network.py +13 -0
  19. simulac-0.0.1/simulac/base/result/result.py +7 -0
  20. simulac-0.0.1/simulac/base/runtime/__init__.py +0 -0
  21. simulac-0.0.1/simulac/base/runtime/runtime.py +37 -0
  22. simulac-0.0.1/simulac/base/test/graph_test.py +100 -0
  23. simulac-0.0.1/simulac/bddl/__init__.py +0 -0
  24. simulac-0.0.1/simulac/bddl/example.json +62 -0
  25. simulac-0.0.1/simulac/cli/__init__.py +9 -0
  26. simulac-0.0.1/simulac/cli/auth.py +160 -0
  27. simulac-0.0.1/simulac/data_types/duckdb_types/__init__.py +64 -0
  28. simulac-0.0.1/simulac/gym_style.py +17 -0
  29. simulac-0.0.1/simulac/lib/gym_style/__init__.py +136 -0
  30. simulac-0.0.1/simulac/lib/gym_style/gym_style_environment.py +314 -0
  31. simulac-0.0.1/simulac/lib/test/benchmark_test.py +857 -0
  32. simulac-0.0.1/simulac/lib/test/entity_test.py +18 -0
  33. simulac-0.0.1/simulac/lib/world_maker/__init__.py +14 -0
  34. simulac-0.0.1/simulac/lib/world_maker/entity.py +20 -0
  35. simulac-0.0.1/simulac/lib/world_maker/object.py +174 -0
  36. simulac-0.0.1/simulac/sdk/__init__.py +3 -0
  37. simulac-0.0.1/simulac/sdk/environment_service/__init__.py +0 -0
  38. simulac-0.0.1/simulac/sdk/environment_service/common/__init__.py +0 -0
  39. simulac-0.0.1/simulac/sdk/environment_service/common/environment.py +65 -0
  40. simulac-0.0.1/simulac/sdk/environment_service/common/environment_build_service.py +193 -0
  41. simulac-0.0.1/simulac/sdk/environment_service/common/environment_service.py +125 -0
  42. simulac-0.0.1/simulac/sdk/environment_service/common/model/component.py +33 -0
  43. simulac-0.0.1/simulac/sdk/environment_service/common/model/entity.py +114 -0
  44. simulac-0.0.1/simulac/sdk/environment_service/common/utils/mjcf_parser.py +235 -0
  45. simulac-0.0.1/simulac/sdk/file_service/common/file_service.py +0 -0
  46. simulac-0.0.1/simulac/sdk/file_service/common/files.py +302 -0
  47. simulac-0.0.1/simulac/sdk/file_service/local/disk_file_service_provider.py +0 -0
  48. simulac-0.0.1/simulac/sdk/file_service/remote/remote_file_service_provider.py +0 -0
  49. simulac-0.0.1/simulac/sdk/log_service/__init__.py +0 -0
  50. simulac-0.0.1/simulac/sdk/log_service/common/__init__.py +0 -0
  51. simulac-0.0.1/simulac/sdk/log_service/common/log_service.py +77 -0
  52. simulac-0.0.1/simulac/sdk/main.py +143 -0
  53. simulac-0.0.1/simulac/sdk/runner_service/__init__.py +0 -0
  54. simulac-0.0.1/simulac/sdk/runner_service/common/__init__.py +0 -0
  55. simulac-0.0.1/simulac/sdk/runner_service/common/physics_engine_adapter.py +31 -0
  56. simulac-0.0.1/simulac/sdk/runner_service/common/runner.py +50 -0
  57. simulac-0.0.1/simulac/sdk/runner_service/common/runner_service.py +165 -0
  58. simulac-0.0.1/simulac/sdk/runner_service/local/__init__.py +0 -0
  59. simulac-0.0.1/simulac/sdk/runner_service/local/mujoco_adapter.py +203 -0
  60. simulac-0.0.1/simulac/sdk/runner_service/local/newton_adapter.py +245 -0
  61. simulac-0.0.1/simulac/sdk/runner_service/remote/__init__.py +0 -0
  62. simulac-0.0.1/simulac/sdk/runner_service/remote/remote_adapter.py +135 -0
  63. simulac-0.0.1/simulac/sdk/runner_service/remote/runner.py +67 -0
  64. simulac-0.0.1/simulac/sdk/runtime.py +86 -0
  65. simulac-0.0.1/simulac/sdk/telemetry_service/__init__.py +0 -0
  66. simulac-0.0.1/simulac/sdk/telemetry_service/common/__init__.py +0 -0
  67. simulac-0.0.1/simulac/sdk/telemetry_service/common/telemetry.py +8 -0
  68. simulac-0.0.1/simulac/sdk/telemetry_service/common/telemetry_service.py +266 -0
  69. simulac-0.0.1/simulac/sdk/telemetry_service/test/telemetry_service_test.py +182 -0
  70. simulac-0.0.1/simulac/sdk/world_maker.py +153 -0
  71. simulac-0.0.1/simulac/sdk/world_service/__init__.py +0 -0
  72. simulac-0.0.1/simulac/sdk/world_service/common/__init__.py +0 -0
  73. simulac-0.0.1/simulac/sdk/world_service/common/world_service.py +63 -0
  74. simulac-0.0.1/simulac/server/__init__.py +0 -0
simulac-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,144 @@
1
+ Metadata-Version: 2.3
2
+ Name: simulac
3
+ Version: 0.0.1
4
+ Summary: A CLI, library, and local server for interacting with the Tektonian backend.
5
+ Keywords: robotics,robot-simulation,simulation,physics-engine,mujoco,newton,genesis,mjcf,urdf,usd
6
+ Author: Jeuk Kang
7
+ Author-email: Jeuk Kang <gangjeuk@tektonian.com>
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Topic :: Software Development :: Build Tools
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Requires-Dist: pydantic<3
14
+ Requires-Dist: duckdb>=1.4
15
+ Requires-Dist: structlog>=25.5.0
16
+ Requires-Dist: mujoco>=3.5.0
17
+ Requires-Dist: websockets>=15.0.1
18
+ Requires-Dist: typer>=0.24.1
19
+ Requires-Dist: zstd>=1.5.7.3
20
+ Requires-Dist: msgpack>=1.1.2
21
+ Requires-Dist: autodoc-pydantic>=2.2.0 ; extra == 'doc'
22
+ Requires-Dist: furo>=2025.12.19 ; extra == 'doc'
23
+ Requires-Dist: myst-parser>=4.0.1 ; extra == 'doc'
24
+ Requires-Dist: sphinx>=8.1.3 ; extra == 'doc'
25
+ Requires-Dist: genesis-world==0.3.12 ; extra == 'genesis'
26
+ Requires-Dist: torch>=2.10.0 ; extra == 'genesis'
27
+ Requires-Dist: newton>=1.0.0rc0 ; extra == 'newton'
28
+ Requires-Dist: warp-lang>=1.12.0 ; extra == 'newton'
29
+ Requires-Dist: mujoco-warp>=3.5.0.2 ; extra == 'newton'
30
+ Requires-Python: >=3.10
31
+ Project-URL: Homepage, https://tektonian.com
32
+ Project-URL: Repository, https://github.com/Tektonian/tektonian-python
33
+ Provides-Extra: doc
34
+ Provides-Extra: genesis
35
+ Provides-Extra: newton
36
+ Description-Content-Type: text/markdown
37
+
38
+ <h1 align="center"><b>Simulac</b></h3>
39
+
40
+ <h3 align="center"><b>⚡️ Developer centric digital twin builder</b></h3>
41
+
42
+ ---
43
+
44
+ [Simulac](https://github.com/Tektonian/simulac) is digital twin build tool filling the gap between physical world and software world.
45
+
46
+ Simulac helps transition between the two worlds, and provides developer-friendly API to building the world.
47
+
48
+ # Quick start
49
+
50
+ ## Installation
51
+
52
+ Simulac requires Python 3.10 or later.
53
+
54
+ ```bash
55
+ $ pip install simulac
56
+ $ uv add simulac
57
+ ```
58
+
59
+ ## Sign up and create an API key
60
+
61
+ Remote benchmark execution requires a Tektonian API key.
62
+ Go to our [website](https://tektonian.com) and get an API key.
63
+
64
+ Store your API key with CLI commend:
65
+ ```bash
66
+ simulac login
67
+ ```
68
+
69
+ You can also provide the key through an environment variable:
70
+ ```bash
71
+ export SIMULAC_API_KEY=<you_api_key>
72
+ ```
73
+ Note: API keys can only be viewed once when created
74
+
75
+ # Key function
76
+ Simulac provides one-line code execution for robot domain benchmark, and world building API (on developing)
77
+
78
+ ## Benchmark
79
+
80
+ You can execution famous Physical-AI benchmarks with one-line of code.
81
+ We currently support:
82
+ - **[Libero](https://tektonian.com/profile/Tektonian/Libero)**
83
+ - **[Calvin](https://tektonian.com/profile/Tektonian/Calvin)**
84
+ - **[Robomimic](https://tektonian.com/profile/Tektonian/Robomimic)**
85
+ - **[Metaworld](https://tektonian.com/profile/Tektonian/Metaworld)**
86
+
87
+ Visit [benchmark list](https://tektonian.com/benchmark) for details for running it.
88
+ ### Run benchmark
89
+ ```python
90
+ from simulac.gym_style import init_bench
91
+
92
+ env = init_bench(
93
+ "Tektonian/Libero",
94
+ "libero_90/KITCHEN_SCENE2_put_the_black_bowl_at_the_back_on_the_plate",
95
+ 0,
96
+ {"control_mode": "ee_pose"},
97
+ )
98
+
99
+ step = env.step(ACTION_ARRAY)
100
+
101
+ ```
102
+ ### Parallel Benchmark Execution
103
+
104
+ ```python
105
+ from simulac.gym_style import init_bench, make_vec
106
+
107
+ args = (
108
+ "Tektonian/Libero",
109
+ "libero_90/KITCHEN_SCENE2_put_the_black_bowl_at_the_back_on_the_plate",
110
+ 0,
111
+ )
112
+ options = {"benchmark_specific": {"control_mode": "ee_pose"}}
113
+
114
+ envs = [init_bench(*args, **options) for _ in range(3)]
115
+ vec_env = make_vec(envs)
116
+
117
+ steps = vec_env.step([[0.0] * 7 for _ in envs])
118
+ print(len(steps))
119
+ ```
120
+
121
+ ## Configuration
122
+
123
+ Simulac reads configuration from environment variables when present:
124
+
125
+ - `SIMULAC_API_KEY`: use an API key without running `simulac login`
126
+ - `SIMULAC_BASE_URL`: override the default Tektonian API endpoint
127
+ - `SIMULAC_LOG_LEVEL`: set log verbosity. choose one of `off, trace, debug, info, warning, error`
128
+ - `SIMULAC_TELEMETRY=off`: disable telemetry
129
+
130
+
131
+ ## World building
132
+
133
+ The world-building surface is best viewed as an evolving foundation for scene assembly and engine integration.
134
+
135
+ ## Project Status
136
+
137
+ Simulac is currently alpha software.
138
+
139
+ - The remote benchmark client is the most complete public surface.
140
+ - Local world-building and runner APIs are still evolving.
141
+
142
+ ## License
143
+
144
+ Apache-2.0
@@ -0,0 +1,107 @@
1
+ <h1 align="center"><b>Simulac</b></h3>
2
+
3
+ <h3 align="center"><b>⚡️ Developer centric digital twin builder</b></h3>
4
+
5
+ ---
6
+
7
+ [Simulac](https://github.com/Tektonian/simulac) is digital twin build tool filling the gap between physical world and software world.
8
+
9
+ Simulac helps transition between the two worlds, and provides developer-friendly API to building the world.
10
+
11
+ # Quick start
12
+
13
+ ## Installation
14
+
15
+ Simulac requires Python 3.10 or later.
16
+
17
+ ```bash
18
+ $ pip install simulac
19
+ $ uv add simulac
20
+ ```
21
+
22
+ ## Sign up and create an API key
23
+
24
+ Remote benchmark execution requires a Tektonian API key.
25
+ Go to our [website](https://tektonian.com) and get an API key.
26
+
27
+ Store your API key with CLI commend:
28
+ ```bash
29
+ simulac login
30
+ ```
31
+
32
+ You can also provide the key through an environment variable:
33
+ ```bash
34
+ export SIMULAC_API_KEY=<you_api_key>
35
+ ```
36
+ Note: API keys can only be viewed once when created
37
+
38
+ # Key function
39
+ Simulac provides one-line code execution for robot domain benchmark, and world building API (on developing)
40
+
41
+ ## Benchmark
42
+
43
+ You can execution famous Physical-AI benchmarks with one-line of code.
44
+ We currently support:
45
+ - **[Libero](https://tektonian.com/profile/Tektonian/Libero)**
46
+ - **[Calvin](https://tektonian.com/profile/Tektonian/Calvin)**
47
+ - **[Robomimic](https://tektonian.com/profile/Tektonian/Robomimic)**
48
+ - **[Metaworld](https://tektonian.com/profile/Tektonian/Metaworld)**
49
+
50
+ Visit [benchmark list](https://tektonian.com/benchmark) for details for running it.
51
+ ### Run benchmark
52
+ ```python
53
+ from simulac.gym_style import init_bench
54
+
55
+ env = init_bench(
56
+ "Tektonian/Libero",
57
+ "libero_90/KITCHEN_SCENE2_put_the_black_bowl_at_the_back_on_the_plate",
58
+ 0,
59
+ {"control_mode": "ee_pose"},
60
+ )
61
+
62
+ step = env.step(ACTION_ARRAY)
63
+
64
+ ```
65
+ ### Parallel Benchmark Execution
66
+
67
+ ```python
68
+ from simulac.gym_style import init_bench, make_vec
69
+
70
+ args = (
71
+ "Tektonian/Libero",
72
+ "libero_90/KITCHEN_SCENE2_put_the_black_bowl_at_the_back_on_the_plate",
73
+ 0,
74
+ )
75
+ options = {"benchmark_specific": {"control_mode": "ee_pose"}}
76
+
77
+ envs = [init_bench(*args, **options) for _ in range(3)]
78
+ vec_env = make_vec(envs)
79
+
80
+ steps = vec_env.step([[0.0] * 7 for _ in envs])
81
+ print(len(steps))
82
+ ```
83
+
84
+ ## Configuration
85
+
86
+ Simulac reads configuration from environment variables when present:
87
+
88
+ - `SIMULAC_API_KEY`: use an API key without running `simulac login`
89
+ - `SIMULAC_BASE_URL`: override the default Tektonian API endpoint
90
+ - `SIMULAC_LOG_LEVEL`: set log verbosity. choose one of `off, trace, debug, info, warning, error`
91
+ - `SIMULAC_TELEMETRY=off`: disable telemetry
92
+
93
+
94
+ ## World building
95
+
96
+ The world-building surface is best viewed as an evolving foundation for scene assembly and engine integration.
97
+
98
+ ## Project Status
99
+
100
+ Simulac is currently alpha software.
101
+
102
+ - The remote benchmark client is the most complete public surface.
103
+ - Local world-building and runner APIs are still evolving.
104
+
105
+ ## License
106
+
107
+ Apache-2.0
@@ -0,0 +1,122 @@
1
+ # START - project setting
2
+ [build-system]
3
+ requires = ["uv_build>=0.11.1,<0.12"]
4
+ build-backend = "uv_build"
5
+
6
+ [project]
7
+ name = "simulac"
8
+ version = "0.0.1"
9
+ description = "A CLI, library, and local server for interacting with the Tektonian backend."
10
+ authors = [{ name = "Jeuk Kang", email = "gangjeuk@tektonian.com" }]
11
+ keywords = [
12
+ "robotics",
13
+ "robot-simulation",
14
+ "simulation",
15
+ "physics-engine",
16
+ "mujoco",
17
+ "newton",
18
+ "genesis",
19
+ "mjcf",
20
+ "urdf",
21
+ "usd",
22
+ ]
23
+ readme = "README.md"
24
+ requires-python = ">=3.10"
25
+ classifiers = [
26
+ # How mature is this project? Common values are
27
+ # 3 - Alpha
28
+ # 4 - Beta
29
+ # 5 - Production/Stable
30
+ "Development Status :: 3 - Alpha",
31
+
32
+ # Indicate who your project is intended for
33
+ "Intended Audience :: Developers",
34
+ "Topic :: Software Development :: Build Tools",
35
+
36
+ # Specify the Python versions you support here.
37
+ "Programming Language :: Python :: 3",
38
+ "Programming Language :: Python :: 3.10",
39
+ ]
40
+ dependencies = [
41
+ "pydantic<3",
42
+ "duckdb>=1.4",
43
+ "structlog>=25.5.0",
44
+ "mujoco>=3.5.0",
45
+ "websockets>=15.0.1",
46
+ "typer>=0.24.1",
47
+ "zstd>=1.5.7.3",
48
+ "msgpack>=1.1.2",
49
+ ]
50
+
51
+ [project.scripts]
52
+ simulac = "simulac.cli:main"
53
+
54
+ [project.urls]
55
+ Homepage = "https://tektonian.com"
56
+ Repository = "https://github.com/Tektonian/tektonian-python"
57
+
58
+ [project.optional-dependencies]
59
+ genesis = ["genesis-world==0.3.12", "torch>=2.10.0"]
60
+
61
+ newton = ["newton>=1.0.0rc", "warp-lang>=1.12.0", "mujoco-warp>=3.5.0.2"]
62
+
63
+ doc = [
64
+ "autodoc-pydantic>=2.2.0",
65
+ "furo>=2025.12.19",
66
+ "myst-parser>=4.0.1",
67
+ "sphinx>=8.1.3",
68
+ ]
69
+
70
+ [dependency-groups]
71
+ dev = [
72
+ "pyright>=1.1.408",
73
+ "pylint==3.3.4",
74
+ "ruff>=0.15.5",
75
+ "pybind11-stubgen>=2.5.5",
76
+ "typing_extensions>=4.8,<5",
77
+ "eval_type_backport; python_version < '3.10'",
78
+ "packaging",
79
+ "pytest",
80
+ "nox>=2026.2.9",
81
+ "pytest-cov>=7.0.0",
82
+ "numpy",
83
+ "pillow",
84
+ "opencv-python",
85
+ ]
86
+
87
+ # END - project setting
88
+
89
+ # START - linting tool setting
90
+ [tool.ruff.lint]
91
+ select = ["E", "F", "I", "TC004"]
92
+ ignore = ["F401"]
93
+
94
+ [tool.ruff.format]
95
+ docstring-code-format = true
96
+ exclude = ["trash"]
97
+
98
+ [tool.pyright]
99
+ stubPath = ".typings"
100
+ typeCheckingMode = "strict"
101
+
102
+ [tool.ruff.lint.isort]
103
+ required-imports = ["from __future__ import annotations"]
104
+
105
+ # END - linting tool setting
106
+
107
+ # START - build tool
108
+
109
+ [tool.uv.build-backend]
110
+ module-name = "simulac"
111
+ module-root = ""
112
+ source-include = ["simulac/**"]
113
+
114
+ # END - build tool
115
+
116
+ # START - testing tool
117
+ [tool.pytest.ini_options]
118
+ markers = [
119
+ "integration: tests requiring external web service",
120
+ ]
121
+ pythonpath = ["."]
122
+ # END - testing tool
@@ -0,0 +1,20 @@
1
+ from .lib.world_maker.entity import Camera, Light, Robot, Stuff
2
+ from .lib.world_maker.object import (
3
+ CameraObject,
4
+ Environment,
5
+ LightObject,
6
+ RobotObject,
7
+ StuffObject,
8
+ )
9
+
10
+ __all__ = [
11
+ "Robot",
12
+ "Stuff",
13
+ "Camera",
14
+ "Light",
15
+ "Environment",
16
+ "RobotObject",
17
+ "StuffObject",
18
+ "CameraObject",
19
+ "LightObject",
20
+ ]
File without changes
File without changes
@@ -0,0 +1,62 @@
1
+ from abc import abstractmethod
2
+ from pathlib import Path
3
+
4
+ from simulac.base.instantiate.instantiate import ServiceIdentifier, service_identifier
5
+
6
+
7
+ @service_identifier("IEnvvarService")
8
+ class IEnvvarService(ServiceIdentifier["IEnvvarService"]):
9
+ # logging
10
+ @property
11
+ @abstractmethod
12
+ def log_level(self) -> str: ...
13
+
14
+ # telemetry
15
+ @property
16
+ @abstractmethod
17
+ def telemetry_disabled(self) -> bool: ...
18
+
19
+ # file path
20
+ @property
21
+ @abstractmethod
22
+ def log_file(self) -> Path: ...
23
+
24
+ @property
25
+ @abstractmethod
26
+ def app_root(self) -> Path:
27
+ """Root path, where this package is being used"""
28
+
29
+ @property
30
+ @abstractmethod
31
+ def user_home(self) -> Path: ...
32
+
33
+ @property
34
+ @abstractmethod
35
+ def tmp_dir(self) -> Path: ...
36
+
37
+ @property
38
+ @abstractmethod
39
+ def simulac_cache_dir(self) -> Path: ...
40
+
41
+ @property
42
+ @abstractmethod
43
+ def asset_dir(self) -> Path: ...
44
+
45
+ @property
46
+ @abstractmethod
47
+ def token_path(self) -> Path: ...
48
+
49
+ # token
50
+ @property
51
+ @abstractmethod
52
+ def token(self) -> str | None: ...
53
+
54
+ # url
55
+ @property
56
+ @abstractmethod
57
+ def base_url(self) -> str: ...
58
+
59
+ # develop
60
+ @property
61
+ @abstractmethod
62
+ def dev_mode(self) -> bool: ...
@@ -0,0 +1,123 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import sys
5
+ import tempfile
6
+ from enum import StrEnum
7
+ from pathlib import Path
8
+ from typing import TYPE_CHECKING
9
+
10
+ from simulac.base.envvar.envvar import IEnvvarService
11
+
12
+ if TYPE_CHECKING:
13
+ from simulac.sdk.log_service.common.log_service import LogLevel
14
+
15
+
16
+ class EnvvarKeyValue(StrEnum):
17
+ SIMULAC_LOG_LEVEL = "SIMULAC_LOG_LEVEL"
18
+ SIMULAC_BASE_URL = "SIMULAC_BASE_URL"
19
+ SIMULAC_TELEMETRY = "SIMULAC_TELEMETRY"
20
+ SIMULAC_API_KEY = "SIMULAC_API_KEY"
21
+
22
+
23
+ class EnvvarService(IEnvvarService):
24
+ """
25
+ TODO: @gangjeuk
26
+ EnvvarService is not idle code
27
+ 1. rename @property names
28
+ 2. is it a good pattern to have directory location related codes here?
29
+ """
30
+
31
+ BASE_URL = "https://tektonian.com/api"
32
+
33
+ KEY_VALUE = EnvvarKeyValue
34
+
35
+ def __init__(self) -> None:
36
+ self._log_level = "info"
37
+
38
+ self._user_home = os.path.expanduser("~")
39
+ self._tmp_dir = tempfile.gettempdir()
40
+ self._app_root = os.getcwd()
41
+
42
+ @property
43
+ def log_level(self) -> str:
44
+ level = os.environ.get(self.KEY_VALUE.SIMULAC_LOG_LEVEL.value, None)
45
+ if level in ["off", "trace", "debug", "info", "warning", "error"]:
46
+ return level
47
+ else:
48
+ return self._log_level
49
+
50
+ @property
51
+ def telemetry_disabled(self) -> bool:
52
+ tele_env = os.environ.get(self.KEY_VALUE.SIMULAC_TELEMETRY.value, None)
53
+ if tele_env is None:
54
+ return False
55
+ elif tele_env == "off":
56
+ return True
57
+
58
+ return False
59
+
60
+ @property
61
+ def log_file(self) -> Path:
62
+ simulac_log_path = os.path.join(self.app_root, ".simulac", "log.json")
63
+ return Path(simulac_log_path)
64
+
65
+ @property
66
+ def app_root(self) -> Path:
67
+ return Path(self._app_root)
68
+
69
+ @property
70
+ def user_home(self) -> Path:
71
+ return Path(self._user_home)
72
+
73
+ @property
74
+ def tmp_dir(self) -> Path:
75
+ return Path(self._tmp_dir)
76
+
77
+ @property
78
+ def simulac_cache_dir(self) -> Path:
79
+ return Path(os.path.join(self.user_home, ".cache", "simulac"))
80
+
81
+ @property
82
+ def asset_dir(self) -> Path:
83
+ return Path(os.path.join(self.simulac_cache_dir, "asset"))
84
+
85
+ @property
86
+ def token_path(self) -> Path:
87
+ return Path(os.path.join(self.simulac_cache_dir, "token"))
88
+
89
+ @property
90
+ def token(self) -> str | None:
91
+ token_env = os.environ.get(self.KEY_VALUE.SIMULAC_API_KEY.value, None)
92
+ if token_env is not None:
93
+ return token_env
94
+
95
+ token_ret = ""
96
+ if self.token_path.exists() and self.token_path.is_file():
97
+ with open(self.token_path, "r") as file:
98
+ token_ret = file.readline()
99
+
100
+ token_ret = token_ret.replace("\n", "").replace("\r", "").strip()
101
+
102
+ if len(token_ret) > 40:
103
+ return token_ret
104
+
105
+ return None
106
+
107
+ @property
108
+ def base_url(self) -> str:
109
+ env_path = os.environ.get(self.KEY_VALUE.SIMULAC_BASE_URL.value, None)
110
+ if env_path is not None:
111
+ return env_path
112
+ else:
113
+ return self.BASE_URL
114
+
115
+ @property
116
+ def dev_mode(self) -> bool:
117
+ _dev_mode = os.environ.get("PYTHONDEVMODE", False)
118
+
119
+ if _dev_mode is False:
120
+ _dev_mode = True if sys.warnoptions == ["default"] else False
121
+ if isinstance(_dev_mode, str):
122
+ _dev_mode = True if _dev_mode == "1" else False
123
+ return _dev_mode
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ class SimulacBaseError(Exception):
5
+ def __init__(self, message: str, context: dict | None = None) -> None:
6
+ super().__init__(message)
7
+ self.message = message
8
+ if context:
9
+ self.context = context
File without changes
@@ -0,0 +1,17 @@
1
+ from typing import Any, Generic, List, Type, TypeVar
2
+
3
+ from .instantiate import ServiceIdentifier
4
+
5
+ T = TypeVar("T", bound=ServiceIdentifier[object])
6
+
7
+
8
+ class SyncDescriptor(Generic[T]):
9
+ def __init__(
10
+ self,
11
+ ctor: Type[T] | object,
12
+ static_arguments: List[Any],
13
+ support_delayed_instantiation: bool,
14
+ ):
15
+ self.ctor = ctor
16
+ self.static_arguments = static_arguments
17
+ self.support_delayed_instantiation = support_delayed_instantiation
@@ -0,0 +1,45 @@
1
+ from abc import ABC, abstractmethod
2
+ from enum import Enum
3
+ from inspect import isclass, signature
4
+ from typing import Any, Generic, List, MutableMapping, Tuple, Type, TypeVar
5
+
6
+ from .descriptor import SyncDescriptor
7
+ from .instantiate import ServiceIdentifier
8
+
9
+
10
+ class InstantiateType(Enum):
11
+ EAGER = True
12
+ DELAYED = False
13
+
14
+
15
+ _registry: List[Tuple[Type[ServiceIdentifier[object]], SyncDescriptor[Any]]] = []
16
+
17
+
18
+ O = TypeVar("O", bound=object)
19
+
20
+
21
+ def register_singleton[O](
22
+ interface: Type[ServiceIdentifier[O]],
23
+ descriptor: Type[object],
24
+ support_delayed_instantiation: InstantiateType = InstantiateType.DELAYED,
25
+ ):
26
+ if not issubclass(interface, ServiceIdentifier):
27
+ raise Exception("")
28
+
29
+ elif not isclass(descriptor):
30
+ raise Exception("")
31
+
32
+ elif not issubclass(descriptor, interface):
33
+ raise Exception("")
34
+
35
+ else:
36
+ _registry.append(
37
+ (
38
+ interface,
39
+ SyncDescriptor(descriptor, [], support_delayed_instantiation.value),
40
+ )
41
+ )
42
+
43
+
44
+ def get_singleton_service_descriptors():
45
+ return _registry