From ebf4f75c719da4777791cd96f5f0c648368131ca Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:45:07 -0400 Subject: [PATCH 01/50] Update uv.lock --- uv.lock | 614 ++++++++++++++++++++++++++------------------------------ 1 file changed, 285 insertions(+), 329 deletions(-) diff --git a/uv.lock b/uv.lock index b1ca22c20..683aef628 100644 --- a/uv.lock +++ b/uv.lock @@ -2,8 +2,7 @@ version = 1 revision = 2 requires-python = ">=3.10" resolution-markers = [ - "python_full_version >= '3.13'", - "python_full_version == '3.12.*'", + "python_full_version >= '3.12'", "python_full_version == '3.11.*'", "python_full_version < '3.11'", ] @@ -31,13 +30,13 @@ wheels = [ [[package]] name = "ansys-dpf-core" -version = "0.13.0" +version = "0.13.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "google-api-python-client" }, { name = "grpcio" }, { name = "importlib-metadata" }, - { name = "numpy" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "packaging" }, { name = "protobuf" }, { name = "psutil" }, @@ -45,10 +44,10 @@ dependencies = [ { name = "tqdm" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/95/1ffd62da9ff7a1715d0e30731e49b987f56ced727c22298f1721e0cb9f7d/ansys_dpf_core-0.13.0-py3-none-any.whl", hash = "sha256:765195ee06db16a124568384caafb334a5d5b777639fd99564abc3f0c7872ea5", size = 2204044, upload-time = "2024-08-02T07:29:10.13Z" }, - { url = "https://files.pythonhosted.org/packages/31/3b/bd2b9b05f1cb1b71351137e7dfc259f634a636a5dcb3ed274885f4f72fcd/ansys_dpf_core-0.13.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:1cf4838a6d0c0efd8cd649c311dd8fc80b404aeaacd0d20fc60041ee27904f27", size = 12628123, upload-time = "2024-08-02T07:29:12.42Z" }, - { url = "https://files.pythonhosted.org/packages/12/65/fe57fe2cbabd600e59f82a06eef5b074f28070bbade666b118d6f7cea598/ansys_dpf_core-0.13.0-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:31c5d45800176db40142f9e9f0f2b797b5a02aba3323951194349b9e792a8472", size = 12628125, upload-time = "2024-08-02T07:29:14.708Z" }, - { url = "https://files.pythonhosted.org/packages/55/d5/c55d4844eb3cba5810f508d1efe2817495e9a1e32d297b747e2dbc89f9ac/ansys_dpf_core-0.13.0-py3-none-win_amd64.whl", hash = "sha256:70ccecd50baf757f1abb88562298df2b66c78a08e0d4124d29bbf95af786372e", size = 6975131, upload-time = "2024-08-02T07:29:17.557Z" }, + { url = "https://files.pythonhosted.org/packages/a8/5f/61cc0d325836e2a7a421fe163aa8130396ec8c09e101bfe7cd6aced48902/ansys_dpf_core-0.13.8-py3-none-any.whl", hash = "sha256:94ffee67a9fe47a09f25de6652106f9dfbe6c43e098ae6cf8190b0948a4fe7e5", size = 2462508, upload-time = "2025-05-21T09:36:36.514Z" }, + { url = "https://files.pythonhosted.org/packages/82/75/b63c7ef4ab091c04c86c362f89add7f8c82b59ef7783b225ce3b3b829a3e/ansys_dpf_core-0.13.8-py3-none-manylinux1_x86_64.whl", hash = "sha256:37eb44e87618c60f128838e115d3db72b27c82e61a434bfb31adf2a5e5921aa6", size = 13400205, upload-time = "2025-05-21T09:36:38.108Z" }, + { url = "https://files.pythonhosted.org/packages/05/53/dc66c2010de5ea0f22a28bdf8f33e86ca61a8141d926352e9ec48f46ccf8/ansys_dpf_core-0.13.8-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:28134eaaa10a2bdf1a86103682832ebe9781be80ec5b0432f6345d59fd38f874", size = 13400211, upload-time = "2025-05-21T09:36:40.616Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6e/5fc6dfa28061bf91678cb3c70eacf3cbdfd658ea17274c5db1484613827d/ansys_dpf_core-0.13.8-py3-none-win_amd64.whl", hash = "sha256:7fad41a7102abcef02c9a865591b07581f2328ea2cdbb45db05490eac435786c", size = 7629481, upload-time = "2025-05-21T09:36:43.154Z" }, ] [[package]] @@ -60,10 +59,12 @@ dependencies = [ { name = "django-guardian" }, { name = "djangorestframework" }, { name = "docker" }, - { name = "filelock" }, - { name = "numpy" }, + { name = "docutils" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pandas" }, { name = "pillow" }, + { name = "psutil" }, { name = "psycopg", extra = ["binary"] }, { name = "pypng" }, { name = "python-dateutil" }, @@ -107,7 +108,7 @@ test-extra = [ [package.metadata] requires-dist = [ - { name = "ansys-dpf-core", marker = "extra == 'test-extra'", specifier = "==0.13.0" }, + { name = "ansys-dpf-core", marker = "extra == 'test-extra'", specifier = "==0.13.8" }, { name = "ansys-sphinx-theme", marker = "extra == 'doc'", specifier = ">=1.1.1" }, { name = "black", marker = "extra == 'dev'", specifier = ">=25.0.0" }, { name = "build", marker = "extra == 'dev'" }, @@ -115,7 +116,7 @@ requires-dist = [ { name = "django-guardian", specifier = "~=2.4" }, { name = "djangorestframework", specifier = "~=3.15" }, { name = "docker", specifier = ">=7.1.0" }, - { name = "filelock", specifier = ">=3.7.1" }, + { name = "docutils", specifier = ">=0.21" }, { name = "ipdb", marker = "extra == 'dev'" }, { name = "ipython", marker = "extra == 'dev'" }, { name = "isort", marker = "extra == 'dev'", specifier = ">=6.0.0" }, @@ -125,6 +126,7 @@ requires-dist = [ { name = "pandas", specifier = ">=2.0" }, { name = "pillow", specifier = ">=9.3.0" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.0.1" }, + { name = "psutil", specifier = ">=6.0.0" }, { name = "psycopg", extras = ["binary"], specifier = ">=3.2.3" }, { name = "pypng", specifier = ">=0.20220715.0" }, { name = "pytest", marker = "extra == 'test'", specifier = ">=8.3.3" }, @@ -132,7 +134,7 @@ requires-dist = [ { name = "python-dateutil", specifier = ">=2.8.0" }, { name = "python-pptx", specifier = "==0.6.19" }, { name = "pytz", specifier = ">=2021.3" }, - { name = "pyvista", marker = "extra == 'test-extra'", specifier = "==0.44.1" }, + { name = "pyvista", marker = "extra == 'test-extra'", specifier = "==0.45.2" }, { name = "requests", specifier = ">=2.32" }, { name = "sphinx", marker = "extra == 'doc'", specifier = ">=8.0.2" }, { name = "sphinx-copybutton", marker = "extra == 'doc'", specifier = ">=0.5.2" }, @@ -141,7 +143,7 @@ requires-dist = [ { name = "twine", marker = "extra == 'dev'" }, { name = "tzlocal", specifier = "~=5.0" }, { name = "urllib3", specifier = "<3.0.0" }, - { name = "vtk", marker = "extra == 'test-extra'", specifier = "==9.4.0" }, + { name = "vtk", marker = "extra == 'test-extra'", specifier = "==9.4.2" }, ] provides-extras = ["test", "test-extra", "doc", "dev"] @@ -264,22 +266,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl", hash = "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", size = 22950, upload-time = "2024-10-06T17:22:23.299Z" }, ] -[[package]] -name = "cachetools" -version = "5.5.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380, upload-time = "2025-02-20T21:01:19.524Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080, upload-time = "2025-02-20T21:01:16.647Z" }, -] - [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -419,7 +412,8 @@ name = "contourpy" version = "1.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } wheels = [ @@ -483,66 +477,66 @@ wheels = [ [[package]] name = "coverage" -version = "7.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/06/d1/7b18a2e0d2994e4e108dadf16580ec192e0a9c65f7456ccb82ced059f9bf/coverage-7.9.0.tar.gz", hash = "sha256:1a93b43de2233a7670a8bf2520fed8ebd5eea6a65b47417500a9d882b0533fa2", size = 813385, upload-time = "2025-06-11T23:23:34.004Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/37/25/c83935ed228bd0ce277a9a92b505a4f67b0b15ba0344680974a77452c5dd/coverage-7.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3d494fa4256e3cb161ca1df14a91d2d703c27d60452eb0d4a58bb05f52f676e4", size = 211940, upload-time = "2025-06-11T23:21:47.353Z" }, - { url = "https://files.pythonhosted.org/packages/36/42/c58ca1fec2a346ad12356fac955a9b6d848ab37f632a7cb1bc7476efcf90/coverage-7.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b613efceeabf242978d14e1a65626ec3be67c5261918a82a985f56c2a05475ee", size = 212329, upload-time = "2025-06-11T23:21:50.216Z" }, - { url = "https://files.pythonhosted.org/packages/64/0a/6b61e4348cf7b0a70f7995247cde5cc4b5ef0b61d9718109896c77d9ed0e/coverage-7.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673a4d2cb7ec78e1f2f6f41039f6785f27bca0f6bc0e722b53a58286d12754e1", size = 241447, upload-time = "2025-06-11T23:21:51.757Z" }, - { url = "https://files.pythonhosted.org/packages/a9/1e/5f7060b909352cba70d34be0e34619659c0ddbef426665e036d5d3046b3c/coverage-7.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1edc2244932e9fed92ad14428b9480a97ecd37c970333688bd35048f6472f260", size = 239322, upload-time = "2025-06-11T23:21:53.826Z" }, - { url = "https://files.pythonhosted.org/packages/f5/78/f4ba669c9bf15b537136b663ccb846032cfb73e28b59458ef6899f18fe07/coverage-7.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec8b92a7617faa2017bd44c94583830bab8be175722d420501680abc4f5bc794", size = 240467, upload-time = "2025-06-11T23:21:55.415Z" }, - { url = "https://files.pythonhosted.org/packages/79/38/3246ea3ac68dc6f85afac0cb0362d3703647378b9882d55796c71fe83a1a/coverage-7.9.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d8f3ca1f128f11812d3baf0a482e7f36ffb856ac1ae14de3b5d1adcfb7af955d", size = 240376, upload-time = "2025-06-11T23:21:57.108Z" }, - { url = "https://files.pythonhosted.org/packages/c0/58/ef1f20afbaf9affe2941e7b077a8cf08075c6e3fe5e1dfc3160908b6a1de/coverage-7.9.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c30eed34eb8206d9b8c2d0d9fa342fa98e10f34b1e9e1eb05f79ccbf4499c8ff", size = 239046, upload-time = "2025-06-11T23:21:58.709Z" }, - { url = "https://files.pythonhosted.org/packages/09/ba/d510b05b3ca0da8fe746acf8ac815b2d560d6c4d5c4e0f6eafb2ec27dc33/coverage-7.9.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:24e6f8e5f125cd8bff33593a484a079305c9f0be911f76c6432f580ade5c1a17", size = 239318, upload-time = "2025-06-11T23:21:59.987Z" }, - { url = "https://files.pythonhosted.org/packages/82/c7/328a412e3bd78c049180df3f4374bb13a332ed8731ff66f49578d5ebf98c/coverage-7.9.0-cp310-cp310-win32.whl", hash = "sha256:a1b0317b4a8ff4d3703cd7aa642b4f963a71255abe4e878659f768238fab6602", size = 214430, upload-time = "2025-06-11T23:22:01.663Z" }, - { url = "https://files.pythonhosted.org/packages/db/a5/0e788cc4796989d77bfb6b1c58819edc2c65522926f0c08cfe42d1529f2b/coverage-7.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:512b1ea57a11dfa23b7f3d8fe8690fcf8cd983a70ae4c2c262cf5c972618fa15", size = 215350, upload-time = "2025-06-11T23:22:02.957Z" }, - { url = "https://files.pythonhosted.org/packages/9d/91/721a7df15263babfe89caf535a08bacbadebdef87338cf37d40f7400161b/coverage-7.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:55b7b9df45174956e0f719a56cf60c0cb4a7f155668881d00de6384e2a3402f4", size = 212055, upload-time = "2025-06-11T23:22:04.389Z" }, - { url = "https://files.pythonhosted.org/packages/8d/d6/1f4c1eae67e698a8535ede02a6958a7587d06869d33a9b134ecc0e17ee07/coverage-7.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87bceebbc91a58c9264c43638729fcb45910805b9f86444f93654d988305b3a2", size = 212445, upload-time = "2025-06-11T23:22:06.044Z" }, - { url = "https://files.pythonhosted.org/packages/bd/48/c375a6e6a266efa2d5fbf9b04eac88c87430d1a337b4f383ea8beeeedd44/coverage-7.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81da3b6e289bf9fc7dc159ab6d5222f5330ac6e94a6d06f147ba46e53fa6ec82", size = 245010, upload-time = "2025-06-11T23:22:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/7a/43/ec070ad02a1ee10837555a852b6fa256f8c71a953c209488e027673fc5b6/coverage-7.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b361684a91224d4362879c1b1802168d2435ff76666f1b7ba52fc300ad832dbc", size = 242725, upload-time = "2025-06-11T23:22:08.64Z" }, - { url = "https://files.pythonhosted.org/packages/fa/ff/8b8efbd058dd59b489d9c5e27ba5766e895c396dd3bd1b78bebef9808c5f/coverage-7.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9a384ea4f77ac0a7e36c9a805ed95ef10f423bdb68b4e9487646cdf548a6a05", size = 244527, upload-time = "2025-06-11T23:22:10.416Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e7/3863f458a3af009a4817656f5b56fa90c7e363d73fef338601b275e979c4/coverage-7.9.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:38a5642aa82ea6de0e4331e346f5ba188a9fdb7d727e00199f55031b85135d0a", size = 244174, upload-time = "2025-06-11T23:22:12.046Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f0/2ff1fa06ccd3c3d653e352b10ddeec511b018890b28dbd3c29b6ea3f742e/coverage-7.9.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8c5ff4ca4890c0b57d3e80850534609493280c0f9e6ea2bd314b10cb8cbd76e0", size = 242227, upload-time = "2025-06-11T23:22:13.438Z" }, - { url = "https://files.pythonhosted.org/packages/32/e2/bae13555436f1d0278e70cfe22a0980eab9809e89361e859c96ffa788cb9/coverage-7.9.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cd052a0c4727ede06393da3c1df1ae6ef6c079e6bdfefb39079877404b3edc22", size = 242815, upload-time = "2025-06-11T23:22:14.723Z" }, - { url = "https://files.pythonhosted.org/packages/20/7c/e1b5b3313c1e3a5e8f8ced567fee67f18c8f18cebee8af0d69052f445a55/coverage-7.9.0-cp311-cp311-win32.whl", hash = "sha256:f73fd1128165e1d665cb7f863a91d00f073044a672c7dfa04ab400af4d1a9226", size = 214469, upload-time = "2025-06-11T23:22:16.187Z" }, - { url = "https://files.pythonhosted.org/packages/6a/c9/0034d3ccbb7b8f80b1ce8a927ea06e2ba265bd0ba4a9a95a83026ac78dfd/coverage-7.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:dd62d62e782d3add529c8e7943f5600efd0d07dadf3819e5f9917edb4acf85d8", size = 215407, upload-time = "2025-06-11T23:22:17.611Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e1/7473bf679a43638c5ccba6228f45f68d33c3b7414ffae757dbb0bb2f1127/coverage-7.9.0-cp311-cp311-win_arm64.whl", hash = "sha256:f75288785cc9a67aff3b04dafd8d0f0be67306018b224d319d23867a161578d6", size = 213778, upload-time = "2025-06-11T23:22:19.217Z" }, - { url = "https://files.pythonhosted.org/packages/dd/6b/7bdef79e79076c7e3303ce2453072528ed13988210fb7a8702bb3d98ea8c/coverage-7.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:969ed1ed0ab0325b50af3204f9024782180e64fb281f5a2952f479ec60a02aba", size = 212252, upload-time = "2025-06-11T23:22:20.662Z" }, - { url = "https://files.pythonhosted.org/packages/08/fe/7e08dd50c3c3cfdbe822ee11e24da9f418983faefb4f5e52fbffae5beeb2/coverage-7.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1abd41781c874e716aaeecb8b27db5f4f2bc568f2ed8d41228aa087d567674f0", size = 212491, upload-time = "2025-06-11T23:22:22.002Z" }, - { url = "https://files.pythonhosted.org/packages/d4/65/9793cf61b3e4c5647e70aabd5b9470958ffd341c42f90730beeb4d21af9c/coverage-7.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eb6e99487dffd28c88a4fc2ea4286beaf0207a43388775900c93e56cc5a8ae3", size = 246294, upload-time = "2025-06-11T23:22:23.297Z" }, - { url = "https://files.pythonhosted.org/packages/2a/c9/fc61695132da06a34b27a49e853010a80d66a5534a1dfa770cb38aca71c0/coverage-7.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c425c85ddb62b32d44f83fb20044fe32edceceee1db1f978c062eec020a73ea5", size = 243311, upload-time = "2025-06-11T23:22:24.966Z" }, - { url = "https://files.pythonhosted.org/packages/62/0e/559a86887580d0de390e018bddfa632ae0762eeeb065bb5557f319071527/coverage-7.9.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0a1f7676bc90ceba67caa66850d689947d586f204ccf6478400c2bf39da5790", size = 245503, upload-time = "2025-06-11T23:22:26.316Z" }, - { url = "https://files.pythonhosted.org/packages/45/09/344d012dc91e60b8c7afee11ffae18338780c703a5b5fb32d8d82987e7cb/coverage-7.9.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f17055c50768d710d6abc789c9469d0353574780935e1381b83e63edc49ff530", size = 245313, upload-time = "2025-06-11T23:22:27.936Z" }, - { url = "https://files.pythonhosted.org/packages/d2/2d/151b23e82aaea28aa7e3c0390d893bd1aef685866132aad36034f7d462b8/coverage-7.9.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:298d2917a6bfadbb272e08545ed026af3965e4d2fe71e3f38bf0a816818b226e", size = 243495, upload-time = "2025-06-11T23:22:29.72Z" }, - { url = "https://files.pythonhosted.org/packages/74/5c/0da7fd4ad44259b4b61bd429dc642c6511314a356ffa782b924bd1ea9e5c/coverage-7.9.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d9be5d26e5f817d478506e4d3c4ff7b92f17d980670b4791bf05baaa37ce2f88", size = 244727, upload-time = "2025-06-11T23:22:31.112Z" }, - { url = "https://files.pythonhosted.org/packages/de/08/6ccf2847c5c0d8fcc153bd8f4341d89ab50c85e01a15cabe4a546d3e943e/coverage-7.9.0-cp312-cp312-win32.whl", hash = "sha256:dc2784edd9ac9fe8692fc5505667deb0b05d895c016aaaf641031ed4a5f93d53", size = 214636, upload-time = "2025-06-11T23:22:33.257Z" }, - { url = "https://files.pythonhosted.org/packages/79/fa/ae2c14d49475215372772f7638c333deaaacda8f3c5717a75377d1992c82/coverage-7.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:18223198464a6d5549db1934cf77a15deb24bb88652c4f5f7cb21cd3ad853704", size = 215448, upload-time = "2025-06-11T23:22:35.125Z" }, - { url = "https://files.pythonhosted.org/packages/62/a9/45309219ba08b89cae84b2cb4ccfed8f941850aa7721c4914282fb3c1081/coverage-7.9.0-cp312-cp312-win_arm64.whl", hash = "sha256:3b00194ff3c84d4b821822ff6c041f245fc55d0d5c7833fc4311d082e97595e8", size = 213817, upload-time = "2025-06-11T23:22:36.557Z" }, - { url = "https://files.pythonhosted.org/packages/0b/59/449eb05f795d0050007b57a4efee79b540fa6fcccad813a191351964a001/coverage-7.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:122c60e92ab66c9c88e17565f67a91b3b3be5617cb50f73cfd34a4c60ed4aab0", size = 212271, upload-time = "2025-06-11T23:22:38.305Z" }, - { url = "https://files.pythonhosted.org/packages/e0/3b/26852a4fb719a6007b0169c1b52116ed14b61267f0bf3ba1e23db516f352/coverage-7.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:813c11b367a6b3cf37212ec36b230f8d086c22b69dbf62877b40939fb2c79e74", size = 212538, upload-time = "2025-06-11T23:22:39.665Z" }, - { url = "https://files.pythonhosted.org/packages/f6/80/99f82896119f36984a5b9189e71c7310fc036613276560b5884b5ee890d7/coverage-7.9.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f05e0f5e87f23d43fefe49e86655c6209dd4f9f034786b983e6803cf4554183", size = 245705, upload-time = "2025-06-11T23:22:41.103Z" }, - { url = "https://files.pythonhosted.org/packages/a9/29/0b007deb096dd527c42e933129a8e4d5f9f1026f4953979c3a1e60e7ea9f/coverage-7.9.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62f465886fa4f86d5515da525aead97c5dff13a5cf997fc4c5097a1a59e063b2", size = 242918, upload-time = "2025-06-11T23:22:42.88Z" }, - { url = "https://files.pythonhosted.org/packages/6f/eb/273855b57c7fb387dd9787f250b8b333ba8c1c100877c21e32eb1b24ff29/coverage-7.9.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:549ea4ca901595bbe3270e1afdef98bf5d4d5791596efbdc90b00449a2bb1f91", size = 244902, upload-time = "2025-06-11T23:22:44.563Z" }, - { url = "https://files.pythonhosted.org/packages/20/57/4e411b47dbfd831538ecf9e5f407e42888b0c56aedbfe0ea7b102a787559/coverage-7.9.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8cae1d4450945c74a6a65a09864ed3eaa917055cf70aa65f83ac1b9b0d8d5f9a", size = 245069, upload-time = "2025-06-11T23:22:46.352Z" }, - { url = "https://files.pythonhosted.org/packages/91/75/b24cf5703fb325fc4b1899d89984dac117b99e757b9fadd525cad7ecc020/coverage-7.9.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d7b263910234c0d5ec913ec79ca921152fe874b805a7bcaf67118ef71708e5d2", size = 243040, upload-time = "2025-06-11T23:22:48.147Z" }, - { url = "https://files.pythonhosted.org/packages/c7/e1/9495751d5315c3d76ee2c7b5dbc1935ab891d45ad585e1910a333dbdef43/coverage-7.9.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7d7b7425215963da8f5968096a20c5b5c9af4a86a950fcc25dcc2177ab33e9e5", size = 244424, upload-time = "2025-06-11T23:22:49.574Z" }, - { url = "https://files.pythonhosted.org/packages/94/2a/ee504188a586da2379939f37fdc69047d9c46d35c34d1196f2605974a17d/coverage-7.9.0-cp313-cp313-win32.whl", hash = "sha256:e7dcfa92867b0c53d2e22e985c66af946dc09e8bb13c556709e396e90a0adf5c", size = 214677, upload-time = "2025-06-11T23:22:51.394Z" }, - { url = "https://files.pythonhosted.org/packages/80/2b/5eab6518643c7560fe180ba5e0f35a0be3d4fc0a88aa6601120407b1fd03/coverage-7.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:aa34ca040785a2b768da489df0c036364d47a6c1c00bdd8f662b98fd3277d3d4", size = 215482, upload-time = "2025-06-11T23:22:53.151Z" }, - { url = "https://files.pythonhosted.org/packages/fd/7f/9c9c8b736c4f40d7247bea8339afac40d8f6465491440608b3d73c10ffce/coverage-7.9.0-cp313-cp313-win_arm64.whl", hash = "sha256:9c5dcb5cd3c52d84c5f52045e1c87c16bf189c2fbfa57cc0d811a3b4059939df", size = 213852, upload-time = "2025-06-11T23:22:54.568Z" }, - { url = "https://files.pythonhosted.org/packages/e5/83/056464aec8b360dee6f4d7a517dc5ae5a9f462ff895ff536588b42f95b2d/coverage-7.9.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b52d2fdc1940f90c4572bd48211475a7b102f75a7f9a5e6cfc6e3da7dc380c44", size = 212994, upload-time = "2025-06-11T23:22:56.173Z" }, - { url = "https://files.pythonhosted.org/packages/a3/87/f0291ecaa6baaaedbd428cf8b7e1d16b5dc010718fe7739cce955149ef83/coverage-7.9.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4cc555a3e6ceb8841df01a4634374f5f9635e661f5c307da00bce19819e8bcdf", size = 213212, upload-time = "2025-06-11T23:22:58.051Z" }, - { url = "https://files.pythonhosted.org/packages/16/a0/9eb39541774a5beb662dc4ae98fee23afb947414b6aa1443b53d2ad3ea05/coverage-7.9.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:244f613617876b7cd32a097788d49c952a8f1698afb25275b2a825a4e895854e", size = 256453, upload-time = "2025-06-11T23:22:59.485Z" }, - { url = "https://files.pythonhosted.org/packages/93/33/d0e99f4c809334dfed20f17234080a9003a713ddb80e33ad22697a8aa8e5/coverage-7.9.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c335d77539e66bc6f83e8f1ef207d038129d9b9acd9dc9f0ca42fa9eedf564a", size = 252674, upload-time = "2025-06-11T23:23:00.984Z" }, - { url = "https://files.pythonhosted.org/packages/0b/3a/d2a64e7ee5eb783e44e6ca404f8fc2a45afef052ed6593afb4ce9663dae6/coverage-7.9.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b335c7077c8da7bb8173d4f9ebd90ff1a97af6a6bec4fc4e6db4856ae80b31e", size = 254830, upload-time = "2025-06-11T23:23:02.445Z" }, - { url = "https://files.pythonhosted.org/packages/e2/6a/9de640f8e2b097d155532d1bc16eb9c5186fccc7c4b8148fe1dd2520875a/coverage-7.9.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:01cbc2c36895b7ab906514042c92b3fc9dd0526bf1c3251cb6aefd9c71ae6dda", size = 256060, upload-time = "2025-06-11T23:23:03.89Z" }, - { url = "https://files.pythonhosted.org/packages/07/72/928fa3583b9783fc32e3dfafb6cc0cf73bdd73d1dc41e3a973f203c6aeff/coverage-7.9.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1ac62880a9dff0726a193ce77a1bcdd4e8491009cb3a0510d31381e8b2c46d7a", size = 254174, upload-time = "2025-06-11T23:23:05.366Z" }, - { url = "https://files.pythonhosted.org/packages/ad/01/2fd0785f8768693b748e36b442352bc26edf3391246eedcc80d480d06da1/coverage-7.9.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:95314eb306cf54af3d1147e27ba008cf78eed6f1309a1310772f4f05b12c9c65", size = 255011, upload-time = "2025-06-11T23:23:07.212Z" }, - { url = "https://files.pythonhosted.org/packages/b7/49/1d0120cfa24e001e0d38795388914183c48cd86fc8640ca3b01337831917/coverage-7.9.0-cp313-cp313t-win32.whl", hash = "sha256:c5cbf3ddfb68de8dc8ce33caa9321df27297a032aeaf2e99b278f183fb4ebc37", size = 215349, upload-time = "2025-06-11T23:23:09.037Z" }, - { url = "https://files.pythonhosted.org/packages/9f/48/7625c09621a206fff0b51fcbcf5d6c1162ab10a5ffa546fc132f01c9132b/coverage-7.9.0-cp313-cp313t-win_amd64.whl", hash = "sha256:e3ec9e1525eb7a0f89d31083539b398d921415d884e9f55400002a1e9fe0cf63", size = 216516, upload-time = "2025-06-11T23:23:11.083Z" }, - { url = "https://files.pythonhosted.org/packages/bb/50/048b55c34985c3aafcecb32cced3abc4291969bfd967dbcaed95cfc26b2a/coverage-7.9.0-cp313-cp313t-win_arm64.whl", hash = "sha256:a02efe6769f74245ce476e89db3d4e110db07b4c0c3d3f81728e2464bbbbcb8e", size = 214308, upload-time = "2025-06-11T23:23:12.522Z" }, - { url = "https://files.pythonhosted.org/packages/e8/b6/d16966f9439ccc3007e1740960d241420d6ba81502642a4be1da1672a103/coverage-7.9.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:ccf1540a0e82ff525844880f988f6caaa2d037005e57bfe203b71cac7626145d", size = 203927, upload-time = "2025-06-11T23:23:30.913Z" }, - { url = "https://files.pythonhosted.org/packages/70/0d/534c1e35cb7688b5c40de93fcca07e3ddc0287659ff85cd376b1dd3f770f/coverage-7.9.0-py3-none-any.whl", hash = "sha256:79ea9a26b27c963cdf541e1eb9ac05311b012bc367d0e31816f1833b06c81c02", size = 203917, upload-time = "2025-06-11T23:23:32.413Z" }, +version = "7.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/e0/98670a80884f64578f0c22cd70c5e81a6e07b08167721c7487b4d70a7ca0/coverage-7.9.1.tar.gz", hash = "sha256:6cf43c78c4282708a28e466316935ec7489a9c487518a77fa68f716c67909cec", size = 813650, upload-time = "2025-06-13T13:02:28.627Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/78/1c1c5ec58f16817c09cbacb39783c3655d54a221b6552f47ff5ac9297603/coverage-7.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc94d7c5e8423920787c33d811c0be67b7be83c705f001f7180c7b186dcf10ca", size = 212028, upload-time = "2025-06-13T13:00:29.293Z" }, + { url = "https://files.pythonhosted.org/packages/98/db/e91b9076f3a888e3b4ad7972ea3842297a52cc52e73fd1e529856e473510/coverage-7.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16aa0830d0c08a2c40c264cef801db8bc4fc0e1892782e45bcacbd5889270509", size = 212420, upload-time = "2025-06-13T13:00:34.027Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d0/2b3733412954576b0aea0a16c3b6b8fbe95eb975d8bfa10b07359ead4252/coverage-7.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf95981b126f23db63e9dbe4cf65bd71f9a6305696fa5e2262693bc4e2183f5b", size = 241529, upload-time = "2025-06-13T13:00:35.786Z" }, + { url = "https://files.pythonhosted.org/packages/b3/00/5e2e5ae2e750a872226a68e984d4d3f3563cb01d1afb449a17aa819bc2c4/coverage-7.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f05031cf21699785cd47cb7485f67df619e7bcdae38e0fde40d23d3d0210d3c3", size = 239403, upload-time = "2025-06-13T13:00:37.399Z" }, + { url = "https://files.pythonhosted.org/packages/37/3b/a2c27736035156b0a7c20683afe7df498480c0dfdf503b8c878a21b6d7fb/coverage-7.9.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb4fbcab8764dc072cb651a4bcda4d11fb5658a1d8d68842a862a6610bd8cfa3", size = 240548, upload-time = "2025-06-13T13:00:39.647Z" }, + { url = "https://files.pythonhosted.org/packages/98/f5/13d5fc074c3c0e0dc80422d9535814abf190f1254d7c3451590dc4f8b18c/coverage-7.9.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0f16649a7330ec307942ed27d06ee7e7a38417144620bb3d6e9a18ded8a2d3e5", size = 240459, upload-time = "2025-06-13T13:00:40.934Z" }, + { url = "https://files.pythonhosted.org/packages/36/24/24b9676ea06102df824c4a56ffd13dc9da7904478db519efa877d16527d5/coverage-7.9.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cea0a27a89e6432705fffc178064503508e3c0184b4f061700e771a09de58187", size = 239128, upload-time = "2025-06-13T13:00:42.343Z" }, + { url = "https://files.pythonhosted.org/packages/be/05/242b7a7d491b369ac5fee7908a6e5ba42b3030450f3ad62c645b40c23e0e/coverage-7.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e980b53a959fa53b6f05343afbd1e6f44a23ed6c23c4b4c56c6662bbb40c82ce", size = 239402, upload-time = "2025-06-13T13:00:43.634Z" }, + { url = "https://files.pythonhosted.org/packages/73/e0/4de7f87192fa65c9c8fbaeb75507e124f82396b71de1797da5602898be32/coverage-7.9.1-cp310-cp310-win32.whl", hash = "sha256:70760b4c5560be6ca70d11f8988ee6542b003f982b32f83d5ac0b72476607b70", size = 214518, upload-time = "2025-06-13T13:00:45.622Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ab/5e4e2fe458907d2a65fab62c773671cfc5ac704f1e7a9ddd91996f66e3c2/coverage-7.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:a66e8f628b71f78c0e0342003d53b53101ba4e00ea8dabb799d9dba0abbbcebe", size = 215436, upload-time = "2025-06-13T13:00:47.245Z" }, + { url = "https://files.pythonhosted.org/packages/60/34/fa69372a07d0903a78ac103422ad34db72281c9fc625eba94ac1185da66f/coverage-7.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95c765060e65c692da2d2f51a9499c5e9f5cf5453aeaf1420e3fc847cc060582", size = 212146, upload-time = "2025-06-13T13:00:48.496Z" }, + { url = "https://files.pythonhosted.org/packages/27/f0/da1894915d2767f093f081c42afeba18e760f12fdd7a2f4acbe00564d767/coverage-7.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba383dc6afd5ec5b7a0d0c23d38895db0e15bcba7fb0fa8901f245267ac30d86", size = 212536, upload-time = "2025-06-13T13:00:51.535Z" }, + { url = "https://files.pythonhosted.org/packages/10/d5/3fc33b06e41e390f88eef111226a24e4504d216ab8e5d1a7089aa5a3c87a/coverage-7.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37ae0383f13cbdcf1e5e7014489b0d71cc0106458878ccde52e8a12ced4298ed", size = 245092, upload-time = "2025-06-13T13:00:52.883Z" }, + { url = "https://files.pythonhosted.org/packages/0a/39/7aa901c14977aba637b78e95800edf77f29f5a380d29768c5b66f258305b/coverage-7.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69aa417a030bf11ec46149636314c24c8d60fadb12fc0ee8f10fda0d918c879d", size = 242806, upload-time = "2025-06-13T13:00:54.571Z" }, + { url = "https://files.pythonhosted.org/packages/43/fc/30e5cfeaf560b1fc1989227adedc11019ce4bb7cce59d65db34fe0c2d963/coverage-7.9.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a4be2a28656afe279b34d4f91c3e26eccf2f85500d4a4ff0b1f8b54bf807338", size = 244610, upload-time = "2025-06-13T13:00:56.932Z" }, + { url = "https://files.pythonhosted.org/packages/bf/15/cca62b13f39650bc87b2b92bb03bce7f0e79dd0bf2c7529e9fc7393e4d60/coverage-7.9.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:382e7ddd5289f140259b610e5f5c58f713d025cb2f66d0eb17e68d0a94278875", size = 244257, upload-time = "2025-06-13T13:00:58.545Z" }, + { url = "https://files.pythonhosted.org/packages/cd/1a/c0f2abe92c29e1464dbd0ff9d56cb6c88ae2b9e21becdb38bea31fcb2f6c/coverage-7.9.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e5532482344186c543c37bfad0ee6069e8ae4fc38d073b8bc836fc8f03c9e250", size = 242309, upload-time = "2025-06-13T13:00:59.836Z" }, + { url = "https://files.pythonhosted.org/packages/57/8d/c6fd70848bd9bf88fa90df2af5636589a8126d2170f3aade21ed53f2b67a/coverage-7.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a39d18b3f50cc121d0ce3838d32d58bd1d15dab89c910358ebefc3665712256c", size = 242898, upload-time = "2025-06-13T13:01:02.506Z" }, + { url = "https://files.pythonhosted.org/packages/c2/9e/6ca46c7bff4675f09a66fe2797cd1ad6a24f14c9c7c3b3ebe0470a6e30b8/coverage-7.9.1-cp311-cp311-win32.whl", hash = "sha256:dd24bd8d77c98557880def750782df77ab2b6885a18483dc8588792247174b32", size = 214561, upload-time = "2025-06-13T13:01:04.012Z" }, + { url = "https://files.pythonhosted.org/packages/a1/30/166978c6302010742dabcdc425fa0f938fa5a800908e39aff37a7a876a13/coverage-7.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:6b55ad10a35a21b8015eabddc9ba31eb590f54adc9cd39bcf09ff5349fd52125", size = 215493, upload-time = "2025-06-13T13:01:05.702Z" }, + { url = "https://files.pythonhosted.org/packages/60/07/a6d2342cd80a5be9f0eeab115bc5ebb3917b4a64c2953534273cf9bc7ae6/coverage-7.9.1-cp311-cp311-win_arm64.whl", hash = "sha256:6ad935f0016be24c0e97fc8c40c465f9c4b85cbbe6eac48934c0dc4d2568321e", size = 213869, upload-time = "2025-06-13T13:01:09.345Z" }, + { url = "https://files.pythonhosted.org/packages/68/d9/7f66eb0a8f2fce222de7bdc2046ec41cb31fe33fb55a330037833fb88afc/coverage-7.9.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8de12b4b87c20de895f10567639c0797b621b22897b0af3ce4b4e204a743626", size = 212336, upload-time = "2025-06-13T13:01:10.909Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/e07cb920ef3addf20f052ee3d54906e57407b6aeee3227a9c91eea38a665/coverage-7.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5add197315a054e92cee1b5f686a2bcba60c4c3e66ee3de77ace6c867bdee7cb", size = 212571, upload-time = "2025-06-13T13:01:12.518Z" }, + { url = "https://files.pythonhosted.org/packages/78/f8/96f155de7e9e248ca9c8ff1a40a521d944ba48bec65352da9be2463745bf/coverage-7.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:600a1d4106fe66f41e5d0136dfbc68fe7200a5cbe85610ddf094f8f22e1b0300", size = 246377, upload-time = "2025-06-13T13:01:14.87Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cf/1d783bd05b7bca5c10ded5f946068909372e94615a4416afadfe3f63492d/coverage-7.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a876e4c3e5a2a1715a6608906aa5a2e0475b9c0f68343c2ada98110512ab1d8", size = 243394, upload-time = "2025-06-13T13:01:16.23Z" }, + { url = "https://files.pythonhosted.org/packages/02/dd/e7b20afd35b0a1abea09fb3998e1abc9f9bd953bee548f235aebd2b11401/coverage-7.9.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81f34346dd63010453922c8e628a52ea2d2ccd73cb2487f7700ac531b247c8a5", size = 245586, upload-time = "2025-06-13T13:01:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/4e/38/b30b0006fea9d617d1cb8e43b1bc9a96af11eff42b87eb8c716cf4d37469/coverage-7.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:888f8eee13f2377ce86d44f338968eedec3291876b0b8a7289247ba52cb984cd", size = 245396, upload-time = "2025-06-13T13:01:19.164Z" }, + { url = "https://files.pythonhosted.org/packages/31/e4/4d8ec1dc826e16791f3daf1b50943e8e7e1eb70e8efa7abb03936ff48418/coverage-7.9.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9969ef1e69b8c8e1e70d591f91bbc37fc9a3621e447525d1602801a24ceda898", size = 243577, upload-time = "2025-06-13T13:01:22.433Z" }, + { url = "https://files.pythonhosted.org/packages/25/f4/b0e96c5c38e6e40ef465c4bc7f138863e2909c00e54a331da335faf0d81a/coverage-7.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:60c458224331ee3f1a5b472773e4a085cc27a86a0b48205409d364272d67140d", size = 244809, upload-time = "2025-06-13T13:01:24.143Z" }, + { url = "https://files.pythonhosted.org/packages/8a/65/27e0a1fa5e2e5079bdca4521be2f5dabf516f94e29a0defed35ac2382eb2/coverage-7.9.1-cp312-cp312-win32.whl", hash = "sha256:5f646a99a8c2b3ff4c6a6e081f78fad0dde275cd59f8f49dc4eab2e394332e74", size = 214724, upload-time = "2025-06-13T13:01:25.435Z" }, + { url = "https://files.pythonhosted.org/packages/9b/a8/d5b128633fd1a5e0401a4160d02fa15986209a9e47717174f99dc2f7166d/coverage-7.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:30f445f85c353090b83e552dcbbdad3ec84c7967e108c3ae54556ca69955563e", size = 215535, upload-time = "2025-06-13T13:01:27.861Z" }, + { url = "https://files.pythonhosted.org/packages/a3/37/84bba9d2afabc3611f3e4325ee2c6a47cd449b580d4a606b240ce5a6f9bf/coverage-7.9.1-cp312-cp312-win_arm64.whl", hash = "sha256:af41da5dca398d3474129c58cb2b106a5d93bbb196be0d307ac82311ca234342", size = 213904, upload-time = "2025-06-13T13:01:29.202Z" }, + { url = "https://files.pythonhosted.org/packages/d0/a7/a027970c991ca90f24e968999f7d509332daf6b8c3533d68633930aaebac/coverage-7.9.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:31324f18d5969feef7344a932c32428a2d1a3e50b15a6404e97cba1cc9b2c631", size = 212358, upload-time = "2025-06-13T13:01:30.909Z" }, + { url = "https://files.pythonhosted.org/packages/f2/48/6aaed3651ae83b231556750280682528fea8ac7f1232834573472d83e459/coverage-7.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0c804506d624e8a20fb3108764c52e0eef664e29d21692afa375e0dd98dc384f", size = 212620, upload-time = "2025-06-13T13:01:32.256Z" }, + { url = "https://files.pythonhosted.org/packages/6c/2a/f4b613f3b44d8b9f144847c89151992b2b6b79cbc506dee89ad0c35f209d/coverage-7.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef64c27bc40189f36fcc50c3fb8f16ccda73b6a0b80d9bd6e6ce4cffcd810bbd", size = 245788, upload-time = "2025-06-13T13:01:33.948Z" }, + { url = "https://files.pythonhosted.org/packages/04/d2/de4fdc03af5e4e035ef420ed26a703c6ad3d7a07aff2e959eb84e3b19ca8/coverage-7.9.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4fe2348cc6ec372e25adec0219ee2334a68d2f5222e0cba9c0d613394e12d86", size = 243001, upload-time = "2025-06-13T13:01:35.285Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e8/eed18aa5583b0423ab7f04e34659e51101135c41cd1dcb33ac1d7013a6d6/coverage-7.9.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34ed2186fe52fcc24d4561041979a0dec69adae7bce2ae8d1c49eace13e55c43", size = 244985, upload-time = "2025-06-13T13:01:36.712Z" }, + { url = "https://files.pythonhosted.org/packages/17/f8/ae9e5cce8885728c934eaa58ebfa8281d488ef2afa81c3dbc8ee9e6d80db/coverage-7.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:25308bd3d00d5eedd5ae7d4357161f4df743e3c0240fa773ee1b0f75e6c7c0f1", size = 245152, upload-time = "2025-06-13T13:01:39.303Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c8/272c01ae792bb3af9b30fac14d71d63371db227980682836ec388e2c57c0/coverage-7.9.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73e9439310f65d55a5a1e0564b48e34f5369bee943d72c88378f2d576f5a5751", size = 243123, upload-time = "2025-06-13T13:01:40.727Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d0/2819a1e3086143c094ab446e3bdf07138527a7b88cb235c488e78150ba7a/coverage-7.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37ab6be0859141b53aa89412a82454b482c81cf750de4f29223d52268a86de67", size = 244506, upload-time = "2025-06-13T13:01:42.184Z" }, + { url = "https://files.pythonhosted.org/packages/8b/4e/9f6117b89152df7b6112f65c7a4ed1f2f5ec8e60c4be8f351d91e7acc848/coverage-7.9.1-cp313-cp313-win32.whl", hash = "sha256:64bdd969456e2d02a8b08aa047a92d269c7ac1f47e0c977675d550c9a0863643", size = 214766, upload-time = "2025-06-13T13:01:44.482Z" }, + { url = "https://files.pythonhosted.org/packages/27/0f/4b59f7c93b52c2c4ce7387c5a4e135e49891bb3b7408dcc98fe44033bbe0/coverage-7.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:be9e3f68ca9edb897c2184ad0eee815c635565dbe7a0e7e814dc1f7cbab92c0a", size = 215568, upload-time = "2025-06-13T13:01:45.772Z" }, + { url = "https://files.pythonhosted.org/packages/09/1e/9679826336f8c67b9c39a359352882b24a8a7aee48d4c9cad08d38d7510f/coverage-7.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:1c503289ffef1d5105d91bbb4d62cbe4b14bec4d13ca225f9c73cde9bb46207d", size = 213939, upload-time = "2025-06-13T13:01:47.087Z" }, + { url = "https://files.pythonhosted.org/packages/bb/5b/5c6b4e7a407359a2e3b27bf9c8a7b658127975def62077d441b93a30dbe8/coverage-7.9.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0b3496922cb5f4215bf5caaef4cf12364a26b0be82e9ed6d050f3352cf2d7ef0", size = 213079, upload-time = "2025-06-13T13:01:48.554Z" }, + { url = "https://files.pythonhosted.org/packages/a2/22/1e2e07279fd2fd97ae26c01cc2186e2258850e9ec125ae87184225662e89/coverage-7.9.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9565c3ab1c93310569ec0d86b017f128f027cab0b622b7af288696d7ed43a16d", size = 213299, upload-time = "2025-06-13T13:01:49.997Z" }, + { url = "https://files.pythonhosted.org/packages/14/c0/4c5125a4b69d66b8c85986d3321520f628756cf524af810baab0790c7647/coverage-7.9.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2241ad5dbf79ae1d9c08fe52b36d03ca122fb9ac6bca0f34439e99f8327ac89f", size = 256535, upload-time = "2025-06-13T13:01:51.314Z" }, + { url = "https://files.pythonhosted.org/packages/81/8b/e36a04889dda9960be4263e95e777e7b46f1bb4fc32202612c130a20c4da/coverage-7.9.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bb5838701ca68b10ebc0937dbd0eb81974bac54447c55cd58dea5bca8451029", size = 252756, upload-time = "2025-06-13T13:01:54.403Z" }, + { url = "https://files.pythonhosted.org/packages/98/82/be04eff8083a09a4622ecd0e1f31a2c563dbea3ed848069e7b0445043a70/coverage-7.9.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a25f814591a8c0c5372c11ac8967f669b97444c47fd794926e175c4047ece", size = 254912, upload-time = "2025-06-13T13:01:56.769Z" }, + { url = "https://files.pythonhosted.org/packages/0f/25/c26610a2c7f018508a5ab958e5b3202d900422cf7cdca7670b6b8ca4e8df/coverage-7.9.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2d04b16a6062516df97969f1ae7efd0de9c31eb6ebdceaa0d213b21c0ca1a683", size = 256144, upload-time = "2025-06-13T13:01:58.19Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8b/fb9425c4684066c79e863f1e6e7ecebb49e3a64d9f7f7860ef1688c56f4a/coverage-7.9.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7931b9e249edefb07cd6ae10c702788546341d5fe44db5b6108a25da4dca513f", size = 254257, upload-time = "2025-06-13T13:01:59.645Z" }, + { url = "https://files.pythonhosted.org/packages/93/df/27b882f54157fc1131e0e215b0da3b8d608d9b8ef79a045280118a8f98fe/coverage-7.9.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52e92b01041151bf607ee858e5a56c62d4b70f4dac85b8c8cb7fb8a351ab2c10", size = 255094, upload-time = "2025-06-13T13:02:01.37Z" }, + { url = "https://files.pythonhosted.org/packages/41/5f/cad1c3dbed8b3ee9e16fa832afe365b4e3eeab1fb6edb65ebbf745eabc92/coverage-7.9.1-cp313-cp313t-win32.whl", hash = "sha256:684e2110ed84fd1ca5f40e89aa44adf1729dc85444004111aa01866507adf363", size = 215437, upload-time = "2025-06-13T13:02:02.905Z" }, + { url = "https://files.pythonhosted.org/packages/99/4d/fad293bf081c0e43331ca745ff63673badc20afea2104b431cdd8c278b4c/coverage-7.9.1-cp313-cp313t-win_amd64.whl", hash = "sha256:437c576979e4db840539674e68c84b3cda82bc824dd138d56bead1435f1cb5d7", size = 216605, upload-time = "2025-06-13T13:02:05.638Z" }, + { url = "https://files.pythonhosted.org/packages/1f/56/4ee027d5965fc7fc126d7ec1187529cc30cc7d740846e1ecb5e92d31b224/coverage-7.9.1-cp313-cp313t-win_arm64.whl", hash = "sha256:18a0912944d70aaf5f399e350445738a1a20b50fbea788f640751c2ed9208b6c", size = 214392, upload-time = "2025-06-13T13:02:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/3e/e5/c723545c3fd3204ebde3b4cc4b927dce709d3b6dc577754bb57f63ca4a4a/coverage-7.9.1-pp39.pp310.pp311-none-any.whl", hash = "sha256:db0f04118d1db74db6c9e1cb1898532c7dcc220f1d2718f058601f7c3f499514", size = 204009, upload-time = "2025-06-13T13:02:25.787Z" }, + { url = "https://files.pythonhosted.org/packages/08/b8/7ddd1e8ba9701dea08ce22029917140e6f66a859427406579fd8d0ca7274/coverage-7.9.1-py3-none-any.whl", hash = "sha256:66b974b145aa189516b6bf2d8423e888b742517d37872f6ee4c5be0073bd9a3c", size = 204000, upload-time = "2025-06-13T13:02:27.173Z" }, ] [package.optional-dependencies] @@ -707,114 +701,43 @@ wheels = [ [[package]] name = "fonttools" -version = "4.58.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b6/a9/3319c6ae07fd9dde51064ddc6d82a2b707efad8ed407d700a01091121bbc/fonttools-4.58.2.tar.gz", hash = "sha256:4b491ddbfd50b856e84b0648b5f7941af918f6d32f938f18e62b58426a8d50e2", size = 3524285, upload-time = "2025-06-06T14:50:58.643Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/6f/1f0158cd9d6168258362369fa003c58fc36f2b141a66bc805c76f28f57cc/fonttools-4.58.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4baaf34f07013ba9c2c3d7a95d0c391fcbb30748cb86c36c094fab8f168e49bb", size = 2735491, upload-time = "2025-06-06T14:49:33.45Z" }, - { url = "https://files.pythonhosted.org/packages/3d/94/d9a36a4ae1ed257ed5117c0905635e89327428cbf3521387c13bd85e6de1/fonttools-4.58.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2e26e4a4920d57f04bb2c3b6e9a68b099c7ef2d70881d4fee527896fa4f7b5aa", size = 2307732, upload-time = "2025-06-06T14:49:36.612Z" }, - { url = "https://files.pythonhosted.org/packages/37/57/0f72a9fe7c051ce316779b8721c707413c53ae75ab00f970d74c7876388f/fonttools-4.58.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0bb956d9d01ea51368415515f664f58abf96557ba3c1aae4e26948ae7c86f29", size = 4718769, upload-time = "2025-06-06T14:49:39.597Z" }, - { url = "https://files.pythonhosted.org/packages/35/dd/8be06b93e24214d7dc52fd8183dbb9e75ab9638940d84d92ced25669f4d8/fonttools-4.58.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d40af8493c80ec17a1133ef429d42f1a97258dd9213b917daae9d8cafa6e0e6c", size = 4751963, upload-time = "2025-06-06T14:49:41.391Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d3/85d60be364cea1b61f47bc8ea82d3e24cd6fb08640ad783fd2494bcaf4e0/fonttools-4.58.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:60b5cde1c76f6ded198da5608dddb1ee197faad7d2f0f6d3348ca0cda0c756c4", size = 4801368, upload-time = "2025-06-06T14:49:44.663Z" }, - { url = "https://files.pythonhosted.org/packages/9f/b9/98abf9c9c1ed67eed263f091fa1bbf0ea32ef65bb8f707c2ee106b877496/fonttools-4.58.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f8df6dc80ecc9033ca25a944ee5db7564fecca28e96383043fd92d9df861a159", size = 4909670, upload-time = "2025-06-06T14:49:46.751Z" }, - { url = "https://files.pythonhosted.org/packages/32/23/d8676da27a1a27cca89549f50b4a22c98e305d9ee4c67357515d9cb25ec4/fonttools-4.58.2-cp310-cp310-win32.whl", hash = "sha256:25728e980f5fbb67f52c5311b90fae4aaec08c3d3b78dce78ab564784df1129c", size = 2191921, upload-time = "2025-06-06T14:49:48.523Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ff/ed6452dde8fd04299ec840a4fb112597a40468106039aed9abc8e35ba7eb/fonttools-4.58.2-cp310-cp310-win_amd64.whl", hash = "sha256:d6997ee7c2909a904802faf44b0d0208797c4d751f7611836011ace165308165", size = 2236374, upload-time = "2025-06-06T14:49:50.759Z" }, - { url = "https://files.pythonhosted.org/packages/63/d0/335d12ee943b8d67847864bba98478fedf3503d8b168eeeefadd8660256a/fonttools-4.58.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:024faaf20811296fd2f83ebdac7682276362e726ed5fea4062480dd36aff2fd9", size = 2755885, upload-time = "2025-06-06T14:49:52.459Z" }, - { url = "https://files.pythonhosted.org/packages/66/c2/d8ceb8b91e3847786a19d4b93749b1d804833482b5f79bee35b68327609e/fonttools-4.58.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2faec6e7f2abd80cd9f2392dfa28c02cfd5b1125be966ea6eddd6ca684deaa40", size = 2317804, upload-time = "2025-06-06T14:49:54.581Z" }, - { url = "https://files.pythonhosted.org/packages/7c/93/865c8d50b3a1f50ebdc02227f28bb81817df88cee75bc6f2652469e754b1/fonttools-4.58.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:520792629a938c14dd7fe185794b156cfc159c609d07b31bbb5f51af8dc7918a", size = 4916900, upload-time = "2025-06-06T14:49:56.366Z" }, - { url = "https://files.pythonhosted.org/packages/60/d1/301aec4f02995958b7af6728f838b2e5cc9296bec7eae350722dec31f685/fonttools-4.58.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12fbc6e0bf0c75ce475ef170f2c065be6abc9e06ad19a13b56b02ec2acf02427", size = 4937358, upload-time = "2025-06-06T14:49:58.392Z" }, - { url = "https://files.pythonhosted.org/packages/15/22/75dc23a4c7200b8feb90baa82c518684a601a3a03be25f7cc3dde1525e37/fonttools-4.58.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:44a39cf856d52109127d55576c7ec010206a8ba510161a7705021f70d1649831", size = 4980151, upload-time = "2025-06-06T14:50:00.778Z" }, - { url = "https://files.pythonhosted.org/packages/14/51/5d402f65c4b0c89ce0cdbffe86646f3996da209f7bc93f1f4a13a7211ee0/fonttools-4.58.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5390a67c55a835ad5a420da15b3d88b75412cbbd74450cb78c4916b0bd7f0a34", size = 5091255, upload-time = "2025-06-06T14:50:02.588Z" }, - { url = "https://files.pythonhosted.org/packages/c7/5e/dee28700276129db1a0ee8ab0d5574d255a1d72df7f6df58a9d26ddef687/fonttools-4.58.2-cp311-cp311-win32.whl", hash = "sha256:f7e10f4e7160bcf6a240d7560e9e299e8cb585baed96f6a616cef51180bf56cb", size = 2190095, upload-time = "2025-06-06T14:50:04.932Z" }, - { url = "https://files.pythonhosted.org/packages/bd/60/b90fda549942808b68c1c5bada4b369f4f55d4c28a7012f7537670438f82/fonttools-4.58.2-cp311-cp311-win_amd64.whl", hash = "sha256:29bdf52bfafdae362570d3f0d3119a3b10982e1ef8cb3a9d3ebb72da81cb8d5e", size = 2238013, upload-time = "2025-06-06T14:50:06.605Z" }, - { url = "https://files.pythonhosted.org/packages/eb/68/7ec64584dc592faf944d540307c3562cd893256c48bb028c90de489e4750/fonttools-4.58.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c6eeaed9c54c1d33c1db928eb92b4e180c7cb93b50b1ee3e79b2395cb01f25e9", size = 2741645, upload-time = "2025-06-06T14:50:08.706Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0c/b327838f63baa7ebdd6db3ffdf5aff638e883f9236d928be4f32c692e1bd/fonttools-4.58.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbe1d9c72b7f981bed5c2a61443d5e3127c1b3aca28ca76386d1ad93268a803f", size = 2311100, upload-time = "2025-06-06T14:50:10.401Z" }, - { url = "https://files.pythonhosted.org/packages/ae/c7/dec024a1c873c79a4db98fe0104755fa62ec2b4518e09d6fda28246c3c9b/fonttools-4.58.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85babe5b3ce2cbe57fc0d09c0ee92bbd4d594fd7ea46a65eb43510a74a4ce773", size = 4815841, upload-time = "2025-06-06T14:50:12.496Z" }, - { url = "https://files.pythonhosted.org/packages/94/33/57c81abad641d6ec9c8b06c99cd28d687cb4849efb6168625b5c6b8f9fa4/fonttools-4.58.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:918a2854537fcdc662938057ad58b633bc9e0698f04a2f4894258213283a7932", size = 4882659, upload-time = "2025-06-06T14:50:14.361Z" }, - { url = "https://files.pythonhosted.org/packages/a5/37/2f8faa2bf8bd1ba016ea86a94c72a5e8ef8ea1c52ec64dada617191f0515/fonttools-4.58.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b379cf05bf776c336a0205632596b1c7d7ab5f7135e3935f2ca2a0596d2d092", size = 4876128, upload-time = "2025-06-06T14:50:16.653Z" }, - { url = "https://files.pythonhosted.org/packages/a0/ca/f1caac24ae7028a33f2a95e66c640571ff0ce5cb06c4c9ca1f632e98e22c/fonttools-4.58.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99ab3547a15a5d168c265e139e21756bbae1de04782ac9445c9ef61b8c0a32ce", size = 5027843, upload-time = "2025-06-06T14:50:18.582Z" }, - { url = "https://files.pythonhosted.org/packages/52/6e/3200fa2bafeed748a3017e4e6594751fd50cce544270919265451b21b75c/fonttools-4.58.2-cp312-cp312-win32.whl", hash = "sha256:6764e7a3188ce36eea37b477cdeca602ae62e63ae9fc768ebc176518072deb04", size = 2177374, upload-time = "2025-06-06T14:50:20.454Z" }, - { url = "https://files.pythonhosted.org/packages/55/ab/8f3e726f3f3ef3062ce9bbb615727c55beb11eea96d1f443f79cafca93ee/fonttools-4.58.2-cp312-cp312-win_amd64.whl", hash = "sha256:41f02182a1d41b79bae93c1551855146868b04ec3e7f9c57d6fef41a124e6b29", size = 2226685, upload-time = "2025-06-06T14:50:22.087Z" }, - { url = "https://files.pythonhosted.org/packages/ac/01/29f81970a508408af20b434ff5136cd1c7ef92198957eb8ddadfbb9ef177/fonttools-4.58.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:829048ef29dbefec35d95cc6811014720371c95bdc6ceb0afd2f8e407c41697c", size = 2732398, upload-time = "2025-06-06T14:50:23.821Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/095f2338359333adb2f1c51b8b2ad94bf9a2fa17e5fcbdf8a7b8e3672d2d/fonttools-4.58.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:64998c5993431e45b474ed5f579f18555f45309dd1cf8008b594d2fe0a94be59", size = 2306390, upload-time = "2025-06-06T14:50:25.942Z" }, - { url = "https://files.pythonhosted.org/packages/bf/d4/9eba134c7666a26668c28945355cd86e5d57828b6b8d952a5489fe45d7e2/fonttools-4.58.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b887a1cf9fbcb920980460ee4a489c8aba7e81341f6cdaeefa08c0ab6529591c", size = 4795100, upload-time = "2025-06-06T14:50:27.653Z" }, - { url = "https://files.pythonhosted.org/packages/2a/34/345f153a24c1340daa62340c3be2d1e5ee6c1ee57e13f6d15613209e688b/fonttools-4.58.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27d74b9f6970cefbcda33609a3bee1618e5e57176c8b972134c4e22461b9c791", size = 4864585, upload-time = "2025-06-06T14:50:29.915Z" }, - { url = "https://files.pythonhosted.org/packages/01/5f/091979a25c9a6c4ba064716cfdfe9431f78ed6ffba4bd05ae01eee3532e9/fonttools-4.58.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec26784610056a770e15a60f9920cee26ae10d44d1e43271ea652dadf4e7a236", size = 4866191, upload-time = "2025-06-06T14:50:32.188Z" }, - { url = "https://files.pythonhosted.org/packages/9d/09/3944d0ece4a39560918cba37c2e0453a5f826b665a6db0b43abbd9dbe7e1/fonttools-4.58.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ed0a71d57dd427c0fb89febd08cac9b925284d2a8888e982a6c04714b82698d7", size = 5003867, upload-time = "2025-06-06T14:50:34.323Z" }, - { url = "https://files.pythonhosted.org/packages/68/97/190b8f9ba22f8b7d07df2faa9fd7087b453776d0705d3cb5b0cbd89b8ef0/fonttools-4.58.2-cp313-cp313-win32.whl", hash = "sha256:994e362b01460aa863ef0cb41a29880bc1a498c546952df465deff7abf75587a", size = 2175688, upload-time = "2025-06-06T14:50:36.211Z" }, - { url = "https://files.pythonhosted.org/packages/94/ea/0e6d4a39528dbb6e0f908c2ad219975be0a506ed440fddf5453b90f76981/fonttools-4.58.2-cp313-cp313-win_amd64.whl", hash = "sha256:f95dec862d7c395f2d4efe0535d9bdaf1e3811e51b86432fa2a77e73f8195756", size = 2226464, upload-time = "2025-06-06T14:50:38.862Z" }, - { url = "https://files.pythonhosted.org/packages/e8/e5/c1cb8ebabb80be76d4d28995da9416816653f8f572920ab5e3d2e3ac8285/fonttools-4.58.2-py3-none-any.whl", hash = "sha256:84f4b0bcfa046254a65ee7117094b4907e22dc98097a220ef108030eb3c15596", size = 1114597, upload-time = "2025-06-06T14:50:56.619Z" }, -] - -[[package]] -name = "google-api-core" -version = "2.25.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "google-auth" }, - { name = "googleapis-common-protos" }, - { name = "proto-plus" }, - { name = "protobuf" }, - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/98/a2/8176b416ca08106b2ae30cd4a006c8176945f682c3a5b42f141c9173f505/google_api_core-2.25.0.tar.gz", hash = "sha256:9b548e688702f82a34ed8409fb8a6961166f0b7795032f0be8f48308dff4333a", size = 164914, upload-time = "2025-06-02T14:45:34.789Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/ca/149e41a277bb0855e8ded85fd7579d7747c1223e253d82c5c0f1be236875/google_api_core-2.25.0-py3-none-any.whl", hash = "sha256:1db79d1281dcf9f3d10023283299ba38f3dc9f639ec41085968fd23e5bcf512e", size = 160668, upload-time = "2025-06-02T14:45:33.272Z" }, -] - -[[package]] -name = "google-api-python-client" -version = "2.172.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "google-api-core" }, - { name = "google-auth" }, - { name = "google-auth-httplib2" }, - { name = "httplib2" }, - { name = "uritemplate" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/02/69/c0cec6be5878d4de161f64096edb3d4a2d1a838f036b8425ea8358d0dfb3/google_api_python_client-2.172.0.tar.gz", hash = "sha256:dcb3b7e067154b2aa41f1776cf86584a5739c0ac74e6ff46fc665790dca0e6a6", size = 13074841, upload-time = "2025-06-10T16:58:41.181Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/15/fc/8850ccf21c5df43faeaf8bba8c4149ee880b41b8dc7066e3259bcfd921ca/google_api_python_client-2.172.0-py3-none-any.whl", hash = "sha256:9f1b9a268d5dc1228207d246c673d3a09ee211b41a11521d38d9212aeaa43af7", size = 13595800, upload-time = "2025-06-10T16:58:38.143Z" }, -] - -[[package]] -name = "google-auth" -version = "2.40.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cachetools" }, - { name = "pyasn1-modules" }, - { name = "rsa" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9e/9b/e92ef23b84fa10a64ce4831390b7a4c2e53c0132568d99d4ae61d04c8855/google_auth-2.40.3.tar.gz", hash = "sha256:500c3a29adedeb36ea9cf24b8d10858e152f2412e3ca37829b3fa18e33d63b77", size = 281029, upload-time = "2025-06-04T18:04:57.577Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/17/63/b19553b658a1692443c62bd07e5868adaa0ad746a0751ba62c59568cd45b/google_auth-2.40.3-py2.py3-none-any.whl", hash = "sha256:1370d4593e86213563547f97a92752fc658456fe4514c809544f330fed45a7ca", size = 216137, upload-time = "2025-06-04T18:04:55.573Z" }, -] - -[[package]] -name = "google-auth-httplib2" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "google-auth" }, - { name = "httplib2" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/56/be/217a598a818567b28e859ff087f347475c807a5649296fb5a817c58dacef/google-auth-httplib2-0.2.0.tar.gz", hash = "sha256:38aa7badf48f974f1eb9861794e9c0cb2a0511a4ec0679b1f886d108f5640e05", size = 10842, upload-time = "2023-12-12T17:40:30.722Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/be/8a/fe34d2f3f9470a27b01c9e76226965863f153d5fbe276f83608562e49c04/google_auth_httplib2-0.2.0-py2.py3-none-any.whl", hash = "sha256:b65a0a2123300dd71281a7bf6e64d65a0759287df52729bdd1ae2e47dc311a3d", size = 9253, upload-time = "2023-12-12T17:40:13.055Z" }, -] - -[[package]] -name = "googleapis-common-protos" -version = "1.70.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "protobuf" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/39/24/33db22342cf4a2ea27c9955e6713140fedd51e8b141b5ce5260897020f1a/googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257", size = 145903, upload-time = "2025-04-14T10:17:02.924Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/86/f1/62a193f0227cf15a920390abe675f386dec35f7ae3ffe6da582d3ade42c7/googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8", size = 294530, upload-time = "2025-04-14T10:17:01.271Z" }, +version = "4.58.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/5a/1124b2c8cb3a8015faf552e92714040bcdbc145dfa29928891b02d147a18/fonttools-4.58.4.tar.gz", hash = "sha256:928a8009b9884ed3aae17724b960987575155ca23c6f0b8146e400cc9e0d44ba", size = 3525026, upload-time = "2025-06-13T17:25:15.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/86/d22c24caa574449b56e994ed1a96d23b23af85557fb62a92df96439d3f6c/fonttools-4.58.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:834542f13fee7625ad753b2db035edb674b07522fcbdd0ed9e9a9e2a1034467f", size = 2748349, upload-time = "2025-06-13T17:23:49.179Z" }, + { url = "https://files.pythonhosted.org/packages/f9/b8/384aca93856def00e7de30341f1e27f439694857d82c35d74a809c705ed0/fonttools-4.58.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2e6c61ce330142525296170cd65666e46121fc0d44383cbbcfa39cf8f58383df", size = 2318565, upload-time = "2025-06-13T17:23:52.144Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f2/273edfdc8d9db89ecfbbf659bd894f7e07b6d53448b19837a4bdba148d17/fonttools-4.58.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9c75f8faa29579c0fbf29b56ae6a3660c6c025f3b671803cb6a9caa7e4e3a98", size = 4838855, upload-time = "2025-06-13T17:23:54.039Z" }, + { url = "https://files.pythonhosted.org/packages/13/fa/403703548c093c30b52ab37e109b369558afa221130e67f06bef7513f28a/fonttools-4.58.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:88dedcedbd5549e35b2ea3db3de02579c27e62e51af56779c021e7b33caadd0e", size = 4767637, upload-time = "2025-06-13T17:23:56.17Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a8/3380e1e0bff6defb0f81c9abf274a5b4a0f30bc8cab4fd4e346c6f923b4c/fonttools-4.58.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae80a895adab43586f4da1521d58fd4f4377cef322ee0cc205abcefa3a5effc3", size = 4819397, upload-time = "2025-06-13T17:23:58.263Z" }, + { url = "https://files.pythonhosted.org/packages/cd/1b/99e47eb17a8ca51d808622a4658584fa8f340857438a4e9d7ac326d4a041/fonttools-4.58.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0d3acc7f0d151da116e87a182aefb569cf0a3c8e0fd4c9cd0a7c1e7d3e7adb26", size = 4926641, upload-time = "2025-06-13T17:24:00.368Z" }, + { url = "https://files.pythonhosted.org/packages/31/75/415254408f038e35b36c8525fc31feb8561f98445688dd2267c23eafd7a2/fonttools-4.58.4-cp310-cp310-win32.whl", hash = "sha256:1244f69686008e7e8d2581d9f37eef330a73fee3843f1107993eb82c9d306577", size = 2201917, upload-time = "2025-06-13T17:24:02.587Z" }, + { url = "https://files.pythonhosted.org/packages/c5/69/f019a15ed2946317c5318e1bcc8876f8a54a313848604ad1d4cfc4c07916/fonttools-4.58.4-cp310-cp310-win_amd64.whl", hash = "sha256:2a66c0af8a01eb2b78645af60f3b787de5fe5eb1fd8348163715b80bdbfbde1f", size = 2246327, upload-time = "2025-06-13T17:24:04.087Z" }, + { url = "https://files.pythonhosted.org/packages/17/7b/cc6e9bb41bab223bd2dc70ba0b21386b85f604e27f4c3206b4205085a2ab/fonttools-4.58.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3841991c9ee2dc0562eb7f23d333d34ce81e8e27c903846f0487da21e0028eb", size = 2768901, upload-time = "2025-06-13T17:24:05.901Z" }, + { url = "https://files.pythonhosted.org/packages/3d/15/98d75df9f2b4e7605f3260359ad6e18e027c11fa549f74fce567270ac891/fonttools-4.58.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c98f91b6a9604e7ffb5ece6ea346fa617f967c2c0944228801246ed56084664", size = 2328696, upload-time = "2025-06-13T17:24:09.18Z" }, + { url = "https://files.pythonhosted.org/packages/a8/c8/dc92b80f5452c9c40164e01b3f78f04b835a00e673bd9355ca257008ff61/fonttools-4.58.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab9f891eb687ddf6a4e5f82901e00f992e18012ca97ab7acd15f13632acd14c1", size = 5018830, upload-time = "2025-06-13T17:24:11.282Z" }, + { url = "https://files.pythonhosted.org/packages/19/48/8322cf177680505d6b0b6062e204f01860cb573466a88077a9b795cb70e8/fonttools-4.58.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:891c5771e8f0094b7c0dc90eda8fc75e72930b32581418f2c285a9feedfd9a68", size = 4960922, upload-time = "2025-06-13T17:24:14.9Z" }, + { url = "https://files.pythonhosted.org/packages/14/e0/2aff149ed7eb0916de36da513d473c6fff574a7146891ce42de914899395/fonttools-4.58.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:43ba4d9646045c375d22e3473b7d82b18b31ee2ac715cd94220ffab7bc2d5c1d", size = 4997135, upload-time = "2025-06-13T17:24:16.959Z" }, + { url = "https://files.pythonhosted.org/packages/e6/6f/4d9829b29a64a2e63a121cb11ecb1b6a9524086eef3e35470949837a1692/fonttools-4.58.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33d19f16e6d2ffd6669bda574a6589941f6c99a8d5cfb9f464038244c71555de", size = 5108701, upload-time = "2025-06-13T17:24:18.849Z" }, + { url = "https://files.pythonhosted.org/packages/6f/1e/2d656ddd1b0cd0d222f44b2d008052c2689e66b702b9af1cd8903ddce319/fonttools-4.58.4-cp311-cp311-win32.whl", hash = "sha256:b59e5109b907da19dc9df1287454821a34a75f2632a491dd406e46ff432c2a24", size = 2200177, upload-time = "2025-06-13T17:24:20.823Z" }, + { url = "https://files.pythonhosted.org/packages/fb/83/ba71ad053fddf4157cb0697c8da8eff6718d059f2a22986fa5f312b49c92/fonttools-4.58.4-cp311-cp311-win_amd64.whl", hash = "sha256:3d471a5b567a0d1648f2e148c9a8bcf00d9ac76eb89e976d9976582044cc2509", size = 2247892, upload-time = "2025-06-13T17:24:22.927Z" }, + { url = "https://files.pythonhosted.org/packages/04/3c/1d1792bfe91ef46f22a3d23b4deb514c325e73c17d4f196b385b5e2faf1c/fonttools-4.58.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:462211c0f37a278494e74267a994f6be9a2023d0557aaa9ecbcbfce0f403b5a6", size = 2754082, upload-time = "2025-06-13T17:24:24.862Z" }, + { url = "https://files.pythonhosted.org/packages/2a/1f/2b261689c901a1c3bc57a6690b0b9fc21a9a93a8b0c83aae911d3149f34e/fonttools-4.58.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0c7a12fb6f769165547f00fcaa8d0df9517603ae7e04b625e5acb8639809b82d", size = 2321677, upload-time = "2025-06-13T17:24:26.815Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6b/4607add1755a1e6581ae1fc0c9a640648e0d9cdd6591cc2d581c2e07b8c3/fonttools-4.58.4-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2d42c63020a922154add0a326388a60a55504629edc3274bc273cd3806b4659f", size = 4896354, upload-time = "2025-06-13T17:24:28.428Z" }, + { url = "https://files.pythonhosted.org/packages/cd/95/34b4f483643d0cb11a1f830b72c03fdd18dbd3792d77a2eb2e130a96fada/fonttools-4.58.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f2b4e6fd45edc6805f5f2c355590b092ffc7e10a945bd6a569fc66c1d2ae7aa", size = 4941633, upload-time = "2025-06-13T17:24:30.568Z" }, + { url = "https://files.pythonhosted.org/packages/81/ac/9bafbdb7694059c960de523e643fa5a61dd2f698f3f72c0ca18ae99257c7/fonttools-4.58.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f155b927f6efb1213a79334e4cb9904d1e18973376ffc17a0d7cd43d31981f1e", size = 4886170, upload-time = "2025-06-13T17:24:32.724Z" }, + { url = "https://files.pythonhosted.org/packages/ae/44/a3a3b70d5709405f7525bb7cb497b4e46151e0c02e3c8a0e40e5e9fe030b/fonttools-4.58.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e38f687d5de97c7fb7da3e58169fb5ba349e464e141f83c3c2e2beb91d317816", size = 5037851, upload-time = "2025-06-13T17:24:35.034Z" }, + { url = "https://files.pythonhosted.org/packages/21/cb/e8923d197c78969454eb876a4a55a07b59c9c4c46598f02b02411dc3b45c/fonttools-4.58.4-cp312-cp312-win32.whl", hash = "sha256:636c073b4da9db053aa683db99580cac0f7c213a953b678f69acbca3443c12cc", size = 2187428, upload-time = "2025-06-13T17:24:36.996Z" }, + { url = "https://files.pythonhosted.org/packages/46/e6/fe50183b1a0e1018e7487ee740fa8bb127b9f5075a41e20d017201e8ab14/fonttools-4.58.4-cp312-cp312-win_amd64.whl", hash = "sha256:82e8470535743409b30913ba2822e20077acf9ea70acec40b10fcf5671dceb58", size = 2236649, upload-time = "2025-06-13T17:24:38.985Z" }, + { url = "https://files.pythonhosted.org/packages/d4/4f/c05cab5fc1a4293e6bc535c6cb272607155a0517700f5418a4165b7f9ec8/fonttools-4.58.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5f4a64846495c543796fa59b90b7a7a9dff6839bd852741ab35a71994d685c6d", size = 2745197, upload-time = "2025-06-13T17:24:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d3/49211b1f96ae49308f4f78ca7664742377a6867f00f704cdb31b57e4b432/fonttools-4.58.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e80661793a5d4d7ad132a2aa1eae2e160fbdbb50831a0edf37c7c63b2ed36574", size = 2317272, upload-time = "2025-06-13T17:24:43.428Z" }, + { url = "https://files.pythonhosted.org/packages/b2/11/c9972e46a6abd752a40a46960e431c795ad1f306775fc1f9e8c3081a1274/fonttools-4.58.4-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fe5807fc64e4ba5130f1974c045a6e8d795f3b7fb6debfa511d1773290dbb76b", size = 4877184, upload-time = "2025-06-13T17:24:45.527Z" }, + { url = "https://files.pythonhosted.org/packages/ea/24/5017c01c9ef8df572cc9eaf9f12be83ad8ed722ff6dc67991d3d752956e4/fonttools-4.58.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b610b9bef841cb8f4b50472494158b1e347d15cad56eac414c722eda695a6cfd", size = 4939445, upload-time = "2025-06-13T17:24:47.647Z" }, + { url = "https://files.pythonhosted.org/packages/79/b0/538cc4d0284b5a8826b4abed93a69db52e358525d4b55c47c8cef3669767/fonttools-4.58.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2daa7f0e213c38f05f054eb5e1730bd0424aebddbeac094489ea1585807dd187", size = 4878800, upload-time = "2025-06-13T17:24:49.766Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9b/a891446b7a8250e65bffceb248508587958a94db467ffd33972723ab86c9/fonttools-4.58.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:66cccb6c0b944496b7f26450e9a66e997739c513ffaac728d24930df2fd9d35b", size = 5021259, upload-time = "2025-06-13T17:24:51.754Z" }, + { url = "https://files.pythonhosted.org/packages/17/b2/c4d2872cff3ace3ddd1388bf15b76a1d8d5313f0a61f234e9aed287e674d/fonttools-4.58.4-cp313-cp313-win32.whl", hash = "sha256:94d2aebb5ca59a5107825520fde596e344652c1f18170ef01dacbe48fa60c889", size = 2185824, upload-time = "2025-06-13T17:24:54.324Z" }, + { url = "https://files.pythonhosted.org/packages/98/57/cddf8bcc911d4f47dfca1956c1e3aeeb9f7c9b8e88b2a312fe8c22714e0b/fonttools-4.58.4-cp313-cp313-win_amd64.whl", hash = "sha256:b554bd6e80bba582fd326ddab296e563c20c64dca816d5e30489760e0c41529f", size = 2236382, upload-time = "2025-06-13T17:24:56.291Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2f/c536b5b9bb3c071e91d536a4d11f969e911dbb6b227939f4c5b0bca090df/fonttools-4.58.4-py3-none-any.whl", hash = "sha256:a10ce13a13f26cbb9f37512a4346bb437ad7e002ff6fa966a7ce7ff5ac3528bd", size = 1114660, upload-time = "2025-06-13T17:25:13.321Z" }, ] [[package]] @@ -865,18 +788,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/35/347db7d2e7674b621afd21b12022e7f48c7b0861b5577134b4e939536141/grpcio-1.73.0-cp313-cp313-win_amd64.whl", hash = "sha256:38cf518cc54cd0c47c9539cefa8888549fcc067db0b0c66a46535ca8032020c4", size = 4335872, upload-time = "2025-06-09T10:04:29.032Z" }, ] -[[package]] -name = "httplib2" -version = "0.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyparsing" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3d/ad/2371116b22d616c194aa25ec410c9c6c37f23599dcd590502b74db197584/httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81", size = 351116, upload-time = "2023-03-21T22:29:37.214Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/6c/d2fbdaaa5959339d53ba38e94c123e4e84b8fbc4b84beb0e70d7c1608486/httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc", size = 96854, upload-time = "2023-03-21T22:29:35.683Z" }, -] - [[package]] name = "id" version = "1.5.0" @@ -982,8 +893,7 @@ name = "ipython" version = "9.3.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13'", - "python_full_version == '3.12.*'", + "python_full_version >= '3.12'", "python_full_version == '3.11.*'", ] dependencies = [ @@ -1360,7 +1270,8 @@ dependencies = [ { name = "cycler" }, { name = "fonttools" }, { name = "kiwisolver" }, - { name = "numpy" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "packaging" }, { name = "pillow" }, { name = "pyparsing" }, @@ -1484,34 +1395,129 @@ wheels = [ [[package]] name = "numpy" -version = "1.26.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129, upload-time = "2024-02-06T00:26:44.495Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/94/ace0fdea5241a27d13543ee117cbc65868e82213fb31a8eb7fe9ff23f313/numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", size = 20631468, upload-time = "2024-02-05T23:48:01.194Z" }, - { url = "https://files.pythonhosted.org/packages/20/f7/b24208eba89f9d1b58c1668bc6c8c4fd472b20c45573cb767f59d49fb0f6/numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", size = 13966411, upload-time = "2024-02-05T23:48:29.038Z" }, - { url = "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", size = 14219016, upload-time = "2024-02-05T23:48:54.098Z" }, - { url = "https://files.pythonhosted.org/packages/4b/d7/ecf66c1cd12dc28b4040b15ab4d17b773b87fa9d29ca16125de01adb36cd/numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f", size = 18240889, upload-time = "2024-02-05T23:49:25.361Z" }, - { url = "https://files.pythonhosted.org/packages/24/03/6f229fe3187546435c4f6f89f6d26c129d4f5bed40552899fcf1f0bf9e50/numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", size = 13876746, upload-time = "2024-02-05T23:49:51.983Z" }, - { url = "https://files.pythonhosted.org/packages/39/fe/39ada9b094f01f5a35486577c848fe274e374bbf8d8f472e1423a0bbd26d/numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", size = 18078620, upload-time = "2024-02-05T23:50:22.515Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ef/6ad11d51197aad206a9ad2286dc1aac6a378059e06e8cf22cd08ed4f20dc/numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", size = 5972659, upload-time = "2024-02-05T23:50:35.834Z" }, - { url = "https://files.pythonhosted.org/packages/19/77/538f202862b9183f54108557bfda67e17603fc560c384559e769321c9d92/numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", size = 15808905, upload-time = "2024-02-05T23:51:03.701Z" }, - { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554, upload-time = "2024-02-05T23:51:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127, upload-time = "2024-02-05T23:52:15.314Z" }, - { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994, upload-time = "2024-02-05T23:52:47.569Z" }, - { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005, upload-time = "2024-02-05T23:53:15.637Z" }, - { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297, upload-time = "2024-02-05T23:53:42.16Z" }, - { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567, upload-time = "2024-02-05T23:54:11.696Z" }, - { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812, upload-time = "2024-02-05T23:54:26.453Z" }, - { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913, upload-time = "2024-02-05T23:54:53.933Z" }, - { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901, upload-time = "2024-02-05T23:55:32.801Z" }, - { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868, upload-time = "2024-02-05T23:55:56.28Z" }, - { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109, upload-time = "2024-02-05T23:56:20.368Z" }, - { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613, upload-time = "2024-02-05T23:56:56.054Z" }, - { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172, upload-time = "2024-02-05T23:57:21.56Z" }, - { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643, upload-time = "2024-02-05T23:57:56.585Z" }, - { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803, upload-time = "2024-02-05T23:58:08.963Z" }, - { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" }, +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, + { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, + { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, + { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, + { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, + { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, + { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, + { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, + { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, + { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, + { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/db/8e12381333aea300890829a0a36bfa738cac95475d88982d538725143fd9/numpy-2.3.0.tar.gz", hash = "sha256:581f87f9e9e9db2cba2141400e160e9dd644ee248788d6f90636eeb8fd9260a6", size = 20382813, upload-time = "2025-06-07T14:54:32.608Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/5f/df67435257d827eb3b8af66f585223dc2c3f2eb7ad0b50cb1dae2f35f494/numpy-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c3c9fdde0fa18afa1099d6257eb82890ea4f3102847e692193b54e00312a9ae9", size = 21199688, upload-time = "2025-06-07T14:36:52.067Z" }, + { url = "https://files.pythonhosted.org/packages/e5/ce/aad219575055d6c9ef29c8c540c81e1c38815d3be1fe09cdbe53d48ee838/numpy-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46d16f72c2192da7b83984aa5455baee640e33a9f1e61e656f29adf55e406c2b", size = 14359277, upload-time = "2025-06-07T14:37:15.325Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/2d31da8e6d2ec99bed54c185337a87f8fbeccc1cd9804e38217e92f3f5e2/numpy-2.3.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a0be278be9307c4ab06b788f2a077f05e180aea817b3e41cebbd5aaf7bd85ed3", size = 5376069, upload-time = "2025-06-07T14:37:25.636Z" }, + { url = "https://files.pythonhosted.org/packages/7d/2a/6c59a062397553ec7045c53d5fcdad44e4536e54972faa2ba44153bca984/numpy-2.3.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:99224862d1412d2562248d4710126355d3a8db7672170a39d6909ac47687a8a4", size = 6913057, upload-time = "2025-06-07T14:37:37.215Z" }, + { url = "https://files.pythonhosted.org/packages/d5/5a/8df16f258d28d033e4f359e29d3aeb54663243ac7b71504e89deeb813202/numpy-2.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2393a914db64b0ead0ab80c962e42d09d5f385802006a6c87835acb1f58adb96", size = 14568083, upload-time = "2025-06-07T14:37:59.337Z" }, + { url = "https://files.pythonhosted.org/packages/0a/92/0528a563dfc2cdccdcb208c0e241a4bb500d7cde218651ffb834e8febc50/numpy-2.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:7729c8008d55e80784bd113787ce876ca117185c579c0d626f59b87d433ea779", size = 16929402, upload-time = "2025-06-07T14:38:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/e4/2f/e7a8c8d4a2212c527568d84f31587012cf5497a7271ea1f23332142f634e/numpy-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:06d4fb37a8d383b769281714897420c5cc3545c79dc427df57fc9b852ee0bf58", size = 15879193, upload-time = "2025-06-07T14:38:48.007Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c3/dada3f005953847fe35f42ac0fe746f6e1ea90b4c6775e4be605dcd7b578/numpy-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c39ec392b5db5088259c68250e342612db82dc80ce044cf16496cf14cf6bc6f8", size = 18665318, upload-time = "2025-06-07T14:39:15.794Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ae/3f448517dedefc8dd64d803f9d51a8904a48df730e00a3c5fb1e75a60620/numpy-2.3.0-cp311-cp311-win32.whl", hash = "sha256:ee9d3ee70d62827bc91f3ea5eee33153212c41f639918550ac0475e3588da59f", size = 6601108, upload-time = "2025-06-07T14:39:27.176Z" }, + { url = "https://files.pythonhosted.org/packages/8c/4a/556406d2bb2b9874c8cbc840c962683ac28f21efbc9b01177d78f0199ca1/numpy-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:43c55b6a860b0eb44d42341438b03513cf3879cb3617afb749ad49307e164edd", size = 13021525, upload-time = "2025-06-07T14:39:46.637Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ee/bf54278aef30335ffa9a189f869ea09e1a195b3f4b93062164a3b02678a7/numpy-2.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:2e6a1409eee0cb0316cb64640a49a49ca44deb1a537e6b1121dc7c458a1299a8", size = 10170327, upload-time = "2025-06-07T14:40:02.703Z" }, + { url = "https://files.pythonhosted.org/packages/89/59/9df493df81ac6f76e9f05cdbe013cdb0c9a37b434f6e594f5bd25e278908/numpy-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:389b85335838155a9076e9ad7f8fdba0827496ec2d2dc32ce69ce7898bde03ba", size = 20897025, upload-time = "2025-06-07T14:40:33.558Z" }, + { url = "https://files.pythonhosted.org/packages/2f/86/4ff04335901d6cf3a6bb9c748b0097546ae5af35e455ae9b962ebff4ecd7/numpy-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9498f60cd6bb8238d8eaf468a3d5bb031d34cd12556af53510f05fcf581c1b7e", size = 14129882, upload-time = "2025-06-07T14:40:55.034Z" }, + { url = "https://files.pythonhosted.org/packages/71/8d/a942cd4f959de7f08a79ab0c7e6cecb7431d5403dce78959a726f0f57aa1/numpy-2.3.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:622a65d40d8eb427d8e722fd410ac3ad4958002f109230bc714fa551044ebae2", size = 5110181, upload-time = "2025-06-07T14:41:04.4Z" }, + { url = "https://files.pythonhosted.org/packages/86/5d/45850982efc7b2c839c5626fb67fbbc520d5b0d7c1ba1ae3651f2f74c296/numpy-2.3.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:b9446d9d8505aadadb686d51d838f2b6688c9e85636a0c3abaeb55ed54756459", size = 6647581, upload-time = "2025-06-07T14:41:14.695Z" }, + { url = "https://files.pythonhosted.org/packages/1a/c0/c871d4a83f93b00373d3eebe4b01525eee8ef10b623a335ec262b58f4dc1/numpy-2.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:50080245365d75137a2bf46151e975de63146ae6d79f7e6bd5c0e85c9931d06a", size = 14262317, upload-time = "2025-06-07T14:41:35.862Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f6/bc47f5fa666d5ff4145254f9e618d56e6a4ef9b874654ca74c19113bb538/numpy-2.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c24bb4113c66936eeaa0dc1e47c74770453d34f46ee07ae4efd853a2ed1ad10a", size = 16633919, upload-time = "2025-06-07T14:42:00.622Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b4/65f48009ca0c9b76df5f404fccdea5a985a1bb2e34e97f21a17d9ad1a4ba/numpy-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4d8d294287fdf685281e671886c6dcdf0291a7c19db3e5cb4178d07ccf6ecc67", size = 15567651, upload-time = "2025-06-07T14:42:24.429Z" }, + { url = "https://files.pythonhosted.org/packages/f1/62/5367855a2018578e9334ed08252ef67cc302e53edc869666f71641cad40b/numpy-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6295f81f093b7f5769d1728a6bd8bf7466de2adfa771ede944ce6711382b89dc", size = 18361723, upload-time = "2025-06-07T14:42:51.167Z" }, + { url = "https://files.pythonhosted.org/packages/d4/75/5baed8cd867eabee8aad1e74d7197d73971d6a3d40c821f1848b8fab8b84/numpy-2.3.0-cp312-cp312-win32.whl", hash = "sha256:e6648078bdd974ef5d15cecc31b0c410e2e24178a6e10bf511e0557eed0f2570", size = 6318285, upload-time = "2025-06-07T14:43:02.052Z" }, + { url = "https://files.pythonhosted.org/packages/bc/49/d5781eaa1a15acb3b3a3f49dc9e2ff18d92d0ce5c2976f4ab5c0a7360250/numpy-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:0898c67a58cdaaf29994bc0e2c65230fd4de0ac40afaf1584ed0b02cd74c6fdd", size = 12732594, upload-time = "2025-06-07T14:43:21.071Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1c/6d343e030815c7c97a1f9fbad00211b47717c7fe446834c224bd5311e6f1/numpy-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:bd8df082b6c4695753ad6193018c05aac465d634834dca47a3ae06d4bb22d9ea", size = 9891498, upload-time = "2025-06-07T14:43:36.332Z" }, + { url = "https://files.pythonhosted.org/packages/73/fc/1d67f751fd4dbafc5780244fe699bc4084268bad44b7c5deb0492473127b/numpy-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5754ab5595bfa2c2387d241296e0381c21f44a4b90a776c3c1d39eede13a746a", size = 20889633, upload-time = "2025-06-07T14:44:06.839Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/73ffdb69e5c3f19ec4530f8924c4386e7ba097efc94b9c0aff607178ad94/numpy-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d11fa02f77752d8099573d64e5fe33de3229b6632036ec08f7080f46b6649959", size = 14151683, upload-time = "2025-06-07T14:44:28.847Z" }, + { url = "https://files.pythonhosted.org/packages/64/d5/06d4bb31bb65a1d9c419eb5676173a2f90fd8da3c59f816cc54c640ce265/numpy-2.3.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:aba48d17e87688a765ab1cd557882052f238e2f36545dfa8e29e6a91aef77afe", size = 5102683, upload-time = "2025-06-07T14:44:38.417Z" }, + { url = "https://files.pythonhosted.org/packages/12/8b/6c2cef44f8ccdc231f6b56013dff1d71138c48124334aded36b1a1b30c5a/numpy-2.3.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4dc58865623023b63b10d52f18abaac3729346a7a46a778381e0e3af4b7f3beb", size = 6640253, upload-time = "2025-06-07T14:44:49.359Z" }, + { url = "https://files.pythonhosted.org/packages/62/aa/fca4bf8de3396ddb59544df9b75ffe5b73096174de97a9492d426f5cd4aa/numpy-2.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:df470d376f54e052c76517393fa443758fefcdd634645bc9c1f84eafc67087f0", size = 14258658, upload-time = "2025-06-07T14:45:10.156Z" }, + { url = "https://files.pythonhosted.org/packages/1c/12/734dce1087eed1875f2297f687e671cfe53a091b6f2f55f0c7241aad041b/numpy-2.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:87717eb24d4a8a64683b7a4e91ace04e2f5c7c77872f823f02a94feee186168f", size = 16628765, upload-time = "2025-06-07T14:45:35.076Z" }, + { url = "https://files.pythonhosted.org/packages/48/03/ffa41ade0e825cbcd5606a5669962419528212a16082763fc051a7247d76/numpy-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fa264d56882b59dcb5ea4d6ab6f31d0c58a57b41aec605848b6eb2ef4a43e8", size = 15564335, upload-time = "2025-06-07T14:45:58.797Z" }, + { url = "https://files.pythonhosted.org/packages/07/58/869398a11863310aee0ff85a3e13b4c12f20d032b90c4b3ee93c3b728393/numpy-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e651756066a0eaf900916497e20e02fe1ae544187cb0fe88de981671ee7f6270", size = 18360608, upload-time = "2025-06-07T14:46:25.687Z" }, + { url = "https://files.pythonhosted.org/packages/2f/8a/5756935752ad278c17e8a061eb2127c9a3edf4ba2c31779548b336f23c8d/numpy-2.3.0-cp313-cp313-win32.whl", hash = "sha256:e43c3cce3b6ae5f94696669ff2a6eafd9a6b9332008bafa4117af70f4b88be6f", size = 6310005, upload-time = "2025-06-07T14:50:13.138Z" }, + { url = "https://files.pythonhosted.org/packages/08/60/61d60cf0dfc0bf15381eaef46366ebc0c1a787856d1db0c80b006092af84/numpy-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:81ae0bf2564cf475f94be4a27ef7bcf8af0c3e28da46770fc904da9abd5279b5", size = 12729093, upload-time = "2025-06-07T14:50:31.82Z" }, + { url = "https://files.pythonhosted.org/packages/66/31/2f2f2d2b3e3c32d5753d01437240feaa32220b73258c9eef2e42a0832866/numpy-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:c8738baa52505fa6e82778580b23f945e3578412554d937093eac9205e845e6e", size = 9885689, upload-time = "2025-06-07T14:50:47.888Z" }, + { url = "https://files.pythonhosted.org/packages/f1/89/c7828f23cc50f607ceb912774bb4cff225ccae7131c431398ad8400e2c98/numpy-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:39b27d8b38942a647f048b675f134dd5a567f95bfff481f9109ec308515c51d8", size = 20986612, upload-time = "2025-06-07T14:46:56.077Z" }, + { url = "https://files.pythonhosted.org/packages/dd/46/79ecf47da34c4c50eedec7511e53d57ffdfd31c742c00be7dc1d5ffdb917/numpy-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0eba4a1ea88f9a6f30f56fdafdeb8da3774349eacddab9581a21234b8535d3d3", size = 14298953, upload-time = "2025-06-07T14:47:18.053Z" }, + { url = "https://files.pythonhosted.org/packages/59/44/f6caf50713d6ff4480640bccb2a534ce1d8e6e0960c8f864947439f0ee95/numpy-2.3.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:b0f1f11d0a1da54927436505a5a7670b154eac27f5672afc389661013dfe3d4f", size = 5225806, upload-time = "2025-06-07T14:47:27.524Z" }, + { url = "https://files.pythonhosted.org/packages/a6/43/e1fd1aca7c97e234dd05e66de4ab7a5be54548257efcdd1bc33637e72102/numpy-2.3.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:690d0a5b60a47e1f9dcec7b77750a4854c0d690e9058b7bef3106e3ae9117808", size = 6735169, upload-time = "2025-06-07T14:47:38.057Z" }, + { url = "https://files.pythonhosted.org/packages/84/89/f76f93b06a03177c0faa7ca94d0856c4e5c4bcaf3c5f77640c9ed0303e1c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:8b51ead2b258284458e570942137155978583e407babc22e3d0ed7af33ce06f8", size = 14330701, upload-time = "2025-06-07T14:47:59.113Z" }, + { url = "https://files.pythonhosted.org/packages/aa/f5/4858c3e9ff7a7d64561b20580cf7cc5d085794bd465a19604945d6501f6c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:aaf81c7b82c73bd9b45e79cfb9476cb9c29e937494bfe9092c26aece812818ad", size = 16692983, upload-time = "2025-06-07T14:48:24.196Z" }, + { url = "https://files.pythonhosted.org/packages/08/17/0e3b4182e691a10e9483bcc62b4bb8693dbf9ea5dc9ba0b77a60435074bb/numpy-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f420033a20b4f6a2a11f585f93c843ac40686a7c3fa514060a97d9de93e5e72b", size = 15641435, upload-time = "2025-06-07T14:48:47.712Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d5/463279fda028d3c1efa74e7e8d507605ae87f33dbd0543cf4c4527c8b882/numpy-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d344ca32ab482bcf8735d8f95091ad081f97120546f3d250240868430ce52555", size = 18433798, upload-time = "2025-06-07T14:49:14.866Z" }, + { url = "https://files.pythonhosted.org/packages/0e/1e/7a9d98c886d4c39a2b4d3a7c026bffcf8fbcaf518782132d12a301cfc47a/numpy-2.3.0-cp313-cp313t-win32.whl", hash = "sha256:48a2e8eaf76364c32a1feaa60d6925eaf32ed7a040183b807e02674305beef61", size = 6438632, upload-time = "2025-06-07T14:49:25.67Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ab/66fc909931d5eb230107d016861824f335ae2c0533f422e654e5ff556784/numpy-2.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ba17f93a94e503551f154de210e4d50c5e3ee20f7e7a1b5f6ce3f22d419b93bb", size = 12868491, upload-time = "2025-06-07T14:49:44.898Z" }, + { url = "https://files.pythonhosted.org/packages/ee/e8/2c8a1c9e34d6f6d600c83d5ce5b71646c32a13f34ca5c518cc060639841c/numpy-2.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f14e016d9409680959691c109be98c436c6249eaf7f118b424679793607b5944", size = 9935345, upload-time = "2025-06-07T14:50:02.311Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a2/f8c1133f90eaa1c11bbbec1dc28a42054d0ce74bc2c9838c5437ba5d4980/numpy-2.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80b46117c7359de8167cc00a2c7d823bdd505e8c7727ae0871025a86d668283b", size = 21070759, upload-time = "2025-06-07T14:51:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/6c/e0/4c05fc44ba28463096eee5ae2a12832c8d2759cc5bcec34ae33386d3ff83/numpy-2.3.0-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:5814a0f43e70c061f47abd5857d120179609ddc32a613138cbb6c4e9e2dbdda5", size = 5301054, upload-time = "2025-06-07T14:51:27.413Z" }, + { url = "https://files.pythonhosted.org/packages/8a/3b/6c06cdebe922bbc2a466fe2105f50f661238ea223972a69c7deb823821e7/numpy-2.3.0-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:ef6c1e88fd6b81ac6d215ed71dc8cd027e54d4bf1d2682d362449097156267a2", size = 6817520, upload-time = "2025-06-07T14:51:38.015Z" }, + { url = "https://files.pythonhosted.org/packages/9d/a3/1e536797fd10eb3c5dbd2e376671667c9af19e241843548575267242ea02/numpy-2.3.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33a5a12a45bb82d9997e2c0b12adae97507ad7c347546190a18ff14c28bbca12", size = 14398078, upload-time = "2025-06-07T14:52:00.122Z" }, + { url = "https://files.pythonhosted.org/packages/7c/61/9d574b10d9368ecb1a0c923952aa593510a20df4940aa615b3a71337c8db/numpy-2.3.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:54dfc8681c1906d239e95ab1508d0a533c4a9505e52ee2d71a5472b04437ef97", size = 16751324, upload-time = "2025-06-07T14:52:25.077Z" }, + { url = "https://files.pythonhosted.org/packages/39/de/bcad52ce972dc26232629ca3a99721fd4b22c1d2bda84d5db6541913ef9c/numpy-2.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e017a8a251ff4d18d71f139e28bdc7c31edba7a507f72b1414ed902cbe48c74d", size = 12924237, upload-time = "2025-06-07T14:52:44.713Z" }, ] [[package]] @@ -1543,7 +1549,8 @@ name = "pandas" version = "2.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, @@ -1609,7 +1616,8 @@ name = "patsy" version = "1.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d1/81/74f6a65b848ffd16c18f920620ce999fe45fe27f01ab3911260ce4ed85e4/patsy-1.0.1.tar.gz", hash = "sha256:e786a9391eec818c054e359b737bbce692f051aee4c661f4141cc88fb459c0c4", size = 396010, upload-time = "2024-11-12T14:10:54.642Z" } wheels = [ @@ -1777,18 +1785,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07", size = 387810, upload-time = "2025-04-15T09:18:44.753Z" }, ] -[[package]] -name = "proto-plus" -version = "1.26.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "protobuf" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f4/ac/87285f15f7cce6d4a008f33f1757fb5a13611ea8914eb58c3d0d26243468/proto_plus-1.26.1.tar.gz", hash = "sha256:21a515a4c4c0088a773899e23c7bbade3d18f9c66c73edd4c7ee3816bc96a012", size = 56142, upload-time = "2025-03-10T15:54:38.843Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/6d/280c4c2ce28b1593a19ad5239c8b826871fc6ec275c21afc8e1820108039/proto_plus-1.26.1-py3-none-any.whl", hash = "sha256:13285478c2dcf2abb829db158e1047e2f1e8d63a077d94263c2b88b043c75a66", size = 50163, upload-time = "2025-03-10T15:54:37.335Z" }, -] - [[package]] name = "protobuf" version = "6.31.1" @@ -1905,27 +1901,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, ] -[[package]] -name = "pyasn1" -version = "0.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, -] - -[[package]] -name = "pyasn1-modules" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyasn1" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload-time = "2025-03-28T02:41:19.028Z" }, -] - [[package]] name = "pycparser" version = "2.22" @@ -1992,7 +1967,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.4.0" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -2003,9 +1978,9 @@ dependencies = [ { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/aa/405082ce2749be5398045152251ac69c0f3578c7077efc53431303af97ce/pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6", size = 1515232, upload-time = "2025-06-02T17:36:30.03Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/de/afa024cbe022b1b318a3d224125aa24939e99b4ff6f22e0ba639a2eaee47/pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e", size = 363797, upload-time = "2025-06-02T17:36:27.859Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] @@ -2056,20 +2031,21 @@ wheels = [ [[package]] name = "pyvista" -version = "0.44.1" +version = "0.45.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "matplotlib" }, - { name = "numpy" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pillow" }, { name = "pooch" }, { name = "scooby" }, { name = "typing-extensions" }, { name = "vtk" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/58/839f30990b29a40e3be40d677dfd60820ffcb58e26e0993d56d9df2469cd/pyvista-0.44.1.tar.gz", hash = "sha256:63976f5d57d151b3f7e1616dde40dcf56a66d1f37f6db067087fa9cc9667f512", size = 2192657, upload-time = "2024-07-20T05:33:25.609Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/82/ca2381cdb5509a7a36e0c360e1d54cb06d6dc13d502da9fd335f97934223/pyvista-0.45.2.tar.gz", hash = "sha256:74c6b48a7366307a7e94d0ba768df652f1035321144674a677e9916ccf358f9f", size = 2361616, upload-time = "2025-05-13T00:37:40.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/ec/ebc65900d1bbc4aec23d15c1d60472565b55ab7c4f9d2bcfba29b8406c38/pyvista-0.44.1-py3-none-any.whl", hash = "sha256:7a80e8114220ca36d57a4def8e6a3067c908b53b62aa426ea76c76069bb6d1c0", size = 2244444, upload-time = "2024-07-20T05:33:22.338Z" }, + { url = "https://files.pythonhosted.org/packages/c8/25/61d16cb75cf3785217dd109cf0970facd49b658873f14dc6fb5a38096771/pyvista-0.45.2-py3-none-any.whl", hash = "sha256:123fd795883b804734b49dd1f5b85a1d38c67bfba514719a5d689d17ff4901f3", size = 2411926, upload-time = "2025-05-13T00:37:31.332Z" }, ] [[package]] @@ -2217,24 +2193,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c", size = 7742, upload-time = "2025-02-22T07:34:52.422Z" }, ] -[[package]] -name = "rsa" -version = "4.9.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyasn1" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, -] - [[package]] name = "scipy" version = "1.15.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } wheels = [ @@ -2379,8 +2344,7 @@ name = "sphinx" version = "8.2.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13'", - "python_full_version == '3.12.*'", + "python_full_version >= '3.12'", "python_full_version == '3.11.*'", ] dependencies = [ @@ -2516,7 +2480,8 @@ name = "statsmodels" version = "0.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "packaging" }, { name = "pandas" }, { name = "patsy" }, @@ -2669,22 +2634,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl", hash = "sha256:eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d", size = 18026, upload-time = "2025-03-05T21:17:39.857Z" }, ] -[[package]] -name = "uritemplate" -version = "4.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e", size = 33267, upload-time = "2025-06-02T15:12:06.318Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686", size = 11488, upload-time = "2025-06-02T15:12:03.405Z" }, -] - [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] @@ -2703,28 +2659,28 @@ wheels = [ [[package]] name = "vtk" -version = "9.4.0" +version = "9.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "matplotlib" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/94/58/717b4e5aa1d8bd6ddd4e176038818109c143b0b20ad2336ea6307dc15f03/vtk-9.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:d12f159913edd06d753f67e582f0199da37b25246e8bfbf7c60b2c391fa1dd39", size = 84076281, upload-time = "2024-11-25T04:50:37.416Z" }, - { url = "https://files.pythonhosted.org/packages/06/08/802e5adc190b825116d3af3b2350d761ae2b2dbc06e0f7cc9afeb901ad09/vtk-9.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:425bddefcd23da5f485e820204011d28af54e15283ad8a3b93eb4f2ecd42062f", size = 76799259, upload-time = "2024-11-25T04:50:43.642Z" }, - { url = "https://files.pythonhosted.org/packages/d7/27/1960b3d5a4e3f9f679f2127155fd8b1688832b9e8adecb8ee86c502ab23a/vtk-9.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b2b4687367f6f490d3795d6a7a9f85b388cc5c79fb13769260361fb45e6479c", size = 104992080, upload-time = "2024-11-25T04:50:50.697Z" }, - { url = "https://files.pythonhosted.org/packages/66/68/3364b55e659b81f0b264538a943dc69b29cb9486c0f69f7a03a593eda625/vtk-9.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:05fa054cb5d21e20651c3f5113dec2743761dd7592dd56c994610cdf6fa60e49", size = 58385261, upload-time = "2024-11-25T04:50:55.732Z" }, - { url = "https://files.pythonhosted.org/packages/37/05/da623200f86c8e4f6745a84fba36bc9a55a488329f281a4408d93bc5fc26/vtk-9.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1258a91429adb4e019f359c0d64f5e7513f3f4faf6af2a5b757c56bdcf77338a", size = 84076348, upload-time = "2024-11-25T04:51:01.335Z" }, - { url = "https://files.pythonhosted.org/packages/d9/2d/e86cdd1a31263e75f48dcfac101db04809cc4f4aaed49370fa22b4da18b1/vtk-9.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c3f22e6defce595944cea924bbc7c5de481d2b530a87e4f63c9fffb7360359da", size = 76799039, upload-time = "2024-11-25T04:51:07.132Z" }, - { url = "https://files.pythonhosted.org/packages/64/24/05adce8e3744f6a4125441b9f6e7b65200b76354b0b9eb9591b1a1518582/vtk-9.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e29ec25ae3de1ec5dddb4e7da67887b305b58cf073ad3b2407c21dd0c7dc525", size = 104991796, upload-time = "2024-11-25T04:51:13.469Z" }, - { url = "https://files.pythonhosted.org/packages/42/e9/12e55d9088f74854efcf5e5400686d96fcd675581f00126f7beb72b46a1d/vtk-9.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:f3a605c69d926690ae707e17d9ee7db830d76a45d052a594acd306916df17208", size = 58385072, upload-time = "2024-11-25T04:51:19.3Z" }, - { url = "https://files.pythonhosted.org/packages/70/69/f8bcf8090f93808a28d1a46c3d174cf9022f2703cfcdeb251d86cf3fa160/vtk-9.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d11bfb89896d793bb6c7cf959646ff38e590556a3e74ffa02e850aa6ebee313e", size = 84259338, upload-time = "2024-11-25T04:51:25.065Z" }, - { url = "https://files.pythonhosted.org/packages/59/cb/c86ffee03c227c047b47793abdf7aef036baa65974dae89a561abaf7e474/vtk-9.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59e0a70ebc827fd82b97ff0b63a945dd16a8bf23fe1450e6eb9da9e73b0978dc", size = 76841906, upload-time = "2024-11-25T04:51:30.773Z" }, - { url = "https://files.pythonhosted.org/packages/aa/03/ea1f2511adfaeb58b3d1f1dba5aa61bcb7d268601e70b1c26f33b4c66afd/vtk-9.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e039decf33863b3199f8da101d90e492c967834833ece8a1689db71b3298c1", size = 105043592, upload-time = "2024-11-25T04:51:38.746Z" }, - { url = "https://files.pythonhosted.org/packages/30/c7/3af925e1942a178c8a633120ad7bd67c593e04ad24cb553f32f3b3ea4eba/vtk-9.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:533a86e74a58f5b516123cd5d13130df8447bd3ccaf46cb36d2d4443f61d8116", size = 58470074, upload-time = "2024-11-25T04:51:46.237Z" }, - { url = "https://files.pythonhosted.org/packages/03/c4/caf5e1af3a1f9e51bd0a3180a78c596a1c7318c3ebb96f2088a6ce8bfee3/vtk-9.4.0-cp313-cp313-macosx_10_10_x86_64.whl", hash = "sha256:3fc41fb7f4fedac9f9308a16d5224cd368f4f6ef8e11874bb0d0315c3e049ec0", size = 84279177, upload-time = "2024-11-25T04:51:54.016Z" }, - { url = "https://files.pythonhosted.org/packages/c5/cb/1273f62e7887e67952e0cdd723aa8c3def4bbc7438c3eedf4725bf209cc2/vtk-9.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4b333c13933797bd7807faf02c186de9d6e6d2c38416264a4c5ad913478bb5a5", size = 76853807, upload-time = "2024-11-25T04:52:14.399Z" }, - { url = "https://files.pythonhosted.org/packages/dd/f9/859c446a2b6d8b946fb46c61e52a0086f0e59c269d8ae9baa47d745239cb/vtk-9.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a228543e72870555573dc5313bd74d6b4ff579d3e214b8f9f4abc0eee6ae297a", size = 105043965, upload-time = "2024-11-25T04:52:27.95Z" }, - { url = "https://files.pythonhosted.org/packages/ad/d0/f247b2b2655303a3d47d4266516b029d04f75793dde08a4e10b24f556630/vtk-9.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:d58d9b11e633caffd5f18b7e231c256626c9a18fd11fc34a2a5c2e3dd0d6c7cb", size = 58469692, upload-time = "2024-11-25T04:52:40.835Z" }, + { url = "https://files.pythonhosted.org/packages/09/c0/7c8d541081d0181b49b9a43597228cfcf0ce1f1584b36bc97aef4a936b21/vtk-9.4.2-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:97788af1881d115d90d118e6b6db4e673d4250473df074015edaf633e134945f", size = 82503633, upload-time = "2025-03-28T20:16:31.894Z" }, + { url = "https://files.pythonhosted.org/packages/85/9a/265b6a7aa7d7d5a6e7140f066e506a9b7dd3f9d2f35c4bd31b0769e5a0e3/vtk-9.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c5b2db2ffb52394cf3a72fb9d74ec980d944b9fecd626bdcd223ac896fa8b975", size = 76491428, upload-time = "2025-03-28T20:16:39.678Z" }, + { url = "https://files.pythonhosted.org/packages/61/b3/8b51d0519e3e10e3b1956de6e68f14ffcad15fda752b0d028afba4b7242f/vtk-9.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20898263a57a2f414d6deaf9fecf0d81f6eb43d8f2002c66b20425d258e2a316", size = 105002344, upload-time = "2025-03-28T20:16:50.176Z" }, + { url = "https://files.pythonhosted.org/packages/0e/73/1dfb537d61a81a8eae79b0233c344a3212b203ed01affef2f0fc09742eb9/vtk-9.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:918830427783737c38f5e3f4ad81f229904c975665897d09748057fcfacab42b", size = 58399309, upload-time = "2025-03-28T20:16:56.782Z" }, + { url = "https://files.pythonhosted.org/packages/57/7b/3765e941db50c46ebb8e007cdcd2f436746b8d9b4971198ad7c1a5e439c8/vtk-9.4.2-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:267302d1def1f28c7a4bed1422bccb55f20db6a9b760d25883535bd56111143b", size = 82503735, upload-time = "2025-03-28T20:17:04.434Z" }, + { url = "https://files.pythonhosted.org/packages/5c/94/e93414d29f443ef8b3c57729c82ded0c910ac1a10b964c7960e6c33003a4/vtk-9.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c378ec0a51fc690268c30484828e6ffe4b525be87bf21229c29a773f910787e1", size = 76491253, upload-time = "2025-03-28T20:17:12.057Z" }, + { url = "https://files.pythonhosted.org/packages/33/04/a119db060ca1c95c673e5755c3c1c60ab6e97d4cf86bc25664e3aea18fc0/vtk-9.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9db93562c9d6b39dafd65f00eccc5eb9bcc6a7c715db789c064536551368f2", size = 105002260, upload-time = "2025-03-28T20:17:23.245Z" }, + { url = "https://files.pythonhosted.org/packages/40/4c/0edf3e0ce0cdc0132e97b924ed16e774639c84cc94eb0e594b90aaf5fb0a/vtk-9.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:ee6013aef653aca14f881a2b4b33b13895166fad34eac340691852444848e971", size = 58397786, upload-time = "2025-03-28T20:17:29.924Z" }, + { url = "https://files.pythonhosted.org/packages/59/df/6c04941922986d2af611e9c7ea289ea1922295455ea08536b8fb9f104664/vtk-9.4.2-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:5482c147e36490a90fadf01333b8b06f2a88659a9cb012523603697e7de37dc7", size = 82686355, upload-time = "2025-03-28T20:17:37.753Z" }, + { url = "https://files.pythonhosted.org/packages/4c/6b/fce6a0040cc877324e5dc8191407a9ab73b7da65c88403d173f834052f70/vtk-9.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ac03471cada196b9465305336649cd502ce4796ee5006eade2cdaf7f2b5b593b", size = 76541862, upload-time = "2025-03-28T20:17:45.559Z" }, + { url = "https://files.pythonhosted.org/packages/9f/61/e998f3d118aa4e70d4cc8549dc0b67acfa138936ef9da896cbf87da21f7b/vtk-9.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef81842d151312b52455b2b613871c57ca7323c2f901914e13fc750b74ce3fd2", size = 105054000, upload-time = "2025-03-28T20:17:55.285Z" }, + { url = "https://files.pythonhosted.org/packages/35/a1/5df9de36c17c42269ae85b4435d346bf38d106b25e9b98c6db6cc2f8ac5f/vtk-9.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:fded22d5bc8cd2193ef27214efb63e1db5318f566fb64f2cf31332b820ece6ac", size = 58482099, upload-time = "2025-03-28T20:18:02.399Z" }, + { url = "https://files.pythonhosted.org/packages/22/30/5df46c3d90267f5b3efb6c8ac91c1014ef3532df2342aa53bd2ebed196e8/vtk-9.4.2-cp313-cp313-macosx_10_10_x86_64.whl", hash = "sha256:ec8c4258ceb9b3eb9c8101e1db1cca16825f0c0daa891ae4d85cd2ae9ec7681c", size = 82708428, upload-time = "2025-03-28T20:18:09.633Z" }, + { url = "https://files.pythonhosted.org/packages/2d/a1/34f61fe0ab3735d9f9127b7be186add12b481251601a1fde564fb08294bc/vtk-9.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1e291fc1a0c6a8432185abd9265d44fc7822b39325dc8e81d01b798858b68733", size = 76553587, upload-time = "2025-03-28T20:18:17.61Z" }, + { url = "https://files.pythonhosted.org/packages/8b/b1/f0deed70f4a72a0c42cf9a0120a0a92bbd1eac37090b501144e39c4792ad/vtk-9.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c6d15129443eb950b8faf127b67935a680533aa08ad832b9137889543084ddd", size = 105054339, upload-time = "2025-03-28T20:18:26.878Z" }, + { url = "https://files.pythonhosted.org/packages/99/52/2f49d4b73ed019b20f4bbbcf1b5f3a371d76af951688f6f70e79ff44fd14/vtk-9.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:5be5096e8c247c1ae151cc68121fbb0b6c5c76217e69d9600e4b8ba0c1c53c9f", size = 58482778, upload-time = "2025-03-28T20:18:33.653Z" }, ] [[package]] @@ -2738,11 +2694,11 @@ wheels = [ [[package]] name = "xlsxwriter" -version = "3.2.3" +version = "3.2.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/d1/e026d33dd5d552e5bf3a873dee54dad66b550230df8290d79394f09b2315/xlsxwriter-3.2.3.tar.gz", hash = "sha256:ad6fd41bdcf1b885876b1f6b7087560aecc9ae5a9cc2ba97dcac7ab2e210d3d5", size = 209135, upload-time = "2025-04-17T10:11:23.481Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/47/7704bac42ac6fe1710ae099b70e6a1e68ed173ef14792b647808c357da43/xlsxwriter-3.2.5.tar.gz", hash = "sha256:7e88469d607cdc920151c0ab3ce9cf1a83992d4b7bc730c5ffdd1a12115a7dbe", size = 213306, upload-time = "2025-06-17T08:59:14.619Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/37/b1/a252d499f2760b314fcf264d2b36fcc4343a1ecdb25492b210cb0db70a68/XlsxWriter-3.2.3-py3-none-any.whl", hash = "sha256:593f8296e8a91790c6d0378ab08b064f34a642b3feb787cf6738236bd0a4860d", size = 169433, upload-time = "2025-04-17T10:11:21.329Z" }, + { url = "https://files.pythonhosted.org/packages/fa/34/a22e6664211f0c8879521328000bdcae9bf6dbafa94a923e531f6d5b3f73/xlsxwriter-3.2.5-py3-none-any.whl", hash = "sha256:4f4824234e1eaf9d95df9a8fe974585ff91d0f5e3d3f12ace5b71e443c1c6abd", size = 172347, upload-time = "2025-06-17T08:59:13.453Z" }, ] [[package]] From 57d2a640a8e9e6c6433e40ab33912484acc9d8b8 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:55:08 -0400 Subject: [PATCH 02/50] Update Makefile --- Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ac2b21f47..d31719ca5 100644 --- a/Makefile +++ b/Makefile @@ -52,4 +52,10 @@ clean: test_clean: python test_cleanup.py -all: clean build install \ No newline at end of file +docs: + $(MAKE) -C doc html + +docs-clean: + $(MAKE) -C doc clean + +all: clean build install From 3673852eb33a68a348c85fdf2f2a158a2df8ec08 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:42:26 -0400 Subject: [PATCH 03/50] Update quickstart.rst --- doc/source/serverless/quickstart.rst | 84 ++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/doc/source/serverless/quickstart.rst b/doc/source/serverless/quickstart.rst index e69de29bb..365bdb801 100644 --- a/doc/source/serverless/quickstart.rst +++ b/doc/source/serverless/quickstart.rst @@ -0,0 +1,84 @@ +Quickstart +========== + +Get started quickly with Serverless ADR using the most common setup: a local SQLite database. + +Instantiation and Setup +----------------------- + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + + install_loc = r"C:\Program Files\ANSYS Inc\v252" + db_dir = r"C:\ADR\DBs\ogdocex" + + adr = ADR( + ansys_installation=install_loc, + db_directory=db_dir, + ) + adr.setup() + +Creating Items +-------------- + +Create report items such as text or tables tied to the default session and dataset. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import String + + item = adr.create_item( + String, + name="intro_text", + content="This is a quickstart demo for Serverless ADR.", + tags="section=intro", + source="quickstart-example", + ) + item.save() + +Building Templates +------------------ + +Create a basic template to structure the report. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import BasicLayout + + template = adr.create_template( + BasicLayout, + name="Quickstart Report", + parent=None, + tags="section=quickstart", + ) + template.set_filter("A|i_tags|cont|section=intro;") + template.save() + +Rendering the Report +-------------------- + +Render the report template to HTML, filtering items as needed. + +.. code-block:: python + + html_content = adr.render_report( + name="Quickstart Report", + context={}, + item_filter="A|i_tags|cont|section=intro;", + ) + + # Save to file or use the HTML content in your application + with open("quickstart_report.html", "w", encoding="utf-8") as f: + f.write(html_content) + +Accessing the ADR Instance +-------------------------- + +Retrieve the active ADR instance anywhere in your code: + +.. code-block:: python + + adr = ADR.get_instance() + +For more detailed setup options and concepts, see the :doc:`overview` and :doc:`instantiation` guides. From c0e2aabe4b2c227cb1fc9bc5565b27f20bea927d Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:42:37 -0400 Subject: [PATCH 04/50] Update index.rst --- doc/source/serverless/index.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/source/serverless/index.rst b/doc/source/serverless/index.rst index 135518fa1..f908153c8 100644 --- a/doc/source/serverless/index.rst +++ b/doc/source/serverless/index.rst @@ -32,17 +32,17 @@ Serverless ADR is ideal for: Key features ============ -- **Drop-in compatibility with Ansys installations**: +- **Drop-in compatibility with Ansys installations and the Service API**: Uses the same Python environment and static/media assets from your installed ADR system. - **Flexible instantiation**: - Supports SQLite and PostgreSQL databases, Docker-based environments, and + Supports SQLite and PostgreSQL databases, Docker-based environments, in-memory and legacy environment-variable configurations. - **In-memory execution**: Runs entirely in your local Python process, with no separate backend or daemon needed. - **First-class objects**: - Items and Templates are actual Python classes, not remote proxies — giving + Sessions, Datasets, Items and Templates are actual Python classes, not remote proxies — giving you full introspection, subclassing, and lifecycle control. - **Comprehensive rendering**: Generates full HTML reports — just like the service-based API — with full @@ -52,7 +52,8 @@ Explore the docs ================ .. toctree:: - :maxdepth: 1 + :maxdepth: 2 + :caption: Contents: quickstart overview @@ -66,5 +67,8 @@ Explore the docs embedding_reports copying_objects deleting_objects + configuration + examples troubleshooting + caveats faq From ef365d035ed56c196366cfd007bb16aa57261045 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:42:40 -0400 Subject: [PATCH 05/50] Update instantiation.rst --- doc/source/serverless/instantiation.rst | 131 ++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/doc/source/serverless/instantiation.rst b/doc/source/serverless/instantiation.rst index e69de29bb..1ba6a9156 100644 --- a/doc/source/serverless/instantiation.rst +++ b/doc/source/serverless/instantiation.rst @@ -0,0 +1,131 @@ +Instantiation +============= + +Serverless ADR supports several ways to instantiate the main ADR object depending on your use case. + +Single SQLite Database (Recommended) +------------------------------------ + +This method creates or uses a local SQLite database directory. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + + install_loc = r"C:\Program Files\ANSYS Inc\v252" + db_dir = r"C:\ADR\DBs\ogdocex" + + adr = ADR( + ansys_installation=install_loc, + db_directory=db_dir, + ) + adr.setup() + +If the specified directory does not exist, it and a media subdirectory will be created automatically. + +Multiple Databases +------------------ + +Use this method when working with multiple databases, e.g., PostgreSQL or database copies. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + import os + + install_loc = r"C:\Program Files\ANSYS Inc\v252" + db_dir = r"C:\ADR\DBs\ogdocex" + dest_dir = fr"{db_dir}_dest" + + database_config = { + "default": { + "ENGINE": "sqlite3", + "NAME": os.path.join(db_dir, "db.sqlite3"), + "USER": "nexus", + "PASSWORD": "cei", + "HOST": "", + "PORT": "", + }, + "dest": { + "ENGINE": "sqlite3", + "NAME": os.path.join(dest_dir, "db.sqlite3"), + "USER": "nexus", + "PASSWORD": "cei", + "HOST": "", + "PORT": "", + }, + } + + adr = ADR( + ansys_installation=install_loc, + databases=database_config, + media_directory=fr"{db_dir}\media", + ) + adr.setup() + +In-Memory Mode +-------------- + +Useful for testing and ephemeral workflows where persistence is not needed. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + + adr = ADR( + ansys_installation=r"C:\Program Files\ANSYS Inc\v252", + in_memory=True, + ) + adr.setup() + +Note: + +- No files are persisted to disk. +- Backup and restore operations are not supported. +- Media and static files use temporary memory locations. +- Data is lost when the process exits. + +Docker-Based Instantiation +-------------------------- + +Use a Docker image to run ADR in containerized environments. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + + adr = ADR( + ansys_installation="docker", + docker_image="ghcr.io/ansys-internal/nexus_dev", + db_directory=db_dir, + media_directory=fr"{db_dir}\media", + ) + adr.setup() + +Legacy Environment Variable Configuration +----------------------------------------- + +Supported for backward compatibility but not recommended for new projects. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + + opts = { + "CEI_NEXUS_DEBUG": "0", + "CEI_NEXUS_SECRET_KEY": "your_secret_key", + "CEI_NEXUS_LOCAL_DB_DIR": r"C:\cygwin64\home\vrajendr\ogdocex", + } + + install_loc = r"C:\Program Files\ANSYS Inc\v252" + adr = ADR(ansys_installation=install_loc, opts=opts) + adr.setup() + +Important Notes +--------------- + +- Always call ``adr.setup()`` once per process before using other ADR APIs. +- In multi-threaded applications, a single call to ``setup()`` per process suffices. +- For multi-process scenarios, each process must call ``setup()`` independently. + +For more usage examples, see the :doc:`examples` section. From 6a24cbb6a48807670866abd44c09f3857b8a6399 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:42:45 -0400 Subject: [PATCH 06/50] Update overview.rst --- doc/source/serverless/overview.rst | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/doc/source/serverless/overview.rst b/doc/source/serverless/overview.rst index e69de29bb..7fa5db570 100644 --- a/doc/source/serverless/overview.rst +++ b/doc/source/serverless/overview.rst @@ -0,0 +1,41 @@ +Overview +======== + +Serverless ADR is a lightweight, local Python API for building and rendering reports +using Ansys Dynamic Reporting (ADR) without requiring a running ADR backend or network connection. + +Key Benefits +------------ + +- Runs entirely within your Python process — no external server needed. +- Supports both SQLite and PostgreSQL databases. +- Uses the same core schema as the traditional ADR service. +- Enables offline report generation with full fidelity (items, templates, layouts). +- Suitable for local workflows, batch processing, and embedding in Python applications. +- Fully backwards compatible with the service-based ADR API. + +Core Concepts +------------- + +- **ADR Instance**: Singleton object managing database connections and report lifecycle. +- **Sessions and Datasets**: Organize your report data and metadata. +- **Items**: Report components such as HTML, tables, images, animations, and more. +- **Templates**: Define report structure and layout using various built-in and custom classes. +- **Static and Media Files**: Handle CSS, JavaScript, images, and other assets required for rendering. + +Built on Django ORM +------------------- + +Serverless ADR uses Django’s ORM for database interaction and schema management. +Unlike traditional ADR, it does not require a running web server but leverages +Django’s powerful database and templating features locally. + +Use Cases +--------- + +- Generating offline simulation reports. +- Integration into batch workflows and automated pipelines. +- Template design and testing before deployment. +- Embedding ADR reporting capabilities inside Python applications. + +For setup details and advanced configuration, see the :doc:`instantiation` guide. From 98e7bab53159103026386bf337bd9ca1706a16e2 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:42:54 -0400 Subject: [PATCH 07/50] Update sessions_and_datasets.rst --- .../serverless/sessions_and_datasets.rst | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index e69de29bb..4be369a7d 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -0,0 +1,113 @@ +Sessions and Datasets +===================== + +Sessions and Datasets are foundational entities in Serverless ADR. They organize and +contextualize the data and report items you create. + +Overview +-------- + +- A **Session** represents a logical reporting session, including metadata like date, + hostname, platform, and application version. +- A **Dataset** represents a collection of simulation or analysis data, such as files, + formats, and element counts. + +Creating Sessions and Datasets +------------------------------ + +You can create new sessions and datasets using the ``create`` class method, which +saves the object to the database immediately. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import Session, Dataset + + session = Session.create(application="My Simulation Run", tags="project=abc") + dataset = Dataset.create(filename="results.cdb", tags="project=abc") + +Setting Defaults in ADR +----------------------- + +The ADR singleton instance keeps track of default session and dataset objects. +This helps when creating report items without specifying them explicitly. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + + adr = ADR.get_instance() + adr.set_default_session(session) + adr.set_default_dataset(dataset) + +Accessing Current Session and Dataset +------------------------------------- + +You can also access or change the current session and dataset through the ADR instance: + +.. code-block:: python + + current_session = adr.session + current_dataset = adr.dataset + + # To change the default session or dataset: + adr.session = session + adr.dataset = dataset + +Fetching Existing Sessions and Datasets +--------------------------------------- + +You can fetch existing sessions or datasets by GUID or filter queries. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import Session, Dataset + + # Fetch by GUID (unique identifier) + session = Session.get(guid="4ee905f0-f611-11e6-8901-ae3af682bb6a") + dataset = Dataset.get(guid="fa473009-deee-34eb-b6b8-8326236ca9a6") + + # Filter sessions by tag + sessions = Session.filter(tags__icontains="project=abc") + +Using Sessions and Datasets When Creating Items +----------------------------------------------- + +When you create report items, the current default session and dataset are used +unless you specify different ones explicitly. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import String + + item = adr.create_item( + String, + name="summary_text", + content="Simulation results summary.", + tags="section=summary", + ) + +Sessions and Datasets Lifecycle Notes +------------------------------------- + +- Sessions and datasets must be saved before creating dependent items. +- Changing the default session or dataset affects all subsequent item creations + that rely on defaults. +- You can delete sessions or datasets if they are no longer needed, but ensure + associated items are handled appropriately. + +Exceptions and Validation +------------------------- + +- Creating or modifying sessions and datasets will raise errors if required fields + are missing or invalid. +- Fetching non-existent sessions or datasets by GUID raises a ``DoesNotExist`` error. +- Multiple objects returned for a single fetch raises a ``MultipleObjectsReturned`` error. + +Summary +------- + +Sessions and Datasets provide the structural context for your report items and +allow you to organize simulation data meaningfully. + +Next, learn about the different kinds of report items you can create in the +:doc:`items` guide. From 18eeca8fcd2848c53ee0ecdd759f844486a9272c Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:43:23 -0400 Subject: [PATCH 08/50] Update sessions_and_datasets.rst --- doc/source/serverless/sessions_and_datasets.rst | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index 4be369a7d..5ef0be643 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -1,8 +1,21 @@ Sessions and Datasets ===================== -Sessions and Datasets are foundational entities in Serverless ADR. They organize and -contextualize the data and report items you create. +Conceptual Overview +------------------- + +In this API, a **Session** represents a logical grouping or “push” of data from an external source +(such as a solver or post-processor) into the ADR system. It captures metadata about when, where, +and how the data was ingested. + +A **Dataset** contains the actual simulation or analysis data associated with a Session. This could +include files, tables, images, or other artifacts generated during the simulation. + +By associating report items with Sessions and Datasets, the API maintains clear context and +provenance, enabling organized, meaningful reports that trace back to the original data source. + +This API provides methods to create, manage, and fetch Sessions and Datasets to support +flexible and efficient report generation workflows. Overview -------- From 45adfffa60bd42378eabb2ca7e5ed543453a3737 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:44:17 -0400 Subject: [PATCH 09/50] Update sessions_and_datasets.rst --- doc/source/serverless/sessions_and_datasets.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index 5ef0be643..ca8176e7c 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -17,13 +17,11 @@ provenance, enabling organized, meaningful reports that trace back to the origin This API provides methods to create, manage, and fetch Sessions and Datasets to support flexible and efficient report generation workflows. -Overview --------- +Key Entities +------------ -- A **Session** represents a logical reporting session, including metadata like date, - hostname, platform, and application version. -- A **Dataset** represents a collection of simulation or analysis data, such as files, - formats, and element counts. +- **Session**: A logical reporting session with metadata like date, hostname, platform, and application version. +- **Dataset**: A collection of simulation or analysis data, such as files, formats, and element counts. Creating Sessions and Datasets ------------------------------ From d0fd594526838451bd182304ed32bae402d5ca68 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:45:41 -0400 Subject: [PATCH 10/50] Update sessions_and_datasets.rst --- doc/source/serverless/sessions_and_datasets.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index ca8176e7c..24ae20b3b 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -20,7 +20,8 @@ flexible and efficient report generation workflows. Key Entities ------------ -- **Session**: A logical reporting session with metadata like date, hostname, platform, and application version. +- **Session**: Represents a logical grouping of data imported into ADR during a single data push or analysis run, +capturing metadata such as date, hostname, platform, and application version. - **Dataset**: A collection of simulation or analysis data, such as files, formats, and element counts. Creating Sessions and Datasets From 840af6af94d6a7206aa51c385d7fef386c73c2cb Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:45:44 -0400 Subject: [PATCH 11/50] Create caveats.rst --- doc/source/serverless/caveats.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/source/serverless/caveats.rst diff --git a/doc/source/serverless/caveats.rst b/doc/source/serverless/caveats.rst new file mode 100644 index 000000000..e69de29bb From aa9d136fbfa733086eb6c27728179bc1d5b923c7 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:45:49 -0400 Subject: [PATCH 12/50] Create configuration.rst --- doc/source/serverless/configuration.rst | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/source/serverless/configuration.rst diff --git a/doc/source/serverless/configuration.rst b/doc/source/serverless/configuration.rst new file mode 100644 index 000000000..3fa02fb9d --- /dev/null +++ b/doc/source/serverless/configuration.rst @@ -0,0 +1,7 @@ +Environment Variables +--------------------- + +- ``CEI_NEXUS_LOCAL_DB_DIR``: Path to local database directory. +- ``CEI_NEXUS_LOCAL_MEDIA_DIR``: Path to media directory. +- ``CEI_NEXUS_LOCAL_STATIC_DIR``: Path to static files directory. +- Additional configuration options can be passed via the ``opts`` dict. From 4d4c4cccf8b178141e3b1f1c9963289efc8809d2 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:45:55 -0400 Subject: [PATCH 13/50] Create examples.rst --- doc/source/serverless/examples.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/source/serverless/examples.rst diff --git a/doc/source/serverless/examples.rst b/doc/source/serverless/examples.rst new file mode 100644 index 000000000..e69de29bb From 9f09d928f7bea3af14b9c58c6a0e6ae7daa2110b Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 12:55:17 -0400 Subject: [PATCH 14/50] Update sessions_and_datasets.rst --- .../serverless/sessions_and_datasets.rst | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index 24ae20b3b..ac5b68175 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -20,9 +20,10 @@ flexible and efficient report generation workflows. Key Entities ------------ -- **Session**: Represents a logical grouping of data imported into ADR during a single data push or analysis run, -capturing metadata such as date, hostname, platform, and application version. -- **Dataset**: A collection of simulation or analysis data, such as files, formats, and element counts. +- **Session**: Stores metadata about the session or logical grouping of data imported into ADR during a single +data push or analysis run, such as date, hostname, platform, and application version. +- **Dataset**: Stores metadata about the dataset or collection of simulation or analysis data, such as files, +formats, and element counts. Creating Sessions and Datasets ------------------------------ @@ -54,17 +55,13 @@ This helps when creating report items without specifying them explicitly. Accessing Current Session and Dataset ------------------------------------- -You can also access or change the current session and dataset through the ADR instance: +You can also access the current session and dataset through the ADR instance: .. code-block:: python current_session = adr.session current_dataset = adr.dataset - # To change the default session or dataset: - adr.session = session - adr.dataset = dataset - Fetching Existing Sessions and Datasets --------------------------------------- @@ -78,8 +75,8 @@ You can fetch existing sessions or datasets by GUID or filter queries. session = Session.get(guid="4ee905f0-f611-11e6-8901-ae3af682bb6a") dataset = Dataset.get(guid="fa473009-deee-34eb-b6b8-8326236ca9a6") - # Filter sessions by tag - sessions = Session.filter(tags__icontains="project=abc") + # Filter sessions by guid or other attributes + sessions = Session.filter(guid="4ee905f0-f611-11e6-8901-ae3af682bb6a") Using Sessions and Datasets When Creating Items ----------------------------------------------- @@ -91,11 +88,16 @@ unless you specify different ones explicitly. from ansys.dynamicreporting.core.serverless import String + session = Session.get(guid="4ee905f0-f611-11e6-8901-ae3af682bb6a") + dataset = Dataset.get(guid="fa473009-deee-34eb-b6b8-8326236ca9a6") + item = adr.create_item( String, name="summary_text", content="Simulation results summary.", tags="section=summary", + session=session, + dataset=dataset, ) Sessions and Datasets Lifecycle Notes From 4b1e32776d601c27fca1bf2214dcdc6f1d38a7d9 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:11:07 -0400 Subject: [PATCH 15/50] Update items.rst --- doc/source/serverless/items.rst | 141 ++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/doc/source/serverless/items.rst b/doc/source/serverless/items.rst index e69de29bb..9094ca7f5 100644 --- a/doc/source/serverless/items.rst +++ b/doc/source/serverless/items.rst @@ -0,0 +1,141 @@ +Items +===== + +In Serverless ADR, **Items** are the fundamental content units that form the building blocks of your reports. +They encapsulate individual pieces of data or visual content, such as text, tables, images, animations, and files, +which you can organize, query, and render within report templates. + +Core Concepts +------------- + +- Items are fully fledged Python classes with type-specific validation and behavior. +- Each item must be associated with a **Session** and a **Dataset** to maintain provenance. +- Items support rich metadata through tags, ordering via sequence numbers, and source attribution. +- Valid content types and file formats are enforced to ensure data integrity. +- Common item types include: + + - `String`: Plain text content. + - `HTML`: Valid HTML content, validated for proper structure. + - `Table`: Two-dimensional numpy arrays representing tabular data, with additional metadata like labels and plot settings. + - `Tree`: Hierarchical data represented as nested dictionaries with keys `key`, `name`, `value`, and optional `children`. + - `Image`: Images in PNG, JPG, and enhanced TIFF formats, supporting embedded metadata. + - `Animation`: Video files, typically MP4 format. + - `Scene`: 3D scene files such as STL, PLY, AVZ, CSF, and related formats. + - `File`: Generic files linked to your reports. + +Creating Items +-------------- + +Create new items via the ADR instance’s `create_item()` method. +Items automatically link to the current default session and dataset unless specified explicitly. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import String, Table + import numpy as np + + # Create a string item + string_item = adr.create_item( + String, + name="summary", + content="This simulation demonstrates fluid flow around a wing.", + tags="section=summary project=wing_sim", + ) + string_item.save() + + # Create a table item with data + data = np.array([ + [0.0, 10.0, 101325.0], + [0.5, 12.5, 101300.0], + [1.0, 15.0, 101280.0], + ], dtype="float") + + table_item = adr.create_item( + Table, + name="pressure_data", + content=data, + tags="section=data project=wing_sim", + ) + # Set additional table metadata + table_item.labels_row = ["Time (s)", "Velocity (m/s)", "Pressure (Pa)"] + table_item.plot = "line" + table_item.xaxis = "Time (s)" + table_item.yaxis = ["Velocity (m/s)", "Pressure (Pa)"] + table_item.save() + +Item Properties and Metadata +---------------------------- + +Items support several useful properties and metadata fields: + +- **name**: Unique identifier for the item within the dataset. +- **content**: The primary payload of the item, type-dependent. +- **tags**: A space-separated string of key or key=value tags for querying and filtering. +- **source**: String to track the data origin or generating process. +- **sequence**: Integer to order items in reports or presentations. +- **session** and **dataset**: Associations to link items to specific data contexts. + +Working With File-Based Items +----------------------------- + +Items like `Image`, `Animation`, `Scene`, and `File` accept file paths as content. +The files are validated for existence and allowed formats before being saved into the configured media directory. + +Example: Creating and saving an image item + +.. code-block:: python + + image_item = adr.create_item( + Image, + name="wing_profile", + content="path/to/wing_profile.png", + tags="section=images project=wing_sim", + ) + image_item.save() + +Rendering Items +--------------- + +Items can be rendered individually into HTML fragments using the `render()` method. +This HTML can then be embedded in reports or served directly. + +.. code-block:: python + + html_fragment = string_item.render(context={}) + print(html_fragment) + +Querying Items +-------------- + +You can query items using the ADR `query()` method with filters based on tags, names, types, and other metadata. + +.. code-block:: python + + items = adr.query( + query_type=String, + query="A|i_tags|cont|project=wing_sim;A|i_name|cont|summary;" + ) + +Lifecycle Notes +--------------- + +- Items must be associated with saved Sessions and Datasets before calling `save()`. +- Modifying an item’s content or metadata requires calling `save()` again to persist changes. +- Deleting an item removes it from the database and deletes associated media files, if any. +- Proper session and dataset management is critical to maintain report integrity and provenance. +- Validation errors are raised if content does not meet item-specific requirements. + +Exceptions and Validation +------------------------- + +- Attempting to create or save items without required fields or with invalid content raises validation errors. +- File-based items validate file existence and format before saving. +- Fetching or querying non-existent items raises a `DoesNotExist` exception. +- Multiple items matching a single fetch criteria raise a `MultipleObjectsReturned` exception. + +Summary +------- + +Items encapsulate the actual data and content in your reports. Understanding item types, content validation, and lifecycle management is essential for effective Serverless ADR usage. + +Next, explore the :doc:`templates` guide to learn how to arrange items into complex, reusable report layouts. From 95d12b76f83007b53b32e97947539ea311b2dc02 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:11:12 -0400 Subject: [PATCH 16/50] Update sessions_and_datasets.rst --- .../serverless/sessions_and_datasets.rst | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index ac5b68175..6879566e2 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -25,6 +25,31 @@ data push or analysis run, such as date, hostname, platform, and application ver - **Dataset**: Stores metadata about the dataset or collection of simulation or analysis data, such as files, formats, and element counts. +Session and Dataset Properties and Metadata +------------------------------------------- + +Sessions and Datasets include important properties and metadata fields that help organize and contextualize your data: + +- **Session properties:** + - **guid**: Unique identifier for the session. + - **date**: Timestamp of when the session was created or recorded. + - **hostname**: The machine or environment where the data push originated. + - **platform**: Operating system or platform information. + - **application**: Name of the application or tool that created the session. + - **version**: Version of the application or tool. + - **tags**: Space-separated string of key or key=value tags for filtering and classification. + +- **Dataset properties:** + - **guid**: Unique identifier for the dataset. + - **filename**: Name of the data file associated with the dataset. + - **dirname**: Directory path or location related to the dataset. + - **format**: Data format descriptor (e.g., CDB, CSV). + - **numparts**: Number of parts or segments in the dataset. + - **numelements**: Number of elements (e.g., mesh elements) in the dataset. + - **tags**: Space-separated string of key or key=value tags for filtering and classification. + +Both Sessions and Datasets play a key role in associating your report items with the proper data context and provenance. + Creating Sessions and Datasets ------------------------------ From 3fb0085ac241e98260f8d1aedf700d76377559eb Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:12:08 -0400 Subject: [PATCH 17/50] Update sessions_and_datasets.rst --- doc/source/serverless/sessions_and_datasets.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index 6879566e2..f065ded98 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -125,8 +125,8 @@ unless you specify different ones explicitly. dataset=dataset, ) -Sessions and Datasets Lifecycle Notes -------------------------------------- +Lifecycle Notes +--------------- - Sessions and datasets must be saved before creating dependent items. - Changing the default session or dataset affects all subsequent item creations From 1030ef98c25eb340c8856932474bc81f79fac58f Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:18:01 -0400 Subject: [PATCH 18/50] Update templates.rst --- doc/source/serverless/templates.rst | 186 ++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/doc/source/serverless/templates.rst b/doc/source/serverless/templates.rst index e69de29bb..ee28ebd93 100644 --- a/doc/source/serverless/templates.rst +++ b/doc/source/serverless/templates.rst @@ -0,0 +1,186 @@ +Templates +========= + +Templates in Serverless ADR define the **layout**, **organization**, and **presentation** +of your report content. They control how Items are arranged, filtered, and rendered +within a report, enabling flexible, reusable, and dynamic reporting structures. + +Overview +-------- + +Templates are Python classes derived from the base ``Template`` model. They come in two main flavors: + +- **Layouts**: Define static or semi-static page structures (e.g., panels, tabs, carousels). +- **Generators**: Automate dynamic content generation by iterating, merging, filtering, or sorting Items. + +Templates can be nested hierarchically to form complex reports with multiple sections and subsections. + +Key Template Types +------------------ + +Some common built-in layout types: + +- ``BasicLayout``: Simple container for report content with minimal structure. +- ``PanelLayout``: Defines a panel section, often used for grouping related content. +- ``BoxLayout``, ``TabLayout``, ``CarouselLayout``, ``SliderLayout``: Provide different UI paradigms for organizing items. +- ``TOCLayout``: Automatically generates a table of contents. +- ``HeaderLayout`` and ``FooterLayout``: Static header and footer regions. +- ``PPTXLayout`` and ``PPTXSlideLayout``: For PowerPoint integration and slide control. + +Some important generator types: + +- ``IteratorGenerator``: Iterates over a set of items and applies a sub-template. +- ``TableMergeGenerator`` and related filter generators: Merge, reduce, or filter tabular data. +- ``StatisticalGenerator``: Produces statistics or aggregated views of data. +- ``SQLQueryGenerator``: Executes SQL queries to produce data-driven content. + +Creating Templates +------------------ + +Use the ADR instance’s ``create_template()`` method to create a new template object. + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import BasicLayout + + top_template = adr.create_template( + BasicLayout, + name="Wing Simulation Report", + parent=None, + tags="project=wing_sim", + ) + top_template.params = '{"HTML": "

Wing Simulation Report

"}' + top_template.set_filter("A|i_tags|cont|project=wing_sim;") + top_template.save() + +Parent-child relationships can be established by passing a ``parent`` template during creation or by appending to ``parent.children`` and saving both. + +Template Parameters and Properties +---------------------------------- + +Each template stores configuration and state in its ``params`` field, a JSON string representing: + +- HTML content or raw strings (e.g., ``"HTML"``) +- Layout-specific options (e.g., column counts, widths) +- Filter parameters and modes controlling which Items are included +- Sorting options (fields, order, selection) +- Custom properties for user-defined metadata + +You can manipulate these through provided methods: + +- ``get_params()`` / ``set_params(dict)`` +- ``add_params(dict)`` to merge parameters +- ``get_property()`` / ``set_property(dict)`` / ``add_property(dict)`` for the ``properties`` subset +- Sorting and filtering helpers (e.g., ``get_sort_fields()``, ``set_sort_fields()``, ``get_filter_mode()``, ``set_filter_mode()``) + +Example modifying parameters: + +.. code-block:: python + + params = top_template.get_params() + params["HTML"] = "

Updated Report Title

" + top_template.set_params(params) + top_template.save() + +Filters +------- + +Filters control which Items are included in a template’s rendered output. + +- Set via ``set_filter(filter_str)``, where ``filter_str`` is a query string, e.g., + ``"A|i_tags|cont|section=intro;"`` selects items tagged "section=intro". + +- Filters can be extended via ``add_filter()``. + +Sorting +------- + +Templates can specify sorting of items by fields using: + +- ``set_sort_fields([...])`` for sorting keys (e.g., ``["date", "name"]``) +- ``set_sort_selection("all" | "first" | "last")`` to choose which items from sorted groups to show. + +Child Templates and Ordering +---------------------------- + +Templates maintain ordered children to compose hierarchical reports. + +- The ``children`` attribute holds nested templates. +- ``children_order`` is a string of comma-separated GUIDs determining rendering order. +- Call ``reorder_children()`` to sync children list order with ``children_order`` field. + +Rendering Templates +------------------ + +Templates can render themselves into complete HTML content using the ``render()`` method. + +.. code-block:: python + + html_report = top_template.render(context={}, item_filter="A|i_tags|cont|project=wing_sim;") + with open("report.html", "w", encoding="utf-8") as f: + f.write(html_report) + +Rendering context supports options like: + +- ``plotly`` flag to enable interactive plots +- Page dimensions and DPI for layout calculations +- Date and time formatting + +Error Handling +-------------- + +If rendering fails, the output HTML will contain an error message for easier debugging. + +Lifecycle Notes +--------------- + +- Templates must be saved to persist changes. +- Parent templates must be saved before saving children. +- Children templates must be saved before their parent saves can complete successfully. +- Deleting a template typically requires handling or deleting its children to avoid orphaned templates. + +Exceptions and Validation +------------------------- + +- Creating or fetching templates with missing or invalid fields raises validation errors. +- Attempting to instantiate the base ``Template`` class directly raises an error. +- Filters using restricted keys (like ``t_types|``) are disallowed on subclasses. +- Invalid parent references or child types will raise type or integrity errors during saving. + +Example: Creating a Nested Template Structure +--------------------------------------------- + +.. code-block:: python + + toc = adr.create_template( + TOCLayout, + name="Table of Contents", + parent=top_template, + tags="project=wing_sim", + ) + toc.params = '{"HTML": "

Contents

"}' + toc.set_filter("A|i_name|eq|__NonexistentName__;") + toc.save() + + results_panel = adr.create_template( + PanelLayout, + name="Results", + parent=top_template, + tags="project=wing_sim", + ) + results_panel.params = '{"HTML": "

Results

Simulation data and figures.

"}' + results_panel.set_filter("A|i_tags|cont|section=results;") + results_panel.save() + + top_template.children.append(results_panel) + top_template.save() + +Summary +------- + +Templates are the backbone of report structure in Serverless ADR. They let you create +rich, dynamic, and highly customizable reports by defining layouts and generators, +setting filters and parameters, and nesting templates to build complex hierarchical reports. + +Next, move on to the :doc:`rendering` guide to learn how to convert templates and items +into final HTML reports for presentation or web serving. From 6fc486db6c5e8cecbc3557b59bcb8f36c0fc10a8 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:20:52 -0400 Subject: [PATCH 19/50] Update templates.rst --- doc/source/serverless/templates.rst | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/doc/source/serverless/templates.rst b/doc/source/serverless/templates.rst index ee28ebd93..f531d397b 100644 --- a/doc/source/serverless/templates.rst +++ b/doc/source/serverless/templates.rst @@ -131,6 +131,83 @@ Error Handling If rendering fails, the output HTML will contain an error message for easier debugging. +Template Properties +------------------- + +Templates support a flexible set of properties stored within the ``params`` JSON field. +These properties allow you to control fine-grained behavior of layouts and generators +and customize rendering without subclassing. + +Common Properties +~~~~~~~~~~~~~~~~~ + +- **HTML** + Raw HTML content to include directly in the template output. Useful for static text or custom markup. + +- **comments** + User-defined comments or notes related to the template. These are not rendered but stored for reference. + +- **column_count** (layouts only) + Number of columns in multi-column layouts. + +- **column_widths** (layouts only) + List of floats defining relative widths of columns, e.g., ``[1.0, 2.0, 1.0]``. + +- **transpose** (layouts only) + Integer flag (0 or 1) to indicate whether tabular content should be transposed. + +- **skip_empty** (layouts only) + Integer flag (0 or 1) to skip rendering empty items or not. + +- **sort_fields** + List of fields by which to sort included items. + +- **sort_selection** + Determines which items to select after sorting. Allowed values: + ``"all"``, ``"first"``, ``"last"``. + +- **filter_type** + Controls filter application mode. Options include: + ``"items"``, ``"root_replace"``, ``"root_append"``. + +Adding and Modifying Properties +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can use the following methods on a template instance to interact with properties: + +.. code-block:: python + + # Get all properties dictionary + props = template.get_property() + + # Set all properties at once (replaces existing) + template.set_property({"column_count": 3, "skip_empty": 1}) + + # Add or update specific properties without overwriting others + template.add_property({"comments": "Reviewed on 2025-06-20"}) + +Examples +~~~~~~~~ + +.. code-block:: python + + # Set multiple properties at creation + layout = adr.create_template( + BasicLayout, + name="Summary Section", + tags="section=summary", + ) + layout.set_property({ + "column_count": 2, + "column_widths": [1.0, 1.5], + "skip_empty": 1, + }) + layout.save() + + # Update an existing property + layout.add_property({"comments": "Updated to include additional charts"}) + layout.save() + Lifecycle Notes --------------- @@ -146,6 +223,7 @@ Exceptions and Validation - Attempting to instantiate the base ``Template`` class directly raises an error. - Filters using restricted keys (like ``t_types|``) are disallowed on subclasses. - Invalid parent references or child types will raise type or integrity errors during saving. +- Only top-level templates (parent=None) can be copied between databases. Example: Creating a Nested Template Structure --------------------------------------------- From f14549792b1d3bdfe3ac7b098bd1ac890afa9132 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:52:25 -0400 Subject: [PATCH 20/50] Update template.py --- src/ansys/dynamicreporting/core/serverless/template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/dynamicreporting/core/serverless/template.py b/src/ansys/dynamicreporting/core/serverless/template.py index 65bad739d..a1785b8e3 100644 --- a/src/ansys/dynamicreporting/core/serverless/template.py +++ b/src/ansys/dynamicreporting/core/serverless/template.py @@ -53,7 +53,7 @@ class Template(BaseModel): compare=False, init=False, default="" ) # computed from self.children _master: bool = field(compare=False, init=False, default=True) - _properties: tuple = tuple() # todo: add properties of each type ref: report_objects + _properties: tuple = tuple() # todo: add properties for each type ref: report_objects _orm_model: str = "reports.models.Template" # Class-level registry of subclasses keyed by type _type_registry = {} From c2958914d30ed55322e210453e286f74d739a64d Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:52:27 -0400 Subject: [PATCH 21/50] Update templates.rst --- doc/source/serverless/templates.rst | 239 +++++++++++++++++----------- 1 file changed, 147 insertions(+), 92 deletions(-) diff --git a/doc/source/serverless/templates.rst b/doc/source/serverless/templates.rst index f531d397b..3badf6baa 100644 --- a/doc/source/serverless/templates.rst +++ b/doc/source/serverless/templates.rst @@ -4,6 +4,7 @@ Templates Templates in Serverless ADR define the **layout**, **organization**, and **presentation** of your report content. They control how Items are arranged, filtered, and rendered within a report, enabling flexible, reusable, and dynamic reporting structures. +The represent report layouts or data generators that organize and present report items. Overview -------- @@ -15,25 +16,6 @@ Templates are Python classes derived from the base ``Template`` model. They come Templates can be nested hierarchically to form complex reports with multiple sections and subsections. -Key Template Types ------------------- - -Some common built-in layout types: - -- ``BasicLayout``: Simple container for report content with minimal structure. -- ``PanelLayout``: Defines a panel section, often used for grouping related content. -- ``BoxLayout``, ``TabLayout``, ``CarouselLayout``, ``SliderLayout``: Provide different UI paradigms for organizing items. -- ``TOCLayout``: Automatically generates a table of contents. -- ``HeaderLayout`` and ``FooterLayout``: Static header and footer regions. -- ``PPTXLayout`` and ``PPTXSlideLayout``: For PowerPoint integration and slide control. - -Some important generator types: - -- ``IteratorGenerator``: Iterates over a set of items and applies a sub-template. -- ``TableMergeGenerator`` and related filter generators: Merge, reduce, or filter tabular data. -- ``StatisticalGenerator``: Produces statistics or aggregated views of data. -- ``SQLQueryGenerator``: Executes SQL queries to produce data-driven content. - Creating Templates ------------------ @@ -53,10 +35,70 @@ Use the ADR instance’s ``create_template()`` method to create a new template o top_template.set_filter("A|i_tags|cont|project=wing_sim;") top_template.save() -Parent-child relationships can be established by passing a ``parent`` template during creation or by appending to ``parent.children`` and saving both. +Parent-child relationships can be established by passing a ``parent`` +template during creation or by appending to ``parent.children`` and saving both. + +Template Types +-------------- -Template Parameters and Properties ----------------------------------- +Common layout types include: + +- BasicLayout +- PanelLayout +- BoxLayout +- TabLayout +- CarouselLayout +- SliderLayout +- FooterLayout +- HeaderLayout +- IteratorLayout +- TagPropertyLayout +- TOCLayout +- ReportLinkLayout +- PPTXLayout +- PPTXSlideLayout +- DataFilterLayout +- UserDefinedLayout + +Generator types include: + +- TableMergeGenerator +- TableReduceGenerator +- TableMergeRCFilterGenerator +- TableMergeValueFilterGenerator +- TableSortFilterGenerator +- TreeMergeGenerator +- SQLQueryGenerator +- ItemsComparisonGenerator +- StatisticalGenerator +- IteratorGenerator + +Template Attributes and Methods +------------------------------- + +Templates have several important properties and methods: + +- ``name``: The template’s unique name. +- ``params``: JSON-encoded string storing rendering parameters and properties. +- ``item_filter``: Query string filter to select items included in this template. +- ``parent``: Reference to the parent template or None for root templates. +- ``children``: List of child templates for hierarchical organization. +- ``report_type``: String representing the template’s layout or generator type. + +Common methods include: + +- ``set_filter(filter_str)``: Replace the item filter string. +- ``add_filter(filter_str)``: Append to the existing item filter. +- ``get_params()``: Return parsed parameters as a dictionary. +- ``set_params(params_dict)``: Set parameters, replacing existing ones. +- ``add_params(params_dict)``: Add or update parameters without overwriting others. +- ``get_property()``: Shortcut to get the “properties” sub-dictionary from parameters. +- ``set_property(props_dict)``: Replace the “properties” dictionary. +- ``add_property(props_dict)``: Add/update keys within the “properties” dictionary. +- ``render(context=None, item_filter="", request=None)``: Render the template to HTML string. + +Template Parameters +------------------- Each template stores configuration and state in its ``params`` field, a JSON string representing: @@ -64,7 +106,7 @@ Each template stores configuration and state in its ``params`` field, a JSON str - Layout-specific options (e.g., column counts, widths) - Filter parameters and modes controlling which Items are included - Sorting options (fields, order, selection) -- Custom properties for user-defined metadata +- Custom properties for configuration and behavior You can manipulate these through provided methods: @@ -82,55 +124,6 @@ Example modifying parameters: top_template.set_params(params) top_template.save() -Filters -------- - -Filters control which Items are included in a template’s rendered output. - -- Set via ``set_filter(filter_str)``, where ``filter_str`` is a query string, e.g., - ``"A|i_tags|cont|section=intro;"`` selects items tagged "section=intro". - -- Filters can be extended via ``add_filter()``. - -Sorting -------- - -Templates can specify sorting of items by fields using: - -- ``set_sort_fields([...])`` for sorting keys (e.g., ``["date", "name"]``) -- ``set_sort_selection("all" | "first" | "last")`` to choose which items from sorted groups to show. - -Child Templates and Ordering ----------------------------- - -Templates maintain ordered children to compose hierarchical reports. - -- The ``children`` attribute holds nested templates. -- ``children_order`` is a string of comma-separated GUIDs determining rendering order. -- Call ``reorder_children()`` to sync children list order with ``children_order`` field. - -Rendering Templates ------------------- - -Templates can render themselves into complete HTML content using the ``render()`` method. - -.. code-block:: python - - html_report = top_template.render(context={}, item_filter="A|i_tags|cont|project=wing_sim;") - with open("report.html", "w", encoding="utf-8") as f: - f.write(html_report) - -Rendering context supports options like: - -- ``plotly`` flag to enable interactive plots -- Page dimensions and DPI for layout calculations -- Date and time formatting - -Error Handling --------------- - -If rendering fails, the output HTML will contain an error message for easier debugging. - Template Properties ------------------- @@ -141,12 +134,6 @@ and customize rendering without subclassing. Common Properties ~~~~~~~~~~~~~~~~~ -- **HTML** - Raw HTML content to include directly in the template output. Useful for static text or custom markup. - -- **comments** - User-defined comments or notes related to the template. These are not rendered but stored for reference. - - **column_count** (layouts only) Number of columns in multi-column layouts. @@ -170,6 +157,8 @@ Common Properties Controls filter application mode. Options include: ``"items"``, ``"root_replace"``, ``"root_append"``. + ... and many more depending on the specific layout or generator. + Adding and Modifying Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -184,7 +173,7 @@ You can use the following methods on a template instance to interact with proper template.set_property({"column_count": 3, "skip_empty": 1}) # Add or update specific properties without overwriting others - template.add_property({"comments": "Reviewed on 2025-06-20"}) + template.add_property({"column_count": 2}) Examples ~~~~~~~~ @@ -208,22 +197,40 @@ Examples layout.add_property({"comments": "Updated to include additional charts"}) layout.save() -Lifecycle Notes ---------------- +Notes +~~~~~ -- Templates must be saved to persist changes. -- Parent templates must be saved before saving children. -- Children templates must be saved before their parent saves can complete successfully. -- Deleting a template typically requires handling or deleting its children to avoid orphaned templates. +- Properties are stored as JSON under ``params`` → ``properties``. +- They provide a flexible way to extend template capabilities without subclassing. +- Some specialized layouts and generators may define their own additional properties accessible through their own APIs. -Exceptions and Validation -------------------------- +Filters +------- -- Creating or fetching templates with missing or invalid fields raises validation errors. -- Attempting to instantiate the base ``Template`` class directly raises an error. -- Filters using restricted keys (like ``t_types|``) are disallowed on subclasses. -- Invalid parent references or child types will raise type or integrity errors during saving. -- Only top-level templates (parent=None) can be copied between databases. +Filters control which Items are included in a template’s rendered output. + +- Set via ``set_filter(filter_str)``, where ``filter_str`` is a query string, e.g., + ``"A|i_tags|cont|section=intro;"`` selects items tagged "section=intro". + +- Filters can be extended via ``add_filter()``. + +Sorting +------- + +Templates can specify sorting of items by fields using: + +- ``set_sort_fields([...])`` for sorting keys (e.g., ``["date", "name"]``) +- ``set_sort_selection("all" | "first" | "last")`` to choose which items from sorted groups to show. + +Working with Template Hierarchies +--------------------------------- + +Templates can be organized in parent-child relationships to structure complex reports. + +- Use the ``parent`` argument to specify a template’s parent during creation. +- The ``children`` list contains all direct child templates. +- The ``children_order`` property stores the ordered GUIDs of children for rendering order. +- The ``reorder_children()`` method will reorder the ``children`` list based on the stored order. Example: Creating a Nested Template Structure --------------------------------------------- @@ -253,6 +260,54 @@ Example: Creating a Nested Template Structure top_template.children.append(results_panel) top_template.save() + +Rendering Templates +------------------ + +Templates can render themselves into complete HTML content using the ``render()`` method. + +.. code-block:: python + + html_report = top_template.render(context={}, item_filter="A|i_tags|cont|project=wing_sim;") + with open("report.html", "w", encoding="utf-8") as f: + f.write(html_report) + +This method generates the full HTML output, including all nested templates and items, +and applies any specified filters. The ``context`` parameter can be used to pass additional +data for rendering, such as user-defined variables or configuration settings. + +Rendering context supports options like: + +- ``plotly`` flag to enable interactive plots +- Page dimensions and DPI for layout calculations +- Date and time formatting + +- If rendering fails, the output HTML will contain an error message for easier debugging. + +- If you would like more information on the error, set the ``debug`` flag to ``True`` when instantiating + the ``ADR`` class. + +Lifecycle Notes +--------------- + +- Templates must be saved to persist changes. +- Parent templates must be saved before saving children. +- Children templates must be saved before their parent saves can complete successfully. +- Deleting a template typically requires handling or deleting its children to avoid orphaned templates. + +Exceptions and Validation +------------------------- + +- Creating or fetching templates with missing or invalid fields raises validation errors. +- Attempting to instantiate the base ``Template`` class directly raises an error. +- Filters using restricted keys (like ``t_types|``) are disallowed on subclasses. +- Invalid parent references or child types will raise type or integrity errors during saving. +- Only top-level templates (parent=None) can be copied between databases. +- Templates must have their parents and children saved before saving themselves to ensure integrity. +- Invalid property types or malformed filters raise errors. +- Fetching non-existent templates raises ``DoesNotExist`` errors. +- Using invalid filter keys in subclasses raises ``ADRException``. + Summary ------- From cd6cf7b11158258467295af40490a6585b4bcc06 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:52:30 -0400 Subject: [PATCH 22/50] Update items.rst --- doc/source/serverless/items.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/source/serverless/items.rst b/doc/source/serverless/items.rst index 9094ca7f5..d8e0d68c9 100644 --- a/doc/source/serverless/items.rst +++ b/doc/source/serverless/items.rst @@ -124,6 +124,8 @@ Lifecycle Notes - Deleting an item removes it from the database and deletes associated media files, if any. - Proper session and dataset management is critical to maintain report integrity and provenance. - Validation errors are raised if content does not meet item-specific requirements. +- Attempting to instantiate an item type directly (e.g., `Item()`) raises an error; + always use the specific item classes like `String`, `Table`, etc. Exceptions and Validation ------------------------- From 60bd80369ee32a2e3aba2a89233857f3bac81106 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:58:44 -0400 Subject: [PATCH 23/50] Update templates.rst --- doc/source/serverless/templates.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/source/serverless/templates.rst b/doc/source/serverless/templates.rst index 3badf6baa..2b35ba7f8 100644 --- a/doc/source/serverless/templates.rst +++ b/doc/source/serverless/templates.rst @@ -175,6 +175,29 @@ You can use the following methods on a template instance to interact with proper # Add or update specific properties without overwriting others template.add_property({"column_count": 2}) +Direct Attribute Access +~~~~~~~~~~~~~~~~~~~~~~ + +Alternatively, some common properties can also be accessed or set using standard attribute +syntax on the template instance. For example: + +.. code-block:: python + + # Set a property using attribute assignment + pptx_template.use_all_slides = 0 + + # Get a property value via attribute access + output_pptx = pptx_template.output_pptx + +You can also use Python’s built-in ``setattr()`` function to set properties dynamically: + +.. code-block:: python + + setattr(template, "output_pptx", "report.pptx") + +Note that attribute access is a convenient shortcut for common properties. +Under the hood, these are proxied to the underlying JSON ``params`` data. + Examples ~~~~~~~~ From c5985281bccda7aa5324026b2b5cab264641e117 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:10:40 -0400 Subject: [PATCH 24/50] Delete rendering.rst --- doc/source/serverless/rendering.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/source/serverless/rendering.rst diff --git a/doc/source/serverless/rendering.rst b/doc/source/serverless/rendering.rst deleted file mode 100644 index e69de29bb..000000000 From a32d5678a89e22b4fea732117f00ea8fb3946d0a Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:10:44 -0400 Subject: [PATCH 25/50] Update index.rst --- doc/source/serverless/index.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/source/serverless/index.rst b/doc/source/serverless/index.rst index f908153c8..7800c128a 100644 --- a/doc/source/serverless/index.rst +++ b/doc/source/serverless/index.rst @@ -61,7 +61,6 @@ Explore the docs sessions_and_datasets items templates - rendering querying media_and_static embedding_reports From 5194fc19a9f1db509eab5c5f4ae82accaccd4322 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:10:48 -0400 Subject: [PATCH 26/50] Update querying.rst --- doc/source/serverless/querying.rst | 165 +++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/doc/source/serverless/querying.rst b/doc/source/serverless/querying.rst index e69de29bb..d7b958f61 100644 --- a/doc/source/serverless/querying.rst +++ b/doc/source/serverless/querying.rst @@ -0,0 +1,165 @@ +Querying +======== + +Serverless ADR provides flexible querying capabilities to retrieve your report data objects, +including **Items**, **Templates**, **Sessions**, and **Datasets**. This lets you find and +filter report content efficiently by attributes, tags, or complex query strings. + +Query Methods +------------- + +The main query methods are available on each model class: + +- ``get(**kwargs)`` + Retrieve a single object matching the given field filters. + Raises an exception if zero or multiple objects are found. + +- ``filter(**kwargs)`` + Return an ``ObjectSet`` containing all objects matching the filters. + +- ``find(query: str, **kwargs)`` + Perform an advanced query using the ADR query language syntax. + +Examples +-------- + +**Fetch a single Session by GUID:** + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import Session + + session = Session.get(guid="4ee905f0-f611-11e6-8901-ae3af682bb6a") + print(session.hostname, session.application) + +**Filter Items by tag substring:** + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import Item + + session = Session.get(guid="4ee905f0-f611-11e6-8901-ae3af682bb6a") + items = Item.filter(session=session) + for item in items: + print(item.name, item.tags) + +**Find Items with a custom ADR query string:** + +.. code-block:: python + + query_str = "A|i_tags|cont|project=wing_sim;A|i_name|eq|summary_text;" + matching_items = Item.find(query=query_str) + print(f"Found {len(matching_items)} matching items") + +Subclass Queries +---------------- + +When using subclasses like ``HTML`` or ``BasicLayout``, queries automatically filter by the subclass type. +Explicitly adding type filters (e.g., ``i_type|eq|html``) in query strings is disallowed and will raise an exception. + +**Correct usage:** + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import HTML + + html_items = HTML.find(query="A|i_tags|cont|intro;") + for html in html_items: + print(html.name) + +**Incorrect usage (raises exception):** + +.. code-block:: python + + html_items = HTML.find(query="A|i_type|eq|html;") # Raises ADRException + +Understanding ADR Query Strings +------------------------------- + +ADR queries use the format: + +``Scope|Field|Operation|Value;`` + + +- **Scope**: Object scope, e.g., ``A`` for all items. +- **Field**: Field name, e.g., ``i_tags`` for item tags. +- **Operation**: Comparison operator, e.g., ``cont`` (contains), ``eq`` (equals). +- **Value**: The value to compare. + +Multiple filters are combined with a logical AND. + +Example: +``A|i_tags|cont|project=wing_sim;A|i_name|eq|summary_text;`` + +Matches items tagged ``project=wing_sim`` AND named ``summary_text``. + +Querying Sessions and Datasets +------------------------------ + +Sessions and Datasets support similar querying by their fields. + +**Get a Dataset by filename:** + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import Dataset + + dataset = Dataset.get(filename="results.cdb") + print(dataset.format, dataset.numparts) + +**Filter Datasets by format:** + +.. code-block:: python + + cdb_datasets = Dataset.filter(format="cdb") + for ds in cdb_datasets: + print(ds.filename) + +Working with Query Results +-------------------------- + +- ``get()`` returns a single model instance. +- ``filter()`` and ``find()`` return an ``ObjectSet`` that behaves like a list. + +You can iterate over results, use ``len()``, or index them: + +.. code-block:: python + + for item in items: + print(item.name, item.tags) + + print(f"Total items: {len(items)}") + first_item = items[0] + +Error Handling +-------------- + +- ``DoesNotExist``: Raised when ``get()`` finds no match. +- ``MultipleObjectsReturned``: Raised when ``get()`` finds multiple matches. +- ``ADRException``: Raised for invalid queries or disallowed filters. + +Example: + +.. code-block:: python + + try: + session = Session.get(guid="non-existent-guid") + except Session.DoesNotExist: + print("Session not found") + +Summary +------- + +Querying in Serverless ADR allows precise and flexible data retrieval using: + +- Field filters for common attributes +- Tag substring filters +- Powerful ADR query language strings +- Subclass-specific automatic type filtering + +Use querying to tailor report content dynamically for analysis and generation. + +Next Steps +---------- + +See the :doc:`media_and_static` guide for managing media and static files linked to your reports. From 7f67a760005ca88fb13f78ed053d78a4832bbbf6 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:15:32 -0400 Subject: [PATCH 27/50] Update items.rst --- doc/source/serverless/items.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/serverless/items.rst b/doc/source/serverless/items.rst index d8e0d68c9..b57d24d25 100644 --- a/doc/source/serverless/items.rst +++ b/doc/source/serverless/items.rst @@ -132,6 +132,7 @@ Exceptions and Validation - Attempting to create or save items without required fields or with invalid content raises validation errors. - File-based items validate file existence and format before saving. +- Querying items with incorrect syntax or unsupported operations raises an `ADRException`. - Fetching or querying non-existent items raises a `DoesNotExist` exception. - Multiple items matching a single fetch criteria raise a `MultipleObjectsReturned` exception. From 9dc12e4a411ad9967b1c75f484ba36130042bbb5 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:15:36 -0400 Subject: [PATCH 28/50] Update sessions_and_datasets.rst --- doc/source/serverless/sessions_and_datasets.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index f065ded98..8f7b3e7a1 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -139,6 +139,7 @@ Exceptions and Validation - Creating or modifying sessions and datasets will raise errors if required fields are missing or invalid. +- Querying items with incorrect syntax or unsupported operations raises an `ADRException`. - Fetching non-existent sessions or datasets by GUID raises a ``DoesNotExist`` error. - Multiple objects returned for a single fetch raises a ``MultipleObjectsReturned`` error. From 88e20aeef37bc1c7e0c9183268e5a8be255b9f44 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:16:16 -0400 Subject: [PATCH 29/50] Update querying.rst --- doc/source/serverless/querying.rst | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/doc/source/serverless/querying.rst b/doc/source/serverless/querying.rst index d7b958f61..ae61d249a 100644 --- a/doc/source/serverless/querying.rst +++ b/doc/source/serverless/querying.rst @@ -11,15 +11,24 @@ Query Methods The main query methods are available on each model class: - ``get(**kwargs)`` + Retrieve a single object matching the given field filters. Raises an exception if zero or multiple objects are found. - ``filter(**kwargs)`` + Return an ``ObjectSet`` containing all objects matching the filters. - ``find(query: str, **kwargs)`` + Perform an advanced query using the ADR query language syntax. +- ``ADR.query(query_type, *, query="", **kwargs)`` + + A static method that allows querying across any of the core object types + by specifying the type explicitly (`Item`, `Template`, `Session`, or `Dataset`). + Returns an ``ObjectSet`` of matching objects. + Examples -------- @@ -51,6 +60,16 @@ Examples matching_items = Item.find(query=query_str) print(f"Found {len(matching_items)} matching items") +**Use the static ADR query method to find Sessions with a name:** + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR, Session + + sessions = ADR.query(Session, query="A|s_name|eq|Test Session;") + for s in sessions: + print(s.guid, s.date) + Subclass Queries ---------------- @@ -78,10 +97,9 @@ Understanding ADR Query Strings ADR queries use the format: -``Scope|Field|Operation|Value;`` - +``Connector|Field|Operation|Value;`` -- **Scope**: Object scope, e.g., ``A`` for all items. +- **Connector**: Connector to chain multiple queries, e.g., ``A`` for 'AND' and ``O`` for 'OR'. - **Field**: Field name, e.g., ``i_tags`` for item tags. - **Operation**: Comparison operator, e.g., ``cont`` (contains), ``eq`` (equals). - **Value**: The value to compare. @@ -89,6 +107,7 @@ ADR queries use the format: Multiple filters are combined with a logical AND. Example: + ``A|i_tags|cont|project=wing_sim;A|i_name|eq|summary_text;`` Matches items tagged ``project=wing_sim`` AND named ``summary_text``. @@ -119,7 +138,7 @@ Working with Query Results -------------------------- - ``get()`` returns a single model instance. -- ``filter()`` and ``find()`` return an ``ObjectSet`` that behaves like a list. +- ``filter()``, ``find()``, and ``ADR.query()`` return an ``ObjectSet`` that behaves like a list. You can iterate over results, use ``len()``, or index them: @@ -137,6 +156,7 @@ Error Handling - ``DoesNotExist``: Raised when ``get()`` finds no match. - ``MultipleObjectsReturned``: Raised when ``get()`` finds multiple matches. - ``ADRException``: Raised for invalid queries or disallowed filters. +- ``TypeError``: Raised by ``ADR.query()`` if an invalid model type is passed. Example: @@ -146,6 +166,8 @@ Example: session = Session.get(guid="non-existent-guid") except Session.DoesNotExist: print("Session not found") + except Session.MultipleObjectsReturned: + print("Multiple sessions matched") Summary ------- From 996bec6791e22b977b1747d0764db269b4fe923c Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:21:14 -0400 Subject: [PATCH 30/50] Update media_and_static.rst --- doc/source/serverless/media_and_static.rst | 132 +++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/doc/source/serverless/media_and_static.rst b/doc/source/serverless/media_and_static.rst index e69de29bb..8daa3e94a 100644 --- a/doc/source/serverless/media_and_static.rst +++ b/doc/source/serverless/media_and_static.rst @@ -0,0 +1,132 @@ +Media and Static Files +===================== + +Serverless ADR manages two important categories of assets that accompany your reports and items: + +- **Media files**: User-uploaded or generated files such as images, animations, 3D models, and other payloads associated with Items. +- **Static files**: Framework assets like CSS, JavaScript, fonts, and icons needed to properly render reports and web interfaces. + +This guide explains how media and static files are organized, accessed, and managed within Serverless ADR. + +Overview +-------- + +### Media Files + +Media files are stored separately from the database and linked to Items via file paths or URLs. Examples include: + +- Images (PNG, JPG, TIFF) +- Animation videos (MP4) +- 3D scene files (STL, OBJ, AVZ) +- Arbitrary user files + +These files reside in a configurable media directory, typically inside or alongside the database directory. + +### Static Files + +Static files contain the frontend resources required to render reports correctly. They include: + +- CSS stylesheets for layout and theming +- JavaScript libraries for interactivity (e.g., Plotly support) +- Fonts and icons + +Static files are collected and served from a configurable static directory. + +Configuration +------------- + +Both media and static directories can be set during ADR instantiation or setup via the following parameters: + +- ``media_directory``: Path where media files are stored. +- ``static_directory``: Path where static files are stored. +- ``media_url``: URL prefix for accessing media files (usually ``/media/``). +- ``static_url``: URL prefix for static files (usually ``/static/``). + +Example: + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + + adr = ADR( + ansys_installation="C:\\Program Files\\ANSYS Inc\\v252", + db_directory="C:\\ADR\\db", + media_directory="C:\\ADR\\db\\media", + static_directory="C:\\ADR\\static", + media_url="/media/", + static_url="/static/", + ) + adr.setup() + +File Storage and Access +----------------------- + +- Media files are saved with unique names based on the Item GUID and type, e.g., ``_image.png``. +- Items with associated files use the ``FilePayloadMixin`` to manage file storage and retrieval. +- The media directory should be accessible by any server or process serving reports or web content. +- Static files are collected during setup if ``collect_static=True`` is passed to ``ADR.setup()``. +- Static files can be served by any compatible web server or via built-in mechanisms in web frameworks. + +Working with Media Files in Items +--------------------------------- + +Many Item subclasses support files, such as: + +- ``Image`` +- ``Animation`` +- ``Scene`` +- ``File`` + +They use the ``FilePayloadMixin``, which provides properties and methods like: + +- ``file_path``: Absolute path to the stored file. +- ``has_file``: Boolean indicating if the file exists. +- ``file_ext``: File extension of the payload file. + +Saving Items with Files: + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import Image + + img_item = adr.create_item( + Image, + name="wing_profile", + content="C:\\images\\wing_profile.png", + tags="section=geometry", + ) + img_item.save() + +File Deletion and Cleanup +------------------------- + +- When an Item with file payload is deleted, the corresponding media file is also removed from the media directory. +- Manual cleanup may be necessary if files are moved or corrupted outside ADR. + +Best Practices +-------------- + +- Always configure media and static directories explicitly to avoid ambiguity. +- Ensure web servers serving reports have read access to media and static directories. +- Use unique tagging in Items to organize media assets logically. +- Use in-memory mode only for transient or test environments, as media files won’t persist. + +Troubleshooting +--------------- + +- **Missing files**: Verify the media directory path is correct and files exist. +- **Permission errors**: Check filesystem permissions for read/write access. +- **Static files not loading**: Confirm static files were collected during setup and served correctly. +- **Corrupted media**: Re-upload or regenerate media files; ensure valid file types. + +Summary +------- + +Media and static file management is crucial for full-fidelity report rendering in Serverless ADR. +Proper configuration and handling ensure smooth integration of rich content into your reports. + +Next Steps +---------- + +Proceed to the :doc:`embedding_reports` guide to learn how to embed Serverless ADR reports +within your own web applications or documentation portals. From f1ab973d9789898bca447c18ae81f020217141b4 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:27:16 -0400 Subject: [PATCH 31/50] Update media_and_static.rst --- doc/source/serverless/media_and_static.rst | 125 ++++++++++++++------- 1 file changed, 82 insertions(+), 43 deletions(-) diff --git a/doc/source/serverless/media_and_static.rst b/doc/source/serverless/media_and_static.rst index 8daa3e94a..70f7dd281 100644 --- a/doc/source/serverless/media_and_static.rst +++ b/doc/source/serverless/media_and_static.rst @@ -1,48 +1,50 @@ Media and Static Files ===================== -Serverless ADR manages two important categories of assets that accompany your reports and items: +Serverless ADR manages two key asset categories essential for rich report presentation: - **Media files**: User-uploaded or generated files such as images, animations, 3D models, and other payloads associated with Items. -- **Static files**: Framework assets like CSS, JavaScript, fonts, and icons needed to properly render reports and web interfaces. +- **Static files**: Framework assets including CSS, JavaScript, fonts, and icons required to render reports and web interfaces correctly. -This guide explains how media and static files are organized, accessed, and managed within Serverless ADR. +This guide covers the storage, access, lifecycle, and best practices for managing these files in Serverless ADR. Overview -------- -### Media Files +Media Files +~~~~~~~~~~~ -Media files are stored separately from the database and linked to Items via file paths or URLs. Examples include: +Media files complement your report Items and can include: - Images (PNG, JPG, TIFF) - Animation videos (MP4) -- 3D scene files (STL, OBJ, AVZ) -- Arbitrary user files +- 3D models and scenes (STL, OBJ, AVZ) +- Generic user files -These files reside in a configurable media directory, typically inside or alongside the database directory. +They are stored separately on disk in a **media directory** configured during ADR setup. Items reference media files by unique GUID-based filenames to avoid collisions and enable retrieval. -### Static Files +Static Files +~~~~~~~~~~~ -Static files contain the frontend resources required to render reports correctly. They include: +Static files provide the frontend styling and interactivity needed for report visualization. They include: -- CSS stylesheets for layout and theming -- JavaScript libraries for interactivity (e.g., Plotly support) +- CSS files for layout and themes +- JavaScript libraries (e.g., Plotly support) - Fonts and icons -Static files are collected and served from a configurable static directory. +Static files reside in a **static directory** and are served alongside media files, typically by a web server or via the framework’s static file handling. Configuration ------------- -Both media and static directories can be set during ADR instantiation or setup via the following parameters: +You configure media and static paths and URLs when instantiating and setting up the ADR object: -- ``media_directory``: Path where media files are stored. -- ``static_directory``: Path where static files are stored. -- ``media_url``: URL prefix for accessing media files (usually ``/media/``). -- ``static_url``: URL prefix for static files (usually ``/static/``). +- ``media_directory``: Path on disk for media files storage. +- ``static_directory``: Path on disk for static assets. +- ``media_url``: URL prefix to access media files (default: ``/media/``). +- ``static_url``: URL prefix to access static files (default: ``/static/``). -Example: +Example configuration: .. code-block:: python @@ -56,7 +58,7 @@ Example: media_url="/media/", static_url="/static/", ) - adr.setup() + adr.setup(collect_static=True) File Storage and Access ----------------------- @@ -66,24 +68,27 @@ File Storage and Access - The media directory should be accessible by any server or process serving reports or web content. - Static files are collected during setup if ``collect_static=True`` is passed to ``ADR.setup()``. - Static files can be served by any compatible web server or via built-in mechanisms in web frameworks. +- Items without files do not consume media storage. -Working with Media Files in Items ---------------------------------- +Managing Media Files in Items +----------------------------- -Many Item subclasses support files, such as: +Several Item subclasses support file payloads using the ``FilePayloadMixin``: - ``Image`` - ``Animation`` - ``Scene`` - ``File`` -They use the ``FilePayloadMixin``, which provides properties and methods like: +These classes provide convenient properties and methods: -- ``file_path``: Absolute path to the stored file. -- ``has_file``: Boolean indicating if the file exists. -- ``file_ext``: File extension of the payload file. +- ``file_path``: Returns the absolute file path on disk for the Item’s media. +- ``has_file``: Boolean indicating if the media file exists. +- ``file_ext``: File extension of the media file. +- ``save()``: Saves both the database record and copies the media file to the media directory. +- ``delete()``: Deletes the database record and removes the associated media file. -Saving Items with Files: +Example: Creating and saving an Image Item with a file .. code-block:: python @@ -97,36 +102,70 @@ Saving Items with Files: ) img_item.save() -File Deletion and Cleanup -------------------------- +Working with Media Files Directly +-------------------------------- -- When an Item with file payload is deleted, the corresponding media file is also removed from the media directory. -- Manual cleanup may be necessary if files are moved or corrupted outside ADR. +You can access media file paths from Items: + +.. code-block:: python + + print(img_item.file_path) # C:\ADR\db\media\_image.png + +Check if the item has a file associated with it: + +.. code-block:: python + + if img_item.has_file: + print("Media file is available.") + +Deleting Items cleans up media files automatically: + +.. code-block:: python + + img_item.delete() # Removes DB record and deletes the image file + +Static Files Collection and Serving +----------------------------------- + +- Static files are typically collected from ADR’s installed packages during setup by calling: + + ``adr.setup(collect_static=True)`` +- This process copies necessary CSS, JS, fonts, and icons into the configured static directory. +- Static files must be served by your web server or framework to enable proper report rendering. +- The static URL prefix (e.g., ``/static/``) must correspond to your web server configuration. + +In-Memory Mode and Temporary Files +---------------------------------- + +- When using ADR in in-memory mode (``in_memory=True``), media and static files are stored in temporary directories. +- These directories are automatically cleaned up when ADR closes, so media files do not persist beyond the session. +- This mode is useful for testing or transient report generation but not for production. Best Practices -------------- -- Always configure media and static directories explicitly to avoid ambiguity. -- Ensure web servers serving reports have read access to media and static directories. -- Use unique tagging in Items to organize media assets logically. -- Use in-memory mode only for transient or test environments, as media files won’t persist. +- Always explicitly configure media and static directories during ADR instantiation to avoid ambiguity. +- Ensure the media directory has sufficient disk space and correct read/write permissions. +- When serving reports on a web server, map the ``media_url`` and ``static_url`` to the correct directories. +- Use meaningful and consistent tags on Items to organize media assets logically. +- Avoid manually deleting or moving media files outside ADR to prevent broken links. Troubleshooting --------------- -- **Missing files**: Verify the media directory path is correct and files exist. -- **Permission errors**: Check filesystem permissions for read/write access. -- **Static files not loading**: Confirm static files were collected during setup and served correctly. -- **Corrupted media**: Re-upload or regenerate media files; ensure valid file types. +- **Media files missing:** Confirm media directory path is correct and files exist on disk. +- **Permission denied errors:** Verify file system permissions allow read/write by the ADR process and web server. +- **Static assets not loading:** Ensure static files were collected during setup and your web server serves the static directory correctly. +- **File corruption:** Re-upload or regenerate files; validate file types before saving. Summary ------- -Media and static file management is crucial for full-fidelity report rendering in Serverless ADR. -Proper configuration and handling ensure smooth integration of rich content into your reports. +Effective media and static file management is critical for generating rich, interactive reports with Serverless ADR. +Proper setup, naming conventions, and lifecycle handling ensure seamless integration of visual and data assets in your reports. Next Steps ---------- -Proceed to the :doc:`embedding_reports` guide to learn how to embed Serverless ADR reports +Explore the :doc:`embedding_reports` guide to learn how to embed Serverless ADR reports within your own web applications or documentation portals. From 521c857c97ec1a74300f9446fd1268eb729e6e00 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:28:39 -0400 Subject: [PATCH 32/50] Update media_and_static.rst --- doc/source/serverless/media_and_static.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/serverless/media_and_static.rst b/doc/source/serverless/media_and_static.rst index 70f7dd281..778a1dc99 100644 --- a/doc/source/serverless/media_and_static.rst +++ b/doc/source/serverless/media_and_static.rst @@ -67,7 +67,7 @@ File Storage and Access - Items with associated files use the ``FilePayloadMixin`` to manage file storage and retrieval. - The media directory should be accessible by any server or process serving reports or web content. - Static files are collected during setup if ``collect_static=True`` is passed to ``ADR.setup()``. -- Static files can be served by any compatible web server or via built-in mechanisms in web frameworks. +- Static files can be served by any compatible web server (eg. NGINX) or via built-in mechanisms in web frameworks. - Items without files do not consume media storage. Managing Media Files in Items From fb800cf5940ed81561d1ca73831550b70b77ce4f Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:35:20 -0400 Subject: [PATCH 33/50] Update embedding_reports.rst --- doc/source/serverless/embedding_reports.rst | 126 ++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/doc/source/serverless/embedding_reports.rst b/doc/source/serverless/embedding_reports.rst index e69de29bb..4cbf5c1ca 100644 --- a/doc/source/serverless/embedding_reports.rst +++ b/doc/source/serverless/embedding_reports.rst @@ -0,0 +1,126 @@ +Embedding Reports +================= + +Serverless ADR enables embedding fully rendered reports and report sections +into external web pages, dashboards, or applications. This allows you to +integrate dynamic ADR content seamlessly with other tools or UI frameworks. + +Overview +-------- + +Embedding involves generating HTML output from templates and items, then +injecting or serving that content within another application or web page. + +You can embed: + +- Entire reports (top-level templates) +- Specific report sections or sub-templates +- Individual report items (e.g., tables, images, summaries) + +Generating Embed-Ready HTML +--------------------------- + +Use the ``render_report()`` method of the ADR instance to render a complete +report or a subset of it as HTML. + +.. code-block:: python + + html_report = adr.render_report( + name="My Simulation Report", + context={"plotly": 1}, + item_filter="A|i_tags|cont|project=my_project;" + ) + +The resulting HTML string can then be inserted into your web page or +application container. + +Embedding Individual Items +-------------------------- + +You can also render individual report items using their ``render()`` method: + +.. code-block:: python + + item = adr.create_item(String, name="summary_text", content="Summary content here.") + item.save() + + html_snippet = item.render(context={"plotly": 0}) + +Embedding Partial Templates or Sections +--------------------------------------- + +Templates can be rendered partially by applying specific item filters or by +rendering child templates individually: + +.. code-block:: python + + partial_html = top_template.render( + context={}, + item_filter="A|i_tags|cont|section=results;" + ) + +Integration Tips +---------------- + +- Make sure your embedded HTML includes references to static and media URLs + configured during ADR setup so that assets like images and stylesheets + load correctly. + +- Use the ``context`` parameter to pass additional context variables + needed for rendering. + +- When embedding in frameworks with isolated DOM (e.g., React, Angular), + be mindful of script execution and CSS scope. + +Serving Embedded Content +------------------------ + +If embedding in a web app, serve static and media files via a web server or +framework static route pointing to ADR’s configured directories. + +Example with Flask: + +.. code-block:: python + + from flask import Flask, render_template_string + app = Flask(__name__) + + @app.route("/embedded-report") + def embedded_report(): + my_app_html = "" + html = adr.render_report(name="My Simulation Report") + return render_template_string(""" + + + Embedded Report + + + {my_app_html} +
+ {html} +
+ + + """, my_app_html=my_app_html, html=html)) + +Security Considerations +----------------------- + +- Validate and sanitize any dynamic input used in filters or templates + to avoid injection attacks. +- Limit exposure of internal data by controlling which templates or items + are accessible for embedding. + +Summary +------- + +Embedding reports with Serverless ADR offers a flexible way to integrate rich, +dynamic simulation reports into custom applications or portals without +running a full ADR backend server. + +Next Steps +---------- + +See the :doc:`copying_objects` guide for details on copying report content +between databases or environments, which may be useful when preparing +reports for embedding in different contexts. From b942387b0cf5ee98f117364e844abf63fe9f7379 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:38:17 -0400 Subject: [PATCH 34/50] Update copying_objects.rst --- doc/source/serverless/copying_objects.rst | 97 +++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/doc/source/serverless/copying_objects.rst b/doc/source/serverless/copying_objects.rst index e69de29bb..7fdf445c4 100644 --- a/doc/source/serverless/copying_objects.rst +++ b/doc/source/serverless/copying_objects.rst @@ -0,0 +1,97 @@ +Copying Objects +============== + +Serverless ADR allows you to copy collections of report objects between databases. +This is useful for migrating reports, backing up data, or synchronizing environments. + +Supported Object Types +---------------------- + +You can copy the following object types: + +- **Items**: Individual report content such as text, tables, images. +- **Templates**: Report layouts and generators defining report structure. +- **Sessions**: Contextual grouping of report data. +- **Datasets**: Collections of simulation or analysis data. + +Copying ensures that related sessions and datasets are preserved and linked correctly. + +Copying Workflow +---------------- + +To copy objects, use the ``copy_objects()`` method on the ADR instance: + +.. code-block:: python + + count = adr.copy_objects( + object_type=Item, + target_database="remote_db", + query="A|i_tags|cont|project=wing_sim;", + target_media_dir="/path/to/media", + test=False, + ) + print(f"Copied {count} objects.") + +Parameters: + +- ``object_type``: The class of objects to copy (e.g., ``Item``, ``Template``). +- ``target_database``: The destination database key as configured in ADR. +- ``query``: An optional ADR query string to select which objects to copy. +- ``target_media_dir``: Directory to copy media files if objects reference files. +- ``test``: If True, only logs the number of objects to copy without performing the copy. + +Copying Templates +----------------- + +Only top-level templates (those with no parent) can be copied directly. +Child templates are recursively copied along with their parent to maintain hierarchy. + +Handling Media Files +-------------------- + +When copying items with media files (e.g., images or geometry files), the +media files are copied to the specified target media directory. + +You must specify ``target_media_dir`` if the target database uses SQLite or +does not provide media storage paths. + +Error Handling +-------------- + +- Raises ``ADRException`` if unsupported object types are passed. +- Raises errors if the source or target database configurations are missing. +- Raises errors if media directory is missing when required. + +Example Copying Items with Media + +.. code-block:: python + + try: + copied_count = adr.copy_objects( + Item, + target_database="remote_db", + query="A|i_tags|cont|section=results;", + target_media_dir="/data/remote/media", + ) + print(f"Successfully copied {copied_count} items with media.") + except ADRException as e: + print(f"Copying failed: {e}") + +Best Practices +-------------- + +- Ensure the target database is properly configured and accessible before copying. +- Verify that media directories have appropriate permissions for file copying. +- Use the ``test=True`` option initially to verify which objects will be copied. +- Copy related sessions and datasets automatically by copying items or templates. + +Summary +------- + +Copying objects in Serverless ADR is a powerful tool to migrate and synchronize +report content, preserving relationships and media assets across environments. + +Next Steps +---------- + +Learn about :doc:`deleting_objects` to manage and clean up unwanted report data after copying. From c39ab64e5b229ebd1f9eae3c33e85ad5f20146c3 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:49:47 -0400 Subject: [PATCH 35/50] Update copying_objects.rst --- doc/source/serverless/copying_objects.rst | 167 ++++++++++++++-------- 1 file changed, 111 insertions(+), 56 deletions(-) diff --git a/doc/source/serverless/copying_objects.rst b/doc/source/serverless/copying_objects.rst index 7fdf445c4..14970a517 100644 --- a/doc/source/serverless/copying_objects.rst +++ b/doc/source/serverless/copying_objects.rst @@ -1,97 +1,152 @@ Copying Objects ============== -Serverless ADR allows you to copy collections of report objects between databases. -This is useful for migrating reports, backing up data, or synchronizing environments. +Serverless ADR supports copying collections of report objects—including **Items**, **Templates**, **Sessions**, and **Datasets**—from one database to another. This functionality facilitates data migration, backup, synchronization, or environment replication. -Supported Object Types ----------------------- +Copying ensures that GUIDs (unique identifiers) are preserved and that related Sessions and Datasets referenced by Items are copied as well to maintain data integrity. -You can copy the following object types: +Prerequisites +------------- -- **Items**: Individual report content such as text, tables, images. -- **Templates**: Report layouts and generators defining report structure. -- **Sessions**: Contextual grouping of report data. -- **Datasets**: Collections of simulation or analysis data. +- Multiple database configurations must be set up in the ADR instance. +- The source and target databases must be properly configured and accessible. +- For objects referencing media files (e.g., images, animations), a valid media directory must be specified for the target database. +- Only top-level Templates (those without parents) can be copied; their children are copied recursively. -Copying ensures that related sessions and datasets are preserved and linked correctly. +API Usage +--------- -Copying Workflow ----------------- - -To copy objects, use the ``copy_objects()`` method on the ADR instance: +Use the ``copy_objects()`` method on an ADR instance: .. code-block:: python count = adr.copy_objects( - object_type=Item, - target_database="remote_db", - query="A|i_tags|cont|project=wing_sim;", - target_media_dir="/path/to/media", - test=False, + object_type=Item, # Class of objects to copy (Item, Template, Session, Dataset) + target_database="dest", # Target database key + query="A|i_tags|cont|project=wing_sim;", # ADR query string to filter objects + target_media_dir="/path/to/media", # Required if copying Items with media in SQLite + test=False # If True, only logs number of objects to be copied, no actual copy ) print(f"Copied {count} objects.") -Parameters: +Parameters +---------- -- ``object_type``: The class of objects to copy (e.g., ``Item``, ``Template``). -- ``target_database``: The destination database key as configured in ADR. -- ``query``: An optional ADR query string to select which objects to copy. -- ``target_media_dir``: Directory to copy media files if objects reference files. -- ``test``: If True, only logs the number of objects to copy without performing the copy. +- ``object_type`` (`type`): The class of objects to copy. Must be a subclass of ``Item``, ``Template``, ``Session``, or ``Dataset``. +- ``target_database`` (`str`): The configured target database key. +- ``query`` (`str`, optional): ADR query string to select which objects to copy. Defaults to copying all. +- ``target_media_dir`` (`str` or `Path`, optional): Directory to copy media files to when copying Items. +- ``test`` (`bool`, optional): If True, no copying occurs; only the count of matching objects is returned. -Copying Templates ------------------ +Copying Logic Details +--------------------- -Only top-level templates (those with no parent) can be copied directly. -Child templates are recursively copied along with their parent to maintain hierarchy. +1. **Validation** -Handling Media Files --------------------- + - Checks that ``object_type`` is valid. + - Validates that both source ("default") and target databases exist in ADR's configuration. -When copying items with media files (e.g., images or geometry files), the -media files are copied to the specified target media directory. +2. **Querying Objects** -You must specify ``target_media_dir`` if the target database uses SQLite or -does not provide media storage paths. + - Uses the ADR query interface to fetch objects matching the query string. -Error Handling --------------- +3. **Handling Items** + + - Checks if any Items reference media files. + - Determines the target media directory: + - Uses provided ``target_media_dir`` if specified. + - If using SQLite for the target DB, attempts to resolve the media directory adjacent to the DB. + - Throws an exception if no suitable media directory can be determined. + - For each Item, attempts to fetch or create the corresponding Session and Dataset in the target DB. + - Updates Items to reference the copied Sessions and Datasets. + +4. **Handling Templates** + + - Only copies top-level Templates. + - Recursively copies child Templates preserving hierarchy and order. -- Raises ``ADRException`` if unsupported object types are passed. -- Raises errors if the source or target database configurations are missing. -- Raises errors if media directory is missing when required. +5. **Handling Sessions and Datasets** -Example Copying Items with Media + - Copies queried Sessions or Datasets as-is. + +6. **Test Mode** + + - If ``test=True``, logs and returns the number of objects that *would* be copied, without performing any write operations. + +7. **Performing Copy** + + - Saves all copied objects to the target database. + - Copies media files referenced by Items to the target media directory. + - Rebuilds 3D geometry files if applicable. + +Example: Copy Sessions .. code-block:: python - try: - copied_count = adr.copy_objects( - Item, - target_database="remote_db", - query="A|i_tags|cont|section=results;", - target_media_dir="/data/remote/media", - ) - print(f"Successfully copied {copied_count} items with media.") - except ADRException as e: - print(f"Copying failed: {e}") + session_count = adr.copy_objects( + object_type=Session, + target_database="dest", + query="A|s_tags|cont|dp=;", + ) + print(f"Copied {session_count} sessions.") + +Example: Copy Items with Media + +.. code-block:: python + + item_count = adr.copy_objects( + Item, + target_database="dest", + query="A|i_tags|cont|dp=dp227;", + target_media_dir=r"C:\ansys\dest_db\media", + ) + print(f"Copied {item_count} items with media.") + +Example: Copy Top-Level Template and Its Children + +.. code-block:: python + + template_count = adr.copy_objects( + Template, + target_database="dest", + query="A|t_name|eq|Serverless Simulation Report;", + ) + print(f"Copied {template_count} templates.") + +Error Handling +-------------- + +- Raises ``TypeError`` if ``object_type`` is not a valid ADR model subclass. +- Raises ``ADRException`` if databases are misconfigured. +- Raises ``ADRException`` if attempting to copy non top-level Templates. +- Raises ``ADRException`` if ``target_media_dir`` is missing when required. +- Exceptions from saving or media copying are caught and re-raised as ``ADRException``. + +Implementation Notes +-------------------- + +- The copying uses a deep copy of Template objects to preserve the hierarchy. +- For Items, Session and Dataset references are fetched or created in the target database to maintain links. +- Media files are copied using standard filesystem operations; ensure appropriate permissions. +- The method supports extensions for future support of source database selection (currently hardcoded to "default"). Best Practices -------------- - Ensure the target database is properly configured and accessible before copying. -- Verify that media directories have appropriate permissions for file copying. -- Use the ``test=True`` option initially to verify which objects will be copied. - Copy related sessions and datasets automatically by copying items or templates. +- Always use ``test=True`` initially to preview the number of objects to be copied. +- Ensure media directories have sufficient space and permissions. +- Use descriptive ADR query strings to limit copy scope. +- Avoid copying Templates with parents; copy only top-level templates to prevent hierarchy issues. +- Call ``adr.setup()`` before copying to ensure proper configuration. Summary ------- -Copying objects in Serverless ADR is a powerful tool to migrate and synchronize -report content, preserving relationships and media assets across environments. +The ``copy_objects()`` method provides robust, automated transfer of ADR report content and metadata between databases, preserving references and media assets to support backup, migration, and distributed workflows. Next Steps ---------- -Learn about :doc:`deleting_objects` to manage and clean up unwanted report data after copying. +Learn how to manage unwanted data after copying with :doc:`deleting_objects`. From a0b0bdef26e0974b54ee706e12bd434f3bf4f6db Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:51:07 -0400 Subject: [PATCH 36/50] Update deleting_objects.rst --- doc/source/serverless/deleting_objects.rst | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/doc/source/serverless/deleting_objects.rst b/doc/source/serverless/deleting_objects.rst index e69de29bb..c9b94c335 100644 --- a/doc/source/serverless/deleting_objects.rst +++ b/doc/source/serverless/deleting_objects.rst @@ -0,0 +1,85 @@ +Deleting Objects +================ + +Serverless ADR allows you to delete report objects such as **Items**, **Templates**, **Sessions**, and **Datasets** either individually or in bulk via query results. Proper deletion helps maintain a clean database and remove obsolete or unwanted report data. + +Methods for Deletion +------------------- + +1. **Delete Individual Objects** + + Each object instance supports a ``.delete()`` method to remove itself from the database. + + .. code-block:: python + + item = Item.get(name="obsolete_item") + item.delete() + +2. **Delete Multiple Objects via Query** + + Query sets (``ObjectSet``) returned by ``filter()``, ``find()``, or ADR’s ``query()`` method support a bulk ``.delete()`` method that deletes all objects in the set. + + .. code-block:: python + + items_to_delete = adr.query(Item, query="A|i_tags|cont|old_project;") + count_deleted = items_to_delete.delete() + print(f"Deleted {count_deleted} items.") + +Usage Examples +-------------- + +**Deleting a Single Session:** + +.. code-block:: python + + session = Session.get(guid="4ee905f0-f611-11e6-8901-ae3af682bb6a") + session.delete() + +**Deleting Multiple Datasets by Tag:** + +.. code-block:: python + + old_datasets = Dataset.filter(tags__icontains="deprecated") + deleted_count = old_datasets.delete() + print(f"Deleted {deleted_count} datasets.") + +**Deleting All Templates with a Specific Name:** + +.. code-block:: python + + templates = Template.filter(name="Old Report Template") + deleted_count = templates.delete() + print(f"Deleted {deleted_count} templates.") + +Important Considerations +------------------------ + +- Deleting a Template does not automatically delete its child Templates or associated Items. Handle dependent objects accordingly to avoid orphaned data. +- Similarly, deleting Sessions or Datasets does not cascade to associated Items; manually delete dependent Items if needed. +- Deletion operations are permanent and cannot be undone. Ensure backups or exports are made if data recovery is required. +- You may need appropriate database permissions to perform deletions. +- Use precise query filters to avoid unintended data loss. + +Error Handling +-------------- + +- Attempting to delete non-existent objects will raise a ``DoesNotExist`` error. +- Database-level integrity errors may occur if cascading constraints exist; handle exceptions accordingly. + +Best Practices +-------------- + +- Perform queries with care and review the list of objects to delete before calling ``.delete()``. +- Consider backing up data before bulk deletion. +- When deleting Templates, consider recursively deleting or archiving child Templates and related Items. +- Use transaction management to ensure atomicity for bulk deletes in complex workflows. + +Summary +------- + +Deletion APIs in Serverless ADR provide flexible, efficient removal of report-related objects to keep your reporting system clean and relevant. + +Next Steps +---------- + +Explore the :doc:`copying_objects` guide to learn how to safely duplicate report content across databases. From 831d47f7f854dc59d8771b09b0784d58873b0f7b Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:08:38 -0400 Subject: [PATCH 37/50] Update deleting_objects.rst --- doc/source/serverless/deleting_objects.rst | 113 ++++++++++++++------- 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/doc/source/serverless/deleting_objects.rst b/doc/source/serverless/deleting_objects.rst index c9b94c335..626a21c14 100644 --- a/doc/source/serverless/deleting_objects.rst +++ b/doc/source/serverless/deleting_objects.rst @@ -1,19 +1,23 @@ Deleting Objects ================ -Serverless ADR allows you to delete report objects such as **Items**, **Templates**, **Sessions**, and **Datasets** either individually or in bulk via query results. Proper deletion helps maintain a clean database and remove obsolete or unwanted report data. +Serverless ADR provides robust APIs for deleting report-related objects, including **Items**, **Templates**, **Sessions**, and **Datasets**. These operations allow you to remove outdated or unnecessary data from your reporting system efficiently. -Methods for Deletion -------------------- +Deletion Methods +---------------- -1. **Delete Individual Objects** +1. **Deleting Individual Objects** - Each object instance supports a ``.delete()`` method to remove itself from the database. +Every model instance exposes a `.delete()` method that permanently removes that object from the database. - .. code-block:: python +Example: + +.. code-block:: python - item = Item.get(name="obsolete_item") - item.delete() + from ansys.dynamicreporting.core.serverless import Item + + item = Item.get(name="intro_text") + item.delete() 2. **Delete Multiple Objects via Query** @@ -21,12 +25,12 @@ Methods for Deletion .. code-block:: python - items_to_delete = adr.query(Item, query="A|i_tags|cont|old_project;") - count_deleted = items_to_delete.delete() - print(f"Deleted {count_deleted} items.") + items_to_delete = adr.query(Item, query="A|i_tags|cont|old_project;") + count_deleted = items_to_delete.delete() + print(f"Deleted {count_deleted} items.") -Usage Examples --------------- +Example Usage Patterns +---------------------- **Deleting a Single Session:** @@ -39,47 +43,80 @@ Usage Examples .. code-block:: python - old_datasets = Dataset.filter(tags__icontains="deprecated") + old_datasets = Dataset.filter(tags__contains="deprecated") deleted_count = old_datasets.delete() print(f"Deleted {deleted_count} datasets.") -**Deleting All Templates with a Specific Name:** + +**Deleting Sessions by Tag** .. code-block:: python - templates = Template.filter(name="Old Report Template") - deleted_count = templates.delete() - print(f"Deleted {deleted_count} templates.") + from ansys.dynamicreporting.core.serverless import Session -Important Considerations ------------------------- + old_sessions = Session.filter(tags__contains="deprecated") + count = old_sessions.delete() + print(f"Deleted {count} sessions.") -- Deleting a Template does not automatically delete its child Templates or associated Items. Handle dependent objects accordingly to avoid orphaned data. -- Similarly, deleting Sessions or Datasets does not cascade to associated Items; manually delete dependent Items if needed. -- Deletion operations are permanent and cannot be undone. Ensure backups or exports are made if data recovery is required. -- You may need appropriate database permissions to perform deletions. -- Use precise query filters to avoid unintended data loss. +**Deleting Datasets with Specific Filename Patterns** + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import Dataset + + datasets_to_remove = Dataset.filter(filename="test_data") + deleted = datasets_to_remove.delete() + print(f"Deleted {deleted} datasets.") + +**Deleting Templates by Name** + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import Template + + templates = Template.filter(name="Old Layout") + deleted = templates.delete() + print(f"Deleted {deleted} templates.") + +Important Notes and Caveats +--------------------------- + +- **Automatic Cascading:** + Deleting a **Template** automatically deletes its child templates but not the associated Items. + Similarly, deleting a **Session** or **Dataset** will delete dependent Items. + +- **Permanent Action:** + Deletions are irreversible through the API. Always ensure that critical data is backed up before deletion. + +- **Permissions:** + Ensure you have proper database access permissions to perform deletion operations. + +- **Query Precision:** + Use precise query filters to prevent accidental mass deletions. Error Handling -------------- -- Attempting to delete non-existent objects will raise a ``DoesNotExist`` error. -- Database-level integrity errors may occur if cascading constraints exist; handle exceptions accordingly. +- **DoesNotExist Exception:** + Raised when `.delete()` is called on an object that no longer exists in the database. + +- **Database Integrity Errors:** + If database constraints prevent deletion (e.g., foreign key constraints), exceptions will be raised. Handle these to avoid partial deletions. + +- **Invalid Query Filters:** + Malformed or unsupported query filters will raise an `ADRException` during query or delete calls. Best Practices -------------- -- Perform queries with care and review the list of objects to delete before calling ``.delete()``. -- Consider backing up data before bulk deletion. -- When deleting Templates, consider recursively deleting or archiving child Templates and related Items. -- Use transaction management to ensure atomicity for bulk deletes in complex workflows. - -Summary -------- +- **Preview Objects Before Deletion:** + Always iterate over query results or inspect objects before deleting to confirm correctness. -Deletion APIs in Serverless ADR provide flexible, efficient removal of report-related objects to keep your reporting system clean and relevant. +- **Backup Important Data:** + Before bulk deletes, create database backups or export data. -Next Steps ----------- +- **Use Soft Deletes If Needed:** + If deletion safety is a concern, consider implementing a "soft delete" flag in your application logic. -Explore the :doc:`copying_objects` guide to learn how to safely duplicate report content across databases. +- **Clean-Up Orphaned Data:** + After deletion, ensure no orphaned references remain that could cause errors. From a6804a81fa9336680074130d3eaf5ba3187e0a6a Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:11:43 -0400 Subject: [PATCH 38/50] Update items.rst --- doc/source/serverless/items.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/source/serverless/items.rst b/doc/source/serverless/items.rst index b57d24d25..f87ec85d2 100644 --- a/doc/source/serverless/items.rst +++ b/doc/source/serverless/items.rst @@ -93,6 +93,30 @@ Example: Creating and saving an image item ) image_item.save() +After saving, the file is copied into the configured media directory. You can access the uploaded file's storage path using the `file_path` property: + +.. code-block:: python + + # Print the absolute path where the media file is stored + print(f"Media file stored at: {image_item.file_path}") + +This path points to the location within the media directory configured during ADR setup. +You can use this path for verification, further processing, or serving the media file in your application. + +When rendering reports or templates that include media items, the HTML references media files using relative URLs, typically prefixed by the configured media URL (default is `/media/`): + +.. code-block:: html + + Image file not found + +Ensure your web server is configured to serve these media URLs from the media directory where files are stored. + +Summary: +- Set the `content` of file-based items to the local file path before saving. +- After saving, `file_path` gives the full path to the uploaded media file. +- Rendered reports use relative media URLs; configure your web server accordingly. + Rendering Items --------------- From f9e78d97c011e1795e33648c26387c2f45cc6da7 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:16:25 -0400 Subject: [PATCH 39/50] Update caveats.rst --- doc/source/serverless/caveats.rst | 111 ++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/doc/source/serverless/caveats.rst b/doc/source/serverless/caveats.rst index e69de29bb..c71229b48 100644 --- a/doc/source/serverless/caveats.rst +++ b/doc/source/serverless/caveats.rst @@ -0,0 +1,111 @@ +Caveats +======= + +Multiprocessing / Multithreading Usage +-------------------------------------- + +When using Serverless ADR in applications that involve multiple processes or threads, +Serverless ADR modifies the Python process environment and dynamically loads +required modules from the Ansys installation during setup. Because of this design, +proper initialization and lifecycle management are critical when using Serverless ADR +in applications involving multiple processes or threads. + +Process-Level Initialization +---------------------------- + +- The ``ADR.setup()`` method configures Serverless ADR for the **entire process**. +- When your application uses multiprocessing (e.g., the ``multiprocessing`` module, + Gunicorn workers, or other process-based concurrency), **each process must call** + ``ADR.setup()`` before accessing Serverless ADR features. +- If ``setup()`` is not called in a new process, ADR APIs will fail or behave + unpredictably due to missing environment configuration. + +Example: Multiprocessing with Serverless ADR + +.. code-block:: python + + import multiprocessing + from ansys.dynamicreporting.core.serverless import ADR + + def worker_task(): + adr = ADR.get_instance() + if not adr.is_setup: + adr.setup() + # Proceed with Serverless ADR API calls here + + if __name__ == "__main__": + adr = ADR(ansys_installation="/path/to/ansys", db_directory="/path/to/db") + adr.setup() + + # Spawn new processes + processes = [] + for _ in range(4): + p = multiprocessing.Process(target=worker_task) + p.start() + processes.append(p) + + for p in processes: + p.join() + +Thread-Level Behavior +--------------------- + +- Serverless ADR configuration applies process-wide and is shared by all threads. +- It is unnecessary and discouraged to call ``ADR.setup()`` multiple times within the + same process. +- Ensure the main thread calls ``ADR.setup()`` **before spawning any threads** that + will use Serverless ADR. +- Calling ``setup()`` concurrently or repeatedly from multiple threads can cause + race conditions or inconsistent environment state. + +Example: Threading with Serverless ADR + +.. code-block:: python + + import threading + from ansys.dynamicreporting.core.serverless import ADR + + def thread_task(): + adr = ADR.get_instance() + # ADR is already setup in main thread, so just use it directly + # Make ADR API calls here + + if __name__ == "__main__": + adr = ADR(ansys_installation="/path/to/ansys", db_directory="/path/to/db") + adr.setup() # Call once in main thread before starting other threads + + threads = [] + for _ in range(4): + t = threading.Thread(target=thread_task) + t.start() + threads.append(t) + + for t in threads: + t.join() + +Common Pitfalls and Solutions +----------------------------- + +- **Error: "ADR has not been set up" in worker processes** + + _Cause_: ``ADR.setup()`` was not called in the worker process. + + _Solution_: Call ``adr.setup()`` early in each new process, as shown above. + +- **Race conditions or inconsistent state due to multiple ``setup()`` calls** + + _Cause_: Concurrent calls to ``setup()`` from multiple threads. + + _Solution_: Call ``setup()`` only once in the main thread before spawning workers. + +Summary and Best Practices +-------------------------- + +- Always call ``ADR.setup()`` once at the application startup or entry point. +- In multiprocessing scenarios, call ``setup()`` separately in each spawned process. +- Avoid calling ``setup()`` multiple times or concurrently within the same process. +- Share the ADR instance across threads within a process after setup completes. +- If unsure whether setup is needed, check ``adr.is_setup`` before calling. + +By following these guidelines, you ensure stable and consistent Serverless ADR usage +in complex multi-threaded or multi-process environments. From de12ed04e98f33fdf8fdc5e0a207f4459185efdb Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:21:18 -0400 Subject: [PATCH 40/50] Update deleting_objects.rst --- doc/source/serverless/deleting_objects.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/serverless/deleting_objects.rst b/doc/source/serverless/deleting_objects.rst index 626a21c14..9177c058b 100644 --- a/doc/source/serverless/deleting_objects.rst +++ b/doc/source/serverless/deleting_objects.rst @@ -23,7 +23,7 @@ Example: Query sets (``ObjectSet``) returned by ``filter()``, ``find()``, or ADR’s ``query()`` method support a bulk ``.delete()`` method that deletes all objects in the set. - .. code-block:: python +.. code-block:: python items_to_delete = adr.query(Item, query="A|i_tags|cont|old_project;") count_deleted = items_to_delete.delete() From 9fe39187ea298760ee6706b0b36f6e94f90f175f Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:21:41 -0400 Subject: [PATCH 41/50] Update deleting_objects.rst --- doc/source/serverless/deleting_objects.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/serverless/deleting_objects.rst b/doc/source/serverless/deleting_objects.rst index 9177c058b..a022756a3 100644 --- a/doc/source/serverless/deleting_objects.rst +++ b/doc/source/serverless/deleting_objects.rst @@ -21,7 +21,7 @@ Example: 2. **Delete Multiple Objects via Query** - Query sets (``ObjectSet``) returned by ``filter()``, ``find()``, or ADR’s ``query()`` method support a bulk ``.delete()`` method that deletes all objects in the set. +Query sets (``ObjectSet``) returned by ``filter()``, ``find()``, or ADR’s ``query()`` method support a bulk ``.delete()`` method that deletes all objects in the set. .. code-block:: python From 94d7a5f3503490f780a47de16a921502097fd7d6 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:26:42 -0400 Subject: [PATCH 42/50] fix style --- doc/source/serverless/caveats.rst | 4 ++++ doc/source/serverless/copying_objects.rst | 6 +++--- doc/source/serverless/embedding_reports.rst | 16 ++++++++++------ doc/source/serverless/instantiation.rst | 6 +++--- doc/source/serverless/items.rst | 16 +++++++++------- doc/source/serverless/templates.rst | 16 ++++++++++------ 6 files changed, 39 insertions(+), 25 deletions(-) diff --git a/doc/source/serverless/caveats.rst b/doc/source/serverless/caveats.rst index c71229b48..33a83c237 100644 --- a/doc/source/serverless/caveats.rst +++ b/doc/source/serverless/caveats.rst @@ -27,12 +27,14 @@ Example: Multiprocessing with Serverless ADR import multiprocessing from ansys.dynamicreporting.core.serverless import ADR + def worker_task(): adr = ADR.get_instance() if not adr.is_setup: adr.setup() # Proceed with Serverless ADR API calls here + if __name__ == "__main__": adr = ADR(ansys_installation="/path/to/ansys", db_directory="/path/to/db") adr.setup() @@ -65,11 +67,13 @@ Example: Threading with Serverless ADR import threading from ansys.dynamicreporting.core.serverless import ADR + def thread_task(): adr = ADR.get_instance() # ADR is already setup in main thread, so just use it directly # Make ADR API calls here + if __name__ == "__main__": adr = ADR(ansys_installation="/path/to/ansys", db_directory="/path/to/db") adr.setup() # Call once in main thread before starting other threads diff --git a/doc/source/serverless/copying_objects.rst b/doc/source/serverless/copying_objects.rst index 14970a517..bc8d68d85 100644 --- a/doc/source/serverless/copying_objects.rst +++ b/doc/source/serverless/copying_objects.rst @@ -21,11 +21,11 @@ Use the ``copy_objects()`` method on an ADR instance: .. code-block:: python count = adr.copy_objects( - object_type=Item, # Class of objects to copy (Item, Template, Session, Dataset) - target_database="dest", # Target database key + object_type=Item, # Class of objects to copy (Item, Template, Session, Dataset) + target_database="dest", # Target database key query="A|i_tags|cont|project=wing_sim;", # ADR query string to filter objects target_media_dir="/path/to/media", # Required if copying Items with media in SQLite - test=False # If True, only logs number of objects to be copied, no actual copy + test=False, # If True, only logs number of objects to be copied, no actual copy ) print(f"Copied {count} objects.") diff --git a/doc/source/serverless/embedding_reports.rst b/doc/source/serverless/embedding_reports.rst index 4cbf5c1ca..f907e40a2 100644 --- a/doc/source/serverless/embedding_reports.rst +++ b/doc/source/serverless/embedding_reports.rst @@ -28,7 +28,7 @@ report or a subset of it as HTML. html_report = adr.render_report( name="My Simulation Report", context={"plotly": 1}, - item_filter="A|i_tags|cont|project=my_project;" + item_filter="A|i_tags|cont|project=my_project;", ) The resulting HTML string can then be inserted into your web page or @@ -55,8 +55,7 @@ rendering child templates individually: .. code-block:: python partial_html = top_template.render( - context={}, - item_filter="A|i_tags|cont|section=results;" + context={}, item_filter="A|i_tags|cont|section=results;" ) Integration Tips @@ -83,13 +82,18 @@ Example with Flask: .. code-block:: python from flask import Flask, render_template_string + app = Flask(__name__) + @app.route("/embedded-report") def embedded_report(): - my_app_html = "" + from ansys.dynamicreporting.core.serverless import ADR + + adr = ADR.get_instance() + my_app_html = "" html = adr.render_report(name="My Simulation Report") - return render_template_string(""" + return f""" Embedded Report @@ -101,7 +105,7 @@ Example with Flask: - """, my_app_html=my_app_html, html=html)) + """ Security Considerations ----------------------- diff --git a/doc/source/serverless/instantiation.rst b/doc/source/serverless/instantiation.rst index 1ba6a9156..642f293d7 100644 --- a/doc/source/serverless/instantiation.rst +++ b/doc/source/serverless/instantiation.rst @@ -35,7 +35,7 @@ Use this method when working with multiple databases, e.g., PostgreSQL or databa install_loc = r"C:\Program Files\ANSYS Inc\v252" db_dir = r"C:\ADR\DBs\ogdocex" - dest_dir = fr"{db_dir}_dest" + dest_dir = rf"{db_dir}_dest" database_config = { "default": { @@ -59,7 +59,7 @@ Use this method when working with multiple databases, e.g., PostgreSQL or databa adr = ADR( ansys_installation=install_loc, databases=database_config, - media_directory=fr"{db_dir}\media", + media_directory=rf"{db_dir}\media", ) adr.setup() @@ -98,7 +98,7 @@ Use a Docker image to run ADR in containerized environments. ansys_installation="docker", docker_image="ghcr.io/ansys-internal/nexus_dev", db_directory=db_dir, - media_directory=fr"{db_dir}\media", + media_directory=rf"{db_dir}\media", ) adr.setup() diff --git a/doc/source/serverless/items.rst b/doc/source/serverless/items.rst index f87ec85d2..558246c4f 100644 --- a/doc/source/serverless/items.rst +++ b/doc/source/serverless/items.rst @@ -44,11 +44,14 @@ Items automatically link to the current default session and dataset unless speci string_item.save() # Create a table item with data - data = np.array([ - [0.0, 10.0, 101325.0], - [0.5, 12.5, 101300.0], - [1.0, 15.0, 101280.0], - ], dtype="float") + data = np.array( + [ + [0.0, 10.0, 101325.0], + [0.5, 12.5, 101300.0], + [1.0, 15.0, 101280.0], + ], + dtype="float", + ) table_item = adr.create_item( Table, @@ -136,8 +139,7 @@ You can query items using the ADR `query()` method with filters based on tags, n .. code-block:: python items = adr.query( - query_type=String, - query="A|i_tags|cont|project=wing_sim;A|i_name|cont|summary;" + query_type=String, query="A|i_tags|cont|project=wing_sim;A|i_name|cont|summary;" ) Lifecycle Notes diff --git a/doc/source/serverless/templates.rst b/doc/source/serverless/templates.rst index 2b35ba7f8..c0f85fff0 100644 --- a/doc/source/serverless/templates.rst +++ b/doc/source/serverless/templates.rst @@ -209,11 +209,13 @@ Examples name="Summary Section", tags="section=summary", ) - layout.set_property({ - "column_count": 2, - "column_widths": [1.0, 1.5], - "skip_empty": 1, - }) + layout.set_property( + { + "column_count": 2, + "column_widths": [1.0, 1.5], + "skip_empty": 1, + } + ) layout.save() # Update an existing property @@ -291,7 +293,9 @@ Templates can render themselves into complete HTML content using the ``render()` .. code-block:: python - html_report = top_template.render(context={}, item_filter="A|i_tags|cont|project=wing_sim;") + html_report = top_template.render( + context={}, item_filter="A|i_tags|cont|project=wing_sim;" + ) with open("report.html", "w", encoding="utf-8") as f: f.write(html_report) From 026d64bb99af26f070213d194a7a827c12b245e8 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:26:45 -0400 Subject: [PATCH 43/50] Update configuration.rst --- doc/source/serverless/configuration.rst | 184 +++++++++++++++++++++++- 1 file changed, 180 insertions(+), 4 deletions(-) diff --git a/doc/source/serverless/configuration.rst b/doc/source/serverless/configuration.rst index 3fa02fb9d..54e9d26f0 100644 --- a/doc/source/serverless/configuration.rst +++ b/doc/source/serverless/configuration.rst @@ -1,7 +1,183 @@ +Configuration +============= + +Serverless ADR requires proper configuration to initialize its environment, connect to databases, +manage media and static files, and control runtime behavior. This guide explains the key configuration +parameters, environment variables, and recommended setup practices. + +Overview +-------- + +Configuration for Serverless ADR can be done through: + +- Constructor parameters when instantiating the ``ADR`` class. +- Environment variables (legacy or advanced usage). +- Optional overrides during the ``setup()`` call. + +Key Configuration Parameters +---------------------------- + +The primary configuration options for the ``ADR`` class constructor are: + +- ``ansys_installation`` (str, optional): + Path to the Ansys installation directory. Special value ``"docker"`` triggers Docker-based setup. + Defaults to automatic detection if omitted. + +- ``ansys_version`` (int, optional): + Specify the Ansys version explicitly. If not provided, automatic detection attempts to determine it. + +- ``db_directory`` (str, optional): + Directory path for the SQLite database files. If omitted, must provide ``databases`` config or environment variable. + +- ``databases`` (dict, optional): + Dictionary specifying multiple database configurations (e.g., for PostgreSQL or multi-DB setups). + Requires a ``"default"`` database entry. + +- ``media_directory`` (str, optional): + Directory path for media file storage (uploaded images, animations, etc.). Falls back to ``db_directory`` media subfolder if not set. + +- ``static_directory`` (str, optional): + Directory path where static files (CSS, JS) will be collected. + +- ``media_url`` (str, optional): + Relative URL prefix for serving media files. Must start and end with a forward slash (e.g., ``"/media/"``). + +- ``static_url`` (str, optional): + Relative URL prefix for serving static files. Must start and end with a forward slash (e.g., ``"/static/"``). + +- ``debug`` (bool, optional): + Enable or disable debug mode. Defaults to production mode if not set. + +- ``opts`` (dict, optional): + Dictionary of environment variables to inject into the process environment. + +- ``logfile`` (str, optional): + File path to write logs. If omitted, logs to console. + +- ``docker_image`` (str, optional): + Docker image URL to use when ``ansys_installation="docker"``. Defaults to official Nexus image. + +- ``in_memory`` (bool, optional): + Enables in-memory database and media storage for ephemeral or test usage. + Environment Variables --------------------- -- ``CEI_NEXUS_LOCAL_DB_DIR``: Path to local database directory. -- ``CEI_NEXUS_LOCAL_MEDIA_DIR``: Path to media directory. -- ``CEI_NEXUS_LOCAL_STATIC_DIR``: Path to static files directory. -- Additional configuration options can be passed via the ``opts`` dict. +Some legacy or advanced configurations are controlled via environment variables: + +- ``CEI_NEXUS_LOCAL_DB_DIR``: Directory for database files (alternative to ``db_directory``). + +- ``CEI_NEXUS_LOCAL_MEDIA_DIR``: Directory for media files (alternative to ``media_directory``). + +- ``CEI_NEXUS_LOCAL_STATIC_DIR``: Directory for static files (alternative to ``static_directory``). + +- ``CEI_NEXUS_DEBUG``: Set debug mode (``"1"`` for debug, ``"0"`` for production). + +- ``CEI_NEXUS_SECRET_KEY``: Secret key used internally by the ADR system. + +**Note:** Prefer constructor parameters for new projects. Environment variables remain supported primarily for legacy compatibility. + +Best Practices +-------------- + +- **Call ``ADR.setup()`` once per process early in your application lifecycle.** + This initializes environment, Django settings, and database migrations. + +- **For multi-process setups (e.g., Gunicorn, multiprocessing), ensure each process calls ``setup()`` independently.** + +- **Within a process, all threads share the ADR configuration after setup; calling ``setup()`` multiple times per process is disallowed.** + +- **Configure ``media_url`` and ``static_url`` to match your web server routing to serve media and static content correctly.** + +- **Use absolute paths for all directory configurations to avoid ambiguity.** + +- **For Docker-based Ansys installations, provide a valid Docker image and ensure Docker is installed and running.** + +Examples +-------- + +**Basic local SQLite setup with explicit directories:** + +.. code-block:: python + + from ansys.dynamicreporting.core.serverless import ADR + + adr = ADR( + ansys_installation=r"C:\Program Files\ANSYS Inc\v252", + db_directory=r"C:\Reports\DB", + media_directory=r"C:\Reports\Media", + static_directory=r"C:\Reports\Static", + media_url="/media/", + static_url="/static/", + debug=True, + ) + adr.setup(collect_static=True) + +**Multi-database PostgreSQL and SQLite setup:** + +.. code-block:: python + + database_config = { + "default": { + "ENGINE": "postgresql", + "NAME": "adr_db", + "USER": "adr_user", + "PASSWORD": "password", + "HOST": "localhost", + "PORT": "5432", + }, + "sqlite_local": { + "ENGINE": "sqlite3", + "NAME": r"C:\Reports\DB\local.sqlite3", + }, + } + + adr = ADR( + ansys_installation=r"/opt/ansys", + databases=database_config, + media_directory=r"/opt/reports/media", + static_directory=r"/opt/reports/static", + media_url="/media/", + static_url="/static/", + ) + adr.setup() + +**Docker-based Ansys installation:** + +.. code-block:: python + + adr = ADR( + ansys_installation="docker", + docker_image="ghcr.io/ansys-internal/nexus_dev", + db_directory=r"C:\Reports\DB", + media_directory=r"C:\Reports\Media", + static_directory=r"C:\Reports\Static", + media_url="/media/", + static_url="/static/", + ) + adr.setup() + +Troubleshooting +--------------- + +- **InvalidPath Error:** Verify all configured directories exist and are accessible. + +- **ImproperlyConfiguredError:** Check database config dictionary and URL prefixes for correctness. + +- **Docker Errors:** Ensure Docker daemon is running and image URLs are valid. + +- **Static files not found:** Confirm ``collect_static=True`` was set during setup and that your web server serves the static directory correctly. + +- **Media files missing:** Verify media upload paths and web server routing for the media URL. + +Summary +------- + +Proper configuration of Serverless ADR ensures seamless database connections, media management, and web serving of report assets. Follow best practices for setup and environment initialization to avoid common issues. + +Next Steps +---------- + +See the :doc:`setup` guide for detailed startup and initialization instructions. + +See the :doc:`media_and_static` guide for managing static and media files in your reports. From 9963b6a5d2cdeef3629ab04af7343154324460dc Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:28:19 -0400 Subject: [PATCH 44/50] Update configuration.rst --- doc/source/serverless/configuration.rst | 155 ++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 8 deletions(-) diff --git a/doc/source/serverless/configuration.rst b/doc/source/serverless/configuration.rst index 54e9d26f0..39c18b67e 100644 --- a/doc/source/serverless/configuration.rst +++ b/doc/source/serverless/configuration.rst @@ -61,21 +61,160 @@ The primary configuration options for the ``ADR`` class constructor are: Enables in-memory database and media storage for ephemeral or test usage. Environment Variables ---------------------- +===================== -Some legacy or advanced configurations are controlled via environment variables: +Serverless ADR supports several environment variables to configure its runtime behavior, +database connections, security settings, and media/static file handling. These variables +can be used for legacy configurations or advanced deployments. -- ``CEI_NEXUS_LOCAL_DB_DIR``: Directory for database files (alternative to ``db_directory``). +Core Variables +-------------- + +- **CEI_NEXUS_TIMEZONE** + Olson format timezone string for the server (e.g., ``America/New_York``). + Used in formatting timestamps in reports. + +- **CEI_NEXUS_LOCAL_DB_DIR** + Filesystem path to the directory containing the SQLite database file(s). + Alternative to configuring ``db_directory`` in code. + +- **CEI_NEXUS_LOCAL_MEDIA_DIR** + Path to the media directory for uploaded files such as images and animations. + Alternative to ``media_directory`` parameter. + +- **CEI_NEXUS_MEDIA_URL_PREFIX** + URL prefix used to access media files remotely. Must start and end with a slash, e.g., ``/media/``. + Corresponds to the ``media_url`` constructor parameter. + +- **CEI_NEXUS_LOCAL_ALLOW_REMOTE_ACCESS** + If set to any value, allows remote access to a local database server (use cautiously). + +- **CEI_NEXUS_SERVE_STATIC_FILES** + If ``True``, enables Django’s built-in static and media file serving (not recommended for production). + +Database Connection Variables +----------------------------- + +- **CEI_NEXUS_DB_ENGINE** + Database engine string (e.g., ``django.db.backends.postgresql_psycopg2``). Defaults to PostgreSQL. + +- **CEI_NEXUS_DB_DATABASE_NAME** + Name of the database to connect to. Defaults to ``nexus_database``. + +- **CEI_NEXUS_DB_USER** + Database username. Default is ``nexus``. + +- **CEI_NEXUS_DB_PASSWORD** + Password for the database user. Default is ``cei``. + +- **CEI_NEXUS_DB_HOSTNAME** + Database server hostname or IP address. Defaults to ``127.0.0.1``. + +- **CEI_NEXUS_DB_PORT** + Database server port number. Default is ``5432``. + +Security and Server Variables +----------------------------- + +- **CEI_NEXUS_SERVER_NAME** + Human-readable name of the server. Defaults to ``mixed``. + +- **CEI_NEXUS_SECRET_KEY** + Django secret key used internally. If not provided, a built-in default key is used (not recommended for production). + +- **CEI_NEXUS_ALLOWED_HOSTS** + Comma-separated list of allowed hostnames for accessing the server (e.g., ``localhost,127.0.0.1``). + +- **CEI_NEXUS_TRUSTED_ORIGINS** + List of trusted origins for unsafe requests like POST, supporting wildcards (e.g., ``https://*.example.com``). + +- **CEI_NEXUS_HTTPS_SECURED** + Boolean flag to indicate if the server runs behind HTTPS only. Enables security headers. + +- **CEI_NEXUS_HSTS_SECURED** + Enables HTTP Strict Transport Security (HSTS) headers. + +- **CEI_NEXUS_HSTS_SECONDS** + Duration in seconds for HSTS policy enforcement. Use with caution to avoid locking out clients. + +- **CEI_NEXUS_X_FRAME_OPTIONS** + Sets the HTTP X-Frame-Options header globally for protection against clickjacking. + +Advanced / Optional Variables +----------------------------- + +- **CEI_NEXUS_ENABLE_ACLS** + Enables per-category Access Control Lists (ACLs). Experimental and not recommended for general use. -- ``CEI_NEXUS_LOCAL_MEDIA_DIR``: Directory for media files (alternative to ``media_directory``). +- **CEI_NEXUS_ACLS_NGINX_LOCATION** + NGINX internal location directive for permission-protected media files. Default is ``/media_secured``. -- ``CEI_NEXUS_LOCAL_STATIC_DIR``: Directory for static files (alternative to ``static_directory``). +Remote Session Configuration +---------------------------- + +- **CEI_NEXUS_REMOTE_WEBSOCKETURL** + URL to the NGINX server proxying to the websocket server. + +- **CEI_NEXUS_REMOTE_WS_PORT** + Port used by the websocket server for WS protocol communication. + +- **CEI_NEXUS_REMOTE_HTML_PORT** + Port used by the websocket server for HTTP REST communication. + +- **CEI_NEXUS_REMOTE_VNCPASSWORD** + Password for VNC server sessions. + +Usage Notes +----------- + +- When running a non-debug local server, use the following command to enable static file serving: + + .. code-block:: bash + + python manage.py runserver --insecure 0.0.0.0:8000 + +- Environment variables override constructor parameters if both are set. + +- Always set secure secret keys in production environments to protect sensitive data. + +- Configure ``CEI_NEXUS_ALLOWED_HOSTS`` and ``CEI_NEXUS_TRUSTED_ORIGINS`` to restrict server access. + +- When enabling HTTPS and HSTS, be cautious with duration settings to avoid client lockout. + +Example: Setting environment variables in Linux shell: + +.. code-block:: bash + + export CEI_NEXUS_LOCAL_DB_DIR="/var/data/adr_db" + export CEI_NEXUS_LOCAL_MEDIA_DIR="/var/data/adr_media" + export CEI_NEXUS_MEDIA_URL_PREFIX="/media/" + export CEI_NEXUS_SECRET_KEY="a-very-secure-secret-key" + export CEI_NEXUS_ALLOWED_HOSTS="localhost,127.0.0.1" + export CEI_NEXUS_HTTPS_SECURED="True" + +Example: Passing variables via ``opts`` parameter: + +.. code-block:: python + + opts = { + "CEI_NEXUS_LOCAL_DB_DIR": "/var/data/adr_db", + "CEI_NEXUS_LOCAL_MEDIA_DIR": "/var/data/adr_media", + "CEI_NEXUS_MEDIA_URL_PREFIX": "/media/", + "CEI_NEXUS_SECRET_KEY": "a-very-secure-secret-key", + } + + adr = ADR(ansys_installation="/opt/ansys", opts=opts) + adr.setup() + +Summary +------- -- ``CEI_NEXUS_DEBUG``: Set debug mode (``"1"`` for debug, ``"0"`` for production). +Proper use of environment variables allows flexible deployment and integration of Serverless ADR +into diverse environments, including containerized, cloud, or on-premises infrastructures. -- ``CEI_NEXUS_SECRET_KEY``: Secret key used internally by the ADR system. +See also the :doc:`configuration` and :doc:`setup` guides for comprehensive initialization instructions. -**Note:** Prefer constructor parameters for new projects. Environment variables remain supported primarily for legacy compatibility. +**Note: Prefer constructor parameters for new projects. Environment variables remain supported primarily for legacy compatibility.** Best Practices -------------- From cfd3f9ed6b76e6752edd4916dfdd3765597c92ce Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Mon, 23 Jun 2025 11:23:44 -0400 Subject: [PATCH 45/50] Update configuration.rst --- doc/source/serverless/configuration.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/source/serverless/configuration.rst b/doc/source/serverless/configuration.rst index 39c18b67e..7a65d41c8 100644 --- a/doc/source/serverless/configuration.rst +++ b/doc/source/serverless/configuration.rst @@ -63,9 +63,15 @@ The primary configuration options for the ``ADR`` class constructor are: Environment Variables ===================== -Serverless ADR supports several environment variables to configure its runtime behavior, -database connections, security settings, and media/static file handling. These variables -can be used for legacy configurations or advanced deployments. +.. warning:: + + **Use of environment variables for Serverless ADR configuration is strongly discouraged.** + Environment variables represent a legacy configuration method and can lead to hidden, + hard-to-debug issues, security risks (such as leaking secrets), and inconsistent behavior + especially in multi-instance or containerized deployments. + + It is highly recommended to use explicit constructor parameters and configuration files + for all setup and runtime options instead. Core Variables -------------- @@ -167,12 +173,6 @@ Remote Session Configuration Usage Notes ----------- -- When running a non-debug local server, use the following command to enable static file serving: - - .. code-block:: bash - - python manage.py runserver --insecure 0.0.0.0:8000 - - Environment variables override constructor parameters if both are set. - Always set secure secret keys in production environments to protect sensitive data. From ac1c5ff961d2cd6490d8b893cddce15a51a66ad2 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Mon, 23 Jun 2025 12:38:34 -0400 Subject: [PATCH 46/50] Update configuration.rst --- doc/source/serverless/configuration.rst | 83 +++---------------------- 1 file changed, 9 insertions(+), 74 deletions(-) diff --git a/doc/source/serverless/configuration.rst b/doc/source/serverless/configuration.rst index 7a65d41c8..b7dc6640f 100644 --- a/doc/source/serverless/configuration.rst +++ b/doc/source/serverless/configuration.rst @@ -92,17 +92,11 @@ Core Variables URL prefix used to access media files remotely. Must start and end with a slash, e.g., ``/media/``. Corresponds to the ``media_url`` constructor parameter. -- **CEI_NEXUS_LOCAL_ALLOW_REMOTE_ACCESS** - If set to any value, allows remote access to a local database server (use cautiously). - -- **CEI_NEXUS_SERVE_STATIC_FILES** - If ``True``, enables Django’s built-in static and media file serving (not recommended for production). - Database Connection Variables ----------------------------- - **CEI_NEXUS_DB_ENGINE** - Database engine string (e.g., ``django.db.backends.postgresql_psycopg2``). Defaults to PostgreSQL. + Database engine. Defaults to SQLite. - **CEI_NEXUS_DB_DATABASE_NAME** Name of the database to connect to. Defaults to ``nexus_database``. @@ -114,72 +108,29 @@ Database Connection Variables Password for the database user. Default is ``cei``. - **CEI_NEXUS_DB_HOSTNAME** - Database server hostname or IP address. Defaults to ``127.0.0.1``. + Database server hostname or IP address. Defaults to the path to the SQLite database file. - **CEI_NEXUS_DB_PORT** - Database server port number. Default is ``5432``. - -Security and Server Variables ------------------------------ + Database server port number. Default is not set for SQLite. -- **CEI_NEXUS_SERVER_NAME** - Human-readable name of the server. Defaults to ``mixed``. +Security Variables +------------------ - **CEI_NEXUS_SECRET_KEY** Django secret key used internally. If not provided, a built-in default key is used (not recommended for production). -- **CEI_NEXUS_ALLOWED_HOSTS** - Comma-separated list of allowed hostnames for accessing the server (e.g., ``localhost,127.0.0.1``). - -- **CEI_NEXUS_TRUSTED_ORIGINS** - List of trusted origins for unsafe requests like POST, supporting wildcards (e.g., ``https://*.example.com``). - -- **CEI_NEXUS_HTTPS_SECURED** - Boolean flag to indicate if the server runs behind HTTPS only. Enables security headers. - -- **CEI_NEXUS_HSTS_SECURED** - Enables HTTP Strict Transport Security (HSTS) headers. - -- **CEI_NEXUS_HSTS_SECONDS** - Duration in seconds for HSTS policy enforcement. Use with caution to avoid locking out clients. - -- **CEI_NEXUS_X_FRAME_OPTIONS** - Sets the HTTP X-Frame-Options header globally for protection against clickjacking. - Advanced / Optional Variables ----------------------------- - **CEI_NEXUS_ENABLE_ACLS** Enables per-category Access Control Lists (ACLs). Experimental and not recommended for general use. -- **CEI_NEXUS_ACLS_NGINX_LOCATION** - NGINX internal location directive for permission-protected media files. Default is ``/media_secured``. - -Remote Session Configuration ----------------------------- - -- **CEI_NEXUS_REMOTE_WEBSOCKETURL** - URL to the NGINX server proxying to the websocket server. - -- **CEI_NEXUS_REMOTE_WS_PORT** - Port used by the websocket server for WS protocol communication. - -- **CEI_NEXUS_REMOTE_HTML_PORT** - Port used by the websocket server for HTTP REST communication. - -- **CEI_NEXUS_REMOTE_VNCPASSWORD** - Password for VNC server sessions. - Usage Notes ----------- -- Environment variables override constructor parameters if both are set. - -- Always set secure secret keys in production environments to protect sensitive data. +- Constructor parameters take precedence over environment variables. If both are set, constructor values will be used. -- Configure ``CEI_NEXUS_ALLOWED_HOSTS`` and ``CEI_NEXUS_TRUSTED_ORIGINS`` to restrict server access. - -- When enabling HTTPS and HSTS, be cautious with duration settings to avoid client lockout. +- Always set secure secret keys in production environments to protect sensitive data. If you do not set a key, a default will be used. Example: Setting environment variables in Linux shell: @@ -189,8 +140,6 @@ Example: Setting environment variables in Linux shell: export CEI_NEXUS_LOCAL_MEDIA_DIR="/var/data/adr_media" export CEI_NEXUS_MEDIA_URL_PREFIX="/media/" export CEI_NEXUS_SECRET_KEY="a-very-secure-secret-key" - export CEI_NEXUS_ALLOWED_HOSTS="localhost,127.0.0.1" - export CEI_NEXUS_HTTPS_SECURED="True" Example: Passing variables via ``opts`` parameter: @@ -206,14 +155,6 @@ Example: Passing variables via ``opts`` parameter: adr = ADR(ansys_installation="/opt/ansys", opts=opts) adr.setup() -Summary -------- - -Proper use of environment variables allows flexible deployment and integration of Serverless ADR -into diverse environments, including containerized, cloud, or on-premises infrastructures. - -See also the :doc:`configuration` and :doc:`setup` guides for comprehensive initialization instructions. - **Note: Prefer constructor parameters for new projects. Environment variables remain supported primarily for legacy compatibility.** Best Practices @@ -312,11 +253,5 @@ Troubleshooting Summary ------- -Proper configuration of Serverless ADR ensures seamless database connections, media management, and web serving of report assets. Follow best practices for setup and environment initialization to avoid common issues. - -Next Steps ----------- - -See the :doc:`setup` guide for detailed startup and initialization instructions. - -See the :doc:`media_and_static` guide for managing static and media files in your reports. +Proper configuration of Serverless ADR ensures seamless database connections, media management, and web serving of report assets. +Follow best practices for setup and environment initialization to avoid common issues. From 8b5351d3dd39b4f0fd51c6624440eba83e49e495 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Mon, 23 Jun 2025 17:58:30 -0400 Subject: [PATCH 47/50] fix docs --- doc/source/serverless/caveats.rst | 28 ++++++------ doc/source/serverless/configuration.rst | 44 ------------------- doc/source/serverless/copying_objects.rst | 2 +- doc/source/serverless/embedding_reports.rst | 11 ++--- doc/source/serverless/examples.rst | 3 ++ doc/source/serverless/index.rst | 7 ++- doc/source/serverless/items.rst | 11 +++-- doc/source/serverless/media_and_static.rst | 9 ++-- doc/source/serverless/overview.rst | 2 +- doc/source/serverless/querying.rst | 8 ++-- doc/source/serverless/quickstart.rst | 1 - .../serverless/sessions_and_datasets.rst | 26 ++++++++--- doc/source/serverless/templates.rst | 17 +++---- 13 files changed, 67 insertions(+), 102 deletions(-) diff --git a/doc/source/serverless/caveats.rst b/doc/source/serverless/caveats.rst index 33a83c237..63c2e2e1e 100644 --- a/doc/source/serverless/caveats.rst +++ b/doc/source/serverless/caveats.rst @@ -87,20 +87,19 @@ Example: Threading with Serverless ADR for t in threads: t.join() -Common Pitfalls and Solutions ------------------------------ - -- **Error: "ADR has not been set up" in worker processes** - - _Cause_: ``ADR.setup()`` was not called in the worker process. - - _Solution_: Call ``adr.setup()`` early in each new process, as shown above. - -- **Race conditions or inconsistent state due to multiple ``setup()`` calls** - - _Cause_: Concurrent calls to ``setup()`` from multiple threads. +Serverless ADR Usage Within Django Apps +-------------------------------------- - _Solution_: Call ``setup()`` only once in the main thread before spawning workers. +- Serverless ADR internally configures Django settings and environment variables at the + process level during ``ADR.setup()``. +- Because Django settings are designed to be configured once per process, **attempting + to initialize Serverless ADR inside an existing Django application causes conflicts.** +- Specifically, setting up Serverless ADR tries to configure Django a second time, which + is unsupported and results in errors or unpredictable behavior. +- This means **embedding or using Serverless ADR as a Django app within another Django + project is not currently supported and strongly discouraged.** +- If you require integration, consider separating Serverless ADR usage into a dedicated + process or microservice to avoid Django settings conflicts. Summary and Best Practices -------------------------- @@ -109,7 +108,8 @@ Summary and Best Practices - In multiprocessing scenarios, call ``setup()`` separately in each spawned process. - Avoid calling ``setup()`` multiple times or concurrently within the same process. - Share the ADR instance across threads within a process after setup completes. +- Avoid embedding Serverless ADR within other Django apps due to Django configuration conflicts. - If unsure whether setup is needed, check ``adr.is_setup`` before calling. By following these guidelines, you ensure stable and consistent Serverless ADR usage -in complex multi-threaded or multi-process environments. +in complex multi-threaded or multi-process environments without risking Django conflicts. diff --git a/doc/source/serverless/configuration.rst b/doc/source/serverless/configuration.rst index b7dc6640f..b5516c24d 100644 --- a/doc/source/serverless/configuration.rst +++ b/doc/source/serverless/configuration.rst @@ -193,50 +193,6 @@ Examples ) adr.setup(collect_static=True) -**Multi-database PostgreSQL and SQLite setup:** - -.. code-block:: python - - database_config = { - "default": { - "ENGINE": "postgresql", - "NAME": "adr_db", - "USER": "adr_user", - "PASSWORD": "password", - "HOST": "localhost", - "PORT": "5432", - }, - "sqlite_local": { - "ENGINE": "sqlite3", - "NAME": r"C:\Reports\DB\local.sqlite3", - }, - } - - adr = ADR( - ansys_installation=r"/opt/ansys", - databases=database_config, - media_directory=r"/opt/reports/media", - static_directory=r"/opt/reports/static", - media_url="/media/", - static_url="/static/", - ) - adr.setup() - -**Docker-based Ansys installation:** - -.. code-block:: python - - adr = ADR( - ansys_installation="docker", - docker_image="ghcr.io/ansys-internal/nexus_dev", - db_directory=r"C:\Reports\DB", - media_directory=r"C:\Reports\Media", - static_directory=r"C:\Reports\Static", - media_url="/media/", - static_url="/static/", - ) - adr.setup() - Troubleshooting --------------- diff --git a/doc/source/serverless/copying_objects.rst b/doc/source/serverless/copying_objects.rst index bc8d68d85..08d51c9c3 100644 --- a/doc/source/serverless/copying_objects.rst +++ b/doc/source/serverless/copying_objects.rst @@ -134,7 +134,7 @@ Best Practices -------------- - Ensure the target database is properly configured and accessible before copying. -- Copy related sessions and datasets automatically by copying items or templates. +- Copy related sessions and datasets automatically by copying items. - Always use ``test=True`` initially to preview the number of objects to be copied. - Ensure media directories have sufficient space and permissions. - Use descriptive ADR query strings to limit copy scope. diff --git a/doc/source/serverless/embedding_reports.rst b/doc/source/serverless/embedding_reports.rst index f907e40a2..531ed2871 100644 --- a/doc/source/serverless/embedding_reports.rst +++ b/doc/source/serverless/embedding_reports.rst @@ -21,7 +21,7 @@ Generating Embed-Ready HTML --------------------------- Use the ``render_report()`` method of the ADR instance to render a complete -report or a subset of it as HTML. +report. .. code-block:: python @@ -42,8 +42,6 @@ You can also render individual report items using their ``render()`` method: .. code-block:: python item = adr.create_item(String, name="summary_text", content="Summary content here.") - item.save() - html_snippet = item.render(context={"plotly": 0}) Embedding Partial Templates or Sections @@ -63,7 +61,7 @@ Integration Tips - Make sure your embedded HTML includes references to static and media URLs configured during ADR setup so that assets like images and stylesheets - load correctly. + load correctly and your web server is configured to serve them. - Use the ``context`` parameter to pass additional context variables needed for rendering. @@ -81,6 +79,7 @@ Example with Flask: .. code-block:: python + from ansys.dynamicreporting.core.serverless import ADR from flask import Flask, render_template_string app = Flask(__name__) @@ -88,8 +87,6 @@ Example with Flask: @app.route("/embedded-report") def embedded_report(): - from ansys.dynamicreporting.core.serverless import ADR - adr = ADR.get_instance() my_app_html = "" html = adr.render_report(name="My Simulation Report") @@ -112,7 +109,7 @@ Security Considerations - Validate and sanitize any dynamic input used in filters or templates to avoid injection attacks. -- Limit exposure of internal data by controlling which templates or items +- Limit exposure of data by controlling which templates or items are accessible for embedding. Summary diff --git a/doc/source/serverless/examples.rst b/doc/source/serverless/examples.rst index e69de29bb..ce68152a0 100644 --- a/doc/source/serverless/examples.rst +++ b/doc/source/serverless/examples.rst @@ -0,0 +1,3 @@ +Examples +======== + diff --git a/doc/source/serverless/index.rst b/doc/source/serverless/index.rst index 7800c128a..3d3636c0d 100644 --- a/doc/source/serverless/index.rst +++ b/doc/source/serverless/index.rst @@ -19,15 +19,14 @@ want to: - Create, manage, and render reports locally using Python - Avoid setting up a centralized ADR service or HTTP connection -- Maintain full fidelity with the ADR schema (items, templates, layout logic) -- Output HTML content and media assets for web apps, automation, or - documentation pipelines +- Maintain full fidelity with the ADR schema (items, templates, etc.) +- Output HTML content and media assets for web and desktop apps. Serverless ADR is ideal for: - Local, file-based workflows (e.g., building offline reports) +- Embedding reports in web or desktop applications - Use in batch scripts, Python notebooks, or simulations -- Building and verifying templates before pushing to production ADR services Key features ============ diff --git a/doc/source/serverless/items.rst b/doc/source/serverless/items.rst index 558246c4f..0f5cb8936 100644 --- a/doc/source/serverless/items.rst +++ b/doc/source/serverless/items.rst @@ -41,7 +41,6 @@ Items automatically link to the current default session and dataset unless speci content="This simulation demonstrates fluid flow around a wing.", tags="section=summary project=wing_sim", ) - string_item.save() # Create a table item with data data = np.array( @@ -71,7 +70,10 @@ Item Properties and Metadata Items support several useful properties and metadata fields: +- **guid**: Unique identifier for the item, automatically generated. - **name**: Unique identifier for the item within the dataset. +- **type**: The item type (e.g., `string`, `table`, etc.). +- **date**: Timestamp indicating when the item was created. - **content**: The primary payload of the item, type-dependent. - **tags**: A space-separated string of key or key=value tags for querying and filtering. - **source**: String to track the data origin or generating process. @@ -94,7 +96,6 @@ Example: Creating and saving an image item content="path/to/wing_profile.png", tags="section=images project=wing_sim", ) - image_item.save() After saving, the file is copied into the configured media directory. You can access the uploaded file's storage path using the `file_path` property: @@ -106,7 +107,8 @@ After saving, the file is copied into the configured media directory. You can ac This path points to the location within the media directory configured during ADR setup. You can use this path for verification, further processing, or serving the media file in your application. -When rendering reports or templates that include media items, the HTML references media files using relative URLs, typically prefixed by the configured media URL (default is `/media/`): +When rendering reports or templates that include media items, the HTML references media files using relative URLs, +typically prefixed by the configured media URL (default is `/media/`): .. code-block:: html @@ -118,7 +120,10 @@ Ensure your web server is configured to serve these media URLs from the media di Summary: - Set the `content` of file-based items to the local file path before saving. - After saving, `file_path` gives the full path to the uploaded media file. +- When the item is loaded again from the database, `content` will be the relative path to the media file. - Rendered reports use relative media URLs; configure your web server accordingly. +- Use the `media_url` property to get the URL prefix for serving media files. +- The media URL is typically `/media/` by default. Rendering Items --------------- diff --git a/doc/source/serverless/media_and_static.rst b/doc/source/serverless/media_and_static.rst index 778a1dc99..36d513d98 100644 --- a/doc/source/serverless/media_and_static.rst +++ b/doc/source/serverless/media_and_static.rst @@ -3,7 +3,7 @@ Media and Static Files Serverless ADR manages two key asset categories essential for rich report presentation: -- **Media files**: User-uploaded or generated files such as images, animations, 3D models, and other payloads associated with Items. +- **Media files**: User-uploaded or generated files such as images, animations, 3D models, and other content associated with Items. - **Static files**: Framework assets including CSS, JavaScript, fonts, and icons required to render reports and web interfaces correctly. This guide covers the storage, access, lifecycle, and best practices for managing these files in Serverless ADR. @@ -64,7 +64,6 @@ File Storage and Access ----------------------- - Media files are saved with unique names based on the Item GUID and type, e.g., ``_image.png``. -- Items with associated files use the ``FilePayloadMixin`` to manage file storage and retrieval. - The media directory should be accessible by any server or process serving reports or web content. - Static files are collected during setup if ``collect_static=True`` is passed to ``ADR.setup()``. - Static files can be served by any compatible web server (eg. NGINX) or via built-in mechanisms in web frameworks. @@ -100,7 +99,6 @@ Example: Creating and saving an Image Item with a file content="C:\\images\\wing_profile.png", tags="section=geometry", ) - img_item.save() Working with Media Files Directly -------------------------------- @@ -130,6 +128,7 @@ Static Files Collection and Serving - Static files are typically collected from ADR’s installed packages during setup by calling: ``adr.setup(collect_static=True)`` + - This process copies necessary CSS, JS, fonts, and icons into the configured static directory. - Static files must be served by your web server or framework to enable proper report rendering. - The static URL prefix (e.g., ``/static/``) must correspond to your web server configuration. @@ -138,8 +137,8 @@ In-Memory Mode and Temporary Files ---------------------------------- - When using ADR in in-memory mode (``in_memory=True``), media and static files are stored in temporary directories. -- These directories are automatically cleaned up when ADR closes, so media files do not persist beyond the session. -- This mode is useful for testing or transient report generation but not for production. +- These directories are automatically cleaned up when ADR closes, so files do not persist beyond the session. +- This mode is useful for testing or transient report generation. Best Practices -------------- diff --git a/doc/source/serverless/overview.rst b/doc/source/serverless/overview.rst index 7fa5db570..8c5ed62d8 100644 --- a/doc/source/serverless/overview.rst +++ b/doc/source/serverless/overview.rst @@ -10,7 +10,7 @@ Key Benefits - Runs entirely within your Python process — no external server needed. - Supports both SQLite and PostgreSQL databases. - Uses the same core schema as the traditional ADR service. -- Enables offline report generation with full fidelity (items, templates, layouts). +- Enables offline report generation with full fidelity (items, templates, etc.). - Suitable for local workflows, batch processing, and embedding in Python applications. - Fully backwards compatible with the service-based ADR API. diff --git a/doc/source/serverless/querying.rst b/doc/source/serverless/querying.rst index ae61d249a..1357b76d4 100644 --- a/doc/source/serverless/querying.rst +++ b/doc/source/serverless/querying.rst @@ -60,13 +60,14 @@ Examples matching_items = Item.find(query=query_str) print(f"Found {len(matching_items)} matching items") -**Use the static ADR query method to find Sessions with a name:** +**Use the ADR query method to find Sessions with a name:** .. code-block:: python from ansys.dynamicreporting.core.serverless import ADR, Session - sessions = ADR.query(Session, query="A|s_name|eq|Test Session;") + adr = ADR.get_instance() + sessions = adr.query(Session, query="A|s_name|eq|Test Session;") for s in sessions: print(s.guid, s.date) @@ -138,7 +139,7 @@ Working with Query Results -------------------------- - ``get()`` returns a single model instance. -- ``filter()``, ``find()``, and ``ADR.query()`` return an ``ObjectSet`` that behaves like a list. +- ``filter()``, ``find()``, and ``ADR.query()`` return an ``ObjectSet`` that behaves like a list and can be cast to a list or iterated over. You can iterate over results, use ``len()``, or index them: @@ -175,7 +176,6 @@ Summary Querying in Serverless ADR allows precise and flexible data retrieval using: - Field filters for common attributes -- Tag substring filters - Powerful ADR query language strings - Subclass-specific automatic type filtering diff --git a/doc/source/serverless/quickstart.rst b/doc/source/serverless/quickstart.rst index 365bdb801..fe46a1d63 100644 --- a/doc/source/serverless/quickstart.rst +++ b/doc/source/serverless/quickstart.rst @@ -35,7 +35,6 @@ Create report items such as text or tables tied to the default session and datas tags="section=intro", source="quickstart-example", ) - item.save() Building Templates ------------------ diff --git a/doc/source/serverless/sessions_and_datasets.rst b/doc/source/serverless/sessions_and_datasets.rst index 8f7b3e7a1..93c5b9825 100644 --- a/doc/source/serverless/sessions_and_datasets.rst +++ b/doc/source/serverless/sessions_and_datasets.rst @@ -8,8 +8,7 @@ In this API, a **Session** represents a logical grouping or “push” of data f (such as a solver or post-processor) into the ADR system. It captures metadata about when, where, and how the data was ingested. -A **Dataset** contains the actual simulation or analysis data associated with a Session. This could -include files, tables, images, or other artifacts generated during the simulation. +A **Dataset** contains the metadata about actual simulation or analysis data associated with a Session. By associating report items with Sessions and Datasets, the API maintains clear context and provenance, enabling organized, meaningful reports that trace back to the original data source. @@ -20,10 +19,9 @@ flexible and efficient report generation workflows. Key Entities ------------ -- **Session**: Stores metadata about the session or logical grouping of data imported into ADR during a single -data push or analysis run, such as date, hostname, platform, and application version. -- **Dataset**: Stores metadata about the dataset or collection of simulation or analysis data, such as files, -formats, and element counts. +- **Session**: Stores metadata about the session or logical grouping of data imported into ADR during a single data push or analysis run, such as date, hostname, platform, and application version. + +- **Dataset**: Stores metadata about the dataset or collection of simulation or analysis data, such as files, formats, and element counts. Session and Dataset Properties and Metadata ------------------------------------------- @@ -31,21 +29,35 @@ Session and Dataset Properties and Metadata Sessions and Datasets include important properties and metadata fields that help organize and contextualize your data: - **Session properties:** + - **guid**: Unique identifier for the session. + - **date**: Timestamp of when the session was created or recorded. + - **hostname**: The machine or environment where the data push originated. + - **platform**: Operating system or platform information. + - **application**: Name of the application or tool that created the session. + - **version**: Version of the application or tool. + - **tags**: Space-separated string of key or key=value tags for filtering and classification. - **Dataset properties:** + - **guid**: Unique identifier for the dataset. + - **filename**: Name of the data file associated with the dataset. + - **dirname**: Directory path or location related to the dataset. + - **format**: Data format descriptor (e.g., CDB, CSV). + - **numparts**: Number of parts or segments in the dataset. + - **numelements**: Number of elements (e.g., mesh elements) in the dataset. + - **tags**: Space-separated string of key or key=value tags for filtering and classification. Both Sessions and Datasets play a key role in associating your report items with the proper data context and provenance. @@ -139,7 +151,7 @@ Exceptions and Validation - Creating or modifying sessions and datasets will raise errors if required fields are missing or invalid. -- Querying items with incorrect syntax or unsupported operations raises an `ADRException`. +- Querying items with incorrect syntax or unsupported operations raises an ``ADRException``. - Fetching non-existent sessions or datasets by GUID raises a ``DoesNotExist`` error. - Multiple objects returned for a single fetch raises a ``MultipleObjectsReturned`` error. diff --git a/doc/source/serverless/templates.rst b/doc/source/serverless/templates.rst index c0f85fff0..ce36f1bbf 100644 --- a/doc/source/serverless/templates.rst +++ b/doc/source/serverless/templates.rst @@ -78,7 +78,10 @@ Template Attributes and Methods Templates have several important properties and methods: +- ``guid``: Unique identifier for the template. - ``name``: The template’s unique name. +- ``date``: The date when the template was created. +- ``tags``: A string of tags for categorization and filtering. - ``params``: JSON-encoded string storing rendering parameters and properties. - ``item_filter``: Query string filter to select items included in this template. - ``parent``: Reference to the parent template or None for root templates. @@ -102,11 +105,11 @@ Template Parameters Each template stores configuration and state in its ``params`` field, a JSON string representing: -- HTML content or raw strings (e.g., ``"HTML"``) +- HTML header (e.g., ``"HTML"``) - Layout-specific options (e.g., column counts, widths) - Filter parameters and modes controlling which Items are included - Sorting options (fields, order, selection) -- Custom properties for configuration and behavior +- Other custom properties for configuration and behavior You can manipulate these through provided methods: @@ -282,10 +285,6 @@ Example: Creating a Nested Template Structure results_panel.set_filter("A|i_tags|cont|section=results;") results_panel.save() - top_template.children.append(results_panel) - top_template.save() - - Rendering Templates ------------------ @@ -319,7 +318,6 @@ Lifecycle Notes - Templates must be saved to persist changes. - Parent templates must be saved before saving children. -- Children templates must be saved before their parent saves can complete successfully. - Deleting a template typically requires handling or deleting its children to avoid orphaned templates. Exceptions and Validation @@ -327,7 +325,7 @@ Exceptions and Validation - Creating or fetching templates with missing or invalid fields raises validation errors. - Attempting to instantiate the base ``Template`` class directly raises an error. -- Filters using restricted keys (like ``t_types|``) are disallowed on subclasses. +- Filters using keys mentioning the type (like ``t_types|``) are disallowed on subclasses. - Invalid parent references or child types will raise type or integrity errors during saving. - Only top-level templates (parent=None) can be copied between databases. - Templates must have their parents and children saved before saving themselves to ensure integrity. @@ -341,6 +339,3 @@ Summary Templates are the backbone of report structure in Serverless ADR. They let you create rich, dynamic, and highly customizable reports by defining layouts and generators, setting filters and parameters, and nesting templates to build complex hierarchical reports. - -Next, move on to the :doc:`rendering` guide to learn how to convert templates and items -into final HTML reports for presentation or web serving. From 10c7cf5cf9f17bd0059b31e3881eb65aaf5cb789 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Tue, 24 Jun 2025 12:25:56 -0400 Subject: [PATCH 48/50] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c6ad5dc54..8cfd03710 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ dependencies = [ "numpy>=1.23.5,<3", "python-pptx==0.6.19", "pandas>=2.0", - "statsmodels>=0.14", + "statsmodels==0.14.3", # later versions break ADR "docutils>=0.21", "psycopg[binary]>=3.2.3", ] From f3a1ebb1e4ec7625b4653c0531c3b202f36e5413 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Tue, 24 Jun 2025 12:51:05 -0400 Subject: [PATCH 49/50] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8cfd03710..c584a99a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ dependencies = [ "numpy>=1.23.5,<3", "python-pptx==0.6.19", "pandas>=2.0", - "statsmodels==0.14.3", # later versions break ADR + "statsmodels==0.14.2", # later versions break ADR "docutils>=0.21", "psycopg[binary]>=3.2.3", ] From c6593ee1c59cf14178d47f66312f5a30e6120435 Mon Sep 17 00:00:00 2001 From: viseshrp <11642379+viseshrp@users.noreply.github.com> Date: Tue, 24 Jun 2025 13:10:12 -0400 Subject: [PATCH 50/50] Update pyproject.toml --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c584a99a8..5321e8f1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,8 @@ dependencies = [ "numpy>=1.23.5,<3", "python-pptx==0.6.19", "pandas>=2.0", - "statsmodels==0.14.2", # later versions break ADR + "statsmodels>=0.14", + "scipy<=1.15.3", # breaks ADR if not included. Remove when statsmodels is updated "docutils>=0.21", "psycopg[binary]>=3.2.3", ]