Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/examples #215

Merged
merged 11 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions doc/source/examples_source/00-basic/00-create_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import numpy as np

import ansys.dynamicreporting.core as adr
import ansys.dynamicreporting.core.examples as examples

ansys_loc = r"C:\Program Files\ANSYS Inc\v232"
db_dir = r"C:\tmp\new_database"
Expand All @@ -39,9 +40,9 @@
my_text = adr_service.create_item()
my_text.item_text = "<h1>Analysis Title</h1>This is the first of many items"
my_image = adr_service.create_item()
my_image.item_image = r"""D:\tmp\tmp_img.png"""
my_image.item_image = examples.download_file("enthalpy_001.png", "input_data")
my_scene = adr_service.create_item()
my_scene.item_scene = r"""D:\tmp\tmp_scene.avz"""
my_scene.item_scene = examples.download_file("dam_break.avz", "input_data")

###############################################################################
# Visualize all items
Expand Down
7 changes: 4 additions & 3 deletions doc/source/examples_source/00-basic/01-connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
# database. The path for the database directory must be to an empty directory.

import ansys.dynamicreporting.core as adr
import ansys.dynamicreporting.core.examples as examples

db_dir = r"C:\tmp\new_database"
adr_service = adr.Service(ansys_installation="docker", db_directory=db_dir)
Expand All @@ -42,9 +43,9 @@
my_text = adr_service.create_item(obj_name="Text", source="Documentation")
my_text.item_text = "This is a simple string with no HTML formatting."
my_animation = adr_service.create_item(obj_name="Animation File", source="Documentation")
my_animation.item_animation = r"D:\tmp\myanim.mp4"
my_animation.item_animation = examples.download_file("dam_break.mp4", "input_data")
my_file = adr_service.create_item(obj_name="General File", source="Documentation")
my_file.item_file = r"D:\tmp\anytfile.txt"
my_file.item_file = examples.download_file("report_template.json", "multi_physics")
adr_service.visualize_report()

###############################################################################
Expand Down Expand Up @@ -75,7 +76,7 @@
# added to the database.

my_image = connected_s.create_item(obj_name="Image", source="Documentation")
my_image.item_image = r"D:\tmp\local_img.png"
my_image.item_image = examples.download_file("introduction.png", "multi_physics")
connected_s.visualize_report()


Expand Down
75 changes: 37 additions & 38 deletions doc/source/examples_source/25-intermediate/01-queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# database directory must be to an empty directory.

import ansys.dynamicreporting.core as adr
import ansys.dynamicreporting.core.examples as examples

ansys_loc = r"C:\Program Files\ANSYS Inc\v232"
db_dir = r"C:\tmp\new_database"
Expand All @@ -31,56 +32,54 @@
# ------------
#
# Now that an Ansys Dynamic Reporting service is running on top of a
# new database, you can populate it. To keep this example simple, this code
# creates multiple text items. It then sets some different names, sources, and
# tags.
# new database, you can populate it. We will download and push to the database
# 14 images.We will then set some different names, sources, and
# tags based on the image names

for i in range(100):
if i % 3 == 0:
my_text = adr_service.create_item(obj_name=f"Name {str(i % 20)}", source="Application X")
elif i % 3 == 1:
my_text = adr_service.create_item(obj_name=f"Name {str(i % 20)}", source="Application Y")
elif i % 3 == 2:
my_text = adr_service.create_item(obj_name=f"Name {str(i % 20)}", source="Application Z")
my_text.item_text = "Any text. Does not matter the actual payload"
if i % 4 == 0:
my_text.set_tags("var=pressure")
elif i % 4 == 1:
my_text.set_tags("var=energy")
elif i % 4 == 2:
my_text.set_tags("var=temperature")
elif i % 4 == 3:
my_text.set_tags("var=vorticity")
my_text.add_tag(tag="dp", value=str(i % 50))
variables = ["enthalpy", "statictemperature"]
for v in variables:
for i in range(7):
if i % 3 == 0:
new_image = adr_service.create_item(
obj_name=f"Image {str(i + 1)}", source="Application X"
)
elif i % 3 == 1:
new_image = adr_service.create_item(
obj_name=f"Image {str(i + 1)}", source="Application Y"
)
elif i % 3 == 2:
new_image = adr_service.create_item(
obj_name=f"Image {str(i + 1)}", source="Application Z"
)
filename = f"{v}_{str(i + 1).zfill(3)}.png"
new_image.item_image = examples.download_file(filename, "input_data")
new_image.set_tags(f"var={v} clip=-{float(i) * 0.01}")

