Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2c3709d
feat: Centralize schema by migrating base models, types, and unit sys…
benflexcompute Mar 16, 2026
c29a490
Merge branch 'develop' into BenY/CentralizedSchema
benflexcompute Mar 17, 2026
b62e739
Corrected the version
benflexcompute Mar 17, 2026
bfbb7b4
Replace custom coverage script with py-cov-action (#1901)
benflexcompute Mar 17, 2026
b039d60
Full unit physical dimension migration into Schema Side (#1888)
benflexcompute Mar 17, 2026
f1795a7
Merge remote-tracking branch 'origin/main' into BenY/CentralizedSchema
benflexcompute Mar 23, 2026
cda388c
Updated lock
benflexcompute Mar 23, 2026
930bc55
Merge remote-tracking branch 'origin/main' into BenY/CentralizedSchema
benflexcompute Mar 26, 2026
d942eaa
Expresssion migration (#1915)
benflexcompute Mar 26, 2026
8ae4221
refactor(flow360): use unified Flow360BaseModel from schema package (…
benflexcompute Mar 30, 2026
e733cd8
Merge main into BenY/CentralizedSchema
benflexcompute Mar 30, 2026
f60f935
refactor(flow360): entity system — client files become re-import rela…
benflexcompute Mar 31, 2026
4a7d3d9
Use schema-owned asset cache models (#1950)
benflexcompute Apr 2, 2026
6565610
schema: remove duplicated client entity tests (#1954)
benflexcompute Apr 3, 2026
ad7a9b6
Merge remote-tracking branch 'origin/main' into BenY/CentralizedSchema
benflexcompute Apr 7, 2026
9743862
refactor(flow360): relay simulation infra helpers to schema (#1963)
benflexcompute Apr 7, 2026
04e00af
schema(): Split draft context managers from schema state (#1983)
benflexcompute Apr 10, 2026
b7a6a9a
Migrate SimulationParams models to flow360-schema (#1989)
benflexcompute Apr 14, 2026
2e212aa
Remove simulation tests migrated to flow360-schema (#1994)
benflexcompute Apr 15, 2026
b0c6fa8
Avoid frozen sequence rewrites during translator transforms (#1996)
benflexcompute Apr 15, 2026
76b490e
Merge origin/main into BenY/CentralizedSchema
benflexcompute Apr 15, 2026
6c43f43
Preserve no-unit values in surface meshing translator
benflexcompute Apr 15, 2026
8a7ee10
Formatted
benflexcompute Apr 15, 2026
b8e0123
Relay simulation validation through schema service
benflexcompute Apr 16, 2026
5879125
Relay migrated simulation services through schema
benflexcompute Apr 16, 2026
fd3943b
Relay more simulation default services through schema
benflexcompute Apr 16, 2026
46453a2
Remove migrated validation-service tests from client
benflexcompute Apr 16, 2026
d326fa7
Relay more simulation service utilities through schema
benflexcompute Apr 17, 2026
9bf503f
Remove migrated simulation test duplicates
benflexcompute Apr 17, 2026
2def56e
Remove migrated simulation params test duplicates
benflexcompute Apr 17, 2026
816c0a0
Remove more migrated simulation params test duplicates
benflexcompute Apr 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/actions/setup-codeartifact-poetry-auth/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Setup CodeArtifact Poetry Auth
description: Configure AWS credentials, fetch CodeArtifact token, and set Poetry auth env vars.

inputs:
aws-access-key-id:
description: AWS access key id for CodeArtifact access.
required: true
aws-secret-access-key:
description: AWS secret access key for CodeArtifact access.
required: true
aws-region:
description: AWS region of the CodeArtifact domain.
required: false
default: us-east-1
domain:
description: CodeArtifact domain name.
required: false
default: flexcompute
domain-owner:
description: AWS account id that owns the CodeArtifact domain.
required: false
default: "625554095313"

outputs:
token:
description: CodeArtifact authorization token.
value: ${{ steps.get-token.outputs.token }}

runs:
using: composite
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ inputs.aws-access-key-id }}
aws-secret-access-key: ${{ inputs.aws-secret-access-key }}
aws-region: ${{ inputs.aws-region }}

- name: Get CodeArtifact token and set Poetry env
id: get-token
shell: bash
run: |
TOKEN=$(aws codeartifact get-authorization-token \
--domain "${{ inputs.domain }}" \
--domain-owner "${{ inputs.domain-owner }}" \
--region "${{ inputs.aws-region }}" \
--query authorizationToken \
--output text)
echo "::add-mask::$TOKEN"
echo "token=$TOKEN" >> "$GITHUB_OUTPUT"
echo "POETRY_HTTP_BASIC_CODEARTIFACT_USERNAME=aws" >> "$GITHUB_ENV"
echo "POETRY_HTTP_BASIC_CODEARTIFACT_PASSWORD=$TOKEN" >> "$GITHUB_ENV"
20 changes: 20 additions & 0 deletions .github/workflows/codestyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ name: Codestyle checking

on:
workflow_call:
secrets:
AWS_CODEARTIFACT_READ_ACCESS_KEY:
required: true
AWS_CODEARTIFACT_READ_ACCESS_SECRET:
required: true
workflow_dispatch:

jobs:
Expand All @@ -15,6 +20,11 @@ jobs:
with:
python-version: '3.10'
cache: 'poetry'
- name: Setup CodeArtifact auth for Poetry
uses: ./.github/actions/setup-codeartifact-poetry-auth
with:
aws-access-key-id: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_SECRET }}
- name: Install black
run: poetry install
- name: Run black
Expand All @@ -30,6 +40,11 @@ jobs:
with:
python-version: '3.10'
cache: 'poetry'
- name: Setup CodeArtifact auth for Poetry
uses: ./.github/actions/setup-codeartifact-poetry-auth
with:
aws-access-key-id: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_SECRET }}
- name: Install isort
run: poetry install
- name: Check isort version
Expand Down Expand Up @@ -57,6 +72,11 @@ jobs:
with:
python-version: '3.10'
cache: 'poetry'
- name: Setup CodeArtifact auth for Poetry
uses: ./.github/actions/setup-codeartifact-poetry-auth
with:
aws-access-key-id: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_SECRET }}
- name: Install dependencies
run: poetry install
- name: Run pylint
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,14 @@ jobs:
with:
python-version: '3.10'
cache: 'poetry'
- name: Setup CodeArtifact auth for Poetry
uses: ./.github/actions/setup-codeartifact-poetry-auth
with:
aws-access-key-id: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_SECRET }}
aws-region: us-east-1
domain: flexcompute
domain-owner: "625554095313"
- name: Install dependencies
run: poetry install
- name: Pump version number
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@ on:
pull_request:
types: [ opened, synchronize, reopened, ready_for_review ]
workflow_call:
secrets:
AWS_CODEARTIFACT_READ_ACCESS_KEY:
required: true
AWS_CODEARTIFACT_READ_ACCESS_SECRET:
required: true

permissions:
contents: read
pull-requests: write

jobs:
code-style:
uses: ./.github/workflows/codestyle.yml
secrets: inherit
testing:
needs: code-style
name: test ${{ matrix.python-version }} - ${{ matrix.platform }}
Expand Down Expand Up @@ -46,11 +56,62 @@ jobs:
virtualenvs-in-project: true
virtualenvs-create: true

- name: Setup CodeArtifact auth for Poetry
uses: ./.github/actions/setup-codeartifact-poetry-auth
with:
aws-access-key-id: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_CODEARTIFACT_READ_ACCESS_SECRET }}

