From 487b2f42d1474dad765b39944e20499cea296fa3 Mon Sep 17 00:00:00 2001 From: KM-R <129882581+KM-R@users.noreply.github.com> Date: Tue, 19 Sep 2023 23:45:10 +0200 Subject: [PATCH] update data based on selected company (#122) Added UI elements to select a company and update shown data depending on chosen company --------- Co-authored-by: Philipp Horstenkamp --- .github/workflows/lint-actions.yaml | 2 +- .gitignore | 3 + .pre-commit-config.yaml | 2 +- .vscode/settings.json | 3 - poetry.lock | 465 ++++++------------ pyproject.toml | 4 +- .../ui/assets/company_stats.css | 69 +++ .../ui/assets/header.css | 58 +++ .../ui/assets/tabs.css | 23 + .../ui/company_finance_dash.py | 422 +++------------- .../ui/ui_elements.py | 331 +++++++++++++ .../utils/data_transfer.py | 2 +- tests/conftest.py | 64 ++- tests/ui/ui_elements_test.py | 118 +++++ tests/utils/data_transfer_test.py | 66 +-- 15 files changed, 900 insertions(+), 732 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 src/aki_prj23_transparenzregister/ui/assets/company_stats.css create mode 100644 src/aki_prj23_transparenzregister/ui/assets/header.css create mode 100644 src/aki_prj23_transparenzregister/ui/assets/tabs.css create mode 100644 src/aki_prj23_transparenzregister/ui/ui_elements.py create mode 100644 tests/ui/ui_elements_test.py diff --git a/.github/workflows/lint-actions.yaml b/.github/workflows/lint-actions.yaml index ffbed26..81cf648 100644 --- a/.github/workflows/lint-actions.yaml +++ b/.github/workflows/lint-actions.yaml @@ -47,7 +47,7 @@ jobs: - uses: actions/checkout@v3 - uses: chartboost/ruff-action@v1 with: - version: 0.0.289 + version: 0.0.290 python-requirements: name: Check Python Requirements diff --git a/.gitignore b/.gitignore index a5206be..d5f8fdc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ *secrets.json *secrets_prod.json +# Settings +.vscode/ + # Snyk .dccache diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f4f2f57..922d607 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.0.289 + rev: v0.0.290 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7e6882b..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "files.eol": "\n" -} diff --git a/poetry.lock b/poetry.lock index ce01744..bd2f1c0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -16,7 +15,6 @@ files = [ name = "ansi2html" version = "1.8.0" description = "" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -32,7 +30,6 @@ test = ["pytest", "pytest-cov"] name = "anyio" version = "4.0.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -53,7 +50,6 @@ trio = ["trio (>=0.22)"] name = "appnope" version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" -category = "dev" optional = false python-versions = "*" files = [ @@ -65,7 +61,6 @@ files = [ name = "argon2-cffi" version = "23.1.0" description = "Argon2 for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -86,7 +81,6 @@ typing = ["mypy"] name = "argon2-cffi-bindings" version = "21.2.0" description = "Low-level CFFI bindings for Argon2" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -124,7 +118,6 @@ tests = ["pytest"] name = "arrow" version = "1.2.3" description = "Better dates & times for Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -139,7 +132,6 @@ python-dateutil = ">=2.7.0" name = "asttokens" version = "2.4.0" description = "Annotate AST trees with source code positions" -category = "dev" optional = false python-versions = "*" files = [ @@ -157,7 +149,6 @@ test = ["astroid", "pytest"] name = "async-lru" version = "2.0.4" description = "Simple LRU cache for asyncio" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -169,7 +160,6 @@ files = [ name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -188,7 +178,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "babel" version = "2.12.1" description = "Internationalization utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -200,7 +189,6 @@ files = [ name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" -category = "dev" optional = false python-versions = "*" files = [ @@ -212,7 +200,6 @@ files = [ name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" -category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -231,7 +218,6 @@ lxml = ["lxml"] name = "black" version = "23.9.1" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -278,7 +264,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "bleach" version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -297,7 +282,6 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] name = "boolean-py" version = "4.0" description = "Define boolean algebras, create and parse boolean expressions and create custom boolean DSL." -category = "dev" optional = false python-versions = "*" files = [ @@ -309,7 +293,6 @@ files = [ name = "cachecontrol" version = "0.13.1" description = "httplib2 caching for requests" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -331,7 +314,6 @@ redis = ["redis (>=2.10.5)"] name = "cachetools" version = "5.3.1" description = "Extensible memoizing collections and decorators" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -343,7 +325,6 @@ files = [ name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -355,7 +336,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -432,7 +412,6 @@ pycparser = "*" name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -444,7 +423,6 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -529,7 +507,6 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -544,7 +521,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -556,7 +532,6 @@ files = [ name = "coloredlogs" version = "15.0.1" description = "Colored terminal output for Python's logging module" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -574,7 +549,6 @@ cron = ["capturer (>=2.4)"] name = "comm" version = "0.1.4" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -594,7 +568,6 @@ typing = ["mypy (>=0.990)"] name = "contourpy" version = "1.1.0" description = "Python library for calculating contours of 2D quadrilateral grids" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -649,11 +622,81 @@ mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.2.0)", "types-Pill test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] test-no-images = ["pytest", "pytest-cov", "wurlitzer"] +[[package]] +name = "contourpy" +version = "1.1.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.8" +files = [ + {file = "contourpy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:46e24f5412c948d81736509377e255f6040e94216bf1a9b5ea1eaa9d29f6ec1b"}, + {file = "contourpy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e48694d6a9c5a26ee85b10130c77a011a4fedf50a7279fa0bdaf44bafb4299d"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66045af6cf00e19d02191ab578a50cb93b2028c3eefed999793698e9ea768ae"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ebf42695f75ee1a952f98ce9775c873e4971732a87334b099dde90b6af6a916"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6aec19457617ef468ff091669cca01fa7ea557b12b59a7908b9474bb9674cf0"}, + {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:462c59914dc6d81e0b11f37e560b8a7c2dbab6aca4f38be31519d442d6cde1a1"}, + {file = "contourpy-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6d0a8efc258659edc5299f9ef32d8d81de8b53b45d67bf4bfa3067f31366764d"}, + {file = "contourpy-1.1.1-cp310-cp310-win32.whl", hash = "sha256:d6ab42f223e58b7dac1bb0af32194a7b9311065583cc75ff59dcf301afd8a431"}, + {file = "contourpy-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:549174b0713d49871c6dee90a4b499d3f12f5e5f69641cd23c50a4542e2ca1eb"}, + {file = "contourpy-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:407d864db716a067cc696d61fa1ef6637fedf03606e8417fe2aeed20a061e6b2"}, + {file = "contourpy-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe80c017973e6a4c367e037cb31601044dd55e6bfacd57370674867d15a899b"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e30aaf2b8a2bac57eb7e1650df1b3a4130e8d0c66fc2f861039d507a11760e1b"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3de23ca4f381c3770dee6d10ead6fff524d540c0f662e763ad1530bde5112532"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:566f0e41df06dfef2431defcfaa155f0acfa1ca4acbf8fd80895b1e7e2ada40e"}, + {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04c2f0adaf255bf756cf08ebef1be132d3c7a06fe6f9877d55640c5e60c72c5"}, + {file = "contourpy-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d0c188ae66b772d9d61d43c6030500344c13e3f73a00d1dc241da896f379bb62"}, + {file = "contourpy-1.1.1-cp311-cp311-win32.whl", hash = "sha256:0683e1ae20dc038075d92e0e0148f09ffcefab120e57f6b4c9c0f477ec171f33"}, + {file = "contourpy-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:8636cd2fc5da0fb102a2504fa2c4bea3cbc149533b345d72cdf0e7a924decc45"}, + {file = "contourpy-1.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:560f1d68a33e89c62da5da4077ba98137a5e4d3a271b29f2f195d0fba2adcb6a"}, + {file = "contourpy-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24216552104ae8f3b34120ef84825400b16eb6133af2e27a190fdc13529f023e"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56de98a2fb23025882a18b60c7f0ea2d2d70bbbcfcf878f9067234b1c4818442"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:07d6f11dfaf80a84c97f1a5ba50d129d9303c5b4206f776e94037332e298dda8"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1eaac5257a8f8a047248d60e8f9315c6cff58f7803971170d952555ef6344a7"}, + {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19557fa407e70f20bfaba7d55b4d97b14f9480856c4fb65812e8a05fe1c6f9bf"}, + {file = "contourpy-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:081f3c0880712e40effc5f4c3b08feca6d064cb8cfbb372ca548105b86fd6c3d"}, + {file = "contourpy-1.1.1-cp312-cp312-win32.whl", hash = "sha256:059c3d2a94b930f4dafe8105bcdc1b21de99b30b51b5bce74c753686de858cb6"}, + {file = "contourpy-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f44d78b61740e4e8c71db1cf1fd56d9050a4747681c59ec1094750a658ceb970"}, + {file = "contourpy-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:70e5a10f8093d228bb2b552beeb318b8928b8a94763ef03b858ef3612b29395d"}, + {file = "contourpy-1.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8394e652925a18ef0091115e3cc191fef350ab6dc3cc417f06da66bf98071ae9"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bd5680f844c3ff0008523a71949a3ff5e4953eb7701b28760805bc9bcff217"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66544f853bfa85c0d07a68f6c648b2ec81dafd30f272565c37ab47a33b220684"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0c02b75acfea5cab07585d25069207e478d12309557f90a61b5a3b4f77f46ce"}, + {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41339b24471c58dc1499e56783fedc1afa4bb018bcd035cfb0ee2ad2a7501ef8"}, + {file = "contourpy-1.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f29fb0b3f1217dfe9362ec55440d0743fe868497359f2cf93293f4b2701b8251"}, + {file = "contourpy-1.1.1-cp38-cp38-win32.whl", hash = "sha256:f9dc7f933975367251c1b34da882c4f0e0b2e24bb35dc906d2f598a40b72bfc7"}, + {file = "contourpy-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:498e53573e8b94b1caeb9e62d7c2d053c263ebb6aa259c81050766beb50ff8d9"}, + {file = "contourpy-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ba42e3810999a0ddd0439e6e5dbf6d034055cdc72b7c5c839f37a7c274cb4eba"}, + {file = "contourpy-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c06e4c6e234fcc65435223c7b2a90f286b7f1b2733058bdf1345d218cc59e34"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca6fab080484e419528e98624fb5c4282148b847e3602dc8dbe0cb0669469887"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93df44ab351119d14cd1e6b52a5063d3336f0754b72736cc63db59307dabb718"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eafbef886566dc1047d7b3d4b14db0d5b7deb99638d8e1be4e23a7c7ac59ff0f"}, + {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efe0fab26d598e1ec07d72cf03eaeeba8e42b4ecf6b9ccb5a356fde60ff08b85"}, + {file = "contourpy-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f08e469821a5e4751c97fcd34bcb586bc243c39c2e39321822060ba902eac49e"}, + {file = "contourpy-1.1.1-cp39-cp39-win32.whl", hash = "sha256:bfc8a5e9238232a45ebc5cb3bfee71f1167064c8d382cadd6076f0d51cff1da0"}, + {file = "contourpy-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:c84fdf3da00c2827d634de4fcf17e3e067490c4aea82833625c4c8e6cdea0887"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:229a25f68046c5cf8067d6d6351c8b99e40da11b04d8416bf8d2b1d75922521e"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10dab5ea1bd4401c9483450b5b0ba5416be799bbd50fc7a6cc5e2a15e03e8a3"}, + {file = "contourpy-1.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f9147051cb8fdb29a51dc2482d792b3b23e50f8f57e3720ca2e3d438b7adf23"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a75cc163a5f4531a256f2c523bd80db509a49fc23721b36dd1ef2f60ff41c3cb"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b53d5769aa1f2d4ea407c65f2d1d08002952fac1d9e9d307aa2e1023554a163"}, + {file = "contourpy-1.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11b836b7dbfb74e049c302bbf74b4b8f6cb9d0b6ca1bf86cfa8ba144aedadd9c"}, + {file = "contourpy-1.1.1.tar.gz", hash = "sha256:96ba37c2e24b7212a77da85004c38e7c4d155d3e72a45eeaf22c1f03f607e8ab"}, +] + +[package.dependencies] +numpy = {version = ">=1.16,<2.0", markers = "python_version <= \"3.11\""} + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.4.1)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "wurlitzer"] + [[package]] name = "coverage" version = "7.3.1" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -716,35 +759,34 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "41.0.3" +version = "41.0.4" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507"}, - {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922"}, - {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81"}, - {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd"}, - {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47"}, - {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116"}, - {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c"}, - {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae"}, - {file = "cryptography-41.0.3-cp37-abi3-win32.whl", hash = "sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306"}, - {file = "cryptography-41.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574"}, - {file = "cryptography-41.0.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087"}, - {file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858"}, - {file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906"}, - {file = "cryptography-41.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e"}, - {file = "cryptography-41.0.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd"}, - {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207"}, - {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84"}, - {file = "cryptography-41.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7"}, - {file = "cryptography-41.0.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d"}, - {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de"}, - {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1"}, - {file = "cryptography-41.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4"}, - {file = "cryptography-41.0.3.tar.gz", hash = "sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34"}, + {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839"}, + {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f"}, + {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714"}, + {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb"}, + {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13"}, + {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143"}, + {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397"}, + {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860"}, + {file = "cryptography-41.0.4-cp37-abi3-win32.whl", hash = "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd"}, + {file = "cryptography-41.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d"}, + {file = "cryptography-41.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67"}, + {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e"}, + {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829"}, + {file = "cryptography-41.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca"}, + {file = "cryptography-41.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d"}, + {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac"}, + {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9"}, + {file = "cryptography-41.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"}, + {file = "cryptography-41.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91"}, + {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8"}, + {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6"}, + {file = "cryptography-41.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311"}, + {file = "cryptography-41.0.4.tar.gz", hash = "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a"}, ] [package.dependencies] @@ -764,7 +806,6 @@ test-randomorder = ["pytest-randomly"] name = "cycler" version = "0.11.0" description = "Composable style cycles" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -776,7 +817,6 @@ files = [ name = "cyclonedx-python-lib" version = "4.2.2" description = "A library for producing CycloneDX SBOM (Software Bill of Materials) files." -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -794,7 +834,6 @@ sortedcontainers = ">=2.4.0,<3.0.0" name = "dash" version = "2.13.0" description = "A Python framework for building reactive web-apps. Developed by Plotly." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -828,7 +867,6 @@ testing = ["beautifulsoup4 (>=4.8.2)", "cryptography (<3.4)", "dash-testing-stub name = "dash-bootstrap-components" version = "1.5.0" description = "Bootstrap themed components for use in Plotly Dash" -category = "main" optional = false python-versions = ">=3.7, <4" files = [ @@ -846,7 +884,6 @@ pandas = ["numpy", "pandas"] name = "dash-core-components" version = "2.0.0" description = "Core component suite for Dash" -category = "main" optional = false python-versions = "*" files = [ @@ -858,7 +895,6 @@ files = [ name = "dash-html-components" version = "2.0.0" description = "Vanilla HTML components for Dash" -category = "main" optional = false python-versions = "*" files = [ @@ -870,7 +906,6 @@ files = [ name = "dash-table" version = "5.0.0" description = "Dash table" -category = "main" optional = false python-versions = "*" files = [ @@ -882,7 +917,6 @@ files = [ name = "dateparser" version = "1.1.8" description = "Date parsing library designed to parse dates from HTML pages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -905,7 +939,6 @@ langdetect = ["langdetect"] name = "de-autobahn" version = "1.0.4" description = "Autobahn App API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -921,7 +954,6 @@ urllib3 = ">=1.25.3" name = "de-bundesrat" version = "0.1.0" description = "Bundesrat: Live Informationen" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -937,7 +969,6 @@ urllib3 = ">=1.25.3" name = "de-bundestag" version = "0.1.0" description = "Bundestag: Live Informationen" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -953,7 +984,6 @@ urllib3 = ">=1.25.3" name = "de-dwd" version = "1.0.1" description = "Deutscher Wetterdienst: API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -969,7 +999,6 @@ urllib3 = ">=1.25.3" name = "de-interpol" version = "0.1.0" description = "Interpol: Interpol Red Notices API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -985,7 +1014,6 @@ urllib3 = ">=1.25.3" name = "de-jobsuche" version = "0.1.0" description = "Arbeitsagentur Jobsuche API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1001,7 +1029,6 @@ urllib3 = ">=1.25.3" name = "de-ladestationen" version = "1.0.5" description = "Bundesnetzagentur: Ladesäulenregister" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1017,7 +1044,6 @@ urllib3 = ">=1.25.3" name = "de-mudab" version = "0.1.0" description = "Umweltbundesamt: Meeresumweltdatenbank (MUDAB)" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1033,7 +1059,6 @@ urllib3 = ">=1.25.3" name = "de-nina" version = "1.1.0" description = "Bundesamt für Bevölkerungsschutz: NINA API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1049,7 +1074,6 @@ urllib3 = ">=1.25.3" name = "de-polizei-brandenburg" version = "0.1.0" description = "Polizei Brandenburg: App" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1065,7 +1089,6 @@ urllib3 = ">=1.25.3" name = "de-risikogebiete" version = "0.1.0" description = "Robert Koch Institut: Corona Risikogebiete API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1081,7 +1104,6 @@ urllib3 = ">=1.25.3" name = "de-smard" version = "0.1.0" description = "Bundesnetzagentur Strommarktdaten" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1097,7 +1119,6 @@ urllib3 = ">=1.25.3" name = "de-strahlenschutz" version = "1.0.0" description = "ODL-Info API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1113,7 +1134,6 @@ urllib3 = ">=1.25.3" name = "de-travelwarning" version = "0.1.0" description = "Auswärtiges Amt: Reisewarnungen OpenData Schnittstelle" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1129,7 +1149,6 @@ urllib3 = ">=1.25.3" name = "de-zoll" version = "0.1.0" description = "Einfuhrzoll API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1145,7 +1164,6 @@ urllib3 = ">=1.25.3" name = "debugpy" version = "1.8.0" description = "An implementation of the Debug Adapter Protocol for Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1173,7 +1191,6 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1185,7 +1202,6 @@ files = [ name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1197,7 +1213,6 @@ files = [ name = "deutschland" version = "0.3.1" description = "" -category = "main" optional = false python-versions = "^3.11" files = [] @@ -1266,7 +1281,6 @@ resolved_reference = "507901b95cffa8dede08b69adab23dd8eda92d87" name = "distlib" version = "0.3.7" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" files = [ @@ -1278,7 +1292,6 @@ files = [ name = "dnspython" version = "2.4.2" description = "DNS toolkit" -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -1298,7 +1311,6 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"] name = "docutils" version = "0.18.1" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1310,7 +1322,6 @@ files = [ name = "et-xmlfile" version = "1.1.0" description = "An implementation of lxml.xmlfile for the standard library" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1322,7 +1333,6 @@ files = [ name = "exceptiongroup" version = "1.1.3" description = "Backport of PEP 654 (exception groups)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1337,7 +1347,6 @@ test = ["pytest (>=6)"] name = "executing" version = "1.2.0" description = "Get the currently executing AST node of a frame, and other information" -category = "dev" optional = false python-versions = "*" files = [ @@ -1352,7 +1361,6 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] name = "fastjsonschema" version = "2.18.0" description = "Fastest Python implementation of JSON schema" -category = "dev" optional = false python-versions = "*" files = [ @@ -1367,7 +1375,6 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "filelock" version = "3.12.4" description = "A platform independent file lock." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1384,7 +1391,6 @@ typing = ["typing-extensions (>=4.7.1)"] name = "flask" version = "2.2.5" description = "A simple framework for building complex web applications." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1406,7 +1412,6 @@ dotenv = ["python-dotenv"] name = "flatbuffers" version = "23.5.26" description = "The FlatBuffers serialization format for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -1418,7 +1423,6 @@ files = [ name = "fonttools" version = "4.42.1" description = "Tools to manipulate font files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1476,7 +1480,6 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "fqdn" version = "1.5.1" description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" -category = "dev" optional = false python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" files = [ @@ -1488,7 +1491,6 @@ files = [ name = "future" version = "0.18.3" description = "Clean single-source support for Python 3 and 2" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1499,7 +1501,6 @@ files = [ name = "gql" version = "2.0.0" description = "GraphQL client for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -1521,7 +1522,6 @@ test = ["coveralls (==2.0.0)", "mock (==4.0.2)", "pytest (==5.4.2)", "pytest-asy name = "graphql-core" version = "2.3.2" description = "GraphQL implementation for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -1542,7 +1542,6 @@ test = ["coveralls (==1.11.1)", "cython (==0.29.17)", "gevent (==1.5.0)", "pyann name = "greenlet" version = "2.0.2" description = "Lightweight in-process concurrent programming" -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -1616,7 +1615,6 @@ test = ["objgraph", "psutil"] name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1628,7 +1626,6 @@ files = [ name = "html5lib" version = "1.1" description = "HTML parser based on the WHATWG HTML specification" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1650,7 +1647,6 @@ lxml = ["lxml"] name = "humanfriendly" version = "10.0" description = "Human friendly output for text interfaces using Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1663,14 +1659,13 @@ pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_ve [[package]] name = "identify" -version = "2.5.28" +version = "2.5.29" description = "File identification library for Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.28-py2.py3-none-any.whl", hash = "sha256:87816de144bf46d161bd5b3e8f5596b16cade3b80be537087334b26bc5c177f3"}, - {file = "identify-2.5.28.tar.gz", hash = "sha256:94bb59643083ebd60dc996d043497479ee554381fbc5307763915cda49b0e78f"}, + {file = "identify-2.5.29-py2.py3-none-any.whl", hash = "sha256:24437fbf6f4d3fe6efd0eb9d67e24dd9106db99af5ceb27996a5f7895f24bf1b"}, + {file = "identify-2.5.29.tar.gz", hash = "sha256:d43d52b86b15918c137e3a74fff5224f60385cd0e9c38e99d07c257f02f151a5"}, ] [package.extras] @@ -1680,7 +1675,6 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1692,7 +1686,6 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1704,7 +1697,6 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1716,7 +1708,6 @@ files = [ name = "ipykernel" version = "6.25.2" description = "IPython Kernel for Jupyter" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1730,7 +1721,7 @@ comm = ">=0.1.1" debugpy = ">=1.6.5" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" @@ -1750,7 +1741,6 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" name = "ipython" version = "8.15.0" description = "IPython: Productive Interactive Computing" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -1789,7 +1779,6 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa name = "ipython-genutils" version = "0.2.0" description = "Vestigial utilities from IPython" -category = "dev" optional = false python-versions = "*" files = [ @@ -1801,7 +1790,6 @@ files = [ name = "ipywidgets" version = "8.1.1" description = "Jupyter interactive widgets" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1823,7 +1811,6 @@ test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] name = "isoduration" version = "20.11.0" description = "Operations with ISO 8601 durations" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1838,7 +1825,6 @@ arrow = ">=0.15.0" name = "itsdangerous" version = "2.1.2" description = "Safely pass data to untrusted environments and back." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1850,7 +1836,6 @@ files = [ name = "jedi" version = "0.19.0" description = "An autocompletion tool for Python that can be used for text editors." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1870,7 +1855,6 @@ testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1888,7 +1872,6 @@ i18n = ["Babel (>=2.7)"] name = "json5" version = "0.9.14" description = "A Python implementation of the JSON5 data format." -category = "dev" optional = false python-versions = "*" files = [ @@ -1903,7 +1886,6 @@ dev = ["hypothesis"] name = "jsonpointer" version = "2.4" description = "Identify specific nodes in a JSON document (RFC 6901)" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" files = [ @@ -1915,7 +1897,6 @@ files = [ name = "jsonschema" version = "4.19.0" description = "An implementation of JSON Schema validation for Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1945,7 +1926,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2023.7.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1960,7 +1940,6 @@ referencing = ">=0.28.0" name = "jupyter" version = "1.0.0" description = "Jupyter metapackage. Install all the Jupyter components in one go." -category = "dev" optional = false python-versions = "*" files = [ @@ -1981,7 +1960,6 @@ qtconsole = "*" name = "jupyter-client" version = "8.3.1" description = "Jupyter protocol implementation and client libraries" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1990,7 +1968,7 @@ files = [ ] [package.dependencies] -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" tornado = ">=6.2" @@ -2004,7 +1982,6 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt name = "jupyter-console" version = "6.6.3" description = "Jupyter terminal console" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2016,7 +1993,7 @@ files = [ ipykernel = ">=6.14" ipython = "*" jupyter-client = ">=7.0.0" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" prompt-toolkit = ">=3.0.30" pygments = "*" pyzmq = ">=17" @@ -2029,7 +2006,6 @@ test = ["flaky", "pexpect", "pytest"] name = "jupyter-core" version = "5.3.1" description = "Jupyter core package. A base package on which Jupyter projects rely." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2050,7 +2026,6 @@ test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] name = "jupyter-events" version = "0.7.0" description = "Jupyter Event System library" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2076,7 +2051,6 @@ test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "p name = "jupyter-lsp" version = "2.2.0" description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2091,7 +2065,6 @@ jupyter-server = ">=1.1.2" name = "jupyter-server" version = "2.7.3" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2104,7 +2077,7 @@ anyio = ">=3.1.0" argon2-cffi = "*" jinja2 = "*" jupyter-client = ">=7.4.4" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" jupyter-events = ">=0.6.0" jupyter-server-terminals = "*" nbconvert = ">=6.4.4" @@ -2128,7 +2101,6 @@ test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-sc name = "jupyter-server-terminals" version = "0.4.4" description = "A Jupyter Server Extension Providing Terminals." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2148,7 +2120,6 @@ test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", name = "jupyterlab" version = "4.0.6" description = "JupyterLab computational environment" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2179,7 +2150,6 @@ test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-cons name = "jupyterlab-pygments" version = "0.2.2" description = "Pygments theme using JupyterLab CSS variables" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2191,7 +2161,6 @@ files = [ name = "jupyterlab-server" version = "2.25.0" description = "A set of server components for JupyterLab and JupyterLab like applications." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2217,7 +2186,6 @@ test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-v name = "jupyterlab-widgets" version = "3.0.9" description = "Jupyter interactive widgets for JupyterLab" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2229,7 +2197,6 @@ files = [ name = "kiwisolver" version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2343,7 +2310,6 @@ files = [ name = "license-expression" version = "30.1.1" description = "license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2362,7 +2328,6 @@ testing = ["black", "isort", "pytest (>=6,!=7.0.0)", "pytest-xdist (>=2)", "twin name = "loguru" version = "0.7.2" description = "Python logging made (stupidly) simple" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2381,7 +2346,6 @@ dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptio name = "loguru-mypy" version = "0.0.4" description = "" -category = "dev" optional = false python-versions = ">=3.6.0" files = [ @@ -2396,7 +2360,6 @@ typing-extensions = "*" name = "lxml" version = "4.9.3" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ @@ -2504,7 +2467,6 @@ source = ["Cython (>=0.29.35)"] name = "mapbox-vector-tile" version = "1.2.1" description = "Mapbox Vector Tile" -category = "main" optional = false python-versions = "*" files = [ @@ -2522,7 +2484,6 @@ shapely = "*" name = "markdown-it-py" version = "2.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2547,7 +2508,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2607,7 +2567,6 @@ files = [ name = "matplotlib" version = "3.8.0" description = "Python plotting package" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2657,7 +2616,6 @@ setuptools_scm = ">=7" name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2672,7 +2630,6 @@ traitlets = "*" name = "mdit-py-plugins" version = "0.3.5" description = "Collection of plugins for markdown-it-py" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2692,7 +2649,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2704,7 +2660,6 @@ files = [ name = "mistune" version = "3.0.1" description = "A sane and fast Markdown parser with useful plugins and renderers" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2716,7 +2671,6 @@ files = [ name = "more-itertools" version = "8.14.0" description = "More routines for operating on iterables, beyond itertools" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2728,7 +2682,6 @@ files = [ name = "mpmath" version = "1.3.0" description = "Python library for arbitrary-precision floating-point arithmetic" -category = "main" optional = false python-versions = "*" files = [ @@ -2746,7 +2699,6 @@ tests = ["pytest (>=4.6)"] name = "msgpack" version = "1.0.5" description = "MessagePack serializer" -category = "dev" optional = false python-versions = "*" files = [ @@ -2819,7 +2771,6 @@ files = [ name = "mypy" version = "1.5.1" description = "Optional static typing for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2865,7 +2816,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2877,7 +2827,6 @@ files = [ name = "myst-parser" version = "1.0.0" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2904,7 +2853,6 @@ testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4, name = "nbclient" version = "0.8.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -2914,7 +2862,7 @@ files = [ [package.dependencies] jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" nbformat = ">=5.1" traitlets = ">=5.4" @@ -2927,7 +2875,6 @@ test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>= name = "nbconvert" version = "7.8.0" description = "Converting Jupyter Notebooks" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2965,7 +2912,6 @@ webpdf = ["playwright"] name = "nbformat" version = "5.9.2" description = "The Jupyter Notebook format" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2987,7 +2933,6 @@ test = ["pep440", "pre-commit", "pytest", "testpath"] name = "nbsphinx" version = "0.9.3" description = "Jupyter Notebook Tools for Sphinx" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3005,21 +2950,19 @@ traitlets = ">=5" [[package]] name = "nest-asyncio" -version = "1.5.7" +version = "1.5.8" description = "Patch asyncio to allow nested event loops" -category = "main" optional = false python-versions = ">=3.5" files = [ - {file = "nest_asyncio-1.5.7-py3-none-any.whl", hash = "sha256:5301c82941b550b3123a1ea772ba9a1c80bad3a182be8c1a5ae6ad3be57a9657"}, - {file = "nest_asyncio-1.5.7.tar.gz", hash = "sha256:6a80f7b98f24d9083ed24608977c09dd608d83f91cccc24c9d2cba6d10e01c10"}, + {file = "nest_asyncio-1.5.8-py3-none-any.whl", hash = "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d"}, + {file = "nest_asyncio-1.5.8.tar.gz", hash = "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb"}, ] [[package]] name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -3034,7 +2977,6 @@ setuptools = "*" name = "notebook" version = "7.0.3" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3058,7 +3000,6 @@ test = ["importlib-resources (>=5.0)", "ipykernel", "jupyter-server[test] (>=2.4 name = "notebook-shim" version = "0.2.3" description = "A shim layer for notebook traits and config" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3076,7 +3017,6 @@ test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync" name = "numpy" version = "1.25.2" description = "Fundamental package for array computing in Python" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -3111,7 +3051,6 @@ files = [ name = "onnxruntime" version = "1.15.1" description = "ONNX Runtime is a runtime accelerator for Machine Learning models" -category = "main" optional = false python-versions = "*" files = [ @@ -3153,7 +3092,6 @@ sympy = "*" name = "openpyxl" version = "3.1.2" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3168,7 +3106,6 @@ et-xmlfile = "*" name = "outcome" version = "1.2.0" description = "Capture the outcome of Python function calls." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3183,7 +3120,6 @@ attrs = ">=19.2.0" name = "overrides" version = "7.4.0" description = "A decorator to automatically detect mismatch when overriding a method." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3195,7 +3131,6 @@ files = [ name = "packageurl-python" version = "0.11.2" description = "A purl aka. Package URL parser and builder" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3213,7 +3148,6 @@ test = ["pytest"] name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3225,7 +3159,6 @@ files = [ name = "pandas" version = "2.1.0" description = "Powerful data structures for data analysis, time series, and statistics" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -3284,7 +3217,6 @@ xml = ["lxml (>=4.8.0)"] name = "pandas-stubs" version = "2.0.3.230814" description = "Type annotations for pandas" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3300,7 +3232,6 @@ types-pytz = ">=2022.1.1" name = "pandocfilters" version = "1.5.0" description = "Utilities for writing pandoc filters in python" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3312,7 +3243,6 @@ files = [ name = "parso" version = "0.8.3" description = "A Python Parser" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3328,7 +3258,6 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3340,7 +3269,6 @@ files = [ name = "pexpect" version = "4.8.0" description = "Pexpect allows easy control of interactive console applications." -category = "dev" optional = false python-versions = "*" files = [ @@ -3355,7 +3283,6 @@ ptyprocess = ">=0.5" name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" -category = "dev" optional = false python-versions = "*" files = [ @@ -3367,7 +3294,6 @@ files = [ name = "pillow" version = "10.0.1" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3435,7 +3361,6 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "pip" version = "23.2.1" description = "The PyPA recommended tool for installing Python packages." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3447,7 +3372,6 @@ files = [ name = "pip-api" version = "0.0.30" description = "An unofficial, importable pip API" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3462,7 +3386,6 @@ pip = "*" name = "pip-audit" version = "2.6.1" description = "A tool for scanning Python environments for known vulnerabilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3491,7 +3414,6 @@ test = ["coverage[toml]", "pretend", "pytest", "pytest-cov"] name = "pip-licenses" version = "4.3.2" description = "Dump the software license list of Python packages installed with pip." -category = "dev" optional = false python-versions = "~=3.8" files = [ @@ -3509,7 +3431,6 @@ test = ["docutils", "mypy", "pytest-cov", "pytest-pycodestyle", "pytest-runner"] name = "pip-requirements-parser" version = "32.0.1" description = "pip requirements parser - a mostly correct pip requirements parsing library because it uses pip's own code." -category = "dev" optional = false python-versions = ">=3.6.0" files = [ @@ -3529,7 +3450,6 @@ testing = ["aboutcode-toolkit (>=6.0.0)", "black", "pytest (>=6,!=7.0.0)", "pyte name = "platformdirs" version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3545,7 +3465,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "plotly" version = "5.17.0" description = "An open-source, interactive data visualization library for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3561,7 +3480,6 @@ tenacity = ">=6.2.0" name = "pluggy" version = "1.3.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3577,7 +3495,6 @@ testing = ["pytest", "pytest-benchmark"] name = "pockets" version = "0.9.1" description = "A collection of helpful Python tools!" -category = "dev" optional = false python-versions = "*" files = [ @@ -3592,7 +3509,6 @@ six = ">=1.5.2" name = "pprintpp" version = "0.4.0" description = "A drop-in replacement for pprint that's actually pretty" -category = "dev" optional = false python-versions = "*" files = [ @@ -3604,7 +3520,6 @@ files = [ name = "pre-commit" version = "3.4.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3623,7 +3538,6 @@ virtualenv = ">=20.10.0" name = "prettytable" version = "3.9.0" description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3641,7 +3555,6 @@ tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"] name = "prometheus-client" version = "0.17.1" description = "Python client for the Prometheus monitoring system." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3656,7 +3569,6 @@ twisted = ["twisted"] name = "promise" version = "2.3" description = "Promises/A+ implementation for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -3673,7 +3585,6 @@ test = ["coveralls", "futures", "mock", "pytest (>=2.7.3)", "pytest-benchmark", name = "prompt-toolkit" version = "3.0.39" description = "Library for building powerful interactive command lines in Python" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -3688,7 +3599,6 @@ wcwidth = "*" name = "protobuf" version = "3.20.3" description = "Protocol Buffers" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3720,7 +3630,6 @@ files = [ name = "psutil" version = "5.9.5" description = "Cross-platform lib for process and system monitoring in Python." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3747,7 +3656,6 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "psycopg2-binary" version = "2.9.7" description = "psycopg2 - Python-PostgreSQL Database Adapter" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3817,7 +3725,6 @@ files = [ name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "dev" optional = false python-versions = "*" files = [ @@ -3829,7 +3736,6 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" -category = "dev" optional = false python-versions = "*" files = [ @@ -3844,7 +3750,6 @@ tests = ["pytest"] name = "py-serializable" version = "0.11.1" description = "Library for serializing and deserializing Python Objects to and from JSON and XML." -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -3859,7 +3764,6 @@ defusedxml = ">=0.7.1,<0.8.0" name = "pyclipper" version = "1.3.0.post5" description = "Cython wrapper for the C++ translation of the Angus Johnson's Clipper library (ver. 6.4.2)" -category = "main" optional = false python-versions = "*" files = [ @@ -3913,7 +3817,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3925,7 +3828,6 @@ files = [ name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3940,7 +3842,6 @@ plugins = ["importlib-metadata"] name = "pymongo" version = "4.5.0" description = "Python driver for MongoDB " -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4042,7 +3943,6 @@ zstd = ["zstandard"] name = "pyparsing" version = "3.1.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "main" optional = false python-versions = ">=3.6.8" files = [ @@ -4057,7 +3957,6 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pyreadline3" version = "3.4.1" description = "A python implementation of GNU readline." -category = "main" optional = false python-versions = "*" files = [ @@ -4069,7 +3968,6 @@ files = [ name = "pysocks" version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -4082,7 +3980,6 @@ files = [ name = "pytest" version = "7.4.2" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4103,7 +4000,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-clarity" version = "1.0.1" description = "A plugin providing an alternative, colourful diff output for failing assertions." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -4119,7 +4015,6 @@ rich = ">=8.0.0" name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4138,7 +4033,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-mock" version = "3.11.1" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4156,7 +4050,6 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "pytest-repeat" version = "0.9.1" description = "pytest plugin for repeating tests" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -4171,7 +4064,6 @@ pytest = ">=3.6" name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -4186,7 +4078,6 @@ six = ">=1.5" name = "python-dotenv" version = "1.0.0" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4201,7 +4092,6 @@ cli = ["click (>=5.0)"] name = "python-json-logger" version = "2.0.7" description = "A python library adding a json log formatter" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -4213,7 +4103,6 @@ files = [ name = "pytz" version = "2023.3.post1" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -4225,7 +4114,6 @@ files = [ name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "dev" optional = false python-versions = "*" files = [ @@ -4249,7 +4137,6 @@ files = [ name = "pywinpty" version = "2.0.11" description = "Pseudo terminal support for Windows from Python." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4264,7 +4151,6 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -4314,7 +4200,6 @@ files = [ name = "pyzmq" version = "25.1.1" description = "Python bindings for 0MQ" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -4420,7 +4305,6 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} name = "qtconsole" version = "5.4.4" description = "Jupyter Qt console" -category = "dev" optional = false python-versions = ">= 3.7" files = [ @@ -4447,7 +4331,6 @@ test = ["flaky", "pytest", "pytest-qt"] name = "qtpy" version = "2.4.0" description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4465,7 +4348,6 @@ test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] name = "referencing" version = "0.30.2" description = "JSON Referencing + Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4481,7 +4363,6 @@ rpds-py = ">=0.7.0" name = "regex" version = "2023.8.8" description = "Alternative regular expression module, to replace re." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4579,7 +4460,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4601,7 +4481,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "retrying" version = "1.3.4" description = "Retrying" -category = "main" optional = false python-versions = "*" files = [ @@ -4616,7 +4495,6 @@ six = ">=1.7.0" name = "rfc3339-validator" version = "0.1.4" description = "A pure python RFC3339 validator" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -4631,7 +4509,6 @@ six = "*" name = "rfc3986-validator" version = "0.1.1" description = "Pure python rfc3986 validator" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -4641,14 +4518,13 @@ files = [ [[package]] name = "rich" -version = "13.5.2" +version = "13.5.3" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808"}, - {file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39"}, + {file = "rich-13.5.3-py3-none-any.whl", hash = "sha256:9257b468badc3d347e146a4faa268ff229039d4c2d176ab0cffb4c4fbc73d5d9"}, + {file = "rich-13.5.3.tar.gz", hash = "sha256:87b43e0543149efa1253f485cd845bb7ee54df16c9617b8a893650ab84b4acb6"}, ] [package.dependencies] @@ -4662,7 +4538,6 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "rise" version = "5.7.1" description = "Reveal.js - Jupyter/IPython Slideshow Extension" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" files = [ @@ -4677,7 +4552,6 @@ notebook = ">=6.0" name = "rpds-py" version = "0.10.3" description = "Python bindings to Rust's persistent data structures (rpds)" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4782,36 +4656,34 @@ files = [ [[package]] name = "ruff" -version = "0.0.289" +version = "0.0.290" description = "An extremely fast Python linter, written in Rust." -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.0.289-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:c9a89d748e90c840bac9c37afe90cf13a5bfd460ca02ea93dad9d7bee3af03b4"}, - {file = "ruff-0.0.289-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:7f7396c6ea01ba332a6ad9d47642bac25d16bd2076aaa595b001f58b2f32ff05"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7180de86c8ecd39624dec1699136f941c07e723201b4ce979bec9e7c67b40ad2"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73f37c65508203dd01a539926375a10243769c20d4fcab3fa6359cd3fbfc54b7"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c14abcd7563b5c80be2dd809eeab20e4aa716bf849860b60a22d87ddf19eb88"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:91b6d63b6b46d4707916472c91baa87aa0592e73f62a80ff55efdf6c0668cfd6"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6479b8c4be3c36046c6c92054762b276fa0fddb03f6b9a310fbbf4c4951267fd"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5424318c254bcb091cb67e140ec9b9f7122074e100b06236f252923fb41e767"}, - {file = "ruff-0.0.289-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4daa90865796aedcedf0d8897fdd4cd09bf0ddd3504529a4ccf211edcaff3c7d"}, - {file = "ruff-0.0.289-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:8057e8ab0016c13b9419bad119e854f881e687bd96bc5e2d52c8baac0f278a44"}, - {file = "ruff-0.0.289-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7eebfab2e6a6991908ff1bf82f2dc1e5095fc7e316848e62124526837b445f4d"}, - {file = "ruff-0.0.289-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ebc7af550018001a7fb39ca22cdce20e1a0de4388ea4a007eb5c822f6188c297"}, - {file = "ruff-0.0.289-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6e4e6eccb753efe760ba354fc8e9f783f6bba71aa9f592756f5bd0d78db898ed"}, - {file = "ruff-0.0.289-py3-none-win32.whl", hash = "sha256:bbb3044f931c09cf17dbe5b339896eece0d6ac10c9a86e172540fcdb1974f2b7"}, - {file = "ruff-0.0.289-py3-none-win_amd64.whl", hash = "sha256:6d043c5456b792be2615a52f16056c3cf6c40506ce1f2d6f9d3083cfcb9eeab6"}, - {file = "ruff-0.0.289-py3-none-win_arm64.whl", hash = "sha256:04a720bcca5e987426bb14ad8b9c6f55e259ea774da1cbeafe71569744cfd20a"}, - {file = "ruff-0.0.289.tar.gz", hash = "sha256:2513f853b0fc42f0339b7ab0d2751b63ce7a50a0032d2689b54b2931b3b866d7"}, + {file = "ruff-0.0.290-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:0e2b09ac4213b11a3520221083866a5816616f3ae9da123037b8ab275066fbac"}, + {file = "ruff-0.0.290-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:4ca6285aa77b3d966be32c9a3cd531655b3d4a0171e1f9bf26d66d0372186767"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35e3550d1d9f2157b0fcc77670f7bb59154f223bff281766e61bdd1dd854e0c5"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d748c8bd97874f5751aed73e8dde379ce32d16338123d07c18b25c9a2796574a"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:982af5ec67cecd099e2ef5e238650407fb40d56304910102d054c109f390bf3c"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bbd37352cea4ee007c48a44c9bc45a21f7ba70a57edfe46842e346651e2b995a"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d9be6351b7889462912e0b8185a260c0219c35dfd920fb490c7f256f1d8313e"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75cdc7fe32dcf33b7cec306707552dda54632ac29402775b9e212a3c16aad5e6"}, + {file = "ruff-0.0.290-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb07f37f7aecdbbc91d759c0c09870ce0fb3eed4025eebedf9c4b98c69abd527"}, + {file = "ruff-0.0.290-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2ab41bc0ba359d3f715fc7b705bdeef19c0461351306b70a4e247f836b9350ed"}, + {file = "ruff-0.0.290-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:150bf8050214cea5b990945b66433bf9a5e0cef395c9bc0f50569e7de7540c86"}, + {file = "ruff-0.0.290-py3-none-musllinux_1_2_i686.whl", hash = "sha256:75386ebc15fe5467248c039f5bf6a0cfe7bfc619ffbb8cd62406cd8811815fca"}, + {file = "ruff-0.0.290-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ac93eadf07bc4ab4c48d8bb4e427bf0f58f3a9c578862eb85d99d704669f5da0"}, + {file = "ruff-0.0.290-py3-none-win32.whl", hash = "sha256:461fbd1fb9ca806d4e3d5c745a30e185f7cf3ca77293cdc17abb2f2a990ad3f7"}, + {file = "ruff-0.0.290-py3-none-win_amd64.whl", hash = "sha256:f1f49f5ec967fd5778813780b12a5650ab0ebcb9ddcca28d642c689b36920796"}, + {file = "ruff-0.0.290-py3-none-win_arm64.whl", hash = "sha256:ae5a92dfbdf1f0c689433c223f8dac0782c2b2584bd502dfdbc76475669f1ba1"}, + {file = "ruff-0.0.290.tar.gz", hash = "sha256:949fecbc5467bb11b8db810a7fa53c7e02633856ee6bd1302b2f43adcd71b88d"}, ] [[package]] name = "rx" version = "1.6.3" description = "Reactive Extensions (Rx) for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -4822,7 +4694,6 @@ files = [ name = "seaborn" version = "0.12.2" description = "Statistical data visualization" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4844,7 +4715,6 @@ stats = ["scipy (>=1.3)", "statsmodels (>=0.10)"] name = "selenium" version = "4.12.0" description = "" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4862,7 +4732,6 @@ urllib3 = {version = ">=1.26,<3", extras = ["socks"]} name = "send2trash" version = "1.8.2" description = "Send file to trash natively under Mac OS X, Windows and Linux" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -4879,7 +4748,6 @@ win32 = ["pywin32"] name = "setuptools" version = "68.2.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4896,7 +4764,6 @@ testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jar name = "setuptools-scm" version = "7.1.0" description = "the blessed package to manage your versions by scm tags" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4917,7 +4784,6 @@ toml = ["setuptools (>=42)"] name = "shapely" version = "1.8.5.post1" description = "Geometric objects, predicates, and operations" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4974,7 +4840,6 @@ vectorized = ["numpy"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -4986,7 +4851,6 @@ files = [ name = "slugify" version = "0.0.1" description = "A generic slugifier." -category = "main" optional = false python-versions = "*" files = [ @@ -4997,7 +4861,6 @@ files = [ name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5009,7 +4872,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -5021,7 +4883,6 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -category = "main" optional = false python-versions = "*" files = [ @@ -5033,7 +4894,6 @@ files = [ name = "soupsieve" version = "2.5" description = "A modern CSS selector implementation for Beautiful Soup." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5045,7 +4905,6 @@ files = [ name = "sphinx" version = "6.2.1" description = "Python documentation generator" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -5080,7 +4939,6 @@ test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] name = "sphinx-autodoc-typehints" version = "1.23.0" description = "Type hints (PEP 484) support for the Sphinx autodoc extension" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5100,7 +4958,6 @@ type-comment = ["typed-ast (>=1.5.4)"] name = "sphinx-copybutton" version = "0.5.2" description = "Add a copy button to each of your code cells." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5119,7 +4976,6 @@ rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] name = "sphinx-notfound-page" version = "1.0.0" description = "Sphinx extension to build a 404 page with absolute URLs" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -5138,7 +4994,6 @@ test = ["tox"] name = "sphinx-rtd-theme" version = "1.3.0" description = "Read the Docs theme for Sphinx" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -5158,7 +5013,6 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] name = "sphinxcontrib-applehelp" version = "1.0.7" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -5177,7 +5031,6 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "1.0.5" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -5196,7 +5049,6 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.0.4" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -5215,7 +5067,6 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jquery" version = "4.1" description = "Extension to include jQuery on newer Sphinx releases" -category = "dev" optional = false python-versions = ">=2.7" files = [ @@ -5230,7 +5081,6 @@ Sphinx = ">=1.8" name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -5245,7 +5095,6 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-mermaid" version = "0.9.2" description = "Mermaid diagrams in yours Sphinx powered docs" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5257,7 +5106,6 @@ files = [ name = "sphinxcontrib-napoleon" version = "0.7" description = "Sphinx \"napoleon\" extension." -category = "dev" optional = false python-versions = "*" files = [ @@ -5273,7 +5121,6 @@ six = ">=1.5.2" name = "sphinxcontrib-qthelp" version = "1.0.6" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -5292,7 +5139,6 @@ test = ["pytest"] name = "sphinxcontrib-serializinghtml" version = "1.1.9" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -5311,7 +5157,6 @@ test = ["pytest"] name = "sqlalchemy" version = "1.4.49" description = "Database Abstraction Library" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -5356,7 +5201,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and platform_machine == \"aarch64\" or python_version >= \"3\" and platform_machine == \"ppc64le\" or python_version >= \"3\" and platform_machine == \"x86_64\" or python_version >= \"3\" and platform_machine == \"amd64\" or python_version >= \"3\" and platform_machine == \"AMD64\" or python_version >= \"3\" and platform_machine == \"win32\" or python_version >= \"3\" and platform_machine == \"WIN32\""} +greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} mypy = {version = ">=0.910", optional = true, markers = "python_version >= \"3\" and extra == \"mypy\""} sqlalchemy2-stubs = {version = "*", optional = true, markers = "extra == \"mypy\""} @@ -5385,7 +5230,6 @@ sqlcipher = ["sqlcipher3-binary"] name = "sqlalchemy2-stubs" version = "0.0.2a35" description = "Typing Stubs for SQLAlchemy 1.4" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5400,7 +5244,6 @@ typing-extensions = ">=3.7.4" name = "stack-data" version = "0.6.2" description = "Extract data from python stack frames and tracebacks for informative displays" -category = "dev" optional = false python-versions = "*" files = [ @@ -5420,7 +5263,6 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "sympy" version = "1.12" description = "Computer algebra system (CAS) in Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5435,7 +5277,6 @@ mpmath = ">=0.19" name = "tenacity" version = "8.2.3" description = "Retry code until it succeeds" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5450,7 +5291,6 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] name = "terminado" version = "0.17.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5471,7 +5311,6 @@ test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] name = "tinycss2" version = "1.2.1" description = "A tiny CSS parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5490,7 +5329,6 @@ test = ["flake8", "isort", "pytest"] name = "tokenize-rt" version = "5.2.0" description = "A wrapper around the stdlib `tokenize` which roundtrips." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -5502,7 +5340,6 @@ files = [ name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -5514,7 +5351,6 @@ files = [ name = "tornado" version = "6.3.3" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "dev" optional = false python-versions = ">= 3.8" files = [ @@ -5535,7 +5371,6 @@ files = [ name = "tqdm" version = "4.66.1" description = "Fast, Extensible Progress Meter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5556,7 +5391,6 @@ telegram = ["requests"] name = "traitlets" version = "5.10.0" description = "Traitlets Python configuration system" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -5572,7 +5406,6 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.5.1)", "pre-commit", "pytest (>=7.0, name = "trio" version = "0.22.2" description = "A friendly Python library for async concurrency and I/O" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5592,7 +5425,6 @@ sortedcontainers = "*" name = "trio-websocket" version = "0.10.4" description = "WebSocket library for Trio" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5609,7 +5441,6 @@ wsproto = ">=0.14" name = "types-cachetools" version = "5.3.0.6" description = "Typing stubs for cachetools" -category = "dev" optional = false python-versions = "*" files = [ @@ -5621,7 +5452,6 @@ files = [ name = "types-pyopenssl" version = "23.2.0.2" description = "Typing stubs for pyOpenSSL" -category = "dev" optional = false python-versions = "*" files = [ @@ -5634,21 +5464,19 @@ cryptography = ">=35.0.0" [[package]] name = "types-pytz" -version = "2023.3.0.1" +version = "2023.3.1.0" description = "Typing stubs for pytz" -category = "dev" optional = false python-versions = "*" files = [ - {file = "types-pytz-2023.3.0.1.tar.gz", hash = "sha256:1a7b8d4aac70981cfa24478a41eadfcd96a087c986d6f150d77e3ceb3c2bdfab"}, - {file = "types_pytz-2023.3.0.1-py3-none-any.whl", hash = "sha256:65152e872137926bb67a8fe6cc9cfd794365df86650c5d5fdc7b167b0f38892e"}, + {file = "types-pytz-2023.3.1.0.tar.gz", hash = "sha256:8e7d2198cba44a72df7628887c90f68a568e1445f14db64631af50c3cab8c090"}, + {file = "types_pytz-2023.3.1.0-py3-none-any.whl", hash = "sha256:a660a38ed86d45970603e4f3b4877c7ba947668386a896fb5d9589c17e7b8407"}, ] [[package]] name = "types-requests" version = "2.31.0.2" description = "Typing stubs for requests" -category = "dev" optional = false python-versions = "*" files = [ @@ -5663,7 +5491,6 @@ types-urllib3 = "*" name = "types-setuptools" version = "68.2.0.0" description = "Typing stubs for setuptools" -category = "dev" optional = false python-versions = "*" files = [ @@ -5675,7 +5502,6 @@ files = [ name = "types-tqdm" version = "4.66.0.2" description = "Typing stubs for tqdm" -category = "dev" optional = false python-versions = "*" files = [ @@ -5687,7 +5513,6 @@ files = [ name = "types-urllib3" version = "1.26.25.14" description = "Typing stubs for urllib3" -category = "dev" optional = false python-versions = "*" files = [ @@ -5697,21 +5522,19 @@ files = [ [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] [[package]] name = "tzdata" version = "2023.3" description = "Provider of IANA time zone data" -category = "main" optional = false python-versions = ">=2" files = [ @@ -5723,7 +5546,6 @@ files = [ name = "tzlocal" version = "5.0.1" description = "tzinfo object for the local timezone" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5741,7 +5563,6 @@ devenv = ["black", "check-manifest", "flake8", "pyroma", "pytest (>=4.3)", "pyte name = "uri-template" version = "1.3.0" description = "RFC 6570 URI Template Processor" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5756,7 +5577,6 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake name = "urllib3" version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5777,7 +5597,6 @@ zstd = ["zstandard (>=0.18.0)"] name = "virtualenv" version = "20.24.5" description = "Virtual Python Environment builder" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5798,7 +5617,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" -category = "dev" optional = false python-versions = "*" files = [ @@ -5810,7 +5628,6 @@ files = [ name = "webcolors" version = "1.13" description = "A library for working with the color formats defined by HTML and CSS." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5826,7 +5643,6 @@ tests = ["pytest", "pytest-cov"] name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" -category = "dev" optional = false python-versions = "*" files = [ @@ -5838,7 +5654,6 @@ files = [ name = "websocket-client" version = "1.6.3" description = "WebSocket client for Python with low level API options" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -5855,7 +5670,6 @@ test = ["websockets"] name = "werkzeug" version = "2.2.3" description = "The comprehensive WSGI web application library." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5873,7 +5687,6 @@ watchdog = ["watchdog"] name = "widgetsnbextension" version = "4.0.9" description = "Jupyter interactive widgets for Jupyter Notebook" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5885,7 +5698,6 @@ files = [ name = "win32-setctime" version = "1.1.0" description = "A small Python utility to set file creation time on Windows" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -5900,7 +5712,6 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] name = "wsproto" version = "1.2.0" description = "WebSockets state-machine based protocol implementation" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -5917,4 +5728,4 @@ ingest = ["selenium"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "07b56bcce6ab9ba9c417c9da908bcabeac7d10be0eb51883868f15482d495d70" +content-hash = "31c5eadf695c95382e7cc8796fa4b978d19a6fb3eea46393e81f7ecd5ffdb406" diff --git a/pyproject.toml b/pyproject.toml index fc09c87..2bac0ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ requires = ["poetry-core"] target-version = ["py311"] [tool.coverage.report] -exclude_also = ["if __name__ == .__main__.:"] +exclude_also = ["if __name__ == .__main__.:", "if not isinstance(engine, Engine):"] [tool.coverage.run] branch = true @@ -81,7 +81,7 @@ mypy = "^1.5.1" pandas-stubs = "^2.0.3.230814" pip-audit = "^2.6.1" pip-licenses = "^4.3.2" -ruff = "^0.0.289" +ruff = "^0.0.290" types-cachetools = "^5.3.0.6" types-pyOpenSSL = "*" types-requests = "^2.31.0.2" diff --git a/src/aki_prj23_transparenzregister/ui/assets/company_stats.css b/src/aki_prj23_transparenzregister/ui/assets/company_stats.css new file mode 100644 index 0000000..a51b778 --- /dev/null +++ b/src/aki_prj23_transparenzregister/ui/assets/company_stats.css @@ -0,0 +1,69 @@ +.company-header { + float: left; + background-color: var(--paynes-gray); + border: 1px solid; + width: 100%; +} + +.company-header .company-header-title { + color: white; + text-align: left; + margin: 0; + vertical-align: middle; + padding: 20px; +} + +.stats-wrapper { + float: left; + width: 100%; + background-color: white; + margin-top: 20px; + margin-right: 2%; +} + +.stats-wrapper .widget-large { + background-color: var(--ash-gray); + border: 1px solid; + border-radius: 10px; + width: 45%; + min-width: 600px; + display: inline-block; + vertical-align: middle; + margin-left: 2%; + overflow: hidden; +} + +.stats-wrapper .widget-large .widget-title { + color: var(--raisin-black); + text-align: center; + margin: 0; + padding-bottom: 10px; + padding-top: 10px; +} + +.stats-wrapper .widget-small { + background-color: var(--ash-gray); + border: 1px solid; + border-radius: 10px; + width: 15%; + min-width: 200px; + height: 150px; + display: inline-block; + vertical-align: middle; + margin-top: 10px; + margin-bottom: 10px; + margin-left: 2%; +} + +.stats-wrapper .widget-small .widget-title { + color: var(--raisin-black); + text-align: center; + margin: 0; + padding-bottom: 10px; + padding-top: 10px; +} + +.stats-wrapper .widget-small .widget-content { + color: var(--raisin-black); + text-align: center; +} diff --git a/src/aki_prj23_transparenzregister/ui/assets/header.css b/src/aki_prj23_transparenzregister/ui/assets/header.css new file mode 100644 index 0000000..9a3690e --- /dev/null +++ b/src/aki_prj23_transparenzregister/ui/assets/header.css @@ -0,0 +1,58 @@ +:root { + --light: #edefef; + --lavender-blush: #f3e8ee; + --ash-gray: #bacdb0; + --cambridge-blue: #729b79; + --paynes-gray: #475b63; + --raisin-black: #2e2c2f; +} + +.header-wrapper { + float:left; + background-color: var(--raisin-black); + border: 1px solid; + width: 100%; + overflow: visible; + min-height: 77px; +} + +.header-wrapper .header-title { + float: left; + text-align: left; + margin: 0; + padding-left: 15px; + padding-top: 20px; + padding-bottom: 20px; + vertical-align: middle; +} + +.header-wrapper .header-title .bi-house-door-fill { + color: white; + font-size: x-large; + display: inline-block; + vertical-align: middle; + padding-right: 15px; +} + +.header-wrapper .header-title .header-title-text { + color: white; + text-align: left; + margin: 0; + display: inline-block; + vertical-align: middle; +} + +.header-wrapper .header-search { + float: right; + width: 400px; + margin: 0; + padding-right: 10px; + padding-bottom: 20px; + padding-top: 20px; + vertical-align: middle; + overflow: visible !important; +} + +.header-wrapper .header-search .header-search-dropdown { + overflow: visible; +} diff --git a/src/aki_prj23_transparenzregister/ui/assets/tabs.css b/src/aki_prj23_transparenzregister/ui/assets/tabs.css new file mode 100644 index 0000000..2ddb1cb --- /dev/null +++ b/src/aki_prj23_transparenzregister/ui/assets/tabs.css @@ -0,0 +1,23 @@ +.tabs { + float: left; + margin-top: 20px; + border: 1px solid; + width: 100%; +} + +.tabs .tab-style { + border-bottom: 1px solid #d6d6d6 !important; + padding: 8px !important; + background-color: white !important; + color: var(--paynes-gray) !important; + font-weight: bold !important; +} + +.tabs .selected-tab-style { + border-bottom: 1px solid #d6d6d6 !important; + border-top: 1px solid #d6d6d6 !important; + padding: 8px !important; + color: white !important; + background-color: var(--paynes-gray) !important; + font-weight: bold !important; +} diff --git a/src/aki_prj23_transparenzregister/ui/company_finance_dash.py b/src/aki_prj23_transparenzregister/ui/company_finance_dash.py index ab6c2fa..f81a78f 100644 --- a/src/aki_prj23_transparenzregister/ui/company_finance_dash.py +++ b/src/aki_prj23_transparenzregister/ui/company_finance_dash.py @@ -1,390 +1,78 @@ """Dash.""" import dash_bootstrap_components as dbc -import pandas as pd -import plotly.graph_objs as go -from dash import Dash, Input, Output, callback, dash_table, dcc, html -from dash.exceptions import PreventUpdate -from sqlalchemy.engine import Engine +from dash import Dash, Input, Output, callback, html from aki_prj23_transparenzregister.config.config_providers import JsonFileConfigProvider -from aki_prj23_transparenzregister.utils.sql import connector, entities +from aki_prj23_transparenzregister.ui.ui_elements import ( + create_company_header, + create_company_stats, + create_header, + create_tabs, + get_company_data, + get_finance_data, +) +from aki_prj23_transparenzregister.utils.sql import connector if __name__ == "__main__": session = connector.get_session(JsonFileConfigProvider("./secrets.json")) - query_finance = session.query( - entities.AnnualFinanceStatement, entities.Company.name, entities.Company.id - ).join(entities.Company) - - query_company = session.query(entities.Company, entities.DistrictCourt.name).join( - entities.DistrictCourt - ) - engine = session.bind - if not isinstance(engine, Engine): - raise TypeError - - finance_df: pd.DataFrame = pd.read_sql(str(query_finance), engine) - company_df: pd.DataFrame = pd.read_sql(str(query_company), engine) - - select_company_df = company_df[["company_id", "company_name"]] - select_company_dropdown = select_company_df.to_dict("records") - options = [ - {"label": i["company_name"], "value": i["company_id"]} - for i in select_company_dropdown - ] - - colors = { - "light": "#edefef", - "lavender-blush": "#f3e8ee", - "ash-gray": "#bacdb0", - "cambridge-blue": "#729b79", - "paynes-gray": "#475b63", - "raisin-black": "#2e2c2f", - } - - def financials_figure( - finance_df: pd.DataFrame, company: str, metric: str - ) -> go.Figure: - """Creates plotly line chart for a specific company and a metric.""" - finance_df = finance_df.loc[finance_df["company_name"] == company] - # create figure - fig_line = go.Figure() - # add trace for company 1 - fig_line.add_trace( - go.Scatter( - x=finance_df["annual_finance_statement_date"], - y=finance_df[metric], - name=company, - line_color=colors["raisin-black"], - marker_color=colors["raisin-black"], - ) - ) - # set title and labels - fig_line.update_layout( - title=metric, - xaxis_title="Jahr", - yaxis_title="in Mio.€", - plot_bgcolor=colors["light"], - ) - return fig_line - - tab_style = { - "borderBottom": "1px solid #d6d6d6", - "padding": "6px", - "backgroundColor": "white", - "color": colors["paynes-gray"], - "fontWeight": "bold", - } - - tab_selected_style = { - "borderTop": "1px solid #d6d6d6", - "borderBottom": "1px solid #d6d6d6", - "padding": "6px", - "backgroundColor": colors["paynes-gray"], - "color": "white", - "fontWeight": "bold", - } - - # TBD: get data from database instead of mock data - company = 1 # selected company id - selected_company = company_df.loc[company_df["company_id"] == company] - - turnover = 123456 - stock = "1,23" - company_data = { - "col1": ["Unternehmen", "Straße", "Stadt"], - "col2": [ - selected_company["company_name"][0], - selected_company["company_street"][0], - str( - selected_company["company_zip_code"][0] - + " " - + selected_company["company_city"][0] - ), - ], - "col3": ["Branche", "Amtsgericht", "Gründungsjahr"], - "col4": [ - selected_company["company_sector"][0], - selected_company["district_court_name"][0], - "xxx", - ], - } - df_company_data = pd.DataFrame(data=company_data) + company_df = get_company_data(session) + finance_df = get_finance_data(session) + options = company_df["company_name"].to_dict() app = Dash( __name__, external_stylesheets=[dbc.icons.BOOTSTRAP] ) # use dbc for icons - - kennzahlen_layout = html.Div( - [ - dcc.Graph( - figure=financials_figure( - finance_df, str(company), "annual_finance_statement_ebit" - ) - ) - ] - ) + app.title = "Company Finance Data" app.layout = html.Div( - [ - # title header of page - html.Div( - style={ - "backgroundColor": colors["raisin-black"], - "border": "1px solid", - }, - children=[ - html.I( - className="bi bi-house-door-fill", - style={ - "fontSize": 24, - "paddingLeft": "10px", - "color": "white", - "display": "inline-block", - "verticalAlign": "middle", - }, - ), - html.H1( - children="Transparenzregister für Kapitalgesellschaften", - style={ - "color": "white", - "textAlign": "left", - "margin": "0", - "paddingLeft": "10px", - "paddingBottom": "20px", - "paddingTop": "20px", - "display": "inline-block", - "verticalAlign": "middle", - }, - ), - html.Div( - dcc.Dropdown( - id="select_company", - placeholder="Suche nach Unternehmen oder Person", - ), - style={ - "float": "right", - "width": "30%", - "margin": "0", - "paddingRight": "10px", - "paddingBottom": "20px", - "paddingTop": "20px", - "display": "inline-block", - "verticalAlign": "middle", - }, - ), - ], - ), - # header company name - html.Div( - style={"backgroundColor": colors["paynes-gray"], "border": "1px solid"}, - children=[ - html.H1( - children=selected_company["company_name"][0], - style={ - "color": "white", - "fontSize": 30, - "textAlign": "left", - "margin": "0", - "paddingLeft": "20px", - "paddingBottom": "20px", - "paddingTop": "20px", - }, - ) - ], - ), - html.Div(style={"height": "20px"}), - html.Div(style={"width": "2%", "display": "inline-block"}), - # table basic company information - html.Div( - style={ - "backgroundColor": colors["ash-gray"], - "border": "1px solid", - "border-radius": 10, - "width": "45%", - "height": "150px", - "display": "inline-block", - "vertical-align": "top", - }, - children=[ - html.H5( - children="Stammdaten", - style={ - "color": colors["raisin-black"], - "fontSize": 16, - "textAlign": "center", - "margin": "0", - "paddingBottom": "10px", - "paddingTop": "10px", - }, - ), - dash_table.DataTable( - df_company_data.to_dict("records"), - [{"name": i, "id": i} for i in df_company_data.columns], - style_table={ - "width": "80%", - "overflowX": "auto", - "marginLeft": "auto", - "marginRight": "auto", - "paddingBottom": "20px", - "color": colors["raisin-black"], - }, - # hide header of table - css=[ - { - "selector": "tr:first-child", - "rule": "display: none", - }, - ], - style_cell={"textAlign": "center"}, - style_cell_conditional=[ - {"if": {"column_id": c}, "fontWeight": "bold"} - for c in ["col1", "col3"] - ], - ), - ], - ), - html.Div(style={"width": "2%", "display": "inline-block"}), - html.Div( - style={ - "backgroundColor": colors["ash-gray"], - "border": "1px solid", - "border-radius": 10, - "width": "15%", - "height": "150px", - "display": "inline-block", - "vertical-align": "top", - }, - children=[ - html.H5( - children="Stimmung", - style={ - "color": colors["raisin-black"], - "fontSize": 16, - "textAlign": "center", - "margin": "0", - "paddingBottom": "10px", - "paddingTop": "10px", - }, - ), - ], - ), - html.Div(style={"width": "2%", "display": "inline-block"}), - html.Div( - style={ - "backgroundColor": colors["ash-gray"], - "border": "1px solid", - "border-radius": 10, - "width": "15%", - "height": "150px", - "display": "inline-block", - "vertical-align": "top", - }, - children=[ - html.H5( - children="Aktienkurs", - style={ - "color": colors["raisin-black"], - "fontSize": 16, - "textAlign": "center", - "margin": "0", - "paddingBottom": "10px", - "paddingTop": "10px", - }, - ), - html.H1( - children=stock, - style={ - "color": colors["raisin-black"], - "textAlign": "center", - }, - ), - ], - ), - html.Div(style={"width": "2%", "display": "inline-block"}), - html.Div( - style={ - "backgroundColor": colors["ash-gray"], - "border": "1px solid", - "border-radius": 10, - "width": "15%", - "height": "150px", - "display": "inline-block", - "vertical-align": "top", - }, - children=[ - html.H5( - children="Umsatz", - style={ - "color": colors["raisin-black"], - "fontSize": 16, - "textAlign": "center", - "margin": "0", - "paddingBottom": "10px", - "paddingTop": "10px", - }, - ), - html.H1( - children=turnover, - style={ - "color": colors["raisin-black"], - "textAlign": "center", - }, - ), - ], - ), - html.Div(style={"width": "2%", "display": "inline-block"}), - # ]), - html.Div( - style={ - "marginTop": "20px", - "border": "1px solid", - }, - children=[ - dcc.Tabs( - id="tabs", - value="tab-1", - children=[ - dcc.Tab( - label="Kennzahlen", - value="tab-1", - style=tab_style, - selected_style=tab_selected_style, - children=[kennzahlen_layout], - ), - dcc.Tab( - label="Beteiligte Personen", - value="tab-2", - style=tab_style, - selected_style=tab_selected_style, - ), - dcc.Tab( - label="Stimmung", - value="tab-3", - style=tab_style, - selected_style=tab_selected_style, - ), - dcc.Tab( - label="Verflechtungen", - value="tab-4", - style=tab_style, - selected_style=tab_selected_style, - ), - ], - ), - html.Div(id="tabs-example-content-1"), - ], - ), - ] + className="page_content", + children=[ + create_header(options), + html.Div(id="id-company-header"), + ], ) @callback( Output("select_company", "options"), Input("select_company", "search_value") ) def update_options(search_value: str) -> list: - """Update page based on selected company.""" + """Update dropdown options based on user input. + + Args: + search_value: The input string in the dropdown field entered by the user. + + Returns: + The available companies matching the input. + """ if not search_value: - raise PreventUpdate - return [o for o in options if search_value in o["label"]] + return [{"label": o, "value": key} for key, o in options.items()] + return [ + {"label": o, "value": key} + for key, o in options.items() + if search_value.upper() in o.upper() + ] + + @callback(Output("id-company-header", "children"), Input("select_company", "value")) + def update_output(value_chosen: int) -> html: + """Update page based on chosen company. + + Args: + value_chosen: Id of the selected company. + + Returns: + The html divs of the company page. + """ + label = options.get(value_chosen) + if not label: + return "" + selected_company = str(label) + selected_company_stats = company_df.loc[value_chosen] + selected_finance_df = finance_df.loc[finance_df["company_id"] == value_chosen] + return ( + create_company_header(selected_company), + create_company_stats(selected_company_stats), + create_tabs(selected_finance_df), + ) app.run_server(debug=True) diff --git a/src/aki_prj23_transparenzregister/ui/ui_elements.py b/src/aki_prj23_transparenzregister/ui/ui_elements.py new file mode 100644 index 0000000..ca06b1a --- /dev/null +++ b/src/aki_prj23_transparenzregister/ui/ui_elements.py @@ -0,0 +1,331 @@ +"""Dash elements.""" + +import pandas as pd +import plotly.graph_objs as go +from dash import dash_table, dcc, html +from sqlalchemy.engine import Engine +from sqlalchemy.orm import Session + +from aki_prj23_transparenzregister.utils.sql import entities + +COLORS = { + "light": "#edefef", + "lavender-blush": "#f3e8ee", + "ash-gray": "#bacdb0", + "cambridge-blue": "#729b79", + "paynes-gray": "#475b63", + "raisin-black": "#2e2c2f", +} + + +def get_company_data(session: Session) -> pd.DataFrame: + """Creates a session to the database and get's all available company data. + + Args: + session: A session connecting to the database. + + Returns: + A dataframe containing all available company data including the corresponding district court. + """ + query_company = session.query(entities.Company, entities.DistrictCourt.name).join( + entities.DistrictCourt + ) + engine = session.bind + if not isinstance(engine, Engine): + raise TypeError + + return pd.read_sql(str(query_company), engine, index_col="company_id") + + +def get_finance_data(session: Session) -> pd.DataFrame: + """Creates a session to the database and get's all available company data. + + Args: + session: A session connecting to the database. + + Returns: + A dataframe containing all financial data of all companies. + """ + query_finance = session.query( + entities.AnnualFinanceStatement, entities.Company.name, entities.Company.id + ).join(entities.Company) + + engine = session.bind + if not isinstance(engine, Engine): + raise TypeError + + return pd.read_sql(str(query_finance), engine) + + +def create_header(options: dict) -> html: + """Creates header for dashboard. + + Args: + options: A dictionary with company names and ids for the dropdown. + + Returns: + The html div to create the page's header including the name of the page and the search for companies. + """ + return html.Div( + className="header-wrapper", + children=[ + html.Div( + className="header-title", + children=[ + html.I( + className="bi-house-door-fill", + ), + html.H1( + className="header-title-text", + children="Transparenzregister für Kapitalgesellschaften", + ), + ], + ), + html.Div( + className="header-search", + children=[ + html.Div( + className="header-search-dropdown", + children=[ + dcc.Dropdown( + id="select_company", + options=[ + {"label": o, "value": key} + for key, o in options.items() + ], + placeholder="Suche nach Unternehmen oder Person", + ), + ], + ), + ], + ), + ], + ) + + +def create_company_header(selected_company_name: str) -> html: + """Create company header based on selected company. + + Args: + selected_company_name: The company name that has been chosen in the dropdown. + + Returns: + The html div to create the company header. + """ + return html.Div( + className="company-header", + children=[ + html.H1( + className="company-header-title", + id="id-company-header-title", + children=selected_company_name, + ), + ], + ) + + +def create_company_stats(selected_company_data: pd.Series) -> html: + """Create company stats. + + Args: + selected_company_data: A series containing all company information of the selected company. + + Returns: + The html div to create the company stats table and the three small widgets. + """ + company_data = { + "col1": ["Unternehmen", "Straße", "Stadt"], + "col2": [ + selected_company_data["company_name"], + selected_company_data["company_street"], + str( + selected_company_data["company_zip_code"] + + " " + + selected_company_data["company_city"] + ), + ], + "col3": ["Branche", "Amtsgericht", "Gründungsjahr"], + "col4": [ + selected_company_data["company_sector"], + selected_company_data["district_court_name"], + "xxx", + ], + } + df_company_data = pd.DataFrame(data=company_data) + return html.Div( + className="stats-wrapper", + children=[ + html.Div( + className="widget-large", + children=[ + html.H3( + className="widget-title", + children="Stammdaten", + ), + dash_table.DataTable( + df_company_data.to_dict("records"), + [{"name": i, "id": i} for i in df_company_data.columns], + style_table={ + "width": "90%", + "marginLeft": "auto", + "marginRight": "auto", + "paddingBottom": "20px", + "color": COLORS["raisin-black"], + }, + # hide header of table + css=[ + { + "selector": "tr:first-child", + "rule": "display: none", + }, + ], + style_cell={"textAlign": "center"}, + style_cell_conditional=[ + {"if": {"column_id": c}, "fontWeight": "bold"} + for c in ["col1", "col3"] + ], + style_data={ + "whiteSpace": "normal", + "height": "auto", + }, + ), + ], + ), + html.Div( + className="widget-small", + children=[ + html.H3( + className="widget-title", + children="Stimmung", + ), + ], + ), + html.Div( + className="widget-small", + children=[ + html.H3( + className="widget-title", + children="Aktienkurs", + ), + html.H1( + className="widget-content", + children="123", + ), + ], + ), + html.Div( + className="widget-small", + children=[ + html.H3( + className="widget-title", + children="Umsatz", + ), + html.H1( + className="widget-content", + children="1234", + ), + ], + ), + ], + ) + + +def create_tabs(selected_finance_df: pd.DataFrame) -> html: + """Create tabs for more company information. + + Args: + selected_company_id: Id of the chosen company in the dropdown. + selected_finance_df: A dataframe containing all available finance information of the companies. + + Returns: + The html div to create the tabs of the company page. + """ + return html.Div( + className="tabs", + children=[ + dcc.Tabs( + id="tabs", + value="tab-1", + children=[ + dcc.Tab( + label="Kennzahlen", + value="tab-1", + className="tab-style", + selected_className="selected-tab-style", + children=[kennzahlen_layout(selected_finance_df)], + ), + dcc.Tab( + label="Beteiligte Personen", + value="tab-2", + className="tab-style", + selected_className="selected-tab-style", + ), + dcc.Tab( + label="Stimmung", + value="tab-3", + className="tab-style", + selected_className="selected-tab-style", + ), + dcc.Tab( + label="Verflechtungen", + value="tab-4", + className="tab-style", + selected_className="selected-tab-style", + ), + ], + ), + html.Div(id="tabs-example-content-1"), + ], + ) + + +def kennzahlen_layout(selected_finance_df: pd.DataFrame) -> html: + """Create metrics tab. + + Args: + selected_company_id: Id of the chosen company in the dropdown. + selected_finance_df: A dataframe containing all available finance information of the companies. + + Returns: + The html div to create the metrics tab of the company page. + """ + return html.Div( + [ + dcc.Graph( + figure=financials_figure( + selected_finance_df, "annual_finance_statement_ebit" + ) + ) + ] + ) + + +def financials_figure(selected_finance_df: pd.DataFrame, metric: str) -> go.Figure: + """Creates plotly line chart for a specific company and a metric. + + Args: + selected_finance_df: A dataframe containing all finance information of the selected company. + metric: The metric that should be visualized. + + Returns: + A plotly figure showing the available metric data of the company. + """ + # create figure + fig_line = go.Figure() + # add trace for company 1 + fig_line.add_trace( + go.Scatter( + x=selected_finance_df["annual_finance_statement_date"], + y=selected_finance_df[metric], + line_color=COLORS["raisin-black"], + marker_color=COLORS["raisin-black"], + ) + ) + # set title and labels + fig_line.update_layout( + title=metric, + xaxis_title="Jahr", + yaxis_title="in Mio.€", + plot_bgcolor=COLORS["light"], + ) + return fig_line diff --git a/src/aki_prj23_transparenzregister/utils/data_transfer.py b/src/aki_prj23_transparenzregister/utils/data_transfer.py index 038a0ab..f28712c 100644 --- a/src/aki_prj23_transparenzregister/utils/data_transfer.py +++ b/src/aki_prj23_transparenzregister/utils/data_transfer.py @@ -124,7 +124,7 @@ def get_district_court_id(name: str, city: str | None, db: Session) -> int: @cached(cache=LRUCache(maxsize=2000), key=lambda name, surname, date_of_birth, db: hash((name, surname, date_of_birth))) # type: ignore def get_person_id( - name: str, surname: str, date_of_birth: date | str, db: Session + name: str, surname: str, date_of_birth: date | str | None, db: Session ) -> int: """Identifies the id of and court. diff --git a/tests/conftest.py b/tests/conftest.py index b8da9d9..e3b4397 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,6 +3,7 @@ import datetime import os from collections.abc import Generator from inspect import getmembers, isfunction +from typing import Any import pytest from sqlalchemy.engine import Engine @@ -49,7 +50,60 @@ def empty_db() -> Generator[Session, None, None]: @pytest.fixture() -def full_db(empty_db: Session) -> Session: +def finance_statements() -> list[dict[str, Any]]: + """Creates a list of finance statements.""" + return [ + { + "id": 1, + "company_id": 1, + "date": datetime.date.fromisoformat("2023-01-01"), + "total_volume": 1000.0, + "ebit": 1000.0, + "ebitda": 1000.0, + "ebit_margin": 1000.0, + "total_balance": 1000.0, + "equity": 1000.0, + "debt": 1000.0, + "return_on_equity": 1000.0, + "capital_turnover_rate": 1000.0, + "current_liabilities": 1000.0, + "dividends": float("NaN"), + "net_income": float("NaN"), + "assets": 1000.0, + "long_term_debt": 1000.0, + "short_term_debt": 1000.0, + "revenue": 1000.0, + "cash_flow": 1000.0, + "current_assets": 1000.0, + }, + { + "id": 2, + "company_id": 1, + "date": datetime.date.fromisoformat("2022-01-01"), + "total_volume": 1100.0, + "ebit": 1100.0, + "ebitda": 1100.0, + "ebit_margin": 1100.0, + "total_balance": 1100.0, + "equity": 1100.0, + "debt": 1100.0, + "return_on_equity": 1100.0, + "capital_turnover_rate": 1100.0, + "current_liabilities": 1100.0, + "dividends": float("NaN"), + "net_income": float("NaN"), + "assets": 1100.0, + "long_term_debt": 1100.0, + "short_term_debt": 1100.0, + "revenue": 1100.0, + "cash_flow": 1100.0, + "current_assets": 1100.0, + }, + ] + + +@pytest.fixture() +def full_db(empty_db: Session, finance_statements: list[dict[str, Any]]) -> Session: """Fills a db with some test data.""" empty_db.add_all( [ @@ -112,5 +166,13 @@ def full_db(empty_db: Session) -> Session: ] ) empty_db.commit() + + empty_db.add_all( + [ + entities.AnnualFinanceStatement(**finance_statement) + for finance_statement in finance_statements + ] + ) + empty_db.commit() # print(pd.read_sql_table("company", empty_db.bind).to_string()) return empty_db diff --git a/tests/ui/ui_elements_test.py b/tests/ui/ui_elements_test.py new file mode 100644 index 0000000..21650df --- /dev/null +++ b/tests/ui/ui_elements_test.py @@ -0,0 +1,118 @@ +"""Tests for ui elements.""" + +import pandas as pd +from sqlalchemy.orm import Session + +from aki_prj23_transparenzregister.ui import ui_elements + + +def test_import() -> None: + """Checks if an import co ui_elements can be made.""" + assert ui_elements is not None + + +def test_get_company_data(full_db: Session) -> None: + """Checks if data from the company and district court tables can be accessed.""" + company_df = ui_elements.get_company_data(full_db) + + test_data = pd.DataFrame( + { + "company_id": {0: 1, 1: 2, 2: 3}, + "company_hr": {0: "HRB 123", 1: "HRB 123", 2: "HRB 12"}, + "company_court_id": {0: 2, 1: 1, 2: 2}, + "company_name": { + 0: "Some Company GmbH", + 1: "Other Company GmbH", + 2: "Third Company GmbH", + }, + "company_street": {0: "Sesamstr.", 1: "Sesamstr.", 2: None}, + "company_zip_code": {0: "12345", 1: "12345", 2: None}, + "company_city": {0: "TV City", 1: "TV City", 2: None}, + "company_last_update": { + 0: "2023-01-01", + 1: "2023-01-01", + 2: "2023-01-01", + }, + "company_sector": {0: None, 1: None, 2: None}, + "district_court_name": { + 0: "Amtsgericht Dortmund", + 1: "Amtsgericht Bochum", + 2: "Amtsgericht Dortmund", + }, + } + ) + test_data = test_data.set_index("company_id") + pd.testing.assert_frame_equal(company_df, test_data) + + +def test_get_finance_data(full_db: Session) -> None: + """Checks if data from the company and finance tables can be accessed.""" + finance_df = ui_elements.get_finance_data(full_db) + test_data = pd.DataFrame( + { + "annual_finance_statement_id": {0: 1, 1: 2}, + "annual_finance_statement_company_id": {0: 1, 1: 1}, + "annual_finance_statement_date": {0: "2023-01-01", 1: "2022-01-01"}, + "annual_finance_statement_total_volume": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_ebit": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_ebitda": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_ebit_margin": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_total_balance": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_equity": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_debt": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_return_on_equity": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_capital_turnover_rate": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_current_liabilities": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_dividends": {0: None, 1: None}, + "annual_finance_statement_net_income": {0: None, 1: None}, + "annual_finance_statement_assets": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_long_term_debt": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_short_term_debt": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_revenue": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_cash_flow": {0: 1000.0, 1: 1100.0}, + "annual_finance_statement_current_assets": {0: 1000.0, 1: 1100.0}, + "company_name": {0: "Some Company GmbH", 1: "Some Company GmbH"}, + "company_id": {0: 1, 1: 1}, + } + ) + pd.testing.assert_frame_equal(finance_df, test_data) + + +def test_create_header() -> None: + """Checks if the header can be created.""" + options = {1: "a", 2: "b"} + ui_elements.create_header(options) + + +def test_create_company_header() -> None: + """Checks if the company header can be created.""" + selected_company = "Test GmbH" + ui_elements.create_company_header(selected_company) + + +def test_create_company_stats(full_db: Session) -> None: + """Checks if the company widgets can be created.""" + company_df = ui_elements.get_company_data(full_db) + value_chosen = 1 + selected_company_stats = company_df.loc[value_chosen] + ui_elements.create_company_stats(selected_company_stats) + + +def test_create_tabs(full_db: Session) -> None: + """Checks if the tabs of the company page can be created.""" + selected_company_id = 1 + finance_df = ui_elements.get_finance_data(full_db) + selected_finance_df = finance_df.loc[ + finance_df["company_id"] == selected_company_id + ] + ui_elements.create_tabs(selected_finance_df) + + +def test_kennzahlen_layout(full_db: Session) -> None: + """Checks if the financial metric layout of the company page can be created.""" + selected_company_id = 1 + finance_df = ui_elements.get_finance_data(full_db) + selected_finance_df = finance_df.loc[ + finance_df["company_id"] == selected_company_id + ] + ui_elements.kennzahlen_layout(selected_finance_df) diff --git a/tests/utils/data_transfer_test.py b/tests/utils/data_transfer_test.py index 275aa7f..b92bb28 100644 --- a/tests/utils/data_transfer_test.py +++ b/tests/utils/data_transfer_test.py @@ -168,7 +168,7 @@ def test_get_person_id_value_check( data_transfer.get_person_id( firstname, surname, - date.fromisoformat(date_str) if date_str else None, # type: ignore + date.fromisoformat(date_str) if date_str else None, full_db, ) @@ -941,7 +941,11 @@ def test_add_annual_report_to_unknown_company( @pytest.mark.parametrize("year", [2023, 2025, 2020]) @pytest.mark.parametrize("short_term_debt", [2023.2, 2025.5, 2020.5, float("NaN")]) def test_add_annual_report( - short_term_debt: float, company_id: int, year: int, full_db: Session + short_term_debt: float, + company_id: int, + year: int, + finance_statements: list[dict[str, Any]], + full_db: Session, ) -> None: """Tests the addition of annual financial records.""" data_transfer.add_annual_report( @@ -961,34 +965,38 @@ def test_add_annual_report( df_prior = pd.read_sql_table( entities.AnnualFinanceStatement.__tablename__, full_db.bind # type: ignore ) + expected_results = pd.DataFrame( + finance_statements + + [ + { + "id": 3, + "company_id": company_id, + "date": pd.to_datetime(date(year, 1, 1)), + "total_volume": float("NaN"), + "ebit": 123.0, + "ebitda": 235.0, + "ebit_margin": float("NaN"), + "total_balance": float("NaN"), + "equity": float("NaN"), + "debt": float("NaN"), + "return_on_equity": float("NaN"), + "capital_turnover_rate": float("NaN"), + "current_liabilities": float("NaN"), + "dividends": float("NaN"), + "net_income": float("NaN"), + "assets": float("NaN"), + "long_term_debt": float("NaN"), + "short_term_debt": short_term_debt, + "revenue": float("NaN"), + "cash_flow": float("NaN"), + "current_assets": float("NaN"), + } + ] + ) + + expected_results["date"] = pd.to_datetime(expected_results["date"]) pd.testing.assert_frame_equal( - pd.DataFrame( - [ - { - "id": 1, - "company_id": company_id, - "date": pd.to_datetime(date(year, 1, 1)), - "total_volume": float("NaN"), - "ebit": 123.0, - "ebitda": 235.0, - "ebit_margin": float("NaN"), - "total_balance": float("NaN"), - "equity": float("NaN"), - "debt": float("NaN"), - "return_on_equity": float("NaN"), - "capital_turnover_rate": float("NaN"), - "current_liabilities": float("NaN"), - "dividends": float("NaN"), - "net_income": float("NaN"), - "assets": float("NaN"), - "long_term_debt": float("NaN"), - "short_term_debt": short_term_debt, - "revenue": float("NaN"), - "cash_flow": float("NaN"), - "current_assets": float("NaN"), - } - ] - ), + expected_results, df_prior, )