###############################################################################
# Query the database
# ------------------
#
# Now that the database is populated with a hundred items with different
# Now that the database is populated with a few items with different
# names, sources, and tags, query the database, beginning with an empty
# query that returns the entire set (all 100 items). Next, query on the
# source name, which results in three different lists, with 34, 33, and 33 items
# respectively. Finally, query on the name and the ``dp`` tag. See that the lists
# have theexpected length. You can try different queries using the other attributes
# that have been set on the items.
#
# query that returns the entire set (all 14 items). Next, query on the
# source name, which results in three different lists, with 6, 4, and 4 items
# respectively. Query on the ``var`` and ``clip`` taga. See that the lists
# have the expected length. You can try different queries using other attributes.
# #

all_items = adr_service.query()
test_one = len(all_items) == 100
test_one = len(all_items) == 14
app_x = adr_service.query(filter="A|i_src|cont|Application X")
app_y = adr_service.query(filter="A|i_src|cont|Application Y")
app_z = adr_service.query(filter="A|i_src|cont|Application Z")
test_two = len(app_x) == 34
test_three = len(app_y) == len(app_z) == 33
name_0 = adr_service.query(filter="A|i_name|cont|Name 0")
name_11 = adr_service.query(filter="A|i_name|cont|Name 11")
name_7 = adr_service.query(filter="A|i_name|cont|Name 7")
test_four = len(name_7) == len(name_0) == len(name_11) == 5
dp0_items = adr_service.query(filter="A|i_tags|cont|dp=0")
dp10_items = adr_service.query(filter="A|i_tags|cont|dp=10")
dp33_items = adr_service.query(filter="A|i_tags|cont|dp=33")
test_five = len(dp0_items) == len(dp10_items) == len(dp33_items) == 2
test_two = len(app_x) == 6
test_three = len(app_y) == len(app_z) == 4
enthalpy_items = adr_service.query(filter="A|i_tags|cont|var=enthalpy")
statictemperature_items = adr_service.query(filter="A|i_tags|cont|var=statictemperature")
test_four = len(enthalpy_items) == len(statictemperature_items) == 7
clip3_items = adr_service.query(filter="A|i_tags|cont|clip=-0.03")
clip5_items = adr_service.query(filter="A|i_tags|cont|clip=-0.05")
test_five = len(clip3_items) == len(clip5_items) == 2

###############################################################################
# Close the service
Expand Down
11 changes: 6 additions & 5 deletions doc/source/examples_source/50-advanced/00-complete_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import numpy as np

import ansys.dynamicreporting.core as adr
import ansys.dynamicreporting.core.examples as examples