- name: Install dependencies
run: poetry install

# Non-coverage matrix combinations: run tests normally
- name: Run simulation_params tests
if: ${{ !(matrix.python-version == '3.10' && matrix.platform == 'ubuntu-latest') }}
run: poetry run pytest -rA tests/simulation -vv

- name: Run flow360_params tests
if: ${{ !(matrix.python-version == '3.10' && matrix.platform == 'ubuntu-latest') }}
run: poetry run pytest -rA --ignore tests/simulation -vv

# Coverage matrix combination (Python 3.10 + ubuntu-latest): run tests with coverage
- name: Run simulation_params tests with coverage
if: matrix.python-version == '3.10' && matrix.platform == 'ubuntu-latest'
run: poetry run pytest -rA tests/simulation -vv --cov=flow360 --cov-report=term-missing:skip-covered

- name: Run flow360_params tests with coverage
if: matrix.python-version == '3.10' && matrix.platform == 'ubuntu-latest'
run: poetry run pytest -rA --ignore tests/simulation -vv --cov=flow360 --cov-append --cov-report=term-missing:skip-covered

- name: Upload coverage data
if: matrix.python-version == '3.10' && matrix.platform == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: coverage-data
path: .coverage
include-hidden-files: true

coverage:
name: Post Coverage Comment
needs: testing
if: always() && !cancelled() && github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4

