Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b612447
added codegen
philipjusher Jun 3, 2026
d7c6438
chore: adding changelog file 344.added.md [dependabot-skip]
pyansys-ci-bot Jun 3, 2026
4585284
feat: Add models for uploaded files, validation errors, and wheel con…
philipjusher Jun 3, 2026
7615873
new api and examples
philipjusher Jun 4, 2026
cfa2104
docs and improvement for autogenerated client
philipjusher Jun 9, 2026
5e7d43b
added log files and test directory to gitignore
philipjusher Jun 22, 2026
2d11187
Merge origin/main into feature/api-generator
philipjusher Jun 22, 2026
07c824c
Add account_id and design_instance_id to JobRequest for v2 job API
philipjusher Jun 23, 2026
79dc28e
Configure e2e tests for v2 API on dev environment
philipjusher Jun 23, 2026
bd6ea06
Fix code style and documentation style CI failures
philipjusher Jun 23, 2026
c8fcc7e
Apply black/isort formatting to generated and schema code
philipjusher Jun 23, 2026
6427ea5
Merge branch 'main' into feature/api-generator
philipjusher Jun 23, 2026
a81fcb3
Fix doc build KeyError and exclude generated code from license-header…
philipjusher Jun 23, 2026
c656993
Fix doc build failure in example 02 and format long line
philipjusher Jun 23, 2026
41d811e
Fix doc build: allow examples to fail gracefully without a running se…
philipjusher Jun 23, 2026
8dd8940
Fix doc build: declare server-dependent examples as expected to fail …
philipjusher Jun 23, 2026
ea28216
Add v2 API examples (04-06) targeting dev environment; restore v1 exa…
philipjusher Jun 23, 2026
f63fce3
Fix code style: black/isort formatting and F841 in examples
philipjusher Jun 23, 2026
7ee6fa8
Run v1 examples against production; exclude v2 examples from doc build
philipjusher Jun 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 7 additions & 5 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[flake8]
exclude = venv, __init__.py, doc/_build, .venv
select = W191, W291, W293, W391, E115, E117, E122, E124, E125, E225, E231, E301, E303, E501, F401, F403
count = True
max-complexity = 10
max-line-length = 100
statistics = True
# schema/ contains reference generated client code that is not part of the published package.
# src/ansys/conceptev/core/generated/ contains auto-generated client code whose long docstring
# lines cannot be automatically wrapped by black without breaking the generator output.
extend-exclude = schema,openapi.json
per-file-ignores =
src/ansys/conceptev/core/generated/*:E501
scripts/*:E501
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,20 @@ cython_debug/
# e2e / optiSLang test artefacts and local debug logs
test_working_dir/
tests/e2e/test_working_dir/
ci_*.txt
ci_failing_job_logs_*.txt
ci_log_*.txt
ci_*_out.txt
ci_*_full.txt
ci_failing_job_logs_*.txt
*_pytest_output*.txt
e2e_pytest_*.txt
poetry_lock_output.txt
shell_test_out.txt

# Local secret / credential files
CONCEPTEV_PASSWORD
conceptev_password
token_cache.bin
examples/project_results.json
examples/results.xlsx
examples/created_designs.xlsx
6 changes: 5 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ repos:
rev: 24.4.2 # IF VERSION CHANGES --> MODIFY "blacken-docs" MANUALLY AS WELL!!
hooks:
- id: black
exclude: ^schema/

- repo: https://github.com/adamchainz/blacken-docs
rev: 1.16.0
Expand All @@ -15,11 +16,13 @@ repos:
rev: 5.13.2
hooks:
- id: isort
exclude: ^schema/

- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
exclude: ^schema/

- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
Expand All @@ -32,7 +35,7 @@ repos:
hooks:
- id: pydocstyle
additional_dependencies: [tomli]
exclude: "^(tests|examples)"
exclude: "^(tests|examples|src/ansys/conceptev/core/generated|schema)"

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
Expand All @@ -47,6 +50,7 @@ repos:
- id: add-license-headers
args:
- --start_year=2023
exclude: "^(src/ansys/conceptev/core/generated|schema)"

# Validate the pre-commit.ci configuration
- repo: https://github.com/pre-commit-ci/pre-commit-ci-config
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/344.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added codegen
15 changes: 11 additions & 4 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,15 @@
# Modules for which function level galleries are created. In
"doc_module": "ansys-conceptev-core",
"image_scrapers": ("matplotlib"),
"ignore_pattern": "flycheck*",
# Exclude flycheck temp files and v2 examples (require dev credentials not
# available during the production doc build).
"ignore_pattern": r"flycheck|0[456]_v2_",
"thumbnail_size": (350, 350),
# v1 examples (01-03) run against production using the conceptev_testing
# service account. They are expected to succeed; abort_on_example_error
# is kept False so a single transient failure doesn't break the whole build.
"abort_on_example_error": False,
"expected_failing_examples": [],
}

linkcheck_exclude_documents = ["index"]
Expand Down Expand Up @@ -194,10 +201,10 @@ def copy_examples(app):
size = directory_size(destination_dir)
logger.info(f"Directory {destination_dir} ({size} MB) already exist, removing it.")
shutil.rmtree(destination_dir)
logger.info(f"Directory removed.")
logger.info("Directory removed.")

shutil.copytree(EXAMPLES_DIRECTORY, destination_dir)
logger.info(f"Copy performed")
logger.info("Copy performed")


def remove_examples(app, exception):
Expand All @@ -207,7 +214,7 @@ def remove_examples(app, exception):
size = directory_size(destination_dir)
logger.info(f"Removing directory {destination_dir} ({size} MB).")
shutil.rmtree(destination_dir, ignore_errors=True)
logger.info(f"Directory removed.")
logger.info("Directory removed.")


def setup(app: sphinx.application.Sphinx):
Expand Down
187 changes: 172 additions & 15 deletions doc/source/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,188 @@

This section explains how to use PyConceptEV.

Create a client
^^^^^^^^^^^^^^^
Create a client (local server, v2 API)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Create a client that can access and talk to the Ansys ConceptEV API. You can use
the health check endpoint to check your connection.
The token is cached within a file called `token_cache.bin` you can configure the cache location with
an argument to the `get_http_client` function `cache_filepath`.
Use ``get_local_client`` to connect to a locally running ConceptEV service at
``http://127.0.0.1:8080/api``. No authentication is required. The returned
client is a typed generated client that works directly with the v2 API modules.

.. code-block:: python

import ansys.conceptev.core.main as pyconceptev
from ansys.conceptev.core.app import get_local_client
from ansys.conceptev.core.generated.api.concept_v2 import (
create_concept,
create_concept_part,
create_job,
get_job,
)
from ansys.conceptev.core.generated.models import (
AeroInput,
ArchitectureInput,
BatteryFixedVoltagesInput,
ConceptInput,
DynamicRequirementInput,
MassInput,
TransmissionLossCoefficientsInput,
WheelInput,
)
from ansys.conceptev.core.generated.models.job_request import JobRequest

with get_local_client() as client:
# Create a study
concept = create_concept.sync(
client=client,
body=ConceptInput(name="My Study"),
)
concept_id = concept.id

# Add configurations
aero = create_concept_part.sync(
id=concept_id,
part_type="configuration",
client=client,
body=AeroInput(name="Aero", drag_coefficient=0.3, cross_sectional_area=2.0),
)
mass = create_concept_part.sync(
id=concept_id,
part_type="configuration",
client=client,
body=MassInput(name="Mass", mass=2000.0),
)
wheel = create_concept_part.sync(
id=concept_id,
part_type="configuration",
client=client,
body=WheelInput(name="Wheel", rolling_radius=0.3),
)

# Add components
transmission = create_concept_part.sync(
id=concept_id,
part_type="component",
client=client,
body=TransmissionLossCoefficientsInput(
name="Transmission",
gear_ratios=[5.0],
headline_efficiencies=[0.95],
max_torque=500.0,
max_speed=2000.0,
static_drags=[0.5],
friction_ratios=[60.0],
),
)
battery = create_concept_part.sync(
id=concept_id,
part_type="component",
client=client,
body=BatteryFixedVoltagesInput(name="Battery", voltage_max=400.0),
)

# Add architecture
arch = create_concept_part.sync(
id=concept_id,
part_type="architecture",
client=client,
body=ArchitectureInput(
battery_id=battery.id,
number_of_front_motors=1,
front_transmission_id=transmission.id,
),
)

# Add requirement and submit job
req = create_concept_part.sync(
id=concept_id,
part_type="requirement",
client=client,
body=DynamicRequirementInput(
name="Req 1",
aero_id=aero.id,
mass_id=mass.id,
wheel_id=wheel.id,
),
)
job = create_job.sync(
concept_id=concept_id,
client=client,
body=JobRequest(
name="My Job",
requirement_ids=[req.id],
architecture_id=arch.id,
),
)
print(f"Job submitted: {job.id}, status: {job.status}")


Create a client (cloud service, legacy API)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For the hosted Ansys ConceptEV cloud service, use ``get_http_client`` (legacy
raw ``httpx`` client with MSAL authentication) or ``get_conceptev_client``
(typed generated client with MSAL authentication).

The token is cached in a file called ``token_cache.bin``. You can configure
the cache location with the ``cache_filepath`` argument.

with pyconceptev.get_http_client(
concept_id, cache_filepath="token_cache.bin"
) as client:
health = get(client, "/health")
print(health)
.. code-block:: python

from ansys.conceptev.core.app import get_conceptev_client

with get_conceptev_client() as client:
# Use with generated API modules (same as local client above)
...


Upload a file component
^^^^^^^^^^^^^^^^^^^^^^^

To use file-based components (motor lab files, battery lookup tables, etc.)
upload the file first, then reference the returned file ID when creating the
component:

.. code-block:: python

from ansys.conceptev.core.generated.api.concept_v2 import (
create_file_item,
create_concept_part,
)
from ansys.conceptev.core.generated.models import (
BodyCreateFileItem,
MotorLabInput,
)

with open("e9.lab", "rb") as f:
file_resp = create_file_item.sync(
id=concept_id,
client=client,
body=BodyCreateFileItem(file=f.read().decode("latin-1")),
name="e9.lab",
component_file_type="motor_lab_file",
)

motor = create_concept_part.sync(
id=concept_id,
part_type="component",
client=client,
body=MotorLabInput(
name="e9 Motor",
lab_data_id=file_resp.id,
max_speed=file_resp.calculated_values["max_speed"],
),
)


Update configuration
^^^^^^^^^^^^^^^^^^^^

Update the configuration of the client by using the `config.toml` the defaults are located in `src/ansys/conceptev/core/resources/config.toml`.
Create a new config.toml file in your working directory with the `account_name` set or create an environment variable called `ACCOUNT_NAME` and the settings management should find it.
Most things can be left as default but the `account_name` should be changed to match your `company account name`.
Update the configuration of the client by using the ``config.toml``. The
defaults are located in ``src/ansys/conceptev/core/resources/config.toml``.
Create a new ``config.toml`` file in your working directory with the
``account_name`` set or create an environment variable called ``ACCOUNT_NAME``
and the settings management will find it.

Check warning on line 187 in doc/source/user_guide.rst

View workflow job for this annotation

GitHub Actions / Documentation style

[vale] reported by reviewdog 🐶 [Google.Will] Avoid using 'will'. Raw Output: {"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "doc/source/user_guide.rst", "range": {"start": {"line": 187, "column": 29}}}, "severity": "WARNING"}
Most things can be left as default but the ``account_name`` should be changed
to match your company account name.

Configure SSL certificate for company networks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion examples/02_get_results_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def generate_and_run_templates(client, account_id, hpc_id):
project_id["projectId"], f"New Concept {datetime.datetime.now()}", token
)
concept = app.copy_concept(template_id, design_instance_id, client)
job_info = app.create_submit_job(
app.create_submit_job(
client,
concept,
account_id,
Expand Down
Loading
Loading