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.
- simulac-0.0.1/PKG-INFO +144 -0
- simulac-0.0.1/README.md +107 -0
- simulac-0.0.1/pyproject.toml +122 -0
- simulac-0.0.1/simulac/__init__.py +20 -0
- simulac-0.0.1/simulac/base/__init__.py +0 -0
- simulac-0.0.1/simulac/base/envvar/__init__.py +0 -0
- simulac-0.0.1/simulac/base/envvar/envvar.py +62 -0
- simulac-0.0.1/simulac/base/envvar/envvar_service.py +123 -0
- simulac-0.0.1/simulac/base/error/error.py +9 -0
- simulac-0.0.1/simulac/base/instantiate/__init__.py +0 -0
- simulac-0.0.1/simulac/base/instantiate/descriptor.py +17 -0
- simulac-0.0.1/simulac/base/instantiate/extensions.py +45 -0
- simulac-0.0.1/simulac/base/instantiate/graph.py +91 -0
- simulac-0.0.1/simulac/base/instantiate/instantiate.py +76 -0
- simulac-0.0.1/simulac/base/instantiate/instantiate_service.py +435 -0
- simulac-0.0.1/simulac/base/instantiate/service_collection.py +46 -0
- simulac-0.0.1/simulac/base/network/__init__.py +0 -0
- simulac-0.0.1/simulac/base/network/network.py +13 -0
- simulac-0.0.1/simulac/base/result/result.py +7 -0
- simulac-0.0.1/simulac/base/runtime/__init__.py +0 -0
- simulac-0.0.1/simulac/base/runtime/runtime.py +37 -0
- simulac-0.0.1/simulac/base/test/graph_test.py +100 -0
- simulac-0.0.1/simulac/bddl/__init__.py +0 -0
- simulac-0.0.1/simulac/bddl/example.json +62 -0
- simulac-0.0.1/simulac/cli/__init__.py +9 -0
- simulac-0.0.1/simulac/cli/auth.py +160 -0
- simulac-0.0.1/simulac/data_types/duckdb_types/__init__.py +64 -0
- simulac-0.0.1/simulac/gym_style.py +17 -0
- simulac-0.0.1/simulac/lib/gym_style/__init__.py +136 -0
- simulac-0.0.1/simulac/lib/gym_style/gym_style_environment.py +314 -0
- simulac-0.0.1/simulac/lib/test/benchmark_test.py +857 -0
- simulac-0.0.1/simulac/lib/test/entity_test.py +18 -0
- simulac-0.0.1/simulac/lib/world_maker/__init__.py +14 -0
- simulac-0.0.1/simulac/lib/world_maker/entity.py +20 -0
- simulac-0.0.1/simulac/lib/world_maker/object.py +174 -0
- simulac-0.0.1/simulac/sdk/__init__.py +3 -0
- simulac-0.0.1/simulac/sdk/environment_service/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/environment_service/common/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/environment_service/common/environment.py +65 -0
- simulac-0.0.1/simulac/sdk/environment_service/common/environment_build_service.py +193 -0
- simulac-0.0.1/simulac/sdk/environment_service/common/environment_service.py +125 -0
- simulac-0.0.1/simulac/sdk/environment_service/common/model/component.py +33 -0
- simulac-0.0.1/simulac/sdk/environment_service/common/model/entity.py +114 -0
- simulac-0.0.1/simulac/sdk/environment_service/common/utils/mjcf_parser.py +235 -0
- simulac-0.0.1/simulac/sdk/file_service/common/file_service.py +0 -0
- simulac-0.0.1/simulac/sdk/file_service/common/files.py +302 -0
- simulac-0.0.1/simulac/sdk/file_service/local/disk_file_service_provider.py +0 -0
- simulac-0.0.1/simulac/sdk/file_service/remote/remote_file_service_provider.py +0 -0
- simulac-0.0.1/simulac/sdk/log_service/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/log_service/common/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/log_service/common/log_service.py +77 -0
- simulac-0.0.1/simulac/sdk/main.py +143 -0
- simulac-0.0.1/simulac/sdk/runner_service/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/runner_service/common/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/runner_service/common/physics_engine_adapter.py +31 -0
- simulac-0.0.1/simulac/sdk/runner_service/common/runner.py +50 -0
- simulac-0.0.1/simulac/sdk/runner_service/common/runner_service.py +165 -0
- simulac-0.0.1/simulac/sdk/runner_service/local/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/runner_service/local/mujoco_adapter.py +203 -0
- simulac-0.0.1/simulac/sdk/runner_service/local/newton_adapter.py +245 -0
- simulac-0.0.1/simulac/sdk/runner_service/remote/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/runner_service/remote/remote_adapter.py +135 -0
- simulac-0.0.1/simulac/sdk/runner_service/remote/runner.py +67 -0
- simulac-0.0.1/simulac/sdk/runtime.py +86 -0
- simulac-0.0.1/simulac/sdk/telemetry_service/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/telemetry_service/common/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/telemetry_service/common/telemetry.py +8 -0
- simulac-0.0.1/simulac/sdk/telemetry_service/common/telemetry_service.py +266 -0
- simulac-0.0.1/simulac/sdk/telemetry_service/test/telemetry_service_test.py +182 -0
- simulac-0.0.1/simulac/sdk/world_maker.py +153 -0
- simulac-0.0.1/simulac/sdk/world_service/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/world_service/common/__init__.py +0 -0
- simulac-0.0.1/simulac/sdk/world_service/common/world_service.py +63 -0
- 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
|
simulac-0.0.1/README.md
ADDED
|
@@ -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
|
|
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
|