- name: Download coverage data
id: download-coverage
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: coverage-data

- name: Post coverage comment
if: steps.download-coverage.outcome == 'success'
uses: py-cov-action/python-coverage-comment-action@7188638f871f721a365d644f505d1ff3df20d683 # v3.40
with:
GITHUB_TOKEN: ${{ github.token }}
SUBPROJECT_ID: flow360
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -339,4 +339,5 @@ flow360/examples/cylinder2D/flow360mesh.json

#Claude:
CLAUDE.md
.claude/
.claude/
docs/plans/
3 changes: 2 additions & 1 deletion examples/migration_guide/example_bet_conversion.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import os

import unyt as u

import flow360 as fl
from flow360.component.simulation.migration import BETDisk
from flow360.component.simulation.unit_system import u

# Get the absolute path to the script file
script_dir = os.path.dirname(os.path.abspath(__file__))
Expand Down
3 changes: 2 additions & 1 deletion examples/migration_guide/example_monitor_conversion.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import os

import unyt as u

from flow360.component.simulation.migration import ProbeOutput
from flow360.component.simulation.unit_system import u

# Get the absolute path to the script file
script_dir = os.path.dirname(os.path.abspath(__file__))
Expand Down
17 changes: 9 additions & 8 deletions flow360/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
This module is flow360 for simulation based models
"""

from flow360_schema.framework.expression import (
UserVariable,
get_user_variable,
remove_user_variable,
show_user_variables,
)
from flow360_schema.models.functions import math
from flow360_schema.models.variables import solution

from flow360.accounts_utils import Accounts
from flow360.cli.api_set_func import configure_caller as configure
from flow360.component.case import Case
Expand Down Expand Up @@ -198,14 +207,6 @@
SI_unit_system,
imperial_unit_system,
)
from flow360.component.simulation.user_code.core.types import (
UserVariable,
get_user_variable,
remove_user_variable,
show_user_variables,
)
from flow360.component.simulation.user_code.functions import math
from flow360.component.simulation.user_code.variables import solution
from flow360.component.simulation.user_defined_dynamics.user_defined_dynamics import (
UserDefinedDynamic,
)
Expand Down
23 changes: 12 additions & 11 deletions flow360/component/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from typing import Any, List, Literal, Optional, Union

import pydantic as pd
from flow360_schema.framework.physical_dimensions import Length
from flow360_schema.framework.validation.context import DeserializationContext
from pydantic import TypeAdapter

from flow360.cloud.flow360_requests import (
GeometryFileMeta,
Expand All @@ -28,8 +31,6 @@
)
from flow360.component.simulation.folder import Folder
from flow360.component.simulation.primitives import Edge, GeometryBodyGroup, Surface
from flow360.component.simulation.unit_system import LengthType
from flow360.component.simulation.utils import model_attribute_unlock
from flow360.component.simulation.web.asset_base import AssetBase
from flow360.component.utils import (
GeometryFiles,
Expand Down Expand Up @@ -434,16 +435,15 @@ def snappy_bodies(self):
def get_dynamic_default_settings(self, simulation_dict: dict):
"""Get the default geometry settings from the simulation dict"""

def _get_default_geometry_accuracy(simulation_dict: dict) -> LengthType.Positive:
def _get_default_geometry_accuracy(simulation_dict: dict):
"""Get the default geometry accuracy from the simulation json"""
if simulation_dict.get("meshing") is None:
return None
if simulation_dict["meshing"].get("defaults") is None:
return None
if simulation_dict["meshing"]["defaults"].get("geometry_accuracy") is None:
return None
# pylint: disable=no-member
return LengthType.validate(simulation_dict["meshing"]["defaults"]["geometry_accuracy"])
return simulation_dict["meshing"]["defaults"]["geometry_accuracy"]

self.default_settings["geometry_accuracy"] = (
self._entity_info.default_geometry_accuracy
Expand All @@ -454,10 +454,12 @@ def _get_default_geometry_accuracy(simulation_dict: dict) -> LengthType.Positive
# Cache project length unit for OBB (avoids extra API call in create_draft)
asset_cache = simulation_dict.get("private_attribute_asset_cache", {})
length_unit_raw = asset_cache.get("project_length_unit")
# pylint: disable=no-member
self._project_length_unit = (
LengthType.validate(length_unit_raw) if length_unit_raw is not None else None
)
if length_unit_raw is not None:
adapter = TypeAdapter(Length.PositiveFloat64)
with DeserializationContext():
self._project_length_unit = adapter.validate_python(length_unit_raw)
else:
self._project_length_unit = None

@classmethod
# pylint: disable=redefined-builtin
Expand Down Expand Up @@ -730,8 +732,7 @@ def _rename_entity(
raise Flow360ValueError(
f"Renaming failed: An entity with the new name: {new_name} already exists."
)
with model_attribute_unlock(entity, "name"):
entity.name = new_name
entity._force_set_attr("name", new_name) # pylint:disable=protected-access

def rename_edges(self, current_name_pattern: str, new_name_prefix: str):
"""
Expand Down
14 changes: 6 additions & 8 deletions flow360/component/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import pydantic as pd
import typing_extensions
from flow360_schema.framework.physical_dimensions import Length
from flow360_schema.models.asset_cache import CoordinateSystemStatus, MirrorStatus
from pydantic import PositiveInt

