luminarycloud 0.22.3__py3-none-any.whl → 0.23.1__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/__init__.py +9 -3
- luminarycloud/_client/client.py +1 -1
- luminarycloud/_helpers/_code_representation.py +1 -0
- luminarycloud/_helpers/_create_simulation.py +5 -1
- luminarycloud/_helpers/proto_decorator.py +46 -38
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.py +214 -137
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.pyi +152 -0
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.py +103 -0
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.pyi +40 -0
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.py +137 -63
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.pyi +166 -6
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.py +68 -0
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.pyi +24 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.py +94 -71
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.pyi +46 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.py +35 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.pyi +16 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.py +25 -3
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.pyi +32 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2_grpc.py +34 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.py +68 -21
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.pyi +119 -0
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2_grpc.py +33 -0
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2_grpc.pyi +10 -0
- luminarycloud/_proto/client/simulation_pb2.py +409 -348
- luminarycloud/_proto/client/simulation_pb2.pyi +188 -27
- luminarycloud/_proto/clusterconfig/clusterconfig_pb2.py +273 -0
- luminarycloud/_proto/clusterconfig/clusterconfig_pb2.pyi +808 -0
- luminarycloud/_proto/geometry/geometry_pb2.pyi +1 -1
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2.py +2 -2
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.py +68 -0
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.pyi +24 -0
- luminarycloud/enum/__init__.py +1 -0
- luminarycloud/enum/gpu_type.py +47 -7
- luminarycloud/enum/vis_enums.py +18 -0
- luminarycloud/geometry.py +81 -0
- luminarycloud/geometry_contacts.py +222 -0
- luminarycloud/meshing/mesh_generation_params.py +4 -4
- luminarycloud/meshing/sizing_strategy/__init__.py +0 -1
- luminarycloud/meshing/sizing_strategy/sizing_strategies.py +0 -20
- luminarycloud/params/geometry/shapes.py +137 -31
- luminarycloud/params/outputs/__init__.py +0 -2
- luminarycloud/params/outputs/output.py +17 -5
- luminarycloud/params/simulation/__init__.py +2 -0
- luminarycloud/params/simulation/adaptive_mesh_refinement/active_region_.py +1 -1
- luminarycloud/params/simulation/adaptive_mesh_refinement/boundary_layer_profile_.py +1 -1
- luminarycloud/params/simulation/adaptive_mesh_refinement_.py +1 -1
- luminarycloud/params/simulation/adjoint_.py +8 -5
- luminarycloud/params/simulation/basic/gravity/gravity_off_.py +1 -1
- luminarycloud/params/simulation/basic/gravity/gravity_on_.py +1 -1
- luminarycloud/params/simulation/basic/gravity_.py +1 -1
- luminarycloud/params/simulation/body_frame_.py +1 -1
- luminarycloud/params/simulation/entity_relationships/volume_material_relationship_.py +1 -1
- luminarycloud/params/simulation/entity_relationships/volume_physics_relationship_.py +1 -1
- luminarycloud/params/simulation/entity_relationships_.py +1 -1
- luminarycloud/params/simulation/general_.py +1 -1
- luminarycloud/params/simulation/material/fluid/boussinesq_approximation/boussinesq_off_.py +1 -1
- luminarycloud/params/simulation/material/fluid/boussinesq_approximation/boussinesq_on_.py +1 -1
- luminarycloud/params/simulation/material/fluid/boussinesq_approximation_.py +1 -1
- luminarycloud/params/simulation/material/fluid/material_model/__init__.py +2 -0
- luminarycloud/params/simulation/material/fluid/material_model/ideal_gas_.py +1 -1
- luminarycloud/params/simulation/material/fluid/material_model/incompressible_fluid_.py +1 -1
- luminarycloud/params/simulation/material/fluid/material_model/incompressible_fluid_with_energy_.py +1 -1
- luminarycloud/params/simulation/material/fluid/material_model/real_gas_backend/__init__.py +2 -0
- luminarycloud/params/simulation/material/fluid/material_model/real_gas_backend/real_gas_coolprop_.py +43 -0
- luminarycloud/params/simulation/material/fluid/material_model/real_gas_backend/real_gas_polynomial_.py +53 -0
- luminarycloud/params/simulation/material/fluid/material_model/real_gas_backend_.py +29 -0
- luminarycloud/params/simulation/material/fluid/material_model_.py +1 -1
- luminarycloud/params/simulation/material/fluid/thermal_conductivity_model/prescribed_conductivity_.py +1 -1
- luminarycloud/params/simulation/material/fluid/thermal_conductivity_model/prescribed_prandtl_number_.py +1 -1
- luminarycloud/params/simulation/material/fluid/thermal_conductivity_model/temperature_dependent_conductivity_.py +1 -1
- luminarycloud/params/simulation/material/fluid/thermal_conductivity_model_.py +1 -1
- luminarycloud/params/simulation/material/fluid/viscosity_model/prescribed_viscosity_.py +1 -1
- luminarycloud/params/simulation/material/fluid/viscosity_model/sutherland_.py +1 -1
- luminarycloud/params/simulation/material/fluid/viscosity_model/temperature_dependent_viscosity_.py +1 -1
- luminarycloud/params/simulation/material/fluid/viscosity_model_.py +1 -1
- luminarycloud/params/simulation/material/material_fluid_.py +78 -2
- luminarycloud/params/simulation/material/material_solid_.py +1 -1
- luminarycloud/params/simulation/material_entity_.py +1 -1
- luminarycloud/params/simulation/monitor_plane_.py +1 -1
- luminarycloud/params/simulation/motion_data/frame_transforms/no_transform_.py +1 -1
- luminarycloud/params/simulation/motion_data/frame_transforms/rotational_transform_.py +1 -1
- luminarycloud/params/simulation/motion_data/frame_transforms/translational_transform_.py +1 -1
- luminarycloud/params/simulation/motion_data/frame_transforms_.py +1 -1
- luminarycloud/params/simulation/motion_data/motion_type/constant_angular_motion_.py +1 -1
- luminarycloud/params/simulation/motion_data/motion_type/constant_translation_motion_.py +1 -1
- luminarycloud/params/simulation/motion_data/motion_type_.py +1 -1
- luminarycloud/params/simulation/motion_data_.py +1 -1
- luminarycloud/params/simulation/multi_physics_coupling_options_.py +1 -1
- luminarycloud/params/simulation/nonlinear_control/__init__.py +1 -0
- luminarycloud/params/simulation/nonlinear_control/nonlinear_control_system_.py +48 -0
- luminarycloud/params/simulation/nonlinear_control_.py +61 -0
- luminarycloud/params/simulation/output_.py +1 -1
- luminarycloud/params/simulation/particle_group/particle_group_type/actuator_disk/actuator_disk_orientation_selection/actuator_disk_specify_normal_vector_.py +1 -1
- luminarycloud/params/simulation/particle_group/particle_group_type/actuator_disk/actuator_disk_orientation_selection/actuator_disk_specify_rotation_angles_.py +1 -1
- luminarycloud/params/simulation/particle_group/particle_group_type/actuator_disk/actuator_disk_orientation_selection_.py +1 -1
- luminarycloud/params/simulation/particle_group/particle_group_type/actuator_disk_.py +1 -1
- luminarycloud/params/simulation/particle_group/particle_group_type/actuator_line_.py +1 -1
- luminarycloud/params/simulation/particle_group/particle_group_type/probe_points_.py +1 -1
- luminarycloud/params/simulation/particle_group/particle_group_type/source_points_.py +1 -1
- luminarycloud/params/simulation/particle_group/particle_group_type_.py +1 -1
- luminarycloud/params/simulation/particle_group_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/adjoint_controls_fluid_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/basic_fluid_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/farfield_.py +1 -1
- 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 +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/mass_flow_inlet_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/total_pressure_inlet_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/velocity_components_inlet_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/velocity_magnitude_inlet_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy/fan_curve_outlet_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy/outlet_pressure_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy/outlet_target_corrected_mass_flow_rate_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy/outlet_target_mass_flow_rate_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/symmetry_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/turbulence_boundary_conditions_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/energy/prescribed_heat_flux_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/energy/prescribed_temperature_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/momentum/no_slip_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/momentum/slip_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/momentum/wall_model_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/wall_energy_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/wall_momentum_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/boundary_conditions_fluid_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/initialization/__init__.py +1 -0
- luminarycloud/params/simulation/physics/fluid/initialization/fluid_existing_solution_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/initialization/fluid_farfield_values_.py +14 -1
- luminarycloud/params/simulation/physics/fluid/initialization/fluid_initialization_per_zone_.py +48 -0
- luminarycloud/params/simulation/physics/fluid/initialization/fluid_prescribed_values_.py +14 -1
- luminarycloud/params/simulation/physics/fluid/initialization/turbulence_initialization_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/initialization_fluid_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/blade_element_airfoil_data_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model/actuator_disk_blade_element_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model/actuator_disk_radial_distribution_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model/actuator_disk_uniform_thrust_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model/fan_curve_internal_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_line_model/actuator_line_blade_element_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_line_model_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/blade_element_params_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/particle_source_model/general_acceleration_source_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/particle_source_model/general_mass_source_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/particle_source_model_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/physical_behavior_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/porous_behavior_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_explicit_relaxation_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/robust_startup_auto_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/robust_startup_off_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/robust_startup_on_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/pseudo_time_step_method/cfl_based_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/pseudo_time_step_method/fixed_pseudo_time_step_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls/pseudo_time_step_method_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/solution_controls_fluid_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme/ec2_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme/fds_.py +3 -1
- luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme/ld2_.py +3 -3
- luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme/rhie_chow_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme_order/first_order_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme_order/second_order_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme_order_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/spatial_discretization_fluid_.py +5 -3
- luminarycloud/params/simulation/physics/fluid/turbulence/des_formulation/ddes_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/des_formulation/ddes_vtm_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/des_formulation/iddes_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/des_formulation_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/komega_sst/constants/custom_komega_sst_constants_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/komega_sst/constants/default_komega_sst_constants_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/komega_sst/komega_sst_constants_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/komega_sst_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/spalart_allmaras/constants/custom_spalart_allmaras_constants_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/spalart_allmaras/constants/default_spalart_allmaras_constants_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/spalart_allmaras/spalart_allmaras_constants_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/spalart_allmaras_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/amd_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/sigma_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/smagorinsky_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/vreman_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/wale_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model_.py +1 -1
- luminarycloud/params/simulation/physics/fluid/turbulence_.py +1 -1
- luminarycloud/params/simulation/physics/fluid_.py +1 -1
- luminarycloud/params/simulation/physics/heat/adjoint_controls_heat_.py +1 -1
- luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_convection_.py +1 -1
- luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_heat_flux_.py +1 -1
- luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_integrated_heat_flux_.py +1 -1
- luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_symmetry_.py +1 -1
- luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_temperature_.py +1 -1
- luminarycloud/params/simulation/physics/heat/boundary_conditions_heat_.py +1 -1
- luminarycloud/params/simulation/physics/heat/heat_source/heat_source_type/heat_source_type_power_.py +1 -1
- luminarycloud/params/simulation/physics/heat/heat_source/heat_source_type/heat_source_type_power_per_unit_of_volume_.py +1 -1
- luminarycloud/params/simulation/physics/heat/heat_source/heat_source_type_.py +1 -1
- luminarycloud/params/simulation/physics/heat/heat_source_.py +1 -1
- luminarycloud/params/simulation/physics/heat/initialization/__init__.py +1 -0
- luminarycloud/params/simulation/physics/heat/initialization/heat_existing_solution_.py +1 -1
- luminarycloud/params/simulation/physics/heat/initialization/heat_prescribed_values/__init__.py +1 -0
- luminarycloud/params/simulation/physics/heat/initialization/heat_prescribed_values/heat_initialization_per_zone_.py +40 -0
- luminarycloud/params/simulation/physics/heat/initialization/heat_prescribed_values_.py +14 -1
- luminarycloud/params/simulation/physics/heat/initialization_heat_.py +1 -1
- luminarycloud/params/simulation/physics/heat/solution_controls/heat_relaxation_method/heat_implicit_relaxation_.py +1 -1
- luminarycloud/params/simulation/physics/heat/solution_controls/heat_relaxation_method_.py +1 -1
- luminarycloud/params/simulation/physics/heat/solution_controls_heat_.py +1 -1
- luminarycloud/params/simulation/physics/heat/spatial_discretization_heat_.py +1 -1
- luminarycloud/params/simulation/physics/heat_.py +1 -1
- luminarycloud/params/simulation/physics/periodic_pair_.py +5 -1
- luminarycloud/params/simulation/physics/solution_controls/linear_solver_type/gauss_seidel_.py +1 -1
- luminarycloud/params/simulation/physics/solution_controls/linear_solver_type/krylov_amg_.py +1 -1
- luminarycloud/params/simulation/physics/solution_controls/linear_solver_type_.py +1 -1
- luminarycloud/params/simulation/physics_.py +1 -1
- luminarycloud/params/simulation/simulation_param_.py +8 -1
- luminarycloud/params/simulation/sliding_interfaces_.py +1 -1
- luminarycloud/params/simulation/surface_name_.py +1 -1
- luminarycloud/params/simulation/time/compute_statistics/compute_statistics_off_.py +1 -1
- luminarycloud/params/simulation/time/compute_statistics/compute_statistics_on_.py +1 -1
- luminarycloud/params/simulation/time/compute_statistics_.py +1 -1
- luminarycloud/params/simulation/time/time_marching/time_explicit_.py +1 -1
- luminarycloud/params/simulation/time/time_marching/time_implicit_.py +1 -1
- luminarycloud/params/simulation/time/time_marching_.py +1 -1
- luminarycloud/params/simulation/time/time_step_ramp/time_step_ramp_off_.py +1 -1
- luminarycloud/params/simulation/time/time_step_ramp/time_step_ramp_on_.py +1 -1
- luminarycloud/params/simulation/time/time_step_ramp_.py +1 -1
- luminarycloud/params/simulation/time_.py +1 -1
- luminarycloud/params/simulation/volume_entity_.py +1 -1
- luminarycloud/physics_ai/__init__.py +9 -0
- luminarycloud/physics_ai/architectures.py +129 -17
- luminarycloud/physics_ai/datasets.py +66 -11
- luminarycloud/physics_ai/training_jobs.py +50 -4
- luminarycloud/pipelines/__init__.py +5 -4
- luminarycloud/pipelines/api.py +148 -34
- luminarycloud/pipelines/arguments.py +8 -3
- luminarycloud/pipelines/core.py +10 -72
- luminarycloud/pipelines/stages.py +28 -25
- luminarycloud/pipelines/user_code_validation.py +122 -0
- luminarycloud/project.py +0 -14
- luminarycloud/simulation.py +42 -11
- luminarycloud/simulation_param.py +0 -62
- luminarycloud/simulation_template.py +1 -11
- luminarycloud/types/adfloat.py +48 -4
- luminarycloud/types/matrix3.py +9 -9
- luminarycloud/types/vector3.py +52 -23
- luminarycloud/vis/__init__.py +3 -0
- luminarycloud/vis/visualization.py +88 -0
- luminarycloud/volume_selection.py +29 -17
- {luminarycloud-0.22.3.dist-info → luminarycloud-0.23.1.dist-info}/METADATA +1 -1
- {luminarycloud-0.22.3.dist-info → luminarycloud-0.23.1.dist-info}/RECORD +257 -244
- luminarycloud/params/outputs/residual_output.py +0 -24
- /luminarycloud/params/{simulation/_lib.py → _lib.py} +0 -0
- {luminarycloud-0.22.3.dist-info → luminarycloud-0.23.1.dist-info}/WHEEL +0 -0
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
# Copyright 2025 Luminary Cloud, Inc. All Rights Reserved.
|
|
2
|
-
from typing import List
|
|
2
|
+
from typing import List
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
|
|
5
5
|
from .._client import get_default_client
|
|
6
6
|
from .._proto.api.v0.luminarycloud.physics_ai import physics_ai_pb2 as physaipb
|
|
7
7
|
from .._proto.base import base_pb2 as basepb
|
|
8
8
|
from .._wrapper import ProtoWrapper, ProtoWrapperBase
|
|
9
|
-
from ..types.ids import PhysicsAiArchitectureVersionID
|
|
9
|
+
from ..types.ids import PhysicsAiArchitectureVersionID, PhysicsAiTrainingJobID
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_training_job(training_job_id: PhysicsAiTrainingJobID) -> "PhysicsAiTrainingJob":
|
|
13
|
+
"""
|
|
14
|
+
Get a Physics AI training job by ID.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
training_job_id: The ID of the training job to retrieve.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
The training job.
|
|
21
|
+
"""
|
|
22
|
+
req = physaipb.GetTrainingJobRequest(training_job_id=training_job_id)
|
|
23
|
+
resp = get_default_client().GetTrainingJob(req)
|
|
24
|
+
return PhysicsAiTrainingJob(resp.training_job)
|
|
10
25
|
|
|
11
26
|
|
|
12
27
|
@ProtoWrapper(physaipb.PhysicsAiTrainingJob)
|
|
13
28
|
class PhysicsAiTrainingJob(ProtoWrapperBase):
|
|
14
29
|
"""
|
|
15
30
|
Represents a Physics AI training job.
|
|
16
|
-
|
|
17
|
-
.. warning:: This feature is experimental and may change or be removed without notice.
|
|
18
31
|
"""
|
|
19
32
|
|
|
20
33
|
id: str
|
|
@@ -24,6 +37,7 @@ class PhysicsAiTrainingJob(ProtoWrapperBase):
|
|
|
24
37
|
training_data_source_type: physaipb.TrainingDataSourceType
|
|
25
38
|
training_description: str
|
|
26
39
|
external_dataset_uri: str
|
|
40
|
+
dataset_id: str
|
|
27
41
|
initialization_type: physaipb.ModelInitializationType
|
|
28
42
|
base_model_version_id: str
|
|
29
43
|
status: basepb.JobStatus
|
|
@@ -35,3 +49,35 @@ class PhysicsAiTrainingJob(ProtoWrapperBase):
|
|
|
35
49
|
|
|
36
50
|
def get_status(self) -> str:
|
|
37
51
|
return basepb.JobStatusType.Name(self.status.typ)
|
|
52
|
+
|
|
53
|
+
def cancel(self) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Cancel this training job.
|
|
56
|
+
|
|
57
|
+
This method requests cancellation of the training job. If the job is already
|
|
58
|
+
suspended or suspending, this is a no-op.
|
|
59
|
+
"""
|
|
60
|
+
req = physaipb.CancelTrainingJobRequest(training_job_id=self.id)
|
|
61
|
+
get_default_client().CancelTrainingJob(req)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def list_training_jobs() -> List[PhysicsAiTrainingJob]:
|
|
65
|
+
"""
|
|
66
|
+
List Physics AI training jobs for the current user.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
List[PhysicsAiTrainingJob]
|
|
71
|
+
A list of training jobs, ordered by creation time (newest first).
|
|
72
|
+
|
|
73
|
+
Examples
|
|
74
|
+
--------
|
|
75
|
+
List all training jobs:
|
|
76
|
+
|
|
77
|
+
>>> jobs = list_training_jobs()
|
|
78
|
+
>>> for job in jobs:
|
|
79
|
+
... print(f"{job.id}: {job.get_status()}")
|
|
80
|
+
"""
|
|
81
|
+
req = physaipb.ListTrainingJobsRequest()
|
|
82
|
+
response = get_default_client().ListTrainingJobs(req)
|
|
83
|
+
return [PhysicsAiTrainingJob(job) for job in response.training_jobs]
|
|
@@ -27,16 +27,17 @@ from .stages import (
|
|
|
27
27
|
ReadGeometryOutputs as ReadGeometryOutputs,
|
|
28
28
|
ReadMesh as ReadMesh,
|
|
29
29
|
ReadMeshOutputs as ReadMeshOutputs,
|
|
30
|
-
ModifyGeometry as ModifyGeometry,
|
|
31
|
-
ModifyGeometryOutputs as ModifyGeometryOutputs,
|
|
32
30
|
Mesh as Mesh,
|
|
33
31
|
MeshOutputs as MeshOutputs,
|
|
32
|
+
WaitForMesh as WaitForMesh,
|
|
33
|
+
WaitForMeshOutputs as WaitForMeshOutputs,
|
|
34
34
|
Simulate as Simulate,
|
|
35
35
|
SimulateOutputs as SimulateOutputs,
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
from .arguments import (
|
|
39
39
|
PipelineArgs as PipelineArgs,
|
|
40
|
+
PP_NAMED_VARIABLE_SET_ID as PP_NAMED_VARIABLE_SET_ID,
|
|
40
41
|
ArgNamedVariableSet as ArgNamedVariableSet,
|
|
41
42
|
)
|
|
42
43
|
|
|
@@ -47,11 +48,11 @@ from .flowables import (
|
|
|
47
48
|
|
|
48
49
|
from .api import (
|
|
49
50
|
create_pipeline as create_pipeline,
|
|
50
|
-
|
|
51
|
+
iterate_pipelines as iterate_pipelines,
|
|
51
52
|
get_pipeline as get_pipeline,
|
|
52
53
|
create_pipeline_job as create_pipeline_job,
|
|
53
54
|
get_pipeline_job as get_pipeline_job,
|
|
54
|
-
|
|
55
|
+
iterate_pipeline_jobs as iterate_pipeline_jobs,
|
|
55
56
|
PipelineJobRecord as PipelineJobRecord,
|
|
56
57
|
PipelineRecord as PipelineRecord,
|
|
57
58
|
PipelineJobRunRecord as PipelineJobRunRecord,
|
luminarycloud/pipelines/api.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# Copyright 2023-
|
|
2
|
-
from typing import
|
|
1
|
+
# Copyright 2023-2025 Luminary Cloud, Inc. All Rights Reserved.
|
|
2
|
+
from typing import Generic, Iterator, Literal, TypeVar
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
5
|
from datetime import datetime
|
|
@@ -7,13 +7,78 @@ from time import time, sleep
|
|
|
7
7
|
import logging
|
|
8
8
|
|
|
9
9
|
from .arguments import PipelineArgValueType
|
|
10
|
-
from .core import Stage
|
|
11
10
|
from ..pipelines import Pipeline, PipelineArgs
|
|
12
11
|
from .._client import get_default_client
|
|
13
12
|
from .._helpers import parse_iso_datetime
|
|
14
13
|
|
|
15
14
|
logger = logging.getLogger(__name__)
|
|
16
15
|
|
|
16
|
+
T = TypeVar("T")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PipelinesPaginationIterator(Generic[T]):
|
|
20
|
+
"""
|
|
21
|
+
Iterator for pipelines API endpoints that use offset-based pagination (skip/limit).
|
|
22
|
+
|
|
23
|
+
This is different from the token-based PaginationIterator in _helpers.pagination.
|
|
24
|
+
Lazily fetches pages as needed and yields individual items.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, http_client, endpoint: str, model_class, page_size: int = 100):
|
|
28
|
+
"""
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
http_client
|
|
32
|
+
HTTP client to use for requests
|
|
33
|
+
endpoint : str
|
|
34
|
+
API endpoint to fetch from
|
|
35
|
+
model_class
|
|
36
|
+
Class to use for deserializing items (must have from_json classmethod)
|
|
37
|
+
page_size : int
|
|
38
|
+
Number of items to fetch per page (default: 100)
|
|
39
|
+
"""
|
|
40
|
+
self.http_client = http_client
|
|
41
|
+
self.endpoint = endpoint
|
|
42
|
+
self.model_class = model_class
|
|
43
|
+
self.page_size = page_size
|
|
44
|
+
self._skip = 0
|
|
45
|
+
self._current_page: list[T] | None = None
|
|
46
|
+
self._exhausted = False
|
|
47
|
+
|
|
48
|
+
def __iter__(self) -> "PipelinesPaginationIterator[T]":
|
|
49
|
+
return self
|
|
50
|
+
|
|
51
|
+
def __next__(self) -> T:
|
|
52
|
+
if self._current_page is None:
|
|
53
|
+
self._fetch_next_page()
|
|
54
|
+
|
|
55
|
+
# mypy needs this assertion even though _current_page can't be None here
|
|
56
|
+
assert self._current_page is not None
|
|
57
|
+
|
|
58
|
+
if len(self._current_page) == 0:
|
|
59
|
+
if self._exhausted:
|
|
60
|
+
raise StopIteration
|
|
61
|
+
self._fetch_next_page()
|
|
62
|
+
# After fetching, check if we're still empty (means we hit the end)
|
|
63
|
+
if len(self._current_page) == 0:
|
|
64
|
+
raise StopIteration
|
|
65
|
+
|
|
66
|
+
return self._current_page.pop(0)
|
|
67
|
+
|
|
68
|
+
def _fetch_next_page(self) -> None:
|
|
69
|
+
"""Fetch the next page of results from the API."""
|
|
70
|
+
response = self.http_client.get(
|
|
71
|
+
self.endpoint, params={"skip": self._skip, "limit": self.page_size}
|
|
72
|
+
)
|
|
73
|
+
items = response["data"]
|
|
74
|
+
|
|
75
|
+
self._current_page = [self.model_class.from_json(item) for item in items]
|
|
76
|
+
|
|
77
|
+
self._skip += len(items)
|
|
78
|
+
|
|
79
|
+
if len(items) < self.page_size:
|
|
80
|
+
self._exhausted = True
|
|
81
|
+
|
|
17
82
|
|
|
18
83
|
@dataclass
|
|
19
84
|
class LogLine:
|
|
@@ -103,17 +168,36 @@ class PipelineRecord:
|
|
|
103
168
|
updated_at=parse_iso_datetime(json["updated_at"]),
|
|
104
169
|
)
|
|
105
170
|
|
|
106
|
-
def pipeline_jobs(self) -> "
|
|
171
|
+
def pipeline_jobs(self, page_size: int = 100) -> Iterator["PipelineJobRecord"]:
|
|
107
172
|
"""
|
|
108
|
-
Returns
|
|
173
|
+
Returns an iterator of pipeline jobs that were created from this pipeline.
|
|
174
|
+
|
|
175
|
+
The iterator will automatically fetch additional pages as needed.
|
|
176
|
+
|
|
177
|
+
Parameters
|
|
178
|
+
----------
|
|
179
|
+
page_size : int, optional
|
|
180
|
+
Number of pipeline jobs to fetch per page. Defaults to 100, max is 1000.
|
|
109
181
|
|
|
110
182
|
Returns
|
|
111
183
|
-------
|
|
112
|
-
|
|
113
|
-
|
|
184
|
+
Iterator[PipelineJobRecord]
|
|
185
|
+
An iterator of PipelineJobRecord objects.
|
|
186
|
+
|
|
187
|
+
Examples
|
|
188
|
+
--------
|
|
189
|
+
>>> pipeline = pipelines.get_pipeline("pipeline-123")
|
|
190
|
+
>>> for job in pipeline.pipeline_jobs():
|
|
191
|
+
... print(job.name)
|
|
192
|
+
>>> # Or convert to a list if needed:
|
|
193
|
+
>>> all_jobs = list(pipeline.pipeline_jobs())
|
|
114
194
|
"""
|
|
115
|
-
|
|
116
|
-
|
|
195
|
+
return PipelinesPaginationIterator(
|
|
196
|
+
get_default_client().http,
|
|
197
|
+
f"/rest/v0/pipelines/{self.id}/pipeline_jobs",
|
|
198
|
+
PipelineJobRecord,
|
|
199
|
+
page_size,
|
|
200
|
+
)
|
|
117
201
|
|
|
118
202
|
def delete(self) -> None:
|
|
119
203
|
"""
|
|
@@ -402,14 +486,17 @@ class PipelineJobRunRecord:
|
|
|
402
486
|
idx: int
|
|
403
487
|
arguments: list[PipelineArgValueType]
|
|
404
488
|
status: Literal["pending", "running", "completed", "failed", "cancelled"]
|
|
489
|
+
tasks: list[PipelineTaskRecord]
|
|
405
490
|
|
|
406
491
|
@classmethod
|
|
407
492
|
def from_json(cls, json: dict) -> "PipelineJobRunRecord":
|
|
493
|
+
tasks_json = json.get("tasks", [])
|
|
408
494
|
return cls(
|
|
409
495
|
pipeline_job_id=json["pipeline_job_id"],
|
|
410
496
|
idx=json["idx"],
|
|
411
497
|
arguments=json["arguments"],
|
|
412
498
|
status=json["status"],
|
|
499
|
+
tasks=[PipelineTaskRecord.from_json(t) for t in tasks_json],
|
|
413
500
|
)
|
|
414
501
|
|
|
415
502
|
def pipeline_job(self) -> PipelineJobRecord:
|
|
@@ -458,23 +545,6 @@ class PipelineJobRunRecord:
|
|
|
458
545
|
)
|
|
459
546
|
return res["data"]
|
|
460
547
|
|
|
461
|
-
def tasks(self) -> list[PipelineTaskRecord]:
|
|
462
|
-
"""
|
|
463
|
-
Returns a list of tasks for this pipeline job run.
|
|
464
|
-
|
|
465
|
-
Each task represents an execution of a stage of the pipeline, with its own
|
|
466
|
-
status, artifacts, and stage information.
|
|
467
|
-
|
|
468
|
-
Returns
|
|
469
|
-
-------
|
|
470
|
-
list[PipelineTaskRecord]
|
|
471
|
-
The tasks associated with this pipeline job run.
|
|
472
|
-
"""
|
|
473
|
-
res = get_default_client().http.get(
|
|
474
|
-
f"/rest/v0/pipeline_jobs/{self.pipeline_job_id}/runs/{self.idx}/tasks"
|
|
475
|
-
)
|
|
476
|
-
return [PipelineTaskRecord.from_json(t) for t in res["data"]]
|
|
477
|
-
|
|
478
548
|
|
|
479
549
|
def create_pipeline(
|
|
480
550
|
name: str, pipeline: Pipeline | str, description: str | None = None
|
|
@@ -504,12 +574,34 @@ def create_pipeline(
|
|
|
504
574
|
return PipelineRecord.from_json(res["data"])
|
|
505
575
|
|
|
506
576
|
|
|
507
|
-
def
|
|
577
|
+
def iterate_pipelines(page_size: int = 100) -> Iterator[PipelineRecord]:
|
|
508
578
|
"""
|
|
509
|
-
|
|
579
|
+
Iterate over all pipelines with pagination.
|
|
580
|
+
|
|
581
|
+
Parameters
|
|
582
|
+
----------
|
|
583
|
+
page_size : int, optional
|
|
584
|
+
Number of pipelines to fetch per page. Defaults to 100, max is 1000.
|
|
585
|
+
|
|
586
|
+
Returns
|
|
587
|
+
-------
|
|
588
|
+
Iterator[PipelineRecord]
|
|
589
|
+
An iterator that yields PipelineRecord objects one at a time.
|
|
590
|
+
|
|
591
|
+
Examples
|
|
592
|
+
--------
|
|
593
|
+
Iterate over all pipelines:
|
|
594
|
+
|
|
595
|
+
>>> for pipeline in pipelines.iterate_pipelines():
|
|
596
|
+
... print(pipeline.name)
|
|
597
|
+
|
|
598
|
+
Convert to a list if needed:
|
|
599
|
+
|
|
600
|
+
>>> all_pipelines = list(pipelines.iterate_pipelines())
|
|
510
601
|
"""
|
|
511
|
-
|
|
512
|
-
|
|
602
|
+
return PipelinesPaginationIterator(
|
|
603
|
+
get_default_client().http, "/rest/v0/pipelines", PipelineRecord, page_size
|
|
604
|
+
)
|
|
513
605
|
|
|
514
606
|
|
|
515
607
|
def get_pipeline(id: str) -> PipelineRecord:
|
|
@@ -572,9 +664,31 @@ def get_pipeline_job(id: str) -> PipelineJobRecord:
|
|
|
572
664
|
return PipelineJobRecord.from_json(res["data"])
|
|
573
665
|
|
|
574
666
|
|
|
575
|
-
def
|
|
667
|
+
def iterate_pipeline_jobs(page_size: int = 100) -> Iterator[PipelineJobRecord]:
|
|
576
668
|
"""
|
|
577
|
-
|
|
669
|
+
Iterate over all pipeline jobs with pagination.
|
|
670
|
+
|
|
671
|
+
Parameters
|
|
672
|
+
----------
|
|
673
|
+
page_size : int, optional
|
|
674
|
+
Number of pipeline jobs to fetch per page. Defaults to 100, max is 1000.
|
|
675
|
+
|
|
676
|
+
Returns
|
|
677
|
+
-------
|
|
678
|
+
Iterator[PipelineJobRecord]
|
|
679
|
+
An iterator that yields PipelineJobRecord objects one at a time.
|
|
680
|
+
|
|
681
|
+
Examples
|
|
682
|
+
--------
|
|
683
|
+
Iterate over all pipeline jobs:
|
|
684
|
+
|
|
685
|
+
>>> for job in pipelines.iterate_pipeline_jobs():
|
|
686
|
+
... print(job.name)
|
|
687
|
+
|
|
688
|
+
Convert to a list if needed:
|
|
689
|
+
|
|
690
|
+
>>> all_jobs = list(pipelines.iterate_pipeline_jobs())
|
|
578
691
|
"""
|
|
579
|
-
|
|
580
|
-
|
|
692
|
+
return PipelinesPaginationIterator(
|
|
693
|
+
get_default_client().http, "/rest/v0/pipeline_jobs", PipelineJobRecord, page_size
|
|
694
|
+
)
|
|
@@ -28,10 +28,15 @@ class _NVS(PipelineParameter):
|
|
|
28
28
|
return isinstance(value, str) and value.startswith("namedvarset-")
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
PP_NAMED_VARIABLE_SET_ID = _NVS("$named-variable-set")
|
|
32
32
|
"""
|
|
33
|
-
|
|
34
|
-
There must be zero or one of these in a PipelineArgs params list.
|
|
33
|
+
A constant PipelineParameter that can be used in a PipelineArgs params list to add a Named Variable
|
|
34
|
+
Set ID column to the args table. There must be zero or one of these in a PipelineArgs params list.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
ArgNamedVariableSet = PP_NAMED_VARIABLE_SET_ID
|
|
38
|
+
"""
|
|
39
|
+
Deprecated alias for PP_NAMED_VARIABLE_SET_ID.
|
|
35
40
|
"""
|
|
36
41
|
|
|
37
42
|
# The types that are allowed as PipelineArgs values. This is a union of all concrete
|
luminarycloud/pipelines/core.py
CHANGED
|
@@ -3,7 +3,9 @@ from __future__ import annotations
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
from dataclasses import is_dataclass, fields
|
|
5
5
|
from typing import Any, Callable, Mapping, Type, TypeVar, Generic, TYPE_CHECKING
|
|
6
|
+
from .user_code_validation import validate_portable_top_level_function
|
|
6
7
|
from typing_extensions import Self
|
|
8
|
+
import builtins
|
|
7
9
|
import inspect
|
|
8
10
|
import re
|
|
9
11
|
import textwrap
|
|
@@ -330,7 +332,7 @@ class RunScript:
|
|
|
330
332
|
|
|
331
333
|
def __init__(
|
|
332
334
|
self,
|
|
333
|
-
script: Callable[..., dict[str, Any]] | str,
|
|
335
|
+
script: Callable[..., dict[str, Any] | None] | str,
|
|
334
336
|
*,
|
|
335
337
|
stage_name: str | None = None,
|
|
336
338
|
inputs: dict[str, PipelineOutput] | None = None,
|
|
@@ -347,11 +349,11 @@ class RunScript:
|
|
|
347
349
|
raise ValueError(f"RunScript params and inputs cannot share names: {overlap}")
|
|
348
350
|
|
|
349
351
|
inputs_and_params = set(inputs.keys()).union(params.keys())
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
self._entrypoint = (
|
|
353
|
-
entrypoint or callable_entrypoint or self._infer_entrypoint(script_source)
|
|
352
|
+
validated_source = validate_portable_top_level_function(
|
|
353
|
+
script, must_have_params=inputs_and_params, can_have_params={"context"}
|
|
354
354
|
)
|
|
355
|
+
self._stage_type_name = "RunScript"
|
|
356
|
+
self._entrypoint = entrypoint or validated_source.entrypoint
|
|
355
357
|
self._name = (
|
|
356
358
|
stage_name if stage_name is not None else self._default_stage_name(self._entrypoint)
|
|
357
359
|
)
|
|
@@ -381,7 +383,7 @@ class RunScript:
|
|
|
381
383
|
self.outputs = DynamicStageOutputs(self, output_flowable_types)
|
|
382
384
|
|
|
383
385
|
reserved_params = {
|
|
384
|
-
"$script":
|
|
386
|
+
"$script": validated_source.source,
|
|
385
387
|
"$output_types": {name: ft.value for name, ft in output_flowable_types.items()},
|
|
386
388
|
"$entrypoint": self._entrypoint,
|
|
387
389
|
}
|
|
@@ -414,8 +416,6 @@ class RunScript:
|
|
|
414
416
|
output_types: Mapping[str, type[PipelineOutput] | str | FlowableType],
|
|
415
417
|
) -> dict[str, FlowableType]:
|
|
416
418
|
normalized: dict[str, FlowableType] = {}
|
|
417
|
-
if not output_types:
|
|
418
|
-
raise ValueError("RunScript stages must declare at least one output")
|
|
419
419
|
for name, value in output_types.items():
|
|
420
420
|
if isinstance(value, FlowableType):
|
|
421
421
|
normalized[name] = value
|
|
@@ -429,68 +429,6 @@ class RunScript:
|
|
|
429
429
|
)
|
|
430
430
|
return normalized
|
|
431
431
|
|
|
432
|
-
@staticmethod
|
|
433
|
-
def _validate_script(
|
|
434
|
-
script: Callable[..., dict[str, Any]], inputs_and_params: set[str]
|
|
435
|
-
) -> None:
|
|
436
|
-
closurevars = inspect.getclosurevars(script)
|
|
437
|
-
if closurevars.nonlocals:
|
|
438
|
-
raise ValueError(
|
|
439
|
-
f"RunScript functions must not close over non-local variables. Found these non-local variables: {', '.join(closurevars.nonlocals.keys())}"
|
|
440
|
-
)
|
|
441
|
-
globals_except_lc = {
|
|
442
|
-
k for k in closurevars.globals.keys() if k != "lc" and k != "luminarycloud"
|
|
443
|
-
}
|
|
444
|
-
if globals_except_lc:
|
|
445
|
-
raise ValueError(
|
|
446
|
-
f"RunScript functions must not rely on global variables, including imports. All modules your script needs (except `luminarycloud` or `lc`) must be imported in the function body. Found globals: {', '.join(globals_except_lc)}"
|
|
447
|
-
)
|
|
448
|
-
script_params = set(inspect.signature(script).parameters.keys())
|
|
449
|
-
if script_params != inputs_and_params and script_params != inputs_and_params | {"context"}:
|
|
450
|
-
raise ValueError(
|
|
451
|
-
f"RunScript function must take exactly the same parameters as the inputs and params (and optionally `context`): {script_params} != {inputs_and_params}"
|
|
452
|
-
)
|
|
453
|
-
|
|
454
|
-
@staticmethod
|
|
455
|
-
def _get_script_source(
|
|
456
|
-
script: Callable[..., dict[str, Any]] | str,
|
|
457
|
-
inputs_and_params: set[str],
|
|
458
|
-
) -> tuple[str, str | None]:
|
|
459
|
-
if callable(script):
|
|
460
|
-
RunScript._validate_script(script, inputs_and_params)
|
|
461
|
-
try:
|
|
462
|
-
source_lines, _ = inspect.getsourcelines(script) # type: ignore[arg-type]
|
|
463
|
-
except (OSError, IOError, TypeError) as exc:
|
|
464
|
-
raise ValueError(f"Unable to retrieve source for {script.__name__}: {exc}") from exc
|
|
465
|
-
# Drop decorator lines (everything before the `def`)
|
|
466
|
-
for i, line in enumerate(source_lines):
|
|
467
|
-
if line.lstrip().startswith("def "):
|
|
468
|
-
source_lines = source_lines[i:]
|
|
469
|
-
break
|
|
470
|
-
source = "".join(source_lines)
|
|
471
|
-
entrypoint = script.__name__
|
|
472
|
-
else:
|
|
473
|
-
source = script
|
|
474
|
-
entrypoint = None
|
|
475
|
-
dedented = textwrap.dedent(source).strip()
|
|
476
|
-
if not dedented:
|
|
477
|
-
raise ValueError("RunScript code cannot be empty")
|
|
478
|
-
return dedented + "\n", entrypoint
|
|
479
|
-
|
|
480
|
-
@staticmethod
|
|
481
|
-
def _infer_entrypoint(script_source: str) -> str:
|
|
482
|
-
matches = re.findall(r"^def\s+([A-Za-z_][\w]*)\s*\(", script_source, re.MULTILINE)
|
|
483
|
-
if not matches:
|
|
484
|
-
raise ValueError(
|
|
485
|
-
"Could not determine the entrypoint for the RunScript code. Please set the `entrypoint` argument."
|
|
486
|
-
)
|
|
487
|
-
unique_matches = [match for match in matches if match]
|
|
488
|
-
if len(unique_matches) > 1:
|
|
489
|
-
raise ValueError(
|
|
490
|
-
"Multiple top-level functions were found in the RunScript code. Please specify the `entrypoint` argument."
|
|
491
|
-
)
|
|
492
|
-
return unique_matches[0]
|
|
493
|
-
|
|
494
432
|
def is_source(self) -> bool:
|
|
495
433
|
return len(self._inputs.inputs) == 0
|
|
496
434
|
|
|
@@ -544,7 +482,7 @@ def stage(
|
|
|
544
482
|
outputs: dict[str, type[PipelineOutput]] | None = None,
|
|
545
483
|
stage_name: str | None = None,
|
|
546
484
|
params: dict[str, PipelineParameter | PipelineArgValueType] | None = None,
|
|
547
|
-
) -> Callable[[Callable[..., dict[str, Any]]], RunScript]:
|
|
485
|
+
) -> Callable[[Callable[..., dict[str, Any] | None]], RunScript]:
|
|
548
486
|
"""
|
|
549
487
|
Decorator for building a RunScript stage from a Python function.
|
|
550
488
|
|
|
@@ -561,7 +499,7 @@ def stage(
|
|
|
561
499
|
... return {"geometry": geometry}
|
|
562
500
|
"""
|
|
563
501
|
|
|
564
|
-
def decorator(fn: Callable[..., dict[str, Any]]) -> RunScript:
|
|
502
|
+
def decorator(fn: Callable[..., dict[str, Any] | None]) -> RunScript:
|
|
565
503
|
return RunScript(
|
|
566
504
|
script=fn,
|
|
567
505
|
stage_name=stage_name,
|
|
@@ -73,15 +73,15 @@ class ReadMesh(StandardStage[ReadMeshOutputs]):
|
|
|
73
73
|
"""
|
|
74
74
|
Reads a Mesh into the Pipeline.
|
|
75
75
|
|
|
76
|
+
Does not complete until the Mesh is ready for simulation. Fails if the meshing job completes
|
|
77
|
+
with errors.
|
|
78
|
+
|
|
76
79
|
.. warning:: This feature is experimental and may change or be removed in the future.
|
|
77
80
|
|
|
78
81
|
Parameters
|
|
79
82
|
----------
|
|
80
83
|
mesh_id : str | StringPipelineParameter
|
|
81
84
|
The ID of the Mesh to retrieve.
|
|
82
|
-
wait_timeout_seconds : int | IntPipelineParameter | None
|
|
83
|
-
The number of seconds to wait for the Mesh to be ready. If None, defaults to 1800 seconds
|
|
84
|
-
(30 minutes).
|
|
85
85
|
|
|
86
86
|
Outputs
|
|
87
87
|
-------
|
|
@@ -94,57 +94,60 @@ class ReadMesh(StandardStage[ReadMeshOutputs]):
|
|
|
94
94
|
*,
|
|
95
95
|
stage_name: str | None = None,
|
|
96
96
|
mesh_id: str | StringPipelineParameter,
|
|
97
|
-
wait_timeout_seconds: int | IntPipelineParameter | None = None,
|
|
98
97
|
):
|
|
99
|
-
if wait_timeout_seconds is None:
|
|
100
|
-
wait_timeout_seconds = 30 * 60
|
|
101
98
|
super().__init__(
|
|
102
99
|
stage_name,
|
|
103
|
-
{"mesh_id": mesh_id
|
|
100
|
+
{"mesh_id": mesh_id},
|
|
104
101
|
StageInputs(self),
|
|
105
102
|
ReadMeshOutputs._instantiate_for(self),
|
|
106
103
|
)
|
|
107
104
|
|
|
108
105
|
|
|
109
106
|
@dataclass
|
|
110
|
-
class
|
|
111
|
-
|
|
112
|
-
"""
|
|
107
|
+
class WaitForMeshOutputs(StageOutputs):
|
|
108
|
+
mesh: PipelineOutputMesh
|
|
109
|
+
"""
|
|
110
|
+
The Mesh that will be waited for.
|
|
111
|
+
"""
|
|
113
112
|
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
class ModifyGeometry(StandardStage[ModifyGeometryOutputs]):
|
|
114
|
+
class WaitForMesh(StandardStage[WaitForMeshOutputs]):
|
|
117
115
|
"""
|
|
118
|
-
|
|
116
|
+
Waits for a Mesh to be ready.
|
|
117
|
+
|
|
118
|
+
This is useful if you have a more complicated meshing setup than the `Mesh` stage can handle.
|
|
119
|
+
|
|
120
|
+
For example, you can use a `RunScript` stage to call `lc.create_or_get_mesh()` with arbitrary
|
|
121
|
+
meshing parameters, then pass the resulting mesh to this stage to wait for it to be ready.
|
|
122
|
+
Mesh creation can take minutes to hours, and `RunScript` has a short timeout, so you can't wait
|
|
123
|
+
for it to complete in the `RunScript` stage, but `lc.create_or_get_mesh()` returns immediately
|
|
124
|
+
and mesh creation happens asynchronously, so you can wait for it to be ready in this stage.
|
|
119
125
|
|
|
120
126
|
.. warning:: This feature is experimental and may change or be removed in the future.
|
|
121
127
|
|
|
122
128
|
Parameters
|
|
123
129
|
----------
|
|
124
|
-
|
|
125
|
-
The
|
|
126
|
-
geometry : PipelineOutputGeometry
|
|
127
|
-
The Geometry to modify.
|
|
130
|
+
mesh : PipelineOutputMesh
|
|
131
|
+
The Mesh to wait for.
|
|
128
132
|
|
|
129
133
|
Outputs
|
|
130
134
|
-------
|
|
131
|
-
|
|
132
|
-
The
|
|
135
|
+
mesh : PipelineOutputMesh
|
|
136
|
+
The same Mesh that was passed in as input. It will now be in a `COMPLETED` status, and ready
|
|
137
|
+
to be used in a Simulation.
|
|
133
138
|
"""
|
|
134
139
|
|
|
135
140
|
def __init__(
|
|
136
141
|
self,
|
|
137
142
|
*,
|
|
138
143
|
stage_name: str | None = None,
|
|
139
|
-
|
|
140
|
-
geometry: PipelineOutputGeometry,
|
|
144
|
+
mesh: PipelineOutputMesh,
|
|
141
145
|
):
|
|
142
|
-
raise NotImplementedError("ModifyGeometry is not implemented yet.")
|
|
143
146
|
super().__init__(
|
|
144
147
|
stage_name,
|
|
145
|
-
{
|
|
146
|
-
StageInputs(self,
|
|
147
|
-
|
|
148
|
+
{},
|
|
149
|
+
StageInputs(self, mesh=(PipelineOutputMesh, mesh)),
|
|
150
|
+
WaitForMeshOutputs._instantiate_for(self),
|
|
148
151
|
)
|
|
149
152
|
|
|
150
153
|
|