From 4d2ca3b3e79f4014ab4c571cc57c543189748b2f Mon Sep 17 00:00:00 2001 From: Tim Date: Sun, 5 Nov 2023 17:50:21 +0100 Subject: [PATCH] Refactored Session handling for Network analysis --- poetry.lock | 180 +++--- pyproject.toml | 7 +- .../ui/pages/home.py | 525 +++++++++--------- .../utils/networkx/networkx_data.py | 18 +- 4 files changed, 375 insertions(+), 355 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2efb83d..da24f1b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3439,36 +3439,43 @@ test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync" [[package]] name = "numpy" -version = "1.25.2" +version = "1.26.1" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.9" +python-versions = "<3.13,>=3.9" files = [ - {file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3"}, - {file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f"}, - {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187"}, - {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357"}, - {file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9"}, - {file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044"}, - {file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545"}, - {file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418"}, - {file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f"}, - {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2"}, - {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf"}, - {file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364"}, - {file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d"}, - {file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4"}, - {file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3"}, - {file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926"}, - {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca"}, - {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295"}, - {file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f"}, - {file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01"}, - {file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901"}, - {file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf"}, - {file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"}, + {file = "numpy-1.26.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82e871307a6331b5f09efda3c22e03c095d957f04bf6bc1804f30048d0e5e7af"}, + {file = "numpy-1.26.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdd9ec98f0063d93baeb01aad472a1a0840dee302842a2746a7a8e92968f9575"}, + {file = "numpy-1.26.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d78f269e0c4fd365fc2992c00353e4530d274ba68f15e968d8bc3c69ce5f5244"}, + {file = "numpy-1.26.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ab9163ca8aeb7fd32fe93866490654d2f7dda4e61bc6297bf72ce07fdc02f67"}, + {file = "numpy-1.26.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:78ca54b2f9daffa5f323f34cdf21e1d9779a54073f0018a3094ab907938331a2"}, + {file = "numpy-1.26.1-cp310-cp310-win32.whl", hash = "sha256:d1cfc92db6af1fd37a7bb58e55c8383b4aa1ba23d012bdbba26b4bcca45ac297"}, + {file = "numpy-1.26.1-cp310-cp310-win_amd64.whl", hash = "sha256:d2984cb6caaf05294b8466966627e80bf6c7afd273279077679cb010acb0e5ab"}, + {file = "numpy-1.26.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cd7837b2b734ca72959a1caf3309457a318c934abef7a43a14bb984e574bbb9a"}, + {file = "numpy-1.26.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c59c046c31a43310ad0199d6299e59f57a289e22f0f36951ced1c9eac3665b9"}, + {file = "numpy-1.26.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d58e8c51a7cf43090d124d5073bc29ab2755822181fcad978b12e144e5e5a4b3"}, + {file = "numpy-1.26.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6081aed64714a18c72b168a9276095ef9155dd7888b9e74b5987808f0dd0a974"}, + {file = "numpy-1.26.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:97e5d6a9f0702c2863aaabf19f0d1b6c2628fbe476438ce0b5ce06e83085064c"}, + {file = "numpy-1.26.1-cp311-cp311-win32.whl", hash = "sha256:b9d45d1dbb9de84894cc50efece5b09939752a2d75aab3a8b0cef6f3a35ecd6b"}, + {file = "numpy-1.26.1-cp311-cp311-win_amd64.whl", hash = "sha256:3649d566e2fc067597125428db15d60eb42a4e0897fc48d28cb75dc2e0454e53"}, + {file = "numpy-1.26.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d1bd82d539607951cac963388534da3b7ea0e18b149a53cf883d8f699178c0f"}, + {file = "numpy-1.26.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:afd5ced4e5a96dac6725daeb5242a35494243f2239244fad10a90ce58b071d24"}, + {file = "numpy-1.26.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03fb25610ef560a6201ff06df4f8105292ba56e7cdd196ea350d123fc32e24e"}, + {file = "numpy-1.26.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcfaf015b79d1f9f9c9fd0731a907407dc3e45769262d657d754c3a028586124"}, + {file = "numpy-1.26.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e509cbc488c735b43b5ffea175235cec24bbc57b227ef1acc691725beb230d1c"}, + {file = "numpy-1.26.1-cp312-cp312-win32.whl", hash = "sha256:af22f3d8e228d84d1c0c44c1fbdeb80f97a15a0abe4f080960393a00db733b66"}, + {file = "numpy-1.26.1-cp312-cp312-win_amd64.whl", hash = "sha256:9f42284ebf91bdf32fafac29d29d4c07e5e9d1af862ea73686581773ef9e73a7"}, + {file = "numpy-1.26.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb894accfd16b867d8643fc2ba6c8617c78ba2828051e9a69511644ce86ce83e"}, + {file = "numpy-1.26.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e44ccb93f30c75dfc0c3aa3ce38f33486a75ec9abadabd4e59f114994a9c4617"}, + {file = "numpy-1.26.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9696aa2e35cc41e398a6d42d147cf326f8f9d81befcb399bc1ed7ffea339b64e"}, + {file = "numpy-1.26.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5b411040beead47a228bde3b2241100454a6abde9df139ed087bd73fc0a4908"}, + {file = "numpy-1.26.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1e11668d6f756ca5ef534b5be8653d16c5352cbb210a5c2a79ff288e937010d5"}, + {file = "numpy-1.26.1-cp39-cp39-win32.whl", hash = "sha256:d1d2c6b7dd618c41e202c59c1413ef9b2c8e8a15f5039e344af64195459e3104"}, + {file = "numpy-1.26.1-cp39-cp39-win_amd64.whl", hash = "sha256:59227c981d43425ca5e5c01094d59eb14e8772ce6975d4b2fc1e106a833d5ae2"}, + {file = "numpy-1.26.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:06934e1a22c54636a059215d6da99e23286424f316fddd979f5071093b648668"}, + {file = "numpy-1.26.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76ff661a867d9272cd2a99eed002470f46dbe0943a5ffd140f49be84f68ffc42"}, + {file = "numpy-1.26.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6965888d65d2848e8768824ca8288db0a81263c1efccec881cb35a0d805fcd2f"}, + {file = "numpy-1.26.1.tar.gz", hash = "sha256:c8c6c72d4a9f831f328efb1312642a1cafafaa88981d9ab76368d50d07d93cbe"}, ] [[package]] @@ -3579,64 +3586,6 @@ files = [ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] -[[package]] -name = "pandas" -version = "2.1.0" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:40dd20439ff94f1b2ed55b393ecee9cb6f3b08104c2c40b0cb7186a2f0046242"}, - {file = "pandas-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d4f38e4fedeba580285eaac7ede4f686c6701a9e618d8a857b138a126d067f2f"}, - {file = "pandas-2.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e6a0fe052cf27ceb29be9429428b4918f3740e37ff185658f40d8702f0b3e09"}, - {file = "pandas-2.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d81e1813191070440d4c7a413cb673052b3b4a984ffd86b8dd468c45742d3cc"}, - {file = "pandas-2.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eb20252720b1cc1b7d0b2879ffc7e0542dd568f24d7c4b2347cb035206936421"}, - {file = "pandas-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:38f74ef7ebc0ffb43b3d633e23d74882bce7e27bfa09607f3c5d3e03ffd9a4a5"}, - {file = "pandas-2.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cda72cc8c4761c8f1d97b169661f23a86b16fdb240bdc341173aee17e4d6cedd"}, - {file = "pandas-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d97daeac0db8c993420b10da4f5f5b39b01fc9ca689a17844e07c0a35ac96b4b"}, - {file = "pandas-2.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8c58b1113892e0c8078f006a167cc210a92bdae23322bb4614f2f0b7a4b510f"}, - {file = "pandas-2.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:629124923bcf798965b054a540f9ccdfd60f71361255c81fa1ecd94a904b9dd3"}, - {file = "pandas-2.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:70cf866af3ab346a10debba8ea78077cf3a8cd14bd5e4bed3d41555a3280041c"}, - {file = "pandas-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:d53c8c1001f6a192ff1de1efe03b31a423d0eee2e9e855e69d004308e046e694"}, - {file = "pandas-2.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:86f100b3876b8c6d1a2c66207288ead435dc71041ee4aea789e55ef0e06408cb"}, - {file = "pandas-2.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28f330845ad21c11db51e02d8d69acc9035edfd1116926ff7245c7215db57957"}, - {file = "pandas-2.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9a6ccf0963db88f9b12df6720e55f337447aea217f426a22d71f4213a3099a6"}, - {file = "pandas-2.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99e678180bc59b0c9443314297bddce4ad35727a1a2656dbe585fd78710b3b9"}, - {file = "pandas-2.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b31da36d376d50a1a492efb18097b9101bdbd8b3fbb3f49006e02d4495d4c644"}, - {file = "pandas-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0164b85937707ec7f70b34a6c3a578dbf0f50787f910f21ca3b26a7fd3363437"}, - {file = "pandas-2.1.0.tar.gz", hash = "sha256:62c24c7fc59e42b775ce0679cfa7b14a5f9bfb7643cfbe708c960699e05fb918"}, -] - -[package.dependencies] -numpy = {version = ">=1.23.2", markers = "python_version >= \"3.11\""} -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.1" - -[package.extras] -all = ["PyQt5 (>=5.15.6)", "SQLAlchemy (>=1.4.36)", "beautifulsoup4 (>=4.11.1)", "bottleneck (>=1.3.4)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=0.8.1)", "fsspec (>=2022.05.0)", "gcsfs (>=2022.05.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.8.0)", "matplotlib (>=3.6.1)", "numba (>=0.55.2)", "numexpr (>=2.8.0)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pandas-gbq (>=0.17.5)", "psycopg2 (>=2.9.3)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.5)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "pyxlsb (>=1.0.9)", "qtpy (>=2.2.0)", "s3fs (>=2022.05.0)", "scipy (>=1.8.1)", "tables (>=3.7.0)", "tabulate (>=0.8.10)", "xarray (>=2022.03.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)", "zstandard (>=0.17.0)"] -aws = ["s3fs (>=2022.05.0)"] -clipboard = ["PyQt5 (>=5.15.6)", "qtpy (>=2.2.0)"] -compression = ["zstandard (>=0.17.0)"] -computation = ["scipy (>=1.8.1)", "xarray (>=2022.03.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pyxlsb (>=1.0.9)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)"] -feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2022.05.0)"] -gcp = ["gcsfs (>=2022.05.0)", "pandas-gbq (>=0.17.5)"] -hdf5 = ["tables (>=3.7.0)"] -html = ["beautifulsoup4 (>=4.11.1)", "html5lib (>=1.1)", "lxml (>=4.8.0)"] -mysql = ["SQLAlchemy (>=1.4.36)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.8.10)"] -parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.4)", "numba (>=0.55.2)", "numexpr (>=2.8.0)"] -plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.36)", "psycopg2 (>=2.9.3)"] -spss = ["pyreadstat (>=1.1.5)"] -sql-other = ["SQLAlchemy (>=1.4.36)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.8.0)"] - [[package]] name = "pandas" version = "2.1.2" @@ -3672,7 +3621,10 @@ files = [ ] [package.dependencies] -numpy = {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""} +numpy = [ + {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""}, +] python-dateutil = ">=2.8.2" pytz = ">=2020.1" tzdata = ">=2022.1" @@ -3703,17 +3655,17 @@ xml = ["lxml (>=4.8.0)"] [[package]] name = "pandas-stubs" -version = "2.0.3.230814" +version = "2.1.1.230928" description = "Type annotations for pandas" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pandas_stubs-2.0.3.230814-py3-none-any.whl", hash = "sha256:4b3dfc027d49779176b7daa031a3405f7b839bcb6e312f4b9f29fea5feec5b4f"}, - {file = "pandas_stubs-2.0.3.230814.tar.gz", hash = "sha256:1d5cc09e36e3d9f9a1ed9dceae4e03eeb26d1b898dd769996925f784365c8769"}, + {file = "pandas_stubs-2.1.1.230928-py3-none-any.whl", hash = "sha256:992d97159e054ca3175ebe8321ac5616cf6502dd8218b03bb0eaf3c4f6939037"}, + {file = "pandas_stubs-2.1.1.230928.tar.gz", hash = "sha256:ce1691c71c5d67b8f332da87763f7f54650f46895d99964d588c3a5d79e2cacc"}, ] [package.dependencies] -numpy = {version = ">=1.25.0", markers = "python_version >= \"3.9\""} +numpy = {version = ">=1.26.0", markers = "python_version < \"3.13\""} types-pytz = ">=2022.1.1" [[package]] @@ -5604,6 +5556,48 @@ tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] testing = ["h5py (>=3.7.0)", "huggingface_hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools_rust (>=1.5.2)"] torch = ["safetensors[numpy]", "torch (>=1.10)"] +[[package]] +name = "scipy" +version = "1.11.3" +description = "Fundamental algorithms for scientific computing in Python" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "scipy-1.11.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:370f569c57e1d888304052c18e58f4a927338eafdaef78613c685ca2ea0d1fa0"}, + {file = "scipy-1.11.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:9885e3e4f13b2bd44aaf2a1a6390a11add9f48d5295f7a592393ceb8991577a3"}, + {file = "scipy-1.11.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e04aa19acc324a1a076abb4035dabe9b64badb19f76ad9c798bde39d41025cdc"}, + {file = "scipy-1.11.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e1a8a4657673bfae1e05e1e1d6e94b0cabe5ed0c7c144c8aa7b7dbb774ce5c1"}, + {file = "scipy-1.11.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7abda0e62ef00cde826d441485e2e32fe737bdddee3324e35c0e01dee65e2a88"}, + {file = "scipy-1.11.3-cp310-cp310-win_amd64.whl", hash = "sha256:033c3fd95d55012dd1148b201b72ae854d5086d25e7c316ec9850de4fe776929"}, + {file = "scipy-1.11.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:925c6f09d0053b1c0f90b2d92d03b261e889b20d1c9b08a3a51f61afc5f58165"}, + {file = "scipy-1.11.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5664e364f90be8219283eeb844323ff8cd79d7acbd64e15eb9c46b9bc7f6a42a"}, + {file = "scipy-1.11.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00f325434b6424952fbb636506f0567898dca7b0f7654d48f1c382ea338ce9a3"}, + {file = "scipy-1.11.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f290cf561a4b4edfe8d1001ee4be6da60c1c4ea712985b58bf6bc62badee221"}, + {file = "scipy-1.11.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:91770cb3b1e81ae19463b3c235bf1e0e330767dca9eb4cd73ba3ded6c4151e4d"}, + {file = "scipy-1.11.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1f97cd89c0fe1a0685f8f89d85fa305deb3067d0668151571ba50913e445820"}, + {file = "scipy-1.11.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dfcc1552add7cb7c13fb70efcb2389d0624d571aaf2c80b04117e2755a0c5d15"}, + {file = "scipy-1.11.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0d3a136ae1ff0883fffbb1b05b0b2fea251cb1046a5077d0b435a1839b3e52b7"}, + {file = "scipy-1.11.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bae66a2d7d5768eaa33008fa5a974389f167183c87bf39160d3fefe6664f8ddc"}, + {file = "scipy-1.11.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2f6dee6cbb0e263b8142ed587bc93e3ed5e777f1f75448d24fb923d9fd4dce6"}, + {file = "scipy-1.11.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:74e89dc5e00201e71dd94f5f382ab1c6a9f3ff806c7d24e4e90928bb1aafb280"}, + {file = "scipy-1.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:90271dbde4be191522b3903fc97334e3956d7cfb9cce3f0718d0ab4fd7d8bfd6"}, + {file = "scipy-1.11.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a63d1ec9cadecce838467ce0631c17c15c7197ae61e49429434ba01d618caa83"}, + {file = "scipy-1.11.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:5305792c7110e32ff155aed0df46aa60a60fc6e52cd4ee02cdeb67eaccd5356e"}, + {file = "scipy-1.11.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ea7f579182d83d00fed0e5c11a4aa5ffe01460444219dedc448a36adf0c3917"}, + {file = "scipy-1.11.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c77da50c9a91e23beb63c2a711ef9e9ca9a2060442757dffee34ea41847d8156"}, + {file = "scipy-1.11.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:15f237e890c24aef6891c7d008f9ff7e758c6ef39a2b5df264650eb7900403c0"}, + {file = "scipy-1.11.3-cp39-cp39-win_amd64.whl", hash = "sha256:4b4bb134c7aa457e26cc6ea482b016fef45db71417d55cc6d8f43d799cdf9ef2"}, + {file = "scipy-1.11.3.tar.gz", hash = "sha256:bba4d955f54edd61899776bad459bf7326e14b9fa1c552181f0479cc60a568cd"}, +] + +[package.dependencies] +numpy = ">=1.21.6,<1.28.0" + +[package.extras] +dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + [[package]] name = "seaborn" version = "0.13.0" @@ -7373,5 +7367,5 @@ web-server = ["dash", "dash-auth", "dash-bootstrap-components", "matplotlib", "s [metadata] lock-version = "2.0" -python-versions = "^3.11" -content-hash = "3b7621baf170bf8c0c5ede80e52d42a5a227c85757a9f4fa2b8648d944496007" +python-versions = ">=3.11,<3.13" +content-hash = "0119b3fb52b3b7ccd99631b5d9418d7c0e139096feacd0c56f8bb2345c2861f0" diff --git a/pyproject.toml b/pyproject.toml index 7320a4d..7f2be19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,9 +66,10 @@ matplotlib = "^3.8.1" pgeocode = "^0.4.1" psycopg2-binary = "^2.9.7" pymongo = "^4.6.0" -python = "^3.11" +python = ">=3.11,<3.13" python-dotenv = "^1.0.0" rapidfuzz = "^3.5.2" +scipy = "^1.11.3" seaborn = "^0.13.0" selenium = "^4.15.2" spacy = "^3.6.1" @@ -112,7 +113,7 @@ SQLAlchemy = {version = "*", extras = ["mypy"]} black = "*" loguru-mypy = "*" mypy = "*" -networkx-stubs = "^0.0.1" +networkx-stubs = "*" pandas-stubs = "*" pip-audit = "*" pip-licenses = "*" @@ -125,7 +126,7 @@ types-setuptools = "*" types-six = "*" types-tabulate = "*" types-tqdm = "*" -types-urllib3 = "^1.26.25.14" +types-urllib3 = "*" [tool.poetry.group.test.dependencies] pytest = "^7.4.2" diff --git a/src/aki_prj23_transparenzregister/ui/pages/home.py b/src/aki_prj23_transparenzregister/ui/pages/home.py index cbede66..65f3aa1 100644 --- a/src/aki_prj23_transparenzregister/ui/pages/home.py +++ b/src/aki_prj23_transparenzregister/ui/pages/home.py @@ -1,10 +1,15 @@ """Content of home page.""" +from functools import lru_cache + import dash import dash_daq as daq import networkx as nx +import numpy as np import pandas as pd import plotly.graph_objects as go +from cachetools import TTLCache, cached from dash import Input, Output, callback, dash_table, dcc, html +from loguru import logger from aki_prj23_transparenzregister.utils.networkx.network_2d import ( create_2d_graph, @@ -19,19 +24,10 @@ from aki_prj23_transparenzregister.utils.networkx.network_base import ( from aki_prj23_transparenzregister.utils.networkx.networkx_data import ( create_edge_and_node_list, filter_relation_type, - filter_relation_with_more_than_one_connection, get_all_company_relations, get_all_person_relations, ) -dash.register_page(__name__, path="/") - -# Get Data -person_relation = filter_relation_type(get_all_person_relations(), "NACHFOLGER") -company_relation = filter_relation_with_more_than_one_connection( - get_all_company_relations(), "id_company_to", "id_company_from" -) - dash.register_page( __name__, path="/", @@ -44,38 +40,40 @@ dash.register_page( ], ) - -# Plotly figure -def networkGraph(EGDE_VAR: None) -> go.Figure: - # find_all_company_relations() - -graph, metrices = initialize_network(nodes = nodes, edges = edges) -# print(graph) -metric = None -network = create_3d_graph(graph, nodes, edges, metrics, metric) # Create Edge and Node List from data -nodes, edges = create_edge_and_node_list(person_relation, company_relation) +# nodes, edges = create_edge_and_node_list(person_relation, company_relation) # Initialize the Network and receive the Graph and a DataFrame with Metrics -graph, metrics = initialize_network(nodes=nodes, edges=edges) +# graph, metrics = initialize_network(nodes=nodes, edges=edges) metric = "None" -layout = "Spring" -# switch_node_annotaion_value = False +# layout = "Spring" +# # switch_node_annotaion_value = False switch_edge_annotaion_value = False egde_thickness = 1 -network = create_3d_graph( - graph, - nodes, - edges, - metrics, - metric, - layout, - switch_edge_annotaion_value, - egde_thickness, -) +network = None +# create_3d_graph( +# graph, +# nodes, +# edges, +# metrics, +# metric, +# layout, +# switch_edge_annotaion_value, +# egde_thickness, +# ) # Get the possible Filter values for the Dropdowns. -person_relation_type_filter = get_all_person_relations()["relation_type"].unique() -company_relation_type_filter = get_all_company_relations()["relation_type"].unique() + + +def person_relation_type_filter() -> np.ndarray: + """Returns an Numpy Array of String with Person telation types.""" + logger.debug("Updating Person Dropdown") + return get_all_person_relations()["relation_type"].unique() + + +def company_relation_type_filter() -> np.ndarray: + """Returns an Numpy Array of String with Company relation types.""" + logger.debug("Updating Person Dropdown") + return get_all_company_relations()["relation_type"].unique() def update_table( @@ -90,6 +88,7 @@ def update_table( Returns: tuple[dict, list]: _description_ """ + logger.debug("Updateing Table") table_df = metrics.sort_values(metric_dropdown_value, ascending=False).head(10) table_df = table_df[["designation", "category", metric_dropdown_value]] table_df.to_dict("records") @@ -97,228 +96,245 @@ def update_table( return table_df.to_dict("records"), columns # type: ignore -top_companies_dict, top_companies_columns = update_table("closeness", metrics) - -layout = html.Div( - children=html.Div( - children=[ - html.Div( - className="top_companytable_style", - children=[ - html.H1( - title="Top Ten Nodes in Graph by Metric", style={"align": "mid"} - ), - html.Div( - className="filter-wrapper-item", - children=[ - html.H5( - className="filter-description", - children=["Filter Metric:"], - ), - dcc.Dropdown( - [ - "eigenvector", - "degree", - "betweenness", - "closeness", - ], - "closeness", - id="dropdown_table_metric", - className="dropdown_style", - ), - ], - ), - dash_table.DataTable( - top_companies_dict, - top_companies_columns, - id="metric_table", - ), - ], - ), - html.Div( - className="networkx_style", - children=[ - html.H1(className="header", children=["Social Graph"]), - # html.Div( - # className="filter-wrapper", - # children=[ - # html.Div( - # className="filter-wrapper-item", - # children=[ - # html.H5( - # className="filter-description", - # children=["Data Source:"], - # ), - # dcc.Dropdown( - # ["Company Data only", "Person Data only", "Company & Person Data"], - # "Company Data only", - # id="dropdown_data_soruce_filter", - # className="dropdown_style", - # ), - # ], - # ), - # ], - # ), - html.Div( - className="filter-wrapper", - id="company_dropdown", - # style="visibility: hidden;", - children=[ - html.Div( - className="filter-wrapper-item", - children=[ - html.H5( - className="filter-description", - children=["Company Relation Type Filter:"], - ), - dcc.Dropdown( - company_relation_type_filter, - company_relation_type_filter[0], - id="dropdown_company_relation_filter", - className="dropdown_style", - ), - ], - ), - html.Div( - className="filter-wrapper-item", - # style="visibility: visible;", - children=[ - html.H5( - className="filter-description", - children=["Person Relation Type Filter:"], - ), - dcc.Dropdown( - person_relation_type_filter, - person_relation_type_filter[0], - id="dropdown_person_relation_filter", - className="dropdown_style", - ), - ], - ), - html.Div( - className="filter-wrapper-item", - children=[ - html.H5( - className="filter-description", - children=["Choose Graph Metric:"], - ), - dcc.Dropdown( - [ - "None", - "eigenvector", - "degree", - "betweenness", - "closeness", - ], - "None", - id="dropdown", - className="dropdown_style", - ), - ], - ), - html.Div( - className="filter-wrapper-item", - children=[ - html.H5( - className="filter-description", - children=["Choose Layout:"], - ), - dcc.Dropdown( - [ - "Spring", - # "Bipartite", - "Circular", - "Kamada Kawai", - # "Planar", - "Random", - "Shell (only 2D)", - # "Spectral", - "Spiral (only 2D)", - # "Multipartite" - ], - "Spring", - id="dropdown_layout", - className="dropdown_style", - ), - ], - ), - html.Div( - className="filter-wrapper-item", - children=[ - html.H5( - className="filter-description", - children=["Adjust Edge Thickness"], - ), - dcc.Slider( - 1, - 4, - 1, - value=1, - id="slider", - ), - ], - ), - ], - ), - html.Div( - className="filter-wrapper", - children=[ - html.Div( - className="filter-wrapper-item", - children=[ - html.H5( - className="filter-description", - children=["Switch to 2D Diagramm"], - ), - html.Div( - className="switch-style", - children=[ - daq.BooleanSwitch(id="switch", on=False) - ], - ), - ], - ), - # html.Div( - # className="filter-wrapper-item", - # children=[ - # html.H5( - # className="filter-description", - # children=["Enable Node Annotation"], - # ), - # html.Div( - # className="switch-style", - # children=[daq.BooleanSwitch(id="switch_node_annotation", on=False)], - # ), - # ], - # ), - html.Div( - className="filter-wrapper-item", - children=[ - html.H5( - className="filter-description", - children=["Enable Edge Annotation"], - ), - html.Div( - className="switch-style", - children=[ - daq.BooleanSwitch( - id="switch_edge_annotation", on=False - ) - ], - ), - ], - ), - ], - ), - dcc.Graph(figure=network, id="my-graph", className="graph-style"), - ], - ), - ] +def layout() -> list[html.Div]: + """Generates the Layout of the Homepage.""" + logger.debug("Layouting Homepage") + person_relation_types = person_relation_type_filter() + company_relation_types = company_relation_type_filter() + top_companies_dict, top_companies_columns, figure = update_figure( + "None", + False, + False, + company_relation_types[0], + person_relation_types[0], + "Spring", + 1, + "degree", + ) + return html.Div( + children=html.Div( + children=[ + html.Div( + className="top_companytable_style", + children=[ + html.H1( + title="Top Ten Nodes in Graph by Metric", + style={"align": "mid"}, + ), + html.Div( + className="filter-wrapper-item", + children=[ + html.H5( + className="filter-description", + children=["Filter Metric:"], + ), + dcc.Dropdown( + [ + "eigenvector", + "degree", + "betweenness", + "closeness", + ], + "closeness", + id="dropdown_table_metric", + className="dropdown_style", + ), + ], + ), + dash_table.DataTable( + top_companies_dict, + top_companies_columns, + id="metric_table", + ), + ], + ), + html.Div( + className="networkx_style", + children=[ + html.H1(className="header", children=["Social Graph"]), + # html.Div( + # className="filter-wrapper", + # children=[ + # html.Div( + # className="filter-wrapper-item", + # children=[ + # html.H5( + # className="filter-description", + # children=["Data Source:"], + # ), + # dcc.Dropdown( + # ["Company Data only", "Person Data only", "Company & Person Data"], + # "Company Data only", + # id="dropdown_data_soruce_filter", + # className="dropdown_style", + # ), + # ], + # ), + # ], + # ), + html.Div( + className="filter-wrapper", + id="company_dropdown", + # style="visibility: hidden;", + children=[ + html.Div( + className="filter-wrapper-item", + children=[ + html.H5( + className="filter-description", + children=["Company Relation Type Filter:"], + ), + dcc.Dropdown( + company_relation_types, + company_relation_types[0], + id="dropdown_company_relation_filter", + className="dropdown_style", + ), + ], + ), + html.Div( + className="filter-wrapper-item", + # style="visibility: visible;", + children=[ + html.H5( + className="filter-description", + children=["Person Relation Type Filter:"], + ), + dcc.Dropdown( + person_relation_types, + person_relation_types[0], + id="dropdown_person_relation_filter", + className="dropdown_style", + ), + ], + ), + html.Div( + className="filter-wrapper-item", + children=[ + html.H5( + className="filter-description", + children=["Choose Graph Metric:"], + ), + dcc.Dropdown( + [ + "None", + "eigenvector", + "degree", + "betweenness", + "closeness", + ], + "None", + id="dropdown", + className="dropdown_style", + ), + ], + ), + html.Div( + className="filter-wrapper-item", + children=[ + html.H5( + className="filter-description", + children=["Choose Layout:"], + ), + dcc.Dropdown( + [ + "Spring", + # "Bipartite", + "Circular", + "Kamada Kawai", + # "Planar", + "Random", + "Shell (only 2D)", + # "Spectral", + "Spiral (only 2D)", + # "Multipartite" + ], + "Spring", + id="dropdown_layout", + className="dropdown_style", + ), + ], + ), + html.Div( + className="filter-wrapper-item", + children=[ + html.H5( + className="filter-description", + children=["Adjust Edge Thickness"], + ), + dcc.Slider( + 1, + 4, + 1, + value=1, + id="slider", + ), + ], + ), + ], + ), + html.Div( + className="filter-wrapper", + children=[ + html.Div( + className="filter-wrapper-item", + children=[ + html.H5( + className="filter-description", + children=["Switch to 2D Diagramm"], + ), + html.Div( + className="switch-style", + children=[ + daq.BooleanSwitch(id="switch", on=False) + ], + ), + ], + ), + # html.Div( + # className="filter-wrapper-item", + # children=[ + # html.H5( + # className="filter-description", + # children=["Enable Node Annotation"], + # ), + # html.Div( + # className="switch-style", + # children=[daq.BooleanSwitch(id="switch_node_annotation", on=False)], + # ), + # ], + # ), + html.Div( + className="filter-wrapper-item", + children=[ + html.H5( + className="filter-description", + children=["Enable Edge Annotation"], + ), + html.Div( + className="switch-style", + children=[ + daq.BooleanSwitch( + id="switch_edge_annotation", + on=False, + ) + ], + ), + ], + ), + ], + ), + dcc.Graph( + figure=figure, id="my-graph", className="graph-style" + ), + ], + ), + ] + ) ) -) -# @lru_cache(200) +@lru_cache(200) def update_graph_data( person_relation_type: str = "HAFTENDER_GESELLSCHAFTER", company_relation_type: str = "GESCHAEFTSFUEHRER", @@ -332,6 +348,7 @@ def update_graph_data( Returns: tuple[nx.Graph, pd.DataFrame, dict, list]: _description_ """ + logger.debug("Updating Graph data") # Get Data person_df = get_all_person_relations() company_df = get_all_company_relations() @@ -369,6 +386,7 @@ def update_graph_data( allow_duplicate=True, ) # @lru_cache(20) +@cached(cache=TTLCache(maxsize=100, ttl=500)) def update_figure( # noqa: PLR0913 selected_metric: str, switch_value: bool, @@ -396,6 +414,7 @@ def update_figure( # noqa: PLR0913 Returns: Network Graph(Plotly Figure): Plotly Figure in 3 or 2D """ + logger.debug("Update Figure") _ = c_relation_filter_value, p_relation_filter_value graph, metrics, nodes, edges = update_graph_data( diff --git a/src/aki_prj23_transparenzregister/utils/networkx/networkx_data.py b/src/aki_prj23_transparenzregister/utils/networkx/networkx_data.py index e06b83b..2653b7d 100644 --- a/src/aki_prj23_transparenzregister/utils/networkx/networkx_data.py +++ b/src/aki_prj23_transparenzregister/utils/networkx/networkx_data.py @@ -5,16 +5,14 @@ import networkx as nx import pandas as pd from sqlalchemy.orm import aliased -from aki_prj23_transparenzregister.config.config_providers import JsonFileConfigProvider +from aki_prj23_transparenzregister.ui.session_handler import SessionHandler from aki_prj23_transparenzregister.utils.networkx.network_base import ( initialize_network_with_reduced_metrics, initialize_network_without_metrics, ) -from aki_prj23_transparenzregister.utils.sql import connector, entities -from aki_prj23_transparenzregister.utils.sql.connector import get_session +from aki_prj23_transparenzregister.utils.sql import entities # Gets the Session Key for the DB Connection. -session = get_session(JsonFileConfigProvider("secrets.json")) # Alias for Company table for the base company to_company = aliased(entities.Company, name="to_company") @@ -32,7 +30,8 @@ def find_all_company_relations() -> pd.DataFrame: Returns: pd.DataFrame: _description_ """ - session = connector.get_session(JsonFileConfigProvider("./secrets.json")) + session = SessionHandler.session + assert session # noqa: S101 query_companies = session.query(entities.Company) # .all() query_relations = session.query(entities.CompanyRelation) # .all() @@ -70,7 +69,8 @@ def find_top_companies() -> pd.DataFrame: Returns: pd.DataFrame: _description_ """ - session = connector.get_session(JsonFileConfigProvider("./secrets.json")) + session = SessionHandler.session + assert session # noqa: S101 query_companies = session.query(entities.Company) # .all() companies_df: pd.DataFrame = pd.read_sql(str(query_companies), session.bind) # type: ignore @@ -87,6 +87,8 @@ def get_all_company_relations() -> pd.DataFrame: Returns: DataFrame: DataFrame with all Relations between Companies. """ + session = SessionHandler.session + assert session # noqa: S101 # Query to fetch relations between companies relations_company_query = ( session.query( @@ -124,6 +126,8 @@ def get_all_person_relations() -> pd.DataFrame: Returns: DataFrame: DataFrame with all Relations between Persons and Companies. """ + session = SessionHandler.session + assert session # noqa: S101 relations_person_query = ( session.query( entities.Company.id.label("id_company"), @@ -285,6 +289,8 @@ def find_company_relations( Returns: Two Dataframes """ + session = SessionHandler.session + assert session # noqa: S101 relations_company_query = ( session.query( to_company.id.label("id_company_to"),