Skip to content

Commit a76e289

Browse files
authored
Merge pull request #1 from ansys-internal/fli/repo_split
initial check-in: files are split out from original ansys-api-workben…
2 parents a74d06e + 1546e85 commit a76e289

File tree

13 files changed

+1068
-2
lines changed

13 files changed

+1068
-2
lines changed

.github/workflows/ci.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Build and Publish ansys-workbench-core
2+
3+
# run only on main branch. This avoids duplicated actions on PRs
4+
on:
5+
pull_request:
6+
push:
7+
tags:
8+
- "*"
9+
branches:
10+
- main
11+
12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
env:
17+
MAIN_PYTHON_VERSION: "3.10"
18+
PACKAGE_NAME: "ansys.workbench.core"
19+
20+
jobs:
21+
22+
package:
23+
name: Package
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Build library source and wheel artifacts
27+
uses: ansys/actions/build-library@v4
28+
with:
29+
library-name: ${{ env.PACKAGE_NAME }}
30+
python-version: ${{ env.MAIN_PYTHON_VERSION }}
31+
- name: Upload package
32+
uses: actions/upload-artifact@v3
33+
with:
34+
name: ansys-workbench-core-packages
35+
path: dist/
36+
retention-days: 7
37+
38+
release:
39+
name: Release
40+
if: github.event_name == 'push' && contains(github.ref, 'refs/tags')
41+
needs: [package]
42+
runs-on: ubuntu-latest
43+
steps:
44+
- name: Set up Python
45+
uses: actions/setup-python@v4
46+
with:
47+
python-version: ${{ env.MAIN_PYTHON_VERSION }}
48+
49+
- name: Download package
50+
uses: actions/download-artifact@v3
51+
with:
52+
name: ansys-workbench-core-packages
53+
54+
- name: Display structure of downloaded files
55+
run: ls -R
56+
57+
- name: Upload to Ansys private PyPI
58+
run: |
59+
pip install twine
60+
twine upload --skip-existing ./*.whl
61+
twine upload --skip-existing ./*.tar.gz
62+
env:
63+
TWINE_USERNAME: __token__
64+
TWINE_PASSWORD: ${{ secrets.PYANSYS_PYPI_PRIVATE_PAT }}
65+
TWINE_REPOSITORY_URL: https://pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/upload
66+
67+
- name: Github release
68+
uses: softprops/action-gh-release@v1
69+
with:
70+
generate_release_notes: true
71+
files: |
72+
./*.whl
73+
./*.tar.gz

README.md

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,103 @@
1-
# pyworkbench
2-
PyWorkbench
1+
### ansys-workbench-core PyWorkbench Package
2+
3+
This Python package contains the public API to PyWorkbench.
4+
5+
6+
#### Installation
7+
8+
NOTE: Users must first apply the `PYANSYS_PRIVATE_PYPI_PAT` token as an environment variable. This allows authentication with Private PyPI.
9+
The value can be found at the following [link](https://dev-docs.solutions.ansys.com/solution_journey/journey_prepare/connect_to_private_pypi.html).
10+
11+
Provided that these wheels have been published to PyPI, they can be
12+
installed with:
13+
14+
Linux (bash)
15+
```bash
16+
# Create and activate a virtualenv
17+
python -m venv .venv
18+
source .venv/bin/activate # can be deactivated with the 'deactivate' command
19+
# Install pre-requisites to connect to artifact feed
20+
pip install --upgrade pip
21+
pip install keyring artifacts-keyring
22+
#Install wMI (Not Available in Private PyPI At This Time)
23+
pip install wMI==1.5.1
24+
# Install the latest package
25+
pip install --index-url https://$PYANSYS_PRIVATE_PYPI_PAT@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple ansys-workbench-core
26+
# OR - Install a package version of your choice
27+
pip install --index-url https://$PYANSYS_PRIVATE_PYPI_PAT@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple ansys-workbench-core==0.1.2
28+
```
29+
30+
Windows (PowerShell)
31+
```powershell
32+
# Create and activate a virtualenv
33+
python.exe -m venv .venv
34+
.\venv\Scripts\Activate.ps1 # can be deactivated with the 'deactivate' command
35+
# Install pre-requisites to connect to artifact feed
36+
pip.exe install --upgrade pip
37+
pip.exe install keyring artifacts-keyring
38+
#Install wMI (Not Available in Private PyPI At This Time)
39+
pip.exe install wMI==1.5.1
40+
# Install the latest package
41+
pip.exe install --index-url https://$env:[email protected]/pyansys/_packaging/pyansys/pypi/simple ansys-workbench-core
42+
# OR - Install a package version of your choice
43+
pip.exe install --index-url https://$env:[email protected]/pyansys/_packaging/pyansys/pypi/simple ansys-workbench-core==0.1.2
44+
```
45+
46+
Windows (Command Prompt)
47+
```
48+
# Create and activate a virtualenv
49+
python -m venv .venv
50+
.\venv\Scripts\activate.bat # can be deactivated with the 'deactivate' command
51+
# Install pre-requisites to connect to artifact feed
52+
pip install --upgrade pip
53+
pip install keyring artifacts-keyring
54+
#Install wMI (Not Available in Private PyPI At This Time)
55+
pip install wMI==1.5.1
56+
# Install the latest package
57+
pip install --index-url https://%PYANSYS_PRIVATE_PYPI_PAT%@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple ansys-workbench-core
58+
# OR - Install a package version of your choice
59+
pip install --index-url https://%PYANSYS_PRIVATE_PYPI_PAT%@pkgs.dev.azure.com/pyansys/_packaging/pyansys/pypi/simple ansys-workbench-core==0.1.2
60+
```
61+
62+
63+
#### Build
64+
65+
To build the gRPC packages, run:
66+
67+
```
68+
pip install build
69+
python -m build
70+
```
71+
72+
This will create both the source distribution containing just the protofiles
73+
along with the wheel containing the protofiles and build Python interface
74+
files.
75+
76+
Note that the interface files are identical regardless of the version of Python
77+
used to generate them, but the last pre-built wheel for ``grpcio~=1.17`` was
78+
Python 3.7, so to improve your build time, use Python 3.7 when building the
79+
wheel.
80+
81+
82+
#### Automatic Deployment
83+
84+
This repository contains GitHub CI/CD that enables the automatic building of
85+
source and wheel packages for these gRPC Python interface files. By default,
86+
these are built on PRs, the main branch, and on tags when pushing. Artifacts
87+
are uploaded to GitHub for each PR and push to the main branch. Artifacts
88+
are published to Ansys Private PyPI when tags are pushed.
89+
90+
To release wheels to PyPI, ensure your branch is up-to-date and then
91+
push tags. For example, for the version ``v0.1.5``. This version MUST MATCH
92+
the version in `pyproject.toml`.
93+
94+
For example, if you intend to release version `0.1.5` to Private PyPI, the
95+
pyproject.toml file should contain '0.1.5'. You will then run:
96+
97+
```bash
98+
git tag v0.1.5
99+
git push --tags
100+
```
101+
102+
Note that there is a 'v' prepended to the GitHub tag, keeping with best practices.
103+
The 'v' is not required in the `pyproject.toml` file.

example/demo.ipynb

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "558376fd-674a-424c-8885-65a872acfd95",
6+
"metadata": {},
7+
"source": [
8+
"# PyFluent and PyMechanical out of PyWorkbench session"
9+
]
10+
},
11+
{
12+
"cell_type": "code",
13+
"execution_count": null,
14+
"id": "014c5732-9f2b-423d-81ed-8e70928b2e47",
15+
"metadata": {
16+
"tags": []
17+
},
18+
"outputs": [],
19+
"source": [
20+
"import os\n",
21+
"import json\n",
22+
"from ansys.workbench.core.launch_workbench import launch_workbench\n",
23+
"import ansys.fluent.core as pyfluent\n",
24+
"from ansys.mechanical.core import launch_mechanical"
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": null,
30+
"id": "705a3b24-b51d-4724-8a17-f7307873197c",
31+
"metadata": {
32+
"tags": []
33+
},
34+
"outputs": [],
35+
"source": [
36+
"# launch Workbench on the local machine\n",
37+
"wb = launch_workbench(client_workdir='C:/Users/fli/demo')"
38+
]
39+
},
40+
{
41+
"cell_type": "code",
42+
"execution_count": null,
43+
"id": "d02aea0f-e99b-434b-b3d1-c60a87b092ea",
44+
"metadata": {},
45+
"outputs": [],
46+
"source": [
47+
"# upload-download-file round trip\n",
48+
"wb.upload_file('sample.png')\n",
49+
"wb.run_script_string(\"\"\"import os\n",
50+
"wdir = GetServerWorkingDirectory()\n",
51+
"if os.path.exists(os.path.join(wdir, 'renamed.png')):\n",
52+
" os.remove(os.path.join(wdir, 'renamed.png'))\n",
53+
"os.rename(os.path.join(wdir, 'sample.png'), os.path.join(wdir, 'renamed.png'))\n",
54+
"\"\"\")\n",
55+
"wb.download_file('renamed.png')\n",
56+
"are_same = open('sample.png', 'rb').read() == open('renamed.png', 'rb').read()\n",
57+
"print('are two files the same? ' + str(are_same))"
58+
]
59+
},
60+
{
61+
"cell_type": "code",
62+
"execution_count": null,
63+
"id": "b6af4888-7482-4c40-96da-c959b4147b3a",
64+
"metadata": {},
65+
"outputs": [],
66+
"source": [
67+
"# create a Fluent system and return its name\n",
68+
"fluent_sys_name = wb.run_script_string('import json\\nwb_script_result=json.dumps(GetTemplate(TemplateName=\\\"FLUENT\\\").CreateSystem().Name)')"
69+
]
70+
},
71+
{
72+
"cell_type": "code",
73+
"execution_count": null,
74+
"id": "e88ab850-d840-4919-954c-eacd29a699fd",
75+
"metadata": {},
76+
"outputs": [],
77+
"source": [
78+
"# start PyFluent server on the system, then create a PyFluent client session\n",
79+
"server_info_file=wb.start_pyfluent(system_name=fluent_sys_name)\n",
80+
"fluent=pyfluent.connect_to_fluent(server_info_filepath=server_info_file)"
81+
]
82+
},
83+
{
84+
"cell_type": "code",
85+
"execution_count": null,
86+
"id": "221ad401-82d1-480d-8910-da0dd34b5a2c",
87+
"metadata": {
88+
"tags": []
89+
},
90+
"outputs": [],
91+
"source": [
92+
"# basic status queries on the PyFluent session\n",
93+
"print('server is serving? ' + str(fluent.health_check_service.is_serving))\n",
94+
"print('server version: ' + fluent.get_fluent_version())"
95+
]
96+
},
97+
{
98+
"cell_type": "code",
99+
"execution_count": null,
100+
"id": "6a3fd1a1-d261-45e0-9c9f-3f043d00aea6",
101+
"metadata": {},
102+
"outputs": [],
103+
"source": [
104+
"# upload an example Fluent case file, load it into the Fluent session\n",
105+
"wb.upload_file_from_example_repo(\"elbow.cas.h5\", \"elbow_case_file\")\n",
106+
"setup_state=wb.run_script_string(f\"\"\"import os\n",
107+
"sys=GetSystem(Name='{fluent_sys_name}')\n",
108+
"dir=GetServerWorkingDirectory()\n",
109+
"sys.GetContainer(ComponentName=\"Setup\").Import(FilePath=os.path.join(dir, 'elbow.cas.h5'), FileType='CffCase')\n",
110+
"setup=sys.GetComponent(Name=\"Setup\")\n",
111+
"setup.Refresh()\n",
112+
"wb_script_result = json.dumps(GetComponentState(Component=setup).State.ToString())\n",
113+
"\"\"\")\n",
114+
"print('Fluent Setup component is ' + setup_state)\n",
115+
]
116+
},
117+
{
118+
"cell_type": "code",
119+
"execution_count": null,
120+
"id": "a94f8a4e-4995-4d48-8966-8734c6c9d4bc",
121+
"metadata": {},
122+
"outputs": [],
123+
"source": [
124+
"# create a Mechanical system on Workbench, then load geometry\n",
125+
"wb.upload_file_from_example_repo(\"2pipes.agdb\", \"2pipes\")\n",
126+
"ss_system_name = wb.run_script_file('load_geometry.wbjn')"
127+
]
128+
},
129+
{
130+
"cell_type": "code",
131+
"execution_count": null,
132+
"id": "110c8edc-e890-422b-8323-3dddb2af346c",
133+
"metadata": {},
134+
"outputs": [],
135+
"source": [
136+
"# start PyMechanical server on the system, then create a PyMechanical client session\n",
137+
"#server_port=wb.start_pymechanical(system_name=ss_system_name)\n",
138+
"mechanical = launch_mechanical(start_instance=False, ip='localhost', port=server_port)"
139+
]
140+
},
141+
{
142+
"cell_type": "code",
143+
"execution_count": null,
144+
"id": "48320724-37fb-41d4-959e-d9b0437a7bff",
145+
"metadata": {},
146+
"outputs": [],
147+
"source": [
148+
"# perform some queries on the PyMechanical session\n",
149+
"print(mechanical.version)\n",
150+
"mechanical.list_files()"
151+
]
152+
},
153+
{
154+
"cell_type": "code",
155+
"execution_count": null,
156+
"id": "6dfe8b49-c81b-4718-851e-e1f6f0f30a12",
157+
"metadata": {
158+
"tags": []
159+
},
160+
"outputs": [],
161+
"source": [
162+
"# shutdown the Workbench service\n",
163+
"wb.exit()"
164+
]
165+
}
166+
],
167+
"metadata": {
168+
"kernelspec": {
169+
"display_name": "Python 3 (ipykernel)",
170+
"language": "python",
171+
"name": "python3"
172+
},
173+
"language_info": {
174+
"codemirror_mode": {
175+
"name": "ipython",
176+
"version": 3
177+
},
178+
"file_extension": ".py",
179+
"mimetype": "text/x-python",
180+
"name": "python",
181+
"nbconvert_exporter": "python",
182+
"pygments_lexer": "ipython3",
183+
"version": "3.9.4"
184+
}
185+
},
186+
"nbformat": 4,
187+
"nbformat_minor": 5
188+
}

example/load_geometry.wbjn

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import os
2+
import json
3+
4+
work_dir = GetServerWorkingDirectory()
5+
geometry_file = os.path.join(work_dir, "2pipes.agdb")
6+
7+
# create a Static Structural system with the given geometry
8+
template = GetTemplate(TemplateName="Static Structural", Solver="ANSYS")
9+
system = CreateSystemFromTemplate(Template=template, Name="Static Structural (ANSYS)")
10+
system.GetContainer(ComponentName="Geometry").SetFile(FilePath=geometry_file)
11+
12+
# output the name of the system
13+
wb_script_result = json.dumps(system.Name)

example/sample.png

79.2 KB
Loading

0 commit comments

Comments
 (0)