from flow360.cloud.file_cache import get_shared_cloud_file_cache
Expand Down Expand Up @@ -46,10 +48,6 @@
DraftContext,
get_active_draft,
)
from flow360.component.simulation.draft_context.coordinate_system_manager import (
CoordinateSystemStatus,
)
from flow360.component.simulation.draft_context.mirror import MirrorStatus
from flow360.component.simulation.draft_context.obb.tessellation_loader import (
TessellationFileLoader,
)
Expand All @@ -60,7 +58,7 @@
from flow360.component.simulation.folder import Folder
from flow360.component.simulation.primitives import ImportedSurface
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.unit_system import LengthType
from flow360.component.simulation.units import validate_length
from flow360.component.simulation.web.asset_base import AssetBase
from flow360.component.simulation.web.draft import Draft
from flow360.component.simulation.web.project_records import (
Expand Down Expand Up @@ -660,13 +658,13 @@ def tags(self) -> List[str]:
return self.metadata.tags

@property
def length_unit(self) -> LengthType.Positive:
def length_unit(self) -> Length.PositiveFloat64:
"""
Returns the length unit of the project.

Returns
-------
LengthType.Positive
Length.PositiveFloat64
The length unit.
"""

Expand All @@ -678,7 +676,7 @@ def length_unit(self) -> LengthType.Positive:
if cache_key not in defaults or length_key not in defaults[cache_key]:
raise Flow360ValueError("[Internal] Simulation params do not contain length unit info.")

return LengthType.validate(defaults[cache_key][length_key])
return validate_length(defaults[cache_key][length_key])

@property
def geometry(self) -> Geometry:
Expand Down
Loading
Loading