luminarycloud 0.16.2__py3-none-any.whl → 0.18.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.
- luminarycloud/_auth/auth.py +23 -34
- luminarycloud/_client/client.py +23 -4
- luminarycloud/_client/retry_interceptor.py +7 -0
- luminarycloud/_helpers/_create_geometry.py +134 -34
- luminarycloud/_helpers/_wait_for_mesh.py +14 -4
- luminarycloud/_helpers/cond.py +0 -1
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.py +146 -123
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.pyi +82 -15
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.py +34 -0
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.py +8 -8
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.pyi +12 -7
- luminarycloud/_proto/api/v0/luminarycloud/mesh/mesh_pb2.py +25 -3
- luminarycloud/_proto/api/v0/luminarycloud/mesh/mesh_pb2.pyi +30 -0
- luminarycloud/_proto/api/v0/luminarycloud/mesh/mesh_pb2_grpc.py +34 -0
- luminarycloud/_proto/api/v0/luminarycloud/mesh/mesh_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/api/v0/luminarycloud/pipelines/pipelines_pb2.py +246 -0
- luminarycloud/_proto/api/v0/luminarycloud/pipelines/pipelines_pb2.pyi +420 -0
- luminarycloud/_proto/api/v0/luminarycloud/pipelines/pipelines_pb2_grpc.py +240 -0
- luminarycloud/_proto/api/v0/luminarycloud/pipelines/pipelines_pb2_grpc.pyi +90 -0
- luminarycloud/_proto/api/v0/luminarycloud/project/project_pb2.py +54 -3
- luminarycloud/_proto/api/v0/luminarycloud/project/project_pb2.pyi +92 -1
- luminarycloud/_proto/api/v0/luminarycloud/project/project_pb2_grpc.py +132 -0
- luminarycloud/_proto/api/v0/luminarycloud/project/project_pb2_grpc.pyi +40 -0
- luminarycloud/_proto/api/v0/luminarycloud/project_ui_state/project_ui_state_pb2.py +97 -0
- luminarycloud/_proto/api/v0/luminarycloud/project_ui_state/project_ui_state_pb2.pyi +93 -0
- luminarycloud/_proto/api/v0/luminarycloud/project_ui_state/project_ui_state_pb2_grpc.py +132 -0
- luminarycloud/_proto/api/v0/luminarycloud/project_ui_state/project_ui_state_pb2_grpc.pyi +44 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.py +48 -26
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.pyi +30 -2
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2_grpc.py +36 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2_grpc.pyi +18 -0
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.py +153 -133
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.pyi +51 -3
- luminarycloud/_proto/client/simulation_pb2.py +261 -251
- luminarycloud/_proto/client/simulation_pb2.pyi +35 -2
- luminarycloud/_proto/frontend/output/output_pb2.py +24 -24
- luminarycloud/_proto/frontend/output/output_pb2.pyi +6 -3
- luminarycloud/_proto/geometry/geometry_pb2.py +63 -63
- luminarycloud/_proto/geometry/geometry_pb2.pyi +16 -8
- luminarycloud/_proto/hexmesh/hexmesh_pb2.py +17 -4
- luminarycloud/_proto/hexmesh/hexmesh_pb2.pyi +22 -1
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.py +10 -10
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.pyi +12 -7
- luminarycloud/_proto/quantity/quantity_pb2.py +19 -19
- luminarycloud/enum/geometry_status.py +15 -8
- luminarycloud/enum/pipeline_job_status.py +23 -0
- luminarycloud/feature_modification.py +3 -6
- luminarycloud/geometry.py +25 -0
- luminarycloud/geometry_version.py +23 -0
- luminarycloud/mesh.py +16 -0
- luminarycloud/params/enum/_enum_wrappers.py +29 -0
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/fan_curve_inlet_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/mach_inlet_.py +5 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/mass_flow_inlet_.py +5 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/total_pressure_inlet_.py +5 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/velocity_magnitude_inlet_.py +5 -1
- luminarycloud/physics_ai/inference.py +46 -30
- luminarycloud/pipelines/__init__.py +7 -0
- luminarycloud/pipelines/api.py +213 -0
- luminarycloud/project.py +98 -11
- luminarycloud/simulation_template.py +15 -6
- luminarycloud/vis/__init__.py +6 -0
- luminarycloud/vis/data_extraction.py +201 -31
- luminarycloud/vis/filters.py +94 -35
- luminarycloud/vis/interactive_inference.py +153 -0
- luminarycloud/vis/interactive_scene.py +35 -16
- luminarycloud/vis/primitives.py +87 -1
- luminarycloud/vis/visualization.py +50 -6
- luminarycloud/volume_selection.py +3 -6
- {luminarycloud-0.16.2.dist-info → luminarycloud-0.18.0.dist-info}/METADATA +18 -18
- {luminarycloud-0.16.2.dist-info → luminarycloud-0.18.0.dist-info}/RECORD +73 -62
- {luminarycloud-0.16.2.dist-info → luminarycloud-0.18.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Copyright 2023-2024 Luminary Cloud, Inc. All Rights Reserved.
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
6
|
+
from luminarycloud._helpers import timestamp_to_datetime
|
|
7
|
+
|
|
8
|
+
from ..enum.pipeline_job_status import PipelineJobStatus
|
|
9
|
+
from ..pipelines import Pipeline, PipelineArgs
|
|
10
|
+
from .._client import get_default_client
|
|
11
|
+
from .._proto.api.v0.luminarycloud.pipelines import pipelines_pb2 as pipelinespb
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class PipelineRecord:
|
|
16
|
+
id: str
|
|
17
|
+
name: str
|
|
18
|
+
description: str | None
|
|
19
|
+
definition_yaml: str
|
|
20
|
+
create_time: datetime
|
|
21
|
+
update_time: datetime
|
|
22
|
+
|
|
23
|
+
def pipeline(self) -> Pipeline:
|
|
24
|
+
return Pipeline._from_yaml(self.definition_yaml)
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def from_proto(cls, proto: pipelinespb.Pipeline) -> "PipelineRecord":
|
|
28
|
+
return cls(
|
|
29
|
+
id=proto.id,
|
|
30
|
+
name=proto.name,
|
|
31
|
+
description=proto.description,
|
|
32
|
+
definition_yaml=proto.definition_yaml,
|
|
33
|
+
create_time=timestamp_to_datetime(proto.created_at),
|
|
34
|
+
update_time=timestamp_to_datetime(proto.updated_at),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class PipelineJobRecord:
|
|
40
|
+
id: str
|
|
41
|
+
pipeline_id: str
|
|
42
|
+
project_id: str
|
|
43
|
+
name: str
|
|
44
|
+
description: str | None
|
|
45
|
+
status: PipelineJobStatus
|
|
46
|
+
create_time: datetime
|
|
47
|
+
update_time: datetime
|
|
48
|
+
started_at: datetime | None
|
|
49
|
+
completed_at: datetime | None
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_proto(cls, proto: pipelinespb.PipelineJob) -> "PipelineJobRecord":
|
|
53
|
+
return cls(
|
|
54
|
+
id=proto.id,
|
|
55
|
+
pipeline_id=proto.pipeline_id,
|
|
56
|
+
project_id=proto.project_id,
|
|
57
|
+
name=proto.name,
|
|
58
|
+
description=proto.description,
|
|
59
|
+
status=PipelineJobStatus(proto.status),
|
|
60
|
+
create_time=timestamp_to_datetime(proto.created_at),
|
|
61
|
+
update_time=timestamp_to_datetime(proto.updated_at),
|
|
62
|
+
started_at=(
|
|
63
|
+
timestamp_to_datetime(proto.started_at) if proto.HasField("started_at") else None
|
|
64
|
+
),
|
|
65
|
+
completed_at=(
|
|
66
|
+
timestamp_to_datetime(proto.completed_at)
|
|
67
|
+
if proto.HasField("completed_at")
|
|
68
|
+
else None
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def create_pipeline(
|
|
74
|
+
name: str, pipeline: Pipeline | str, description: str | None = None
|
|
75
|
+
) -> PipelineRecord:
|
|
76
|
+
"""
|
|
77
|
+
Create a new pipeline.
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
name : str
|
|
82
|
+
Name of the pipeline.
|
|
83
|
+
pipeline : Pipeline | str
|
|
84
|
+
The pipeline to create. Accepts a Pipeline object or a YAML-formatted pipeline definition.
|
|
85
|
+
description : str, optional
|
|
86
|
+
Description of the pipeline.
|
|
87
|
+
"""
|
|
88
|
+
if isinstance(pipeline, Pipeline):
|
|
89
|
+
definition_yaml = pipeline.to_yaml()
|
|
90
|
+
else:
|
|
91
|
+
definition_yaml = pipeline
|
|
92
|
+
req = pipelinespb.CreatePipelineRequest(
|
|
93
|
+
name=name, definition_yaml=definition_yaml, description=description
|
|
94
|
+
)
|
|
95
|
+
res: pipelinespb.CreatePipelineResponse = get_default_client().CreatePipeline(req)
|
|
96
|
+
return PipelineRecord.from_proto(res.pipeline)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def list_pipelines() -> list[PipelineRecord]:
|
|
100
|
+
"""
|
|
101
|
+
List all pipelines.
|
|
102
|
+
"""
|
|
103
|
+
req = pipelinespb.ListPipelinesRequest()
|
|
104
|
+
res: pipelinespb.ListPipelinesResponse = get_default_client().ListPipelines(req)
|
|
105
|
+
return [PipelineRecord.from_proto(p) for p in res.pipelines]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_pipeline(id: str) -> PipelineRecord:
|
|
109
|
+
"""
|
|
110
|
+
Get a pipeline by ID.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
id : str
|
|
115
|
+
ID of the pipeline to fetch.
|
|
116
|
+
"""
|
|
117
|
+
req = pipelinespb.GetPipelineRequest(id=id)
|
|
118
|
+
res: pipelinespb.GetPipelineResponse = get_default_client().GetPipeline(req)
|
|
119
|
+
return PipelineRecord.from_proto(res.pipeline)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def create_pipeline_job(
|
|
123
|
+
pipeline_id: str, args: PipelineArgs, project_id: str, name: str, description: str | None = None
|
|
124
|
+
) -> PipelineJobRecord:
|
|
125
|
+
"""
|
|
126
|
+
Create a new pipeline job.
|
|
127
|
+
|
|
128
|
+
Parameters
|
|
129
|
+
----------
|
|
130
|
+
pipeline_id : str
|
|
131
|
+
ID of the pipeline to invoke.
|
|
132
|
+
args : PipelineArgs
|
|
133
|
+
Arguments to pass to the pipeline.
|
|
134
|
+
project_id : str
|
|
135
|
+
ID of the project to run the pipeline job in.
|
|
136
|
+
name : str
|
|
137
|
+
Name of the pipeline job.
|
|
138
|
+
description : str, optional
|
|
139
|
+
Description of the pipeline job.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
col_values = [[] for _ in args.params]
|
|
143
|
+
for row in args.rows:
|
|
144
|
+
for i, v in enumerate(row.row_values):
|
|
145
|
+
col_values[i].append(v)
|
|
146
|
+
|
|
147
|
+
cols = []
|
|
148
|
+
|
|
149
|
+
for i, param in enumerate(args.params):
|
|
150
|
+
if param._represented_type() == str:
|
|
151
|
+
cols.append(
|
|
152
|
+
pipelinespb.PipelineJobArgsColumn(
|
|
153
|
+
string_column=pipelinespb.PipelineJobArgsColumn.StringColumn(
|
|
154
|
+
name=param.name,
|
|
155
|
+
values=col_values[i],
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
elif param._represented_type() == int:
|
|
160
|
+
cols.append(
|
|
161
|
+
pipelinespb.PipelineJobArgsColumn(
|
|
162
|
+
int_column=pipelinespb.PipelineJobArgsColumn.IntColumn(
|
|
163
|
+
name=param.name,
|
|
164
|
+
values=col_values[i],
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
)
|
|
168
|
+
elif param._represented_type() == float:
|
|
169
|
+
cols.append(
|
|
170
|
+
pipelinespb.PipelineJobArgsColumn(
|
|
171
|
+
double_column=pipelinespb.PipelineJobArgsColumn.DoubleColumn(
|
|
172
|
+
name=param.name,
|
|
173
|
+
values=col_values[i],
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
)
|
|
177
|
+
elif param._represented_type() == bool:
|
|
178
|
+
cols.append(
|
|
179
|
+
pipelinespb.PipelineJobArgsColumn(
|
|
180
|
+
bool_column=pipelinespb.PipelineJobArgsColumn.BoolColumn(
|
|
181
|
+
name=param.name,
|
|
182
|
+
values=col_values[i],
|
|
183
|
+
)
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
req = pipelinespb.CreatePipelineJobRequest(
|
|
188
|
+
pipeline_id=pipeline_id,
|
|
189
|
+
args_columns=cols,
|
|
190
|
+
name=name,
|
|
191
|
+
description=description,
|
|
192
|
+
project_id=project_id,
|
|
193
|
+
)
|
|
194
|
+
res: pipelinespb.CreatePipelineJobResponse = get_default_client().CreatePipelineJob(req)
|
|
195
|
+
return PipelineJobRecord.from_proto(res.pipeline_job)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def get_pipeline_job(id: str) -> PipelineJobRecord:
|
|
199
|
+
"""
|
|
200
|
+
Get a pipeline job by ID.
|
|
201
|
+
"""
|
|
202
|
+
req = pipelinespb.GetPipelineJobRequest(id=id)
|
|
203
|
+
res: pipelinespb.GetPipelineJobResponse = get_default_client().GetPipelineJob(req)
|
|
204
|
+
return PipelineJobRecord.from_proto(res.pipeline_job)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def list_pipeline_jobs() -> list[PipelineJobRecord]:
|
|
208
|
+
"""
|
|
209
|
+
List all pipeline jobs.
|
|
210
|
+
"""
|
|
211
|
+
req = pipelinespb.ListPipelineJobsRequest()
|
|
212
|
+
res: pipelinespb.ListPipelineJobsResponse = get_default_client().ListPipelineJobs(req)
|
|
213
|
+
return [PipelineJobRecord.from_proto(p) for p in res.pipeline_jobs]
|
luminarycloud/project.py
CHANGED
|
@@ -6,7 +6,7 @@ import re
|
|
|
6
6
|
import uuid
|
|
7
7
|
from datetime import datetime
|
|
8
8
|
from os import PathLike, path
|
|
9
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
|
9
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union, Literal
|
|
10
10
|
|
|
11
11
|
import concurrent
|
|
12
12
|
|
|
@@ -38,6 +38,9 @@ from ._proto.api.v0.luminarycloud.simulation import simulation_pb2 as simulation
|
|
|
38
38
|
from ._proto.api.v0.luminarycloud.simulation_template import (
|
|
39
39
|
simulation_template_pb2 as simtemplatepb,
|
|
40
40
|
)
|
|
41
|
+
from ._proto.api.v0.luminarycloud.project_ui_state import (
|
|
42
|
+
project_ui_state_pb2 as projectuistatepb,
|
|
43
|
+
)
|
|
41
44
|
from ._proto.client import simulation_pb2 as clientpb
|
|
42
45
|
from ._proto.table import table_pb2 as tablepb
|
|
43
46
|
from ._proto.hexmesh import hexmesh_pb2 as hexmeshpb
|
|
@@ -118,23 +121,22 @@ class Project(ProtoWrapperBase):
|
|
|
118
121
|
|
|
119
122
|
def create_geometry(
|
|
120
123
|
self,
|
|
121
|
-
cad_file_path: PathLike | str,
|
|
124
|
+
cad_file_path: PathLike | str | List[PathLike | str],
|
|
122
125
|
*,
|
|
123
126
|
name: Optional[str] = None,
|
|
124
127
|
scaling: Optional[float] = None,
|
|
125
128
|
wait: bool = False,
|
|
126
|
-
convert_to_discrete: bool = False,
|
|
127
129
|
) -> "Geometry":
|
|
128
130
|
"""
|
|
129
|
-
Create a new geometry in the project by uploading
|
|
131
|
+
Create a new geometry in the project by uploading supported CAD file(s).
|
|
130
132
|
|
|
131
133
|
For more information on supported formats and best practices, see:
|
|
132
134
|
https://docs.luminarycloud.com/en/articles/9274255-upload-cad
|
|
133
135
|
|
|
134
136
|
Parameters
|
|
135
137
|
----------
|
|
136
|
-
cad_file_path : PathLike
|
|
137
|
-
Path or URL to the CAD file to upload.
|
|
138
|
+
cad_file_path : PathLike | str | List[PathLike | str]
|
|
139
|
+
Path(s) or URL to the CAD file(s) to upload.
|
|
138
140
|
|
|
139
141
|
Other Parameters
|
|
140
142
|
----------------
|
|
@@ -148,10 +150,6 @@ class Project(ProtoWrapperBase):
|
|
|
148
150
|
If set to True, this function will block until the geometry import
|
|
149
151
|
completes. Otherwise, it will return immediately and the import will
|
|
150
152
|
occur in the background. Defaults to False.
|
|
151
|
-
convert_to_discrete : bool, optional
|
|
152
|
-
If set to True, the geometry will be converted to a discrete geometry.
|
|
153
|
-
This allows using the Shrinkwrap operation to create a watertight
|
|
154
|
-
geometry. Defaults to False.
|
|
155
153
|
|
|
156
154
|
Returns
|
|
157
155
|
-------
|
|
@@ -183,7 +181,6 @@ class Project(ProtoWrapperBase):
|
|
|
183
181
|
name=name,
|
|
184
182
|
scaling=scaling,
|
|
185
183
|
wait=wait,
|
|
186
|
-
convert_to_discrete=convert_to_discrete,
|
|
187
184
|
)
|
|
188
185
|
return lc.Geometry(_geometry)
|
|
189
186
|
|
|
@@ -629,12 +626,102 @@ class Project(ProtoWrapperBase):
|
|
|
629
626
|
return lc.NamedVariableSet(res.named_variable_set)
|
|
630
627
|
|
|
631
628
|
def list_named_variable_sets(self) -> list[NamedVariableSet]:
|
|
629
|
+
"""
|
|
630
|
+
.. warning:: This feature is experimental and may change or be removed without notice.
|
|
631
|
+
"""
|
|
632
632
|
req = namedvariablepb.ListNamedVariableSetsRequest(project_id=self.id)
|
|
633
633
|
res: namedvariablepb.ListNamedVariableSetsResponse = (
|
|
634
634
|
get_default_client().ListNamedVariableSets(req)
|
|
635
635
|
)
|
|
636
636
|
return [lc.NamedVariableSet(n) for n in res.named_variable_sets]
|
|
637
637
|
|
|
638
|
+
def set_active_named_variable_set(self, named_variable_set: NamedVariableSet) -> None:
|
|
639
|
+
"""
|
|
640
|
+
This is a purely a construct for setting the active NamedVariableSet in the UI. It does not
|
|
641
|
+
affect any previous or future SDK behavior.
|
|
642
|
+
|
|
643
|
+
.. warning:: This feature is experimental and may change or be removed without notice.
|
|
644
|
+
"""
|
|
645
|
+
req = projectuistatepb.SetActiveNamedVariableSetRequest(
|
|
646
|
+
project_id=self.id, named_variable_set_id=named_variable_set.id
|
|
647
|
+
)
|
|
648
|
+
get_default_client().SetActiveNamedVariableSet(req)
|
|
649
|
+
|
|
650
|
+
def get_active_named_variable_set(self) -> Optional[NamedVariableSet]:
|
|
651
|
+
"""
|
|
652
|
+
This is a purely a construct for getting the active NamedVariableSet for a project in the UI.
|
|
653
|
+
It does not affect any previous or future SDK behavior.
|
|
654
|
+
|
|
655
|
+
.. warning:: This feature is experimental and may change or be removed without notice.
|
|
656
|
+
"""
|
|
657
|
+
req = projectuistatepb.GetActiveNamedVariableSetRequest(project_id=self.id)
|
|
658
|
+
res: projectuistatepb.GetActiveNamedVariableSetResponse = (
|
|
659
|
+
get_default_client().GetActiveNamedVariableSet(req)
|
|
660
|
+
)
|
|
661
|
+
if not res.active_named_variable_set_id:
|
|
662
|
+
return None
|
|
663
|
+
return get_named_variable_set(NamedVariableSetID(res.active_named_variable_set_id))
|
|
664
|
+
|
|
665
|
+
def share(self, email: str, role: Literal["viewer", "editor"]) -> None:
|
|
666
|
+
"""
|
|
667
|
+
Share the project with a user identified by their email address. This function also allows
|
|
668
|
+
changing the role of the user in the project if the project has already been shared with
|
|
669
|
+
the input user.
|
|
670
|
+
|
|
671
|
+
Parameters
|
|
672
|
+
----------
|
|
673
|
+
email : str
|
|
674
|
+
Email address of the user to share the project with. It must be an email whose domain
|
|
675
|
+
is registered within the allowed domains settings of your company account.
|
|
676
|
+
role : Literal["viewer", "editor"]
|
|
677
|
+
The role to assign to the user in the project. Must be either "viewer" or "editor".
|
|
678
|
+
"""
|
|
679
|
+
if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
|
|
680
|
+
raise ValueError(f"Invalid email address: {email}")
|
|
681
|
+
if role not in ["viewer", "editor"]:
|
|
682
|
+
raise ValueError(f"Invalid role: {role}. Must be 'viewer' or 'editor'.")
|
|
683
|
+
roleModel = (
|
|
684
|
+
projectpb.ShareProjectRequest.USER_ROLE_VIEWER
|
|
685
|
+
if role == "viewer"
|
|
686
|
+
else projectpb.ShareProjectRequest.USER_ROLE_EDITOR
|
|
687
|
+
)
|
|
688
|
+
req = projectpb.ShareProjectRequest(id=self.id, email=email, role=roleModel)
|
|
689
|
+
get_default_client().ShareProject(req)
|
|
690
|
+
|
|
691
|
+
def unshare(self, email: str) -> None:
|
|
692
|
+
"""
|
|
693
|
+
Unshare the project with a user identified by their email address.
|
|
694
|
+
|
|
695
|
+
Parameters
|
|
696
|
+
----------
|
|
697
|
+
email : str
|
|
698
|
+
Email address of the user to unshare the project with. It must be an email whose domain
|
|
699
|
+
must be registered within the allowed domains settings of your company account.
|
|
700
|
+
"""
|
|
701
|
+
if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
|
|
702
|
+
raise ValueError(f"Invalid email address: {email}")
|
|
703
|
+
req = projectpb.UnshareProjectRequest(id=self.id, email=email)
|
|
704
|
+
get_default_client().UnshareProject(req)
|
|
705
|
+
|
|
706
|
+
def share_with_support(self, message: str = "") -> None:
|
|
707
|
+
"""
|
|
708
|
+
Share the project with Luminary Cloud support.
|
|
709
|
+
|
|
710
|
+
Parameters
|
|
711
|
+
----------
|
|
712
|
+
message : str, optional
|
|
713
|
+
Message to include with the support share request.
|
|
714
|
+
"""
|
|
715
|
+
req = projectpb.ShareProjectWithSupportRequest(id=self.id, message=message)
|
|
716
|
+
get_default_client().ShareProjectWithSupport(req)
|
|
717
|
+
|
|
718
|
+
def unshare_with_support(self) -> None:
|
|
719
|
+
"""
|
|
720
|
+
Unshare the project with Luminary Cloud support.
|
|
721
|
+
"""
|
|
722
|
+
req = projectpb.UnshareProjectWithSupportRequest(id=self.id)
|
|
723
|
+
get_default_client().UnshareProjectWithSupport(req)
|
|
724
|
+
|
|
638
725
|
|
|
639
726
|
def add_named_variables_from_csv(project: Project, csv_path: str) -> list[NamedVariableSet]:
|
|
640
727
|
"""
|
|
@@ -17,7 +17,7 @@ from ._proto.api.v0.luminarycloud.simulation_template import (
|
|
|
17
17
|
)
|
|
18
18
|
from ._proto.client import simulation_pb2 as clientpb
|
|
19
19
|
from ._wrapper import ProtoWrapper, ProtoWrapperBase
|
|
20
|
-
from .types import SimulationTemplateID
|
|
20
|
+
from .types import SimulationTemplateID, ProjectID
|
|
21
21
|
from .tables import RectilinearTable
|
|
22
22
|
from .simulation_param import SimulationParam
|
|
23
23
|
from .outputs import (
|
|
@@ -59,7 +59,9 @@ class SimulationTemplate(ProtoWrapperBase):
|
|
|
59
59
|
id: SimulationTemplateID
|
|
60
60
|
"Simulation template ID."
|
|
61
61
|
name: str
|
|
62
|
-
"Simulation name."
|
|
62
|
+
"Simulation template name."
|
|
63
|
+
project_id: ProjectID
|
|
64
|
+
"Project this simulation template belongs to."
|
|
63
65
|
|
|
64
66
|
_proto: simtemplatepb.SimulationTemplate
|
|
65
67
|
|
|
@@ -71,6 +73,13 @@ class SimulationTemplate(ProtoWrapperBase):
|
|
|
71
73
|
def update_time(self) -> datetime:
|
|
72
74
|
return timestamp_to_datetime(self._proto.update_time)
|
|
73
75
|
|
|
76
|
+
def sync_to_ui(self) -> None:
|
|
77
|
+
"""
|
|
78
|
+
Sets this simulation template as the one that is used for the "Setup" tab in the UI.
|
|
79
|
+
"""
|
|
80
|
+
req = simtemplatepb.SyncSimulationTemplateToUIRequest(id=self.id)
|
|
81
|
+
get_default_client().SyncSimulationTemplateToUI(req)
|
|
82
|
+
|
|
74
83
|
def update(
|
|
75
84
|
self,
|
|
76
85
|
*,
|
|
@@ -480,10 +489,10 @@ class SimulationTemplate(ProtoWrapperBase):
|
|
|
480
489
|
code = code.replace("SimulationParam", "SimulationTemplate")
|
|
481
490
|
code += "\n\n\n"
|
|
482
491
|
code += '# Create a new simulation template or modify the one that is synced with the UI "Setup" tab.\n'
|
|
483
|
-
code +=
|
|
484
|
-
code +=
|
|
485
|
-
code +=
|
|
486
|
-
code += "template = project.list_simulation_templates()[0] # Setup template\n\n"
|
|
492
|
+
code += f'project = luminarycloud.get_project("{self.project_id}")\n'
|
|
493
|
+
code += f"template = project.create_simulation_template(name={self.name})\n"
|
|
494
|
+
code += '# TODO(USER): To modify the "Setup" template, uncomment the line below and comment out the line above.\n'
|
|
495
|
+
code += "# template = project.list_simulation_templates()[0] # Setup template\n\n"
|
|
487
496
|
|
|
488
497
|
if parameters._table_references:
|
|
489
498
|
code += "# Upload tabular data.\n"
|
luminarycloud/vis/__init__.py
CHANGED
|
@@ -11,6 +11,7 @@ from .visualization import (
|
|
|
11
11
|
from .primitives import (
|
|
12
12
|
Plane as Plane,
|
|
13
13
|
Box as Box,
|
|
14
|
+
AABB as AABB,
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
from .filters import (
|
|
@@ -23,6 +24,7 @@ from .filters import (
|
|
|
23
24
|
GridStreamlines as GridStreamlines,
|
|
24
25
|
SurfaceStreamlines as SurfaceStreamlines,
|
|
25
26
|
SurfaceLIC as SurfaceLIC,
|
|
27
|
+
SurfaceLICPlane as SurfaceLICPlane,
|
|
26
28
|
Threshold as Threshold,
|
|
27
29
|
Isosurface as Isosurface,
|
|
28
30
|
)
|
|
@@ -46,3 +48,7 @@ from .display import (
|
|
|
46
48
|
from .interactive_scene import (
|
|
47
49
|
InteractiveScene as InteractiveScene,
|
|
48
50
|
)
|
|
51
|
+
|
|
52
|
+
from .interactive_inference import (
|
|
53
|
+
InteractiveInference as InteractiveInference,
|
|
54
|
+
)
|