ansys_loc = r"C:\Program Files\ANSYS Inc\v232"
db_dir = r"C:\tmp\new_database"
Expand Down Expand Up @@ -277,16 +278,16 @@
b.set_tags("solution=solverA section=intro")
b.get_tags()
c = adr_service.create_item(obj_name="Schema")
c.item_image = r"C:\tmp\schema.png"
c.item_image = examples.download_file("multiphysics_workflow_diagram.PNG", "multi_physics")
c.set_tags("solution=solverA section=intro")
d = adr_service.create_item(obj_name="Schema")
d.item_image = r"C:\tmp\sections.png"
d.item_image = examples.download_file("summary.png", "multi_physics")
d.set_tags("solution=solverA section=cad_summary")
e = adr_service.create_item(obj_name="Schema")
e.item_image = r"C:\tmp\preliminary.png"
e.item_image = examples.download_file("preliminary.png", "multi_physics")
e.set_tags("solution=solverA section=preliminar_summary")
f = adr_service.create_item(obj_name="Schema")
f.item_image = r"C:\tmp\solution.png"
f = adr_service.create_item(obj_name="Details")
f.item_image = examples.download_file("detailed.png", "multi_physics")
f.set_tags("solution=solverA section=detailed_summary")
g = adr_service.create_item(obj_name="param_input")
g.table_dict["rowlbls"] = [
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ requires = [

[project]
name = "ansys-dynamicreporting-core"
version = "0.9.0.dev0"
version = "0.10.0.dev0"
authors = [
{name = "ANSYS, Inc.", email = "[email protected]"},
]
Expand Down
1 change: 1 addition & 0 deletions src/ansys/dynamicreporting/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Version
# ------------------------------------------------------------------------------
from pathlib import Path

try:
import importlib.metadata as importlib_metadata # type: ignore
Expand Down
3 changes: 3 additions & 0 deletions src/ansys/dynamicreporting/core/examples/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Provides a module to download a file."""

from .downloads import RemoteFileNotFoundError, download_file # noqa: F401
150 changes: 150 additions & 0 deletions src/ansys/dynamicreporting/core/examples/downloads.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
"""Functions to download sample datasets from the Ansys example data repository."""

import logging
import os
from pathlib import Path
import re
from urllib import parse, request

import ansys.dynamicreporting.core as adr


class RemoteFileNotFoundError(FileNotFoundError):
"""Raised on an attempt to download a non-existent remote file."""

def __init__(self, url):
"""Initializes RemoteFileNotFoundError."""
super().__init__(f"{url} does not exist.")


def uri_validator(url: str) -> bool:
try:
result = parse.urlparse(url)
return all([result.scheme, result.netloc])
except AttributeError:
return False


def check_url_exists(url: str) -> bool:
"""Check if a URL exists.

Parameters
----------
url : str
URL to check

Returns
-------
bool
True if the URL exists, False otherwise
"""
if uri_validator(url) is False:
logging.debug(f"Passed url is invalid: {url}\n")
return False
try:
with request.urlopen(url) as response:
return response.status == 200
except Exception:
return False


def get_url_content(url: str) -> str:
margalva marked this conversation as resolved.
Show resolved Hide resolved
"""Get the content of a URL.

Parameters
----------
url : str
URL to get content from

Returns
-------
str
content of the URL
"""
with request.urlopen(url) as response:
return response.read()


def _get_file_url(file_name: str, directory: str | None = None) -> str:
"""Get file URL."""
if directory:
return (
"https://github.com/ansys/example-data/raw/refs/heads/master/pydynamicreporting/"
f"{directory}/{file_name}"
)
return f"https://github.com/ansys/example-data/raw/refs/heads/master/pydynamicreporting/{file_name}"


def _retrieve_file(
url: str,
file_name: str,
save_path: str | None = None,
) -> str:
"""Download specified file from specified URL."""
file_name = os.path.basename(file_name)
if save_path is None:
save_path = os.getcwd()
else:
save_path = os.path.abspath(save_path)
local_path = os.path.join(save_path, file_name)
# First check if file has already been downloaded
logging.debug(f"Checking if {local_path} already exists...")
if os.path.isfile(local_path) or os.path.isdir(local_path):
logging.debug("File already exists.")
return local_path

logging.debug("File does not exist. Downloading specified file...")

# Check if save path exists
if not os.path.exists(save_path):
os.makedirs(save_path)

# Download file
logging.debug(f'Downloading URL: "{url}"')
content = get_url_content(url)
with open(local_path, "wb") as f:
f.write(content)

logging.debug("Download successful.")
return local_path


def download_file(
file_name: str,
directory: str | None = None,
save_path: str | None = None,
) -> str:
"""Download specified example file from the Ansys example data repository.

Parameters
----------
file_name : str
File to download.
directory : str, optional
Ansys example data repository directory where specified file is located. If not specified, looks for the file
in the root directory of the repository.
save_path : str, optional
Path to download the specified file to.

Raises
------
RemoteFileNotFoundError
If remote file does not exist.

Returns
-------
str
file path of the downloaded or already existing file.

Examples
--------
>>> from ansys.dynamicreporting.core import examples
>>> file_path = examples.download_file("bracket.iges", "geometry")
>>> file_path
'/home/user/.local/share/adr_core/examples/bracket.iges'
"""

url = _get_file_url(file_name, directory)
if not check_url_exists(url):
raise RemoteFileNotFoundError(url)
return _retrieve_file(url, file_name, save_path)
41 changes: 41 additions & 0 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import pytest
margalva marked this conversation as resolved.
Show resolved Hide resolved

import ansys.dynamicreporting.core.examples as examples


@pytest.mark.ado_test
def test_download_image(adr_service_create, request) -> None:
filter_str = "A|i_type|cont|image"
img_items = adr_service_create.query(query_type="Item", filter=filter_str)
my_img = adr_service_create.create_item()
my_img.item_image = examples.download_file("enthalpy_001.png", "input_data")
new_img_items = adr_service_create.query(query_type="Item", filter=filter_str)
assert len(new_img_items) == (len(img_items) + 1)


@pytest.mark.ado_test
def test_download_error(adr_service_create, request) -> None:
my_img = adr_service_create.create_item()
success = False
try:
my_img.item_image = examples.download_file("does_not_exist.png", "input_data")
except examples.RemoteFileNotFoundError:
success = True
assert success


@pytest.mark.ado_test
def test_download_image_newdir(adr_service_create, request) -> None:
filter_str = "A|i_type|cont|image"
img_items = adr_service_create.query(query_type="Item", filter=filter_str)
my_img = adr_service_create.create_item()
my_img.item_image = examples.download_file("enthalpy_001.png", "input_data", "new_dir")
new_img_items = adr_service_create.query(query_type="Item", filter=filter_str)
assert len(new_img_items) == (len(img_items) + 1)


@pytest.mark.ado_test
def test_url_validation() -> None:
is_valid = examples.downloads.uri_validator("http://google.com")
is_not_valid = examples.downloads.uri_validator("google.com")
assert is_valid and (not is_not_valid)
Loading