Skip to content

Commit 88c2087

Browse files
[FXC-1974] Dry run for run_case() (#1334)
* [FXC-1974] Dry run for run_case() Fix linting [FXC-2051] Removed unsteady initial_blade_direction check and also removed comments in v1 json (#1310) (#1312) * Added for sm and vm generations too * revert change on examples
1 parent 91cdefd commit 88c2087

File tree

3 files changed

+83
-12
lines changed

3 files changed

+83
-12
lines changed

flow360/component/project.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,7 @@ def _run(
12501250
use_geometry_AI: bool,
12511251
raise_on_error: bool,
12521252
tags: List[str],
1253+
draft_only: bool,
12531254
**kwargs,
12541255
):
12551256
"""
@@ -1277,11 +1278,13 @@ def _run(
12771278
Option to raise if submission error occurs (default is False)
12781279
tags: List[str], optional
12791280
A list of tags to add to the target asset.
1281+
draft_only: bool, optional
1282+
Whether to only create and submit a draft and not run the simulation.
12801283
12811284
Returns
12821285
-------
12831286
AssetOrResource
1284-
The destination asset
1287+
The destination asset or the draft if `draft_only` is True.
12851288
12861289
Raises
12871290
------
@@ -1349,6 +1352,15 @@ def _run(
13491352

13501353
draft.update_simulation_params(params)
13511354

1355+
if draft_only:
1356+
# pylint: disable=import-outside-toplevel
1357+
import click
1358+
1359+
log.info("Draft submitted, copy the link to browser to view the draft:")
1360+
# Not using log.info to avoid the link being wrapped and thus not clickable.
1361+
click.secho(draft.web_url, fg="blue", underline=True)
1362+
return draft
1363+
13521364
try:
13531365
destination_id = draft.run_up_to_target_asset(
13541366
target,
@@ -1398,6 +1410,7 @@ def generate_surface_mesh(
13981410
use_geometry_AI: bool = False, # pylint: disable=invalid-name
13991411
raise_on_error: bool = False,
14001412
tags: List[str] = None,
1413+
draft_only: bool = False,
14011414
**kwargs,
14021415
):
14031416
"""
@@ -1421,11 +1434,18 @@ def generate_surface_mesh(
14211434
Option to raise if submission error occurs (default is False)
14221435
tags: List[str], optional
14231436
A list of tags to add to the generated surface mesh.
1437+
draft_only: bool, optional
1438+
Whether to only create and submit a draft and not generate the surface mesh.
14241439
14251440
Raises
14261441
------
14271442
Flow360ValueError
14281443
If the root item type is not Geometry.
1444+
1445+
Returns
1446+
-------
1447+
SurfaceMeshV2 | Draft
1448+
The surface mesh asset or the draft if `draft_only` is True.
14291449
"""
14301450
self._check_initialized()
14311451
if self.metadata.root_item_type is not RootType.GEOMETRY:
@@ -1444,6 +1464,7 @@ def generate_surface_mesh(
14441464
use_geometry_AI=use_geometry_AI,
14451465
raise_on_error=raise_on_error,
14461466
tags=tags,
1467+
draft_only=draft_only,
14471468
**kwargs,
14481469
)
14491470
return surface_mesh
@@ -1459,6 +1480,7 @@ def generate_volume_mesh(
14591480
use_geometry_AI: bool = False, # pylint: disable=invalid-name
14601481
raise_on_error: bool = False,
14611482
tags: List[str] = None,
1483+
draft_only: bool = False,
14621484
**kwargs,
14631485
):
14641486
"""
@@ -1482,11 +1504,18 @@ def generate_volume_mesh(
14821504
Option to raise if submission error occurs (default is False)
14831505
tags: List[str], optional
14841506
A list of tags to add to the generated volume mesh.
1507+
draft_only: bool, optional
1508+
Whether to only create and submit a draft and not generate the volume mesh.
14851509
14861510
Raises
14871511
------
14881512
Flow360ValueError
14891513
If the root item type is not Geometry.
1514+
1515+
Returns
1516+
-------
1517+
VolumeMeshV2 | Draft
1518+
The volume mesh asset or the draft if `draft_only` is True.
14901519
"""
14911520
self._check_initialized()
14921521
if (
@@ -1496,7 +1525,7 @@ def generate_volume_mesh(
14961525
raise Flow360ValueError(
14971526
"Volume mesher can only be run by projects with a geometry or surface mesh root asset"
14981527
)
1499-
volume_mesh = self._run(
1528+
volume_mesh_or_draft = self._run(
15001529
params=params,
15011530
target=VolumeMeshV2,
15021531
draft_name=name,
@@ -1508,8 +1537,13 @@ def generate_volume_mesh(
15081537
use_geometry_AI=use_geometry_AI,
15091538
raise_on_error=raise_on_error,
15101539
tags=tags,
1540+
draft_only=draft_only,
15111541
**kwargs,
15121542
)
1543+
if draft_only:
1544+
draft = volume_mesh_or_draft
1545+
return draft
1546+
volume_mesh = volume_mesh_or_draft
15131547
return volume_mesh
15141548

15151549
@pd.validate_call(config={"arbitrary_types_allowed": True})
@@ -1525,6 +1559,7 @@ def run_case(
15251559
use_geometry_AI: bool = False, # pylint: disable=invalid-name
15261560
raise_on_error: bool = False,
15271561
tags: List[str] = None,
1562+
draft_only: bool = False,
15281563
**kwargs,
15291564
):
15301565
"""
@@ -1552,9 +1587,16 @@ def run_case(
15521587
Option to raise if submission error occurs (default is False)
15531588
tags: List[str], optional
15541589
A list of tags to add to the case.
1590+
draft_only: bool, optional
1591+
Whether to only create and submit a draft and not run the case.
1592+
1593+
Returns
1594+
-------
1595+
Case | Draft
1596+
The case asset or the draft if `draft_only` is True.
15551597
"""
15561598
self._check_initialized()
1557-
case = self._run(
1599+
case_or_draft = self._run(
15581600
params=params,
15591601
target=Case,
15601602
draft_name=name,
@@ -1566,8 +1608,14 @@ def run_case(
15661608
use_geometry_AI=use_geometry_AI,
15671609
raise_on_error=raise_on_error,
15681610
tags=tags,
1611+
draft_only=draft_only,
15691612
**kwargs,
15701613
)
1614+
1615+
if draft_only:
1616+
draft = case_or_draft
1617+
return draft
1618+
case = case_or_draft
15711619
report_template = get_default_report_summary_template()
15721620
report_template.create_in_cloud(
15731621
name=f"{name}-summary",

flow360/component/resource_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def _from_meta(cls, meta):
293293
"This is abstract method. Needs to be implemented by specialised class."
294294
)
295295

296-
def get_info(self, force=False) -> AssetMetaBaseModel:
296+
def get_info(self, force=False):
297297
"""
298298
returns metadata info for resource
299299
"""

flow360/component/simulation/web/draft.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
import ast
66
import json
7+
from functools import cached_property
78
from typing import Literal, Union
89

10+
from pydantic import BaseModel, ConfigDict, Field
11+
912
from flow360.cloud.flow360_requests import (
1013
DraftCreateRequest,
1114
DraftRunRequest,
@@ -14,16 +17,25 @@
1417
)
1518
from flow360.cloud.rest_api import RestApi
1619
from flow360.component.interfaces import DraftInterface
17-
from flow360.component.resource_base import (
18-
AssetMetaBaseModel,
19-
Flow360Resource,
20-
ResourceDraft,
21-
)
20+
from flow360.component.resource_base import Flow360Resource, ResourceDraft
2221
from flow360.component.utils import formatting_validation_errors, validate_type
22+
from flow360.environment import Env
2323
from flow360.exceptions import Flow360RuntimeError, Flow360WebError
2424
from flow360.log import log
2525

2626

27+
class DraftMetaModel(BaseModel):
28+
"""Draft metadata deserializer"""
29+
30+
type: Literal["Draft"] = "Draft"
31+
name: str
32+
id: str
33+
project_id: str = Field(alias="projectId")
34+
solver_version: str = Field(alias="solverVersion")
35+
36+
model_config = ConfigDict(extra="ignore")
37+
38+
2739
class DraftDraft(ResourceDraft):
2840
"""
2941
Draft Draft component
@@ -71,14 +83,14 @@ class Draft(Flow360Resource):
7183
def __init__(self, draft_id: IDStringType):
7284
super().__init__(
7385
interface=DraftInterface,
74-
meta_class=AssetMetaBaseModel, # We do not have dedicated meta class for Draft
86+
meta_class=DraftMetaModel, # We do not have dedicated meta class for Draft
7587
id=draft_id,
7688
)
7789

7890
@classmethod
7991
# pylint: disable=protected-access
80-
def _from_meta(cls, meta: AssetMetaBaseModel):
81-
validate_type(meta, "meta", AssetMetaBaseModel)
92+
def _from_meta(cls, meta: DraftMetaModel):
93+
validate_type(meta, "meta", DraftMetaModel)
8294
resource = cls(draft_id=meta.id)
8395
return resource
8496

@@ -185,3 +197,14 @@ def run_up_to_target_asset(
185197
"An unexpected error has occurred. Please contact customer support."
186198
) from None
187199
raise RuntimeError("Submission not successful.")
200+
201+
@cached_property
202+
def project_id(self) -> str:
203+
"""Get the project ID of the draft"""
204+
return self.info.project_id
205+
206+
@property
207+
def web_url(self) -> str:
208+
"""Get the web URL of the draft"""
209+
210+
return Env.current.web_url + f"/workbench/{self.project_id}?id={self.id}&type=Draft"

0 commit comments

Comments
 (0)