diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6c397b7..8a8ed5a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## UNRELEASED
+
+* Revamp data model
+ * All objects unified in one main table
+ * Renamed surveys/projects -> Assessments
+ * Added object library table
+* Revamp user experience
+ * Enter assessment data all on one page
+ * Manage object library separately from assessment data
+* Revamp architecture
+ * Use HTMX to start implementing HATEOAS architecture
+
+
## v1.6.1 (2023-12-22)
* Spelling fixes
diff --git a/compose.dev.yml b/compose.dev.yml
index 543f9543..b46c3bd9 100644
--- a/compose.dev.yml
+++ b/compose.dev.yml
@@ -38,7 +38,7 @@ services:
###############################################################
# DEV DANGER ZONE: These settings are INSECURE IN PRODUCTION. #
###############################################################
- # Enable the in-browser debugger:
+ # Enable the in-browser debugger and hot reloading:
FLASK_DEBUG: "True"
# In dev, we don't need to secure our sessions
FLASK_SECRET_KEY: "supersecret"
diff --git a/conda-lock.yml b/conda-lock.yml
index e939b363..3d5e1fec 100644
--- a/conda-lock.yml
+++ b/conda-lock.yml
@@ -13,8 +13,8 @@
version: 1
metadata:
content_hash:
- linux-64: 3c85e729777cea39a5d837f199656760051edb8561c51b36f39a2e8b4e7df2b9
- osx-64: 4d575856ffd08afa420bcb0c0ef5f829441f3f12c72f16da8726ed981a167698
+ linux-64: 0bb6ddfa648e8fc40c3e143bf574aa650d425b8723cfb85e30e0aa1654737588
+ osx-64: 6ec08693e22debeeef9a823de83fd4f4c264e6c9c59fe83c8eb849fb3e27f4b3
channels:
- url: conda-forge
used_env_vars: []
@@ -35,407 +35,407 @@ package:
sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726
category: main
optional: false
-- name: ca-certificates
- version: 2023.11.17
+- name: _openmp_mutex
+ version: '4.5'
manager: conda
platform: linux-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2023.11.17-hbcca054_0.conda
+ dependencies:
+ _libgcc_mutex: '0.1'
+ libgomp: '>=7.5.0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2
hash:
- md5: 01ffc8d36f9eba0ce0b3c1955fa780ee
- sha256: fb4b9f4b7d885002db0b93e22f44b5b03791ef3d4efdc9d0662185a0faafd6b6
+ md5: 73aaf86a425cc6e73fcf236a5a46396d
+ sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22
category: main
optional: false
-- name: ld_impl_linux-64
- version: '2.40'
+- name: amqp
+ version: 5.2.0
manager: conda
platform: linux-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h41732ed_0.conda
+ dependencies:
+ python: '>=3.6'
+ vine: '>=5.0.0,<6.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/amqp-5.2.0-pyhd8ed1ab_1.conda
hash:
- md5: 7aca3059a1729aa76c597603f10b0dd3
- sha256: f6cc89d887555912d6c61b295d398cff9ec982a3417d38025c45d5dd9b9e79cd
+ md5: 23e198e6df09c2c441640f1bcd1c7822
+ sha256: d445abfa5580fc4978eae39dd9268379cc6cffdb630108b38b03f0032899bc63
category: main
optional: false
-- name: libstdcxx-ng
- version: 13.2.0
+- name: amqp
+ version: 5.2.0
manager: conda
- platform: linux-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-h7e041cc_3.conda
+ platform: osx-64
+ dependencies:
+ python: '>=3.6'
+ vine: '>=5.0.0,<6.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/amqp-5.2.0-pyhd8ed1ab_1.conda
hash:
- md5: 937eaed008f6bf2191c5fe76f87755e9
- sha256: 6c6c49efedcc5709a66f19fb6b26b69c6a5245310fd1d9a901fd5e38aaf7f882
+ md5: 23e198e6df09c2c441640f1bcd1c7822
+ sha256: d445abfa5580fc4978eae39dd9268379cc6cffdb630108b38b03f0032899bc63
category: main
optional: false
-- name: python_abi
- version: '3.11'
+- name: backports.zoneinfo
+ version: 0.2.1
manager: conda
platform: linux-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-4_cp311.conda
+ dependencies:
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/backports.zoneinfo-0.2.1-py311h38be061_8.conda
hash:
- md5: d786502c97404c94d7d58d258a445a65
- sha256: 0be3ac1bf852d64f553220c7e6457e9c047dfb7412da9d22fbaa67e60858b3cf
+ md5: 5384590f14dfe6ccd02811236afc9f8e
+ sha256: 1708c5e6729567f30ccde7761492cb43ee72fa2f7d5065b9102785278718505b
category: main
optional: false
-- name: shellcheck
- version: 0.8.0
+- name: backports.zoneinfo
+ version: 0.2.1
manager: conda
- platform: linux-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/linux-64/shellcheck-0.8.0-ha770c72_0.tar.bz2
+ platform: osx-64
+ dependencies:
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/osx-64/backports.zoneinfo-0.2.1-py311h6eed73b_8.conda
hash:
- md5: 0276737172793e3ec3dbc1631840ead7
- sha256: dfeecf516522c4b040ef9e4c6ec9c204d2b09f985f114c6a655522ed6407c27f
+ md5: 82f37234dbc0254423c109e9e21ce332
+ sha256: f6064fc69833fed6d02738d29132bc87a6195098ec74257f53044de306694ff3
category: main
optional: false
-- name: tzdata
- version: 2023c
+- name: billiard
+ version: 4.2.0
manager: conda
platform: linux-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2023c-h71feb2d_0.conda
+ dependencies:
+ libgcc-ng: '>=12'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/billiard-4.2.0-py311h459d7ec_0.conda
hash:
- md5: 939e3e74d8be4dac89ce83b20de2492a
- sha256: 0449138224adfa125b220154408419ec37c06b0b49f63c5954724325903ecf55
+ md5: d408435aabfb23b364dcca868386cf0b
+ sha256: fc947afbd0eb61ac2e98195ae26a1b43b89ffb91b71c43cb0db7b52f131bc60c
category: main
optional: false
-- name: libgomp
- version: 13.2.0
+- name: billiard
+ version: 4.2.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- _libgcc_mutex: '0.1'
- url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h807b86a_3.conda
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/osx-64/billiard-4.2.0-py311he705e18_0.conda
hash:
- md5: 7124cbb46b13d395bdde68f2d215c989
- sha256: 6ebedee39b6bbbc969715d0d7fa4b381cce67e1139862604ffa393f821c08e81
+ md5: fec58d777f1c6d0d680dfbe33c8c959c
+ sha256: b148e75ee6374f5e9ad1174c66761ad46fa20248ce816cf7cdea7d39af500891
category: main
optional: false
-- name: _openmp_mutex
- version: '4.5'
+- name: blinker
+ version: 1.7.0
manager: conda
platform: linux-64
dependencies:
- _libgcc_mutex: '0.1'
- libgomp: '>=7.5.0'
- url: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.7.0-pyhd8ed1ab_0.conda
hash:
- md5: 73aaf86a425cc6e73fcf236a5a46396d
- sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22
+ md5: 550da20b2c2e38be9cc44bb819fda5d5
+ sha256: c8d72c2af4f57898dfd5e4c62ae67f7fea1490a37c8b6855460a170d61591177
category: main
optional: false
-- name: libgcc-ng
- version: 13.2.0
+- name: blinker
+ version: 1.7.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- _libgcc_mutex: '0.1'
- _openmp_mutex: '>=4.5'
- url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h807b86a_3.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.7.0-pyhd8ed1ab_0.conda
hash:
- md5: 23fdf1fef05baeb7eadc2aed5fb0011f
- sha256: 5e88f658e07a30ab41b154b42c59f079b168acfa9551a75bdc972099453f4105
+ md5: 550da20b2c2e38be9cc44bb819fda5d5
+ sha256: c8d72c2af4f57898dfd5e4c62ae67f7fea1490a37c8b6855460a170d61591177
category: main
optional: false
-- name: bzip2
- version: 1.0.8
+- name: boto3
+ version: 1.34.61
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- url: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda
+ botocore: '>=1.34.61,<1.35.0'
+ jmespath: '>=0.7.1,<2.0.0'
+ python: '>=3.8'
+ s3transfer: '>=0.10.0,<0.11.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/boto3-1.34.61-pyhd8ed1ab_1.conda
hash:
- md5: 69b8b6202a07720f448be700e300ccf4
- sha256: 242c0c324507ee172c0e0dd2045814e746bb303d1eb78870d182ceb0abc726a8
+ md5: 0e2e76e883b22b5688f2538f49f415c4
+ sha256: a5460fbc566bc50d421f8fd2cd3b4467785eb604d57e30e5271bd6d00e58edad
category: main
optional: false
-- name: keyutils
- version: 1.6.1
+- name: boto3
+ version: 1.34.61
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- libgcc-ng: '>=10.3.0'
- url: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2
+ python: '>=3.8'
+ jmespath: '>=0.7.1,<2.0.0'
+ s3transfer: '>=0.10.0,<0.11.0'
+ botocore: '>=1.34.61,<1.35.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/boto3-1.34.61-pyhd8ed1ab_1.conda
hash:
- md5: 30186d27e2c9fa62b45fb1476b7200e3
- sha256: 150c05a6e538610ca7c43beb3a40d65c90537497a4f6a5f4d15ec0451b6f5ebb
+ md5: 0e2e76e883b22b5688f2538f49f415c4
+ sha256: a5460fbc566bc50d421f8fd2cd3b4467785eb604d57e30e5271bd6d00e58edad
category: main
optional: false
-- name: libexpat
- version: 2.5.0
+- name: botocore
+ version: 1.34.61
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- url: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda
+ jmespath: '>=0.7.1,<2.0.0'
+ python: '>=3.10'
+ python-dateutil: '>=2.1,<3.0.0'
+ urllib3: '>=1.25.4,<2.1'
+ url: https://conda.anaconda.org/conda-forge/noarch/botocore-1.34.61-pyge310_1234567_0.conda
hash:
- md5: 6305a3dd2752c76335295da4e581f2fd
- sha256: 74c98a563777ae2ad71f1f74d458a8ab043cee4a513467c159ccf159d0e461f3
+ md5: 9049a6fcebd20b5ec96bf9305b15f20f
+ sha256: a9387776de19e09f1235a85818ef5eb5df118e5ac49cd3f92f462091f84ae6ac
category: main
optional: false
-- name: libffi
- version: 3.4.2
+- name: botocore
+ version: 1.34.61
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- libgcc-ng: '>=9.4.0'
- url: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2
+ python-dateutil: '>=2.1,<3.0.0'
+ jmespath: '>=0.7.1,<2.0.0'
+ python: '>=3.10'
+ urllib3: '>=1.25.4,<2.1'
+ url: https://conda.anaconda.org/conda-forge/noarch/botocore-1.34.61-pyge310_1234567_0.conda
hash:
- md5: d645c6d2ac96843a2bfaccd2d62b3ac3
- sha256: ab6e9856c21709b7b517e940ae7028ae0737546122f83c2aa5d692860c3b149e
+ md5: 9049a6fcebd20b5ec96bf9305b15f20f
+ sha256: a9387776de19e09f1235a85818ef5eb5df118e5ac49cd3f92f462091f84ae6ac
category: main
optional: false
-- name: libnsl
- version: 2.0.1
+- name: brotli-python
+ version: 1.1.0
manager: conda
platform: linux-64
dependencies:
libgcc-ng: '>=12'
- url: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda
+ libstdcxx-ng: '>=12'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hb755f60_1.conda
hash:
- md5: 30fd6e37fe21f86f4bd26d6ee73eeec7
- sha256: 26d77a3bb4dceeedc2a41bd688564fe71bf2d149fdcf117049970bc02ff1add6
+ md5: cce9e7c3f1c307f2a5fb08a2922d6164
+ sha256: 559093679e9fdb6061b7b80ca0f9a31fe6ffc213f1dae65bc5c82e2cd1a94107
category: main
optional: false
-- name: libuuid
- version: 2.38.1
+- name: brotli-python
+ version: 1.1.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- libgcc-ng: '>=12'
- url: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda
+ libcxx: '>=15.0.7'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py311hdf8f085_1.conda
hash:
- md5: 40b61aab5c7ba9ff276c41cfffe6b80b
- sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18
+ md5: 546fdccabb90492fbaf2da4ffb78f352
+ sha256: 0f5e0a7de58006f349220365e32db521a1fe494c37ee455e5ecf05b8fe567dcc
category: main
optional: false
-- name: libzlib
- version: 1.2.13
+- name: bump-my-version
+ version: 0.9.3
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda
+ click: ''
+ pydantic: <2.0.0
+ python: '>=3.8'
+ rich: ''
+ rich-click: ''
+ tomlkit: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/bump-my-version-0.9.3-pyhd8ed1ab_0.conda
hash:
- md5: f36c115f1ee199da648e0597ec2047ad
- sha256: 370c7c5893b737596fd6ca0d9190c9715d89d888b8c88537ae1ef168c25e82e4
+ md5: 24f0c263af3783651f77b021a6ad97a8
+ sha256: b5530371b54677cb72d93ae091052327b2c809a6066d85366af4f3f0728888eb
category: main
optional: false
-- name: ncurses
- version: '6.4'
+- name: bump-my-version
+ version: 0.9.3
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- libgcc-ng: '>=12'
- url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-h59595ed_2.conda
+ click: ''
+ rich: ''
+ tomlkit: ''
+ rich-click: ''
+ python: '>=3.8'
+ pydantic: <2.0.0
+ url: https://conda.anaconda.org/conda-forge/noarch/bump-my-version-0.9.3-pyhd8ed1ab_0.conda
hash:
- md5: 7dbaa197d7ba6032caf7ae7f32c1efa0
- sha256: 91cc03f14caf96243cead96c76fe91ab5925a695d892e83285461fb927dece5e
+ md5: 24f0c263af3783651f77b021a6ad97a8
+ sha256: b5530371b54677cb72d93ae091052327b2c809a6066d85366af4f3f0728888eb
category: main
optional: false
-- name: openssl
- version: 3.2.0
+- name: bzip2
+ version: 1.0.8
manager: conda
platform: linux-64
dependencies:
- ca-certificates: ''
libgcc-ng: '>=12'
- url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.2.0-hd590300_1.conda
+ url: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda
hash:
- md5: 603827b39ea2b835268adb8c821b8570
- sha256: 80efc6f429bd8e622d999652e5cba2ca56fcdb9c16a439d2ce9b4313116e4a87
+ md5: 69b8b6202a07720f448be700e300ccf4
+ sha256: 242c0c324507ee172c0e0dd2045814e746bb303d1eb78870d182ceb0abc726a8
category: main
optional: false
-- name: xz
- version: 5.2.6
+- name: bzip2
+ version: 1.0.8
manager: conda
- platform: linux-64
- dependencies:
- libgcc-ng: '>=12'
- url: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2
+ platform: osx-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda
hash:
- md5: 2161070d867d1b1204ea749c8eec4ef0
- sha256: 03a6d28ded42af8a347345f82f3eebdd6807a08526d47899a42d62d319609162
+ md5: 6097a6ca9ada32699b5fc4312dd6ef18
+ sha256: 61fb2b488928a54d9472113e1280b468a309561caa54f33825a3593da390b242
category: main
optional: false
-- name: yaml
- version: 0.2.5
+- name: ca-certificates
+ version: 2024.2.2
manager: conda
platform: linux-64
- dependencies:
- libgcc-ng: '>=9.4.0'
- url: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda
hash:
- md5: 4cb3ad778ec2d5a7acbdf254eb1c42ae
- sha256: a4e34c710eeb26945bdbdaba82d3d74f60a78f54a874ec10d373811a5d217535
+ md5: 2f4327a1cbe7f022401b236e915a5fef
+ sha256: 91d81bfecdbb142c15066df70cc952590ae8991670198f92c66b62019b251aeb
category: main
optional: false
-- name: libedit
- version: 3.1.20191231
+- name: ca-certificates
+ version: 2024.2.2
manager: conda
- platform: linux-64
- dependencies:
- libgcc-ng: '>=7.5.0'
- ncurses: '>=6.2,<7.0.0a0'
- url: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2
+ platform: osx-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.2.2-h8857fd0_0.conda
hash:
- md5: 4d331e44109e3f0e19b4cb8f9b82f3e1
- sha256: a57d37c236d8f7c886e01656f4949d9dcca131d2a0728609c6f7fa338b65f1cf
+ md5: f2eacee8c33c43692f1ccfd33d0f50b1
+ sha256: 54a794aedbb4796afeabdf54287b06b1d27f7b13b3814520925f4c2c80f58ca9
category: main
optional: false
-- name: libsqlite
- version: 3.44.2
+- name: celery
+ version: 5.3.6
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- libzlib: '>=1.2.13,<1.3.0a0'
- url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.44.2-h2797004_0.conda
+ backports.zoneinfo: '>=0.2.1'
+ billiard: '>=4.2.0,<5.0'
+ click: '>=8.1.2,<9.0'
+ click-didyoumean: '>=0.3.0'
+ click-plugins: '>=1.1.1'
+ click-repl: '>=0.2.0'
+ importlib-metadata: '>=3.6'
+ kombu: '>=5.3.4,<6.0'
+ python: '>=3.8'
+ python-dateutil: '>=2.8.2'
+ python-tzdata: '>=2022.7'
+ vine: '>=5.1.0,<6.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/celery-5.3.6-pyhd8ed1ab_0.conda
hash:
- md5: 3b6a9f225c3dbe0d24f4fedd4625c5bf
- sha256: ee2c4d724a3ed60d5b458864d66122fb84c6ce1df62f735f90d8db17b66cd88a
+ md5: f3949418e3578d5cbea5df5d32c5b6ff
+ sha256: bafedd098b75f9baf88167e9bbbbd687fbbc0b06b1a056bdb3bf16221e329def
category: main
optional: false
-- name: readline
- version: '8.2'
+- name: celery
+ version: 5.3.6
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- libgcc-ng: '>=12'
- ncurses: '>=6.3,<7.0a0'
- url: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda
+ python: '>=3.8'
+ backports.zoneinfo: '>=0.2.1'
+ python-dateutil: '>=2.8.2'
+ importlib-metadata: '>=3.6'
+ click-plugins: '>=1.1.1'
+ click-repl: '>=0.2.0'
+ click: '>=8.1.2,<9.0'
+ click-didyoumean: '>=0.3.0'
+ python-tzdata: '>=2022.7'
+ billiard: '>=4.2.0,<5.0'
+ vine: '>=5.1.0,<6.0'
+ kombu: '>=5.3.4,<6.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/celery-5.3.6-pyhd8ed1ab_0.conda
hash:
- md5: 47d31b792659ce70f470b5c82fdfb7a4
- sha256: 5435cf39d039387fbdc977b0a762357ea909a7694d9528ab40f005e9208744d7
+ md5: f3949418e3578d5cbea5df5d32c5b6ff
+ sha256: bafedd098b75f9baf88167e9bbbbd687fbbc0b06b1a056bdb3bf16221e329def
category: main
optional: false
-- name: tk
- version: 8.6.13
+- name: certifi
+ version: 2024.2.2
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- libzlib: '>=1.2.13,<1.3.0a0'
- url: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda
hash:
- md5: d453b98d9c83e71da0741bb0ff4d76bc
- sha256: e0569c9caa68bf476bead1bed3d79650bb080b532c64a4af7d8ca286c08dea4e
+ md5: 0876280e409658fc6f9e75d035960333
+ sha256: f1faca020f988696e6b6ee47c82524c7806380b37cfdd1def32f92c326caca54
category: main
optional: false
-- name: krb5
- version: 1.21.2
+- name: certifi
+ version: 2024.2.2
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- keyutils: '>=1.6.1,<2.0a0'
- libedit: '>=3.1.20191231,<4.0a0'
- libgcc-ng: '>=12'
- libstdcxx-ng: '>=12'
- openssl: '>=3.1.2,<4.0a0'
- url: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda
hash:
- md5: cd95826dbd331ed1be26bdf401432844
- sha256: 259bfaae731989b252b7d2228c1330ef91b641c9d68ff87dae02cbae682cb3e4
+ md5: 0876280e409658fc6f9e75d035960333
+ sha256: f1faca020f988696e6b6ee47c82524c7806380b37cfdd1def32f92c326caca54
category: main
optional: false
-- name: python
- version: 3.11.7
+- name: cffi
+ version: 1.16.0
manager: conda
platform: linux-64
dependencies:
- bzip2: '>=1.0.8,<2.0a0'
- ld_impl_linux-64: '>=2.36.1'
- libexpat: '>=2.5.0,<3.0a0'
libffi: '>=3.4,<4.0a0'
libgcc-ng: '>=12'
- libnsl: '>=2.0.1,<2.1.0a0'
- libsqlite: '>=3.44.2,<4.0a0'
- libuuid: '>=2.38.1,<3.0a0'
- libzlib: '>=1.2.13,<1.3.0a0'
- ncurses: '>=6.4,<7.0a0'
- openssl: '>=3.2.0,<4.0a0'
- readline: '>=8.2,<9.0a0'
- tk: '>=8.6.13,<8.7.0a0'
- tzdata: ''
- xz: '>=5.2.6,<6.0a0'
- url: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.7-hab00c5b_0_cpython.conda
- hash:
- md5: bf281a975393266ab95734a8cfd532ec
- sha256: 3b758231658ab3db25e5f6e3e589419ac0d13f63e2927e75ee34f4b9dd31bc1f
- category: main
- optional: false
-- name: backports.zoneinfo
- version: 0.2.1
- manager: conda
- platform: linux-64
- dependencies:
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/backports.zoneinfo-0.2.1-py311h38be061_8.conda
- hash:
- md5: 5384590f14dfe6ccd02811236afc9f8e
- sha256: 1708c5e6729567f30ccde7761492cb43ee72fa2f7d5065b9102785278718505b
- category: main
- optional: false
-- name: billiard
- version: 4.1.0
- manager: conda
- platform: linux-64
- dependencies:
- libgcc-ng: '>=12'
+ pycparser: ''
python: '>=3.11,<3.12.0a0'
python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/billiard-4.1.0-py311h459d7ec_1.conda
- hash:
- md5: f4042c39668430f920ab9f5b42ca062e
- sha256: b3a3bd417f6e68134d59c7a64508b3d73d7a78894625ed14a9dc827c640beb2e
- category: main
- optional: false
-- name: blinker
- version: 1.7.0
- manager: conda
- platform: linux-64
- dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.7.0-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py311hb3a22ac_0.conda
hash:
- md5: 550da20b2c2e38be9cc44bb819fda5d5
- sha256: c8d72c2af4f57898dfd5e4c62ae67f7fea1490a37c8b6855460a170d61591177
+ md5: b3469563ac5e808b0cd92810d0697043
+ sha256: b71c94528ca0c35133da4b7ef69b51a0b55eeee570376057f3d2ad60c3ab1444
category: main
optional: false
-- name: brotli-python
- version: 1.1.0
+- name: cffi
+ version: 1.16.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- libgcc-ng: '>=12'
- libstdcxx-ng: '>=12'
+ libffi: '>=3.4,<4.0a0'
+ pycparser: ''
python: '>=3.11,<3.12.0a0'
python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hb755f60_1.conda
+ url: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py311hc0b63fd_0.conda
hash:
- md5: cce9e7c3f1c307f2a5fb08a2922d6164
- sha256: 559093679e9fdb6061b7b80ca0f9a31fe6ffc213f1dae65bc5c82e2cd1a94107
+ md5: 15d07b82223cac96af629e5e747ba27a
+ sha256: 1f13a5fa7f310fdbd27f5eddceb9e62cfb10012c58a58c923dd6f51fa979748a
category: main
optional: false
-- name: certifi
- version: 2023.11.17
+- name: cfgv
+ version: 3.3.1
manager: conda
platform: linux-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/certifi-2023.11.17-pyhd8ed1ab_0.conda
+ python: '>=3.6.1'
+ url: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 2011bcf45376341dd1d690263fdbc789
- sha256: afa22b77128a812cb57bc707c297d926561bd225a3d9dd74205d87a3b2d14a96
+ md5: ebb5f5f7dc4f1a3780ef7ea7738db08c
+ sha256: fbc03537a27ef756162c49b1d0608bf7ab12fa5e38ceb8563d6f4859e835ac5c
category: main
optional: false
- name: cfgv
version: 3.3.1
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
python: '>=3.6.1'
url: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_0.tar.bz2
@@ -456,6 +456,18 @@ package:
sha256: 20cae47d31fdd58d99c4d2e65fbdcefa0b0de0c84e455ba9d6356a4bdbc4b5b9
category: main
optional: false
+- name: charset-normalizer
+ version: 3.3.2
+ manager: conda
+ platform: osx-64
+ dependencies:
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda
+ hash:
+ md5: 7f4a9e3fcff3f6356ae99244a014da6a
+ sha256: 20cae47d31fdd58d99c4d2e65fbdcefa0b0de0c84e455ba9d6356a4bdbc4b5b9
+ category: main
+ optional: false
- name: click
version: 8.1.7
manager: conda
@@ -469,1352 +481,1166 @@ package:
sha256: f0016cbab6ac4138a429e28dbcb904a90305b34b3fe41a9b89d697c90401caec
category: main
optional: false
-- name: colorama
- version: 0.4.6
+- name: click
+ version: 8.1.7
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2
+ __unix: ''
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda
hash:
- md5: 3faab06a954c2a04039983f2c4a50d99
- sha256: 2c1b2e9755ce3102bca8d69e8f26e4f087ece73f50418186aee7c74bef8e1698
+ md5: f3ad426304898027fc619827ff428eca
+ sha256: f0016cbab6ac4138a429e28dbcb904a90305b34b3fe41a9b89d697c90401caec
category: main
optional: false
-- name: distlib
- version: 0.3.8
+- name: click-didyoumean
+ version: 0.3.0
manager: conda
platform: linux-64
dependencies:
- python: 2.7|>=3.6
- url: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.8-pyhd8ed1ab_0.conda
+ click: '>=7'
+ python: '>=3.6.2,<4.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/click-didyoumean-0.3.0-pyhd8ed1ab_0.tar.bz2
hash:
- md5: db16c66b759a64dc5183d69cc3745a52
- sha256: 3ff11acdd5cc2f80227682966916e878e45ced94f59c402efb94911a5774e84e
+ md5: a49aa7bc1a82485f6a0a8849dcfefcad
+ sha256: e1af96905976a83f5545b0914830e272415e2e66428165fdf178e73dc4bc9cff
category: main
optional: false
-- name: exceptiongroup
- version: 1.2.0
+- name: click-didyoumean
+ version: 0.3.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_0.conda
+ click: '>=7'
+ python: '>=3.6.2,<4.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/click-didyoumean-0.3.0-pyhd8ed1ab_0.tar.bz2
hash:
- md5: f6c211fee3c98229652b60a9a42ef363
- sha256: cf83dcaf9006015c8ccab3fc6770f478464a66a8769e1763ca5d7dff09d11d08
+ md5: a49aa7bc1a82485f6a0a8849dcfefcad
+ sha256: e1af96905976a83f5545b0914830e272415e2e66428165fdf178e73dc4bc9cff
category: main
optional: false
-- name: filelock
- version: 3.13.1
+- name: click-plugins
+ version: 1.1.1
manager: conda
platform: linux-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/filelock-3.13.1-pyhd8ed1ab_0.conda
+ click: '>=3.0'
+ python: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2
hash:
- md5: 0c1729b74a8152fde6a38ba0a2ab9f45
- sha256: 4d742d91412d1f163e5399d2b50c5d479694ebcd309127abb549ca3977f89d2b
+ md5: 4fd2c6b53934bd7d96d1f3fdaf99b79f
+ sha256: ddef6e559dde6673ee504b0e29dd814d36e22b6b9b1f519fa856ee268905bf92
category: main
optional: false
-- name: greenlet
- version: 3.0.2
+- name: click-plugins
+ version: 1.1.1
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- libgcc-ng: '>=12'
- libstdcxx-ng: '>=12'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.0.2-py311hb755f60_0.conda
+ python: ''
+ click: '>=3.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2
hash:
- md5: 59bf81c0e43e96ff1ebb5140ccc135b5
- sha256: e11f4bf977c21d3c70bb772c57bb800319f1353a8f0bd947f7561e28eae8d808
+ md5: 4fd2c6b53934bd7d96d1f3fdaf99b79f
+ sha256: ddef6e559dde6673ee504b0e29dd814d36e22b6b9b1f519fa856ee268905bf92
category: main
optional: false
-- name: idna
- version: '3.6'
+- name: click-repl
+ version: 0.3.0
manager: conda
platform: linux-64
dependencies:
+ click: ''
+ prompt_toolkit: ''
python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/idna-3.6-pyhd8ed1ab_0.conda
+ six: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/click-repl-0.3.0-pyhd8ed1ab_0.conda
hash:
- md5: 1a76f09108576397c41c0b0c5bd84134
- sha256: 6ee4c986d69ce61e60a20b2459b6f2027baeba153f0a64995fd3cb47c2cc7e07
+ md5: 27eb8f68250666c1a19d1b6ec9d12c4e
+ sha256: 69c16e0b89e1fb4fc444af4798ef1222b3075d074cbcbe70b9af793668200a14
category: main
optional: false
-- name: iniconfig
- version: 2.0.0
+- name: click-repl
+ version: 0.3.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda
+ six: ''
+ click: ''
+ prompt_toolkit: ''
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/click-repl-0.3.0-pyhd8ed1ab_0.conda
hash:
- md5: f800d2da156d08e289b14e87e43c1ae5
- sha256: 38740c939b668b36a50ef455b077e8015b8c9cf89860d421b3fff86048f49666
+ md5: 27eb8f68250666c1a19d1b6ec9d12c4e
+ sha256: 69c16e0b89e1fb4fc444af4798ef1222b3075d074cbcbe70b9af793668200a14
category: main
optional: false
-- name: invoke
- version: 2.0.0
+- name: colorama
+ version: 0.4.6
manager: conda
platform: linux-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/invoke-2.0.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2
hash:
- md5: c282e4567f7b800a855f7092b3c44a5a
- sha256: 637e51d8df0159bae9d67f840a24a5fc7973d48fac09418b01e2fb6f3c03224b
+ md5: 3faab06a954c2a04039983f2c4a50d99
+ sha256: 2c1b2e9755ce3102bca8d69e8f26e4f087ece73f50418186aee7c74bef8e1698
category: main
optional: false
-- name: itsdangerous
- version: 2.1.2
+- name: colorama
+ version: 0.4.6
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.1.2-pyhd8ed1ab_0.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 3c3de74912f11d2b590184f03c7cd09b
- sha256: 31e3492686b4e92b53db9b48bc0eb03873b1caaf28629fee7d2d47627a2c56d3
+ md5: 3faab06a954c2a04039983f2c4a50d99
+ sha256: 2c1b2e9755ce3102bca8d69e8f26e4f087ece73f50418186aee7c74bef8e1698
category: main
optional: false
-- name: jmespath
- version: 1.0.1
+- name: cryptography
+ version: 42.0.5
manager: conda
platform: linux-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/jmespath-1.0.1-pyhd8ed1ab_0.tar.bz2
- hash:
- md5: 2cfa3e1cf3fb51bb9b17acc5b5e9ea11
- sha256: 95ac5f9ee95fd4e34dc051746fc86016d3d4f6abefed113e2ede049d59ec2991
- category: main
- optional: false
-- name: libpq
- version: '16.1'
- manager: conda
- platform: linux-64
- dependencies:
- krb5: '>=1.21.2,<1.22.0a0'
+ cffi: '>=1.12'
libgcc-ng: '>=12'
- openssl: '>=3.2.0,<4.0a0'
- url: https://conda.anaconda.org/conda-forge/linux-64/libpq-16.1-h33b98f1_7.conda
+ openssl: '>=3.2.1,<4.0a0'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/cryptography-42.0.5-py311h63ff55d_0.conda
hash:
- md5: 675317e46167caea24542d85c72f19a3
- sha256: 833fd96338dffc6784fb5f79ab805fa5a4c2cabf5c08c4f1d5caf4e290e39c28
+ md5: 76909c8c7b915f0af4f35e80da5f9a87
+ sha256: d3531a63f2bf9e234a8ebbbcef3dffc0721c8320166e3b86c05e05aef8c02480
category: main
optional: false
-- name: loguru
- version: 0.6.0
+- name: cryptography
+ version: 42.0.5
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
+ __osx: '>=10.12'
+ cffi: '>=1.12'
+ openssl: '>=3.2.1,<4.0a0'
python: '>=3.11,<3.12.0a0'
python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/loguru-0.6.0-py311h38be061_2.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/osx-64/cryptography-42.0.5-py311hda9c3b6_0.conda
hash:
- md5: 8495a2a957bbeacad2c25f277f407f24
- sha256: 202d08801360bd4da179428107cb12ed31816d42acf5d5df179fb2aa55014a1a
+ md5: 493a350a1d4d8099eb16943489a2c664
+ sha256: 28fb0c60e30a3236477c6476683f5f167036e30b829881895e0b98d28337f6b7
category: main
optional: false
-- name: markupsafe
- version: 2.1.3
+- name: distlib
+ version: 0.3.8
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-2.1.3-py311h459d7ec_1.conda
+ python: 2.7|>=3.6
+ url: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.8-pyhd8ed1ab_0.conda
hash:
- md5: 71120b5155a0c500826cf81536721a15
- sha256: e1a9930f35e39bf65bc293e24160b83ebf9f800f02749f65358e1c04882ee6b0
+ md5: db16c66b759a64dc5183d69cc3745a52
+ sha256: 3ff11acdd5cc2f80227682966916e878e45ced94f59c402efb94911a5774e84e
category: main
optional: false
-- name: mdurl
- version: 0.1.0
+- name: distlib
+ version: 0.3.8
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.0-pyhd8ed1ab_0.tar.bz2
+ python: 2.7|>=3.6
+ url: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.8-pyhd8ed1ab_0.conda
hash:
- md5: f8dab71fdc13b1bf29a01248b156d268
- sha256: c678b9194e025b1fb665bec30ee20aab93399203583875b1dcc0a3b52a8f5523
+ md5: db16c66b759a64dc5183d69cc3745a52
+ sha256: 3ff11acdd5cc2f80227682966916e878e45ced94f59c402efb94911a5774e84e
category: main
optional: false
-- name: mypy_extensions
- version: 1.0.0
+- name: exceptiongroup
+ version: 1.2.0
manager: conda
platform: linux-64
dependencies:
- python: '>=3.5'
- url: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda
hash:
- md5: 4eccaeba205f0aed9ac3a9ea58568ca3
- sha256: f240217476e148e825420c6bc3a0c0efb08c0718b7042fae960400c02af858a3
+ md5: 8d652ea2ee8eaee02ed8dc820bc794aa
+ sha256: a6ae416383bda0e3ed14eaa187c653e22bec94ff2aa3b56970cdf0032761e80d
category: main
optional: false
-- name: packaging
- version: '23.2'
+- name: exceptiongroup
+ version: 1.2.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/packaging-23.2-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda
hash:
- md5: 79002079284aa895f883c6b7f3f88fd6
- sha256: 69b3ace6cca2dab9047b2c24926077d81d236bef45329d264b394001e3c3e52f
+ md5: 8d652ea2ee8eaee02ed8dc820bc794aa
+ sha256: a6ae416383bda0e3ed14eaa187c653e22bec94ff2aa3b56970cdf0032761e80d
category: main
optional: false
-- name: platformdirs
- version: 4.1.0
+- name: filelock
+ version: 3.13.1
manager: conda
platform: linux-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.1.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/filelock-3.13.1-pyhd8ed1ab_0.conda
hash:
- md5: 45a5065664da0d1dfa8f8cd2eaf05ab9
- sha256: 9e4ff17ce802159ed31344eb913eaa877688226765b77947b102b42255a53853
+ md5: 0c1729b74a8152fde6a38ba0a2ab9f45
+ sha256: 4d742d91412d1f163e5399d2b50c5d479694ebcd309127abb549ca3977f89d2b
category: main
optional: false
-- name: pluggy
- version: 1.3.0
+- name: filelock
+ version: 3.13.1
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.3.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/filelock-3.13.1-pyhd8ed1ab_0.conda
hash:
- md5: 2390bd10bed1f3fdc7a537fb5a447d8d
- sha256: 7bf2ad9d747e71f1e93d0863c2c8061dd0f2fe1e582f28d292abfb40264a2eb5
+ md5: 0c1729b74a8152fde6a38ba0a2ab9f45
+ sha256: 4d742d91412d1f163e5399d2b50c5d479694ebcd309127abb549ca3977f89d2b
category: main
optional: false
-- name: psutil
- version: 5.9.7
+- name: flask
+ version: 2.2.5
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.7-py311h459d7ec_0.conda
+ celery: '>=5.2.7'
+ click: '>=8.0'
+ importlib-metadata: '>=3.6.0'
+ itsdangerous: '>=2.0'
+ jinja2: '>=3.0'
+ python: '>=3.7'
+ werkzeug: '>=2.2.2'
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-2.2.5-pyhd8ed1ab_0.conda
hash:
- md5: b4f2d78860bf9c8887b528c10995b427
- sha256: a2f08e5bcca5e067c452708d5ce6389c1012c7b6139ffe26b3386674f036eb27
+ md5: 66c558a28b9b47c1e2aa8e8cb80b9037
+ sha256: 9356ae47278788439770eb9d05bfeb72c39a53a8b10a0e534b612f99b9c18e9b
category: main
optional: false
-- name: pycparser
- version: '2.21'
+- name: flask
+ version: 2.2.5
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: 2.7.*|>=3.4
- url: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2
+ python: '>=3.7'
+ jinja2: '>=3.0'
+ click: '>=8.0'
+ importlib-metadata: '>=3.6.0'
+ itsdangerous: '>=2.0'
+ werkzeug: '>=2.2.2'
+ celery: '>=5.2.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-2.2.5-pyhd8ed1ab_0.conda
hash:
- md5: 076becd9e05608f8dc72757d5f3a91ff
- sha256: 74c63fd03f1f1ea2b54e8bc529fd1a600aaafb24027b738d0db87909ee3a33dc
+ md5: 66c558a28b9b47c1e2aa8e8cb80b9037
+ sha256: 9356ae47278788439770eb9d05bfeb72c39a53a8b10a0e534b612f99b9c18e9b
category: main
optional: false
-- name: pygments
- version: 2.17.2
+- name: flask-dance
+ version: 7.0.0
manager: conda
platform: linux-64
dependencies:
+ flask: '>=2.0.3'
+ oauthlib: '>=3.2'
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/pygments-2.17.2-pyhd8ed1ab_0.conda
+ requests: '>=2.0'
+ requests-oauthlib: '>=1.0.0'
+ urlobject: ''
+ werkzeug: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-dance-7.0.0-pyhd8ed1ab_0.conda
hash:
- md5: 140a7f159396547e9799aa98f9f0742e
- sha256: af5f8867450dc292f98ea387d4d8945fc574284677c8f60eaa9846ede7387257
+ md5: a0007a17aa03b39c941f921f082afe9e
+ sha256: 7f3b75ba7f321c9058e0adbd4113fe3bfad3fc28ea266fb42f7636091cd4ca34
category: main
optional: false
-- name: pyjwt
- version: 2.8.0
+- name: flask-dance
+ version: 7.0.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/pyjwt-2.8.0-pyhd8ed1ab_0.conda
+ werkzeug: ''
+ urlobject: ''
+ python: '>=3.7'
+ requests-oauthlib: '>=1.0.0'
+ requests: '>=2.0'
+ flask: '>=2.0.3'
+ oauthlib: '>=3.2'
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-dance-7.0.0-pyhd8ed1ab_0.conda
hash:
- md5: 912c0194f898fdb783021fd25f913c31
- sha256: 88ac94c42ade15113397e30d1831dd341399b5262fb5330b9240f915c33cd232
+ md5: a0007a17aa03b39c941f921f082afe9e
+ sha256: 7f3b75ba7f321c9058e0adbd4113fe3bfad3fc28ea266fb42f7636091cd4ca34
category: main
optional: false
-- name: pysocks
- version: 1.7.1
+- name: flask-login
+ version: 0.6.3
manager: conda
platform: linux-64
dependencies:
- __unix: ''
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2
+ flask: '>=1.0.4'
+ python: '>=3.7'
+ werkzeug: '>=1.0.1'
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-login-0.6.3-pyhd8ed1ab_1.conda
hash:
- md5: 2a7de29fb590ca14b5243c4c812c8025
- sha256: a42f826e958a8d22e65b3394f437af7332610e43ee313393d1cf143f0a2d274b
+ md5: 1d3523e7b18b38e4be992bf462d99e40
+ sha256: 23ffed52801132e3e434c82a544ef1b77efbc025878a1a1cd0fbcc4c361cd9de
category: main
optional: false
-- name: python-dotenv
- version: 1.0.0
+- name: flask-login
+ version: 0.6.3
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.0-pyhd8ed1ab_1.conda
+ python: '>=3.7'
+ flask: '>=1.0.4'
+ werkzeug: '>=1.0.1'
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-login-0.6.3-pyhd8ed1ab_1.conda
hash:
- md5: 111e7f9edd31865e2659fa9aad8ec8fd
- sha256: bc5663f224ff6d8a399ec6bd8517e0c0f87a69ead438f82e5ce5c30f00077586
+ md5: 1d3523e7b18b38e4be992bf462d99e40
+ sha256: 23ffed52801132e3e434c82a544ef1b77efbc025878a1a1cd0fbcc4c361cd9de
category: main
optional: false
-- name: python-tzdata
- version: '2023.3'
+- name: flask-sqlalchemy
+ version: 3.0.3
manager: conda
platform: linux-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2023.3-pyhd8ed1ab_0.conda
+ flask: '>=2.2'
+ python: '>=3.7'
+ sqlalchemy: '>=1.4.18'
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-sqlalchemy-3.0.3-pyhd8ed1ab_0.conda
hash:
- md5: 2590495f608a63625e165915fb4e2e34
- sha256: 0108888507014fb24573c31e4deceb61c99e63d37776dddcadd7c89b2ecae0b6
+ md5: 6a301e2aa76aef91787e15f59ab03390
+ sha256: 460693607ab0e2feb600bb755851c0c19db8d6dbd1c7636904c8de6f2c63040d
category: main
optional: false
-- name: pytz
- version: 2023.3.post1
+- name: flask-sqlalchemy
+ version: 3.0.3
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ flask: '>=2.2'
+ sqlalchemy: '>=1.4.18'
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-sqlalchemy-3.0.3-pyhd8ed1ab_0.conda
hash:
- md5: c93346b446cd08c169d843ae5fc0da97
- sha256: 6b680e63d69aaf087cd43ca765a23838723ef59b0a328799e6363eb13f52c49e
+ md5: 6a301e2aa76aef91787e15f59ab03390
+ sha256: 460693607ab0e2feb600bb755851c0c19db8d6dbd1c7636904c8de6f2c63040d
category: main
optional: false
-- name: pyyaml
- version: 6.0.1
+- name: flask-wtf
+ version: 1.2.1
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- yaml: '>=0.2.5,<0.3.0a0'
- url: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda
+ flask: ''
+ itsdangerous: ''
+ python: '>=3.8'
+ wtforms: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-wtf-1.2.1-pyhd8ed1ab_0.conda
hash:
- md5: 52719a74ad130de8fb5d047dc91f247a
- sha256: 28729ef1ffa7f6f9dfd54345a47c7faac5d34296d66a2b9891fb147f4efe1348
+ md5: e7b75c25f98d7b55943466683e400529
+ sha256: cee583240eec93d27f262f3bb8cdecf8334e502d81923295d98f378b15fe26d5
category: main
optional: false
-- name: setuptools
- version: 68.2.2
+- name: flask-wtf
+ version: 1.2.1
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/setuptools-68.2.2-pyhd8ed1ab_0.conda
+ flask: ''
+ itsdangerous: ''
+ wtforms: ''
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/flask-wtf-1.2.1-pyhd8ed1ab_0.conda
hash:
- md5: fc2166155db840c634a1291a5c35a709
- sha256: 851901b1f8f2049edb36a675f0c3f9a98e1495ef4eb214761b048c6f696a06f7
+ md5: e7b75c25f98d7b55943466683e400529
+ sha256: cee583240eec93d27f262f3bb8cdecf8334e502d81923295d98f378b15fe26d5
category: main
optional: false
-- name: six
- version: 1.16.0
+- name: gmp
+ version: 6.3.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: ''
- url: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2
+ libcxx: '>=16'
+ url: https://conda.anaconda.org/conda-forge/osx-64/gmp-6.3.0-h73e2aa4_1.conda
hash:
- md5: e5f25f8dbc060e9a8d912e432202afc2
- sha256: a85c38227b446f42c5b90d9b642f2c0567880c15d72492d8da074a59c8f91dd6
+ md5: 92f8d748d95d97f92fc26cfac9bb5b6e
+ sha256: 1a5b117908deb5a12288aba84dd0cb913f779c31c75f5a57d1a00e659e8fa3d3
category: main
optional: false
-- name: tomli
- version: 2.0.1
+- name: greenlet
+ version: 3.0.3
manager: conda
platform: linux-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2
+ libgcc-ng: '>=12'
+ libstdcxx-ng: '>=12'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.0.3-py311hb755f60_0.conda
hash:
- md5: 5844808ffab9ebdb694585b50ba02a96
- sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f
+ md5: 6f4b03b4d1e0da0962ea02113382677c
+ sha256: e6228b46b15ee3f54592c8a1fc1bf3846d519719ac65c238c20e21eb431971ec
category: main
optional: false
-- name: tomlkit
- version: 0.12.3
+- name: greenlet
+ version: 3.0.3
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.12.3-pyha770c72_0.conda
+ libcxx: '>=15'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/osx-64/greenlet-3.0.3-py311hdd0406b_0.conda
hash:
- md5: 074d0ce7a6261ab8b497c3518796ef3e
- sha256: 53cc436ab92d38683df1320e4468a8b978428e800195bf1c8c2460e90b0bc117
+ md5: 4f538c462a4fed3aa89ea7993506c478
+ sha256: 472971e11c0a4bffdad925523ae524361567a6428e7d5e38a76fadc59eaa8efc
category: main
optional: false
-- name: types-markdown
- version: 3.5.0.3
+- name: gunicorn
+ version: 21.2.0
manager: conda
platform: linux-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/types-markdown-3.5.0.3-pyhd8ed1ab_0.conda
+ packaging: ''
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ setuptools: '>=3.0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/gunicorn-21.2.0-py311h38be061_1.conda
hash:
- md5: 9a78be2f67528371edc1bf3f908530b8
- sha256: a64b305419e2f0d537c42aa9c30285e31e41b852904e85d25243f9bc9a4c6d2d
+ md5: 6ffcdfe45b9b37a4a735d03a71b1a708
+ sha256: b5d204fe26ad7e4b2a4b40761b12ec1f54fa63e498001ad14a75821e0f19297d
category: main
optional: false
-- name: typing_extensions
- version: 4.9.0
+- name: gunicorn
+ version: 21.2.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.9.0-pyha770c72_0.conda
+ packaging: ''
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ setuptools: '>=3.0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/gunicorn-21.2.0-py311h6eed73b_1.conda
hash:
- md5: a92a6440c3fe7052d63244f3aba2a4a7
- sha256: f3c5be8673bfd905c4665efcb27fa50192f24f84fa8eff2f19cba5d09753d905
+ md5: f818ed3365dbee71c75368587fc976b3
+ sha256: dd5e241c4f1ad7982ea6aa5bc2cb5c03ce35af6a73ecc1a86c4dbb621ed12c68
category: main
optional: false
-- name: urlobject
- version: 2.4.3
+- name: identify
+ version: 2.5.35
manager: conda
platform: linux-64
dependencies:
- python: ''
- url: https://conda.anaconda.org/conda-forge/noarch/urlobject-2.4.3-py_1.tar.bz2
+ python: '>=3.6'
+ ukkonen: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.35-pyhd8ed1ab_0.conda
hash:
- md5: 91140cccf570095e69d84b58075bc9b2
- sha256: 21354dad71b83bf6d0224f962565018c055f2d7f60205851491b9ff8f1d04936
+ md5: 9472bfd206a2b7bb8143835e37667054
+ sha256: 971683b13d1b820157bef9993c63dd8b0611d2d60fc4b522da163aee2e70e518
category: main
optional: false
-- name: vine
- version: 5.0.0
+- name: identify
+ version: 2.5.35
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
+ ukkonen: ''
python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/vine-5.0.0-pyhd8ed1ab_1.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.35-pyhd8ed1ab_0.conda
hash:
- md5: 7cb5b514698cfd164ad5103e58e1e201
- sha256: 53e1239bd2ef11f75d381ba6944d8339a247e42d088de87b9d9f751ddf7176bc
+ md5: 9472bfd206a2b7bb8143835e37667054
+ sha256: 971683b13d1b820157bef9993c63dd8b0611d2d60fc4b522da163aee2e70e518
category: main
optional: false
-- name: wcwidth
- version: 0.2.12
+- name: idna
+ version: '3.6'
manager: conda
platform: linux-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.12-pyhd8ed1ab_0.conda
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/idna-3.6-pyhd8ed1ab_0.conda
hash:
- md5: bf4a1d1a97ca27b0b65bacd9e238b484
- sha256: ca757d0fc2dbd422af9d3238a8b4b630a6e11df3707a447bd89540656770d1d7
+ md5: 1a76f09108576397c41c0b0c5bd84134
+ sha256: 6ee4c986d69ce61e60a20b2459b6f2027baeba153f0a64995fd3cb47c2cc7e07
category: main
optional: false
-- name: wheel
- version: 0.42.0
+- name: idna
+ version: '3.6'
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.42.0-pyhd8ed1ab_0.conda
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/idna-3.6-pyhd8ed1ab_0.conda
hash:
- md5: 1cdea58981c5cbc17b51973bcaddcea7
- sha256: 80be0ccc815ce22f80c141013302839b0ed938a2edb50b846cf48d8a8c1cfa01
+ md5: 1a76f09108576397c41c0b0c5bd84134
+ sha256: 6ee4c986d69ce61e60a20b2459b6f2027baeba153f0a64995fd3cb47c2cc7e07
category: main
optional: false
-- name: zipp
- version: 3.17.0
+- name: importlib-metadata
+ version: 7.0.2
manager: conda
platform: linux-64
dependencies:
python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda
+ zipp: '>=0.5'
+ url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.0.2-pyha770c72_0.conda
hash:
- md5: 2e4d6bc0b14e10f895fc6791a7d9b26a
- sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26
+ md5: b050a4bb0e90ebd6e7fa4093d6346867
+ sha256: 9a26136d2cc81ccac209d6ae24281ceba3365fe34e34b2c45570f2a96e9d9c1b
category: main
optional: false
-- name: amqp
- version: 5.2.0
+- name: importlib-metadata
+ version: 7.0.2
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- python: '>=3.6'
- vine: 5.0.0
- url: https://conda.anaconda.org/conda-forge/noarch/amqp-5.2.0-pyhd8ed1ab_0.conda
+ python: '>=3.8'
+ zipp: '>=0.5'
+ url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.0.2-pyha770c72_0.conda
hash:
- md5: 7ab12cc04a0596a8ab937e9d211503cc
- sha256: 9993eb1df7e4a9a4e59c82a87495ab03762c94801f7c4bb8db922ca28681c126
+ md5: b050a4bb0e90ebd6e7fa4093d6346867
+ sha256: 9a26136d2cc81ccac209d6ae24281ceba3365fe34e34b2c45570f2a96e9d9c1b
category: main
optional: false
-- name: cffi
- version: 1.16.0
+- name: iniconfig
+ version: 2.0.0
manager: conda
platform: linux-64
dependencies:
- libffi: '>=3.4,<4.0a0'
- libgcc-ng: '>=12'
- pycparser: ''
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py311hb3a22ac_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda
hash:
- md5: b3469563ac5e808b0cd92810d0697043
- sha256: b71c94528ca0c35133da4b7ef69b51a0b55eeee570376057f3d2ad60c3ab1444
+ md5: f800d2da156d08e289b14e87e43c1ae5
+ sha256: 38740c939b668b36a50ef455b077e8015b8c9cf89860d421b3fff86048f49666
category: main
optional: false
-- name: click-didyoumean
- version: 0.3.0
+- name: iniconfig
+ version: 2.0.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- click: '>=7'
- python: '>=3.6.2,<4.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/click-didyoumean-0.3.0-pyhd8ed1ab_0.tar.bz2
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda
hash:
- md5: a49aa7bc1a82485f6a0a8849dcfefcad
- sha256: e1af96905976a83f5545b0914830e272415e2e66428165fdf178e73dc4bc9cff
+ md5: f800d2da156d08e289b14e87e43c1ae5
+ sha256: 38740c939b668b36a50ef455b077e8015b8c9cf89860d421b3fff86048f49666
category: main
optional: false
-- name: click-plugins
- version: 1.1.1
+- name: invoke
+ version: 2.0.0
manager: conda
platform: linux-64
dependencies:
- click: '>=3.0'
- python: ''
- url: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/invoke-2.0.0-pyhd8ed1ab_0.conda
hash:
- md5: 4fd2c6b53934bd7d96d1f3fdaf99b79f
- sha256: ddef6e559dde6673ee504b0e29dd814d36e22b6b9b1f519fa856ee268905bf92
+ md5: c282e4567f7b800a855f7092b3c44a5a
+ sha256: 637e51d8df0159bae9d67f840a24a5fc7973d48fac09418b01e2fb6f3c03224b
category: main
optional: false
-- name: gunicorn
- version: 21.2.0
+- name: invoke
+ version: 2.0.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- packaging: ''
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- setuptools: '>=3.0'
- url: https://conda.anaconda.org/conda-forge/linux-64/gunicorn-21.2.0-py311h38be061_1.conda
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/invoke-2.0.0-pyhd8ed1ab_0.conda
hash:
- md5: 6ffcdfe45b9b37a4a735d03a71b1a708
- sha256: b5d204fe26ad7e4b2a4b40761b12ec1f54fa63e498001ad14a75821e0f19297d
+ md5: c282e4567f7b800a855f7092b3c44a5a
+ sha256: 637e51d8df0159bae9d67f840a24a5fc7973d48fac09418b01e2fb6f3c03224b
category: main
optional: false
-- name: importlib-metadata
- version: 7.0.0
+- name: itsdangerous
+ version: 2.1.2
manager: conda
platform: linux-64
dependencies:
- python: '>=3.8'
- zipp: '>=0.5'
- url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.0.0-pyha770c72_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.1.2-pyhd8ed1ab_0.tar.bz2
hash:
- md5: a941237cd06538837b25cd245fcd25d8
- sha256: 9731e82a00d36b182dc515e31723e711ac82890bb1ca86c6a17a4b471135564f
+ md5: 3c3de74912f11d2b590184f03c7cd09b
+ sha256: 31e3492686b4e92b53db9b48bc0eb03873b1caaf28629fee7d2d47627a2c56d3
category: main
optional: false
-- name: jinja2
- version: 3.1.2
+- name: itsdangerous
+ version: 2.1.2
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- markupsafe: '>=2.0'
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.2-pyhd8ed1ab_1.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.1.2-pyhd8ed1ab_0.tar.bz2
hash:
- md5: c8490ed5c70966d232fdd389d0dbed37
- sha256: b045faba7130ab263db6a8fdc96b1a3de5fcf85c4a607c5f11a49e76851500b5
+ md5: 3c3de74912f11d2b590184f03c7cd09b
+ sha256: 31e3492686b4e92b53db9b48bc0eb03873b1caaf28629fee7d2d47627a2c56d3
category: main
optional: false
-- name: markdown-it-py
- version: 3.0.0
+- name: jinja2
+ version: 3.1.3
manager: conda
platform: linux-64
dependencies:
- mdurl: '>=0.1,<1'
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda
+ markupsafe: '>=2.0'
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.3-pyhd8ed1ab_0.conda
hash:
- md5: 93a8e71256479c62074356ef6ebf501b
- sha256: c041b0eaf7a6af3344d5dd452815cdc148d6284fec25a4fa3f4263b3a021e962
+ md5: e7d8df6509ba635247ff9aea31134262
+ sha256: fd517b7dd3a61eca34f8a6f9f92f306397149cae1204fce72ac3d227107dafdc
category: main
optional: false
-- name: mypy
- version: 1.7.1
+- name: jinja2
+ version: 3.1.3
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- libgcc-ng: '>=12'
- mypy_extensions: '>=1.0.0'
- psutil: '>=4.0'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- typing_extensions: '>=4.1.0'
- url: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.7.1-py311h459d7ec_1.conda
+ python: '>=3.7'
+ markupsafe: '>=2.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.3-pyhd8ed1ab_0.conda
hash:
- md5: 0a861b29266afe8c315ecdcb92f9e692
- sha256: 8c9365ecf8e56666253f987ba83d1dcde141ef3d0f73300a92adf5aa63c8e5bd
+ md5: e7d8df6509ba635247ff9aea31134262
+ sha256: fd517b7dd3a61eca34f8a6f9f92f306397149cae1204fce72ac3d227107dafdc
category: main
optional: false
-- name: nodeenv
- version: 1.8.0
+- name: jmespath
+ version: 1.0.1
manager: conda
platform: linux-64
dependencies:
- python: 2.7|>=3.7
- setuptools: ''
- url: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.8.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/jmespath-1.0.1-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 2a75b296096adabbabadd5e9782e5fcc
- sha256: 1320306234552717149f36f825ddc7e27ea295f24829e9db4cc6ceaff0b032bd
+ md5: 2cfa3e1cf3fb51bb9b17acc5b5e9ea11
+ sha256: 95ac5f9ee95fd4e34dc051746fc86016d3d4f6abefed113e2ede049d59ec2991
category: main
optional: false
-- name: pip
- version: 23.3.2
+- name: jmespath
+ version: 1.0.1
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
python: '>=3.7'
- setuptools: ''
- wheel: ''
- url: https://conda.anaconda.org/conda-forge/noarch/pip-23.3.2-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/jmespath-1.0.1-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 8591c748f98dcc02253003533bc2e4b1
- sha256: 29096d1d53c61aeef518729add2f405df86b3629d1d738a35b15095e6a02eeed
+ md5: 2cfa3e1cf3fb51bb9b17acc5b5e9ea11
+ sha256: 95ac5f9ee95fd4e34dc051746fc86016d3d4f6abefed113e2ede049d59ec2991
category: main
optional: false
-- name: prompt-toolkit
- version: 3.0.42
+- name: keyutils
+ version: 1.6.1
manager: conda
platform: linux-64
dependencies:
- python: '>=3.7'
- wcwidth: ''
- url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda
+ libgcc-ng: '>=10.3.0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2
hash:
- md5: 0bf64bf10eee21f46ac83c161917fa86
- sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16
+ md5: 30186d27e2c9fa62b45fb1476b7200e3
+ sha256: 150c05a6e538610ca7c43beb3a40d65c90537497a4f6a5f4d15ec0451b6f5ebb
category: main
optional: false
-- name: psycopg2
- version: 2.9.9
+- name: kombu
+ version: 5.3.5
manager: conda
platform: linux-64
dependencies:
- libgcc-ng: '>=12'
- libpq: '>=16.1,<17.0a0'
+ amqp: '>=5.1.1,<6.0.0'
+ boto3: '>=1.26.143'
python: '>=3.11,<3.12.0a0'
python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/psycopg2-2.9.9-py311h03dec38_0.conda
+ vine: ''
+ url: https://conda.anaconda.org/conda-forge/linux-64/kombu-5.3.5-py311h38be061_0.conda
hash:
- md5: 3cc2decd316838bce14d73818e0bf7a4
- sha256: 4e78d9fe1799d028d9a2da3636a3a68a531aeca5d2c679d4fc78627a426b11cb
+ md5: 00508fb0af467a4b7ac70f4bf3825c81
+ sha256: 9da60412961f4e0b224f08825a041c8e1446753fb733265606b81f5746568cb9
category: main
optional: false
-- name: pytest
- version: 7.4.3
+- name: kombu
+ version: 5.3.5
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- colorama: ''
- exceptiongroup: '>=1.0.0rc8'
- iniconfig: ''
- packaging: ''
- pluggy: '>=0.12,<2.0'
- python: '>=3.7'
- tomli: '>=1.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/pytest-7.4.3-pyhd8ed1ab_0.conda
+ amqp: '>=5.1.1,<6.0.0'
+ boto3: '>=1.26.143'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ vine: ''
+ url: https://conda.anaconda.org/conda-forge/osx-64/kombu-5.3.5-py311h6eed73b_0.conda
hash:
- md5: 5bdca0aca30b0ee62bb84854e027eae0
- sha256: 14e948e620ec87d9e62a8d9c21d40084b4805a939cfee322be7d457379dc96a0
+ md5: 87d591ff96c71329c6430b5ad63d9d85
+ sha256: 917244687c06ecf3c3754075eb546f0d897b284eaf134c1ca29151ddadecdaaf
category: main
optional: false
-- name: python-dateutil
- version: 2.8.2
+- name: krb5
+ version: 1.21.2
manager: conda
platform: linux-64
dependencies:
- python: '>=3.6'
- six: '>=1.5'
- url: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2
+ keyutils: '>=1.6.1,<2.0a0'
+ libedit: '>=3.1.20191231,<4.0a0'
+ libgcc-ng: '>=12'
+ libstdcxx-ng: '>=12'
+ openssl: '>=3.1.2,<4.0a0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda
hash:
- md5: dd999d1cc9f79e67dbb855c8924c7984
- sha256: 54d7785c7678166aa45adeaccfc1d2b8c3c799ca2dc05d4a82bb39b1968bd7da
- category: main
+ md5: cd95826dbd331ed1be26bdf401432844
+ sha256: 259bfaae731989b252b7d2228c1330ef91b641c9d68ff87dae02cbae682cb3e4
+ category: main
optional: false
-- name: sqlalchemy
- version: 1.4.49
+- name: krb5
+ version: 1.21.2
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- greenlet: '!=0.4.17'
- libgcc-ng: '>=12'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/sqlalchemy-1.4.49-py311h459d7ec_1.conda
+ libcxx: '>=15.0.7'
+ libedit: '>=3.1.20191231,<4.0a0'
+ openssl: '>=3.1.2,<4.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.2-hb884880_0.conda
hash:
- md5: 17392bcb4ceac1b2c95db9d54b4ac018
- sha256: 542dea4823e2e1283936fbd25c9f3fa960ec6df2dd54589b192b4dac68af7295
+ md5: 80505a68783f01dc8d7308c075261b2f
+ sha256: 081ae2008a21edf57c048f331a17c65d1ccb52d6ca2f87ee031a73eff4dc0fc6
category: main
optional: false
-- name: typing-extensions
- version: 4.9.0
+- name: ld_impl_linux-64
+ version: '2.40'
manager: conda
platform: linux-64
- dependencies:
- typing_extensions: 4.9.0
- url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.9.0-hd8ed1ab_0.conda
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h41732ed_0.conda
hash:
- md5: c16524c1b7227dc80b36b4fa6f77cc86
- sha256: d795c1eb1db4ea147f01ece74e5a504d7c2e8d5ee8c11ec987884967dd938f9c
+ md5: 7aca3059a1729aa76c597603f10b0dd3
+ sha256: f6cc89d887555912d6c61b295d398cff9ec982a3417d38025c45d5dd9b9e79cd
category: main
optional: false
-- name: urllib3
- version: 1.26.18
+- name: libcxx
+ version: 16.0.6
manager: conda
- platform: linux-64
- dependencies:
- brotli-python: '>=1.0.9'
- pysocks: '>=1.5.6,<2.0,!=1.5.7'
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/urllib3-1.26.18-pyhd8ed1ab_0.conda
+ platform: osx-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/libcxx-16.0.6-hd57cbcb_0.conda
hash:
- md5: bf61cfd2a7f212efba378167a07d4a6a
- sha256: 1cc0bab65a6ad0f5a8bd7657760a4fb4e670d30377f9dab88b792977cb3687e7
+ md5: 7d6972792161077908b62971802f289a
+ sha256: 9063271847cf05f3a6cc6cae3e7f0ced032ab5f3a3c9d3f943f876f39c5c2549
category: main
optional: false
-- name: virtualenv
- version: 20.25.0
+- name: libedit
+ version: 3.1.20191231
manager: conda
platform: linux-64
dependencies:
- distlib: <1,>=0.3.7
- filelock: <4,>=3.12.2
- platformdirs: <5,>=3.9.1
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.25.0-pyhd8ed1ab_0.conda
+ libgcc-ng: '>=7.5.0'
+ ncurses: '>=6.2,<7.0.0a0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2
hash:
- md5: c119653cba436d8183c27bf6d190e587
- sha256: 50827c3721a9dbf973b568709d4381add2a6552fa562f26a385c5edc16a534af
+ md5: 4d331e44109e3f0e19b4cb8f9b82f3e1
+ sha256: a57d37c236d8f7c886e01656f4949d9dcca131d2a0728609c6f7fa338b65f1cf
category: main
optional: false
-- name: werkzeug
- version: 2.2.3
+- name: libedit
+ version: 3.1.20191231
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- markupsafe: '>=2.1.1'
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-2.2.3-pyhd8ed1ab_0.conda
+ ncurses: '>=6.2,<7.0.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20191231-h0678c8f_2.tar.bz2
hash:
- md5: 94dea682ba9d8e091e1f46872886fb1f
- sha256: 38f68541580b74ed91396a67766fb96088f7b161bfd203675ed7a257d642e2e3
+ md5: 6016a8a1d0e63cac3de2c352cd40208b
+ sha256: dbd3c3f2eca1d21c52e4c03b21930bbce414c4592f8ce805801575b9e9256095
category: main
optional: false
-- name: wtforms
- version: 3.0.1
+- name: libexpat
+ version: 2.6.1
manager: conda
platform: linux-64
dependencies:
- markupsafe: ''
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/wtforms-3.0.1-pyhd8ed1ab_0.tar.bz2
+ libgcc-ng: '>=12'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.1-h59595ed_0.conda
hash:
- md5: 62a19155ee3896566849634586c1813d
- sha256: fc6bc71fc1bd5966ad024a1c828652b9a1ceee06ea514a94968b9b53492e3abe
+ md5: 476fb82aba5358a08d52ec44e286ce33
+ sha256: 1c993845e8c25545565f50ab74511276a519e969acc406603e3f4539a14288b2
category: main
optional: false
-- name: annotated-types
- version: 0.6.0
+- name: libexpat
+ version: 2.6.1
manager: conda
- platform: linux-64
- dependencies:
- python: '>=3.7'
- typing-extensions: '>=4.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.6.0-pyhd8ed1ab_0.conda
+ platform: osx-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.6.1-h73e2aa4_0.conda
hash:
- md5: 997c29372bdbe2afee073dff71f35923
- sha256: 3a2c98154d95cfd54daba6b7d507d31f5ba07ac2ad955c44eb041b66563193cd
+ md5: 1596476cfdb3183d820afb9293f412e1
+ sha256: 677471f90d844fcf6c9eae49ecbb812bdd87a6a272ffa69fcc322d6b71b4c060
category: main
optional: false
-- name: botocore
- version: 1.34.2
+- name: libffi
+ version: 3.4.2
manager: conda
platform: linux-64
dependencies:
- jmespath: '>=0.7.1,<2.0.0'
- python: '>=3.8'
- python-dateutil: '>=2.1,<3.0.0'
- urllib3: '>=1.25.4,<1.27'
- url: https://conda.anaconda.org/conda-forge/noarch/botocore-1.34.2-pyhd8ed1ab_0.conda
+ libgcc-ng: '>=9.4.0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2
hash:
- md5: 90d807074ce872ffb1e20ea0e7c76c10
- sha256: e404de75c98ee31d06b52c631078df97f77e50ebcb644758c22ec86fcca2d6c4
+ md5: d645c6d2ac96843a2bfaccd2d62b3ac3
+ sha256: ab6e9856c21709b7b517e940ae7028ae0737546122f83c2aa5d692860c3b149e
category: main
optional: false
-- name: cryptography
- version: 41.0.7
+- name: libffi
+ version: 3.4.2
manager: conda
- platform: linux-64
- dependencies:
- cffi: '>=1.12'
- libgcc-ng: '>=12'
- openssl: '>=3.1.4,<4.0a0'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/cryptography-41.0.7-py311hcb13ee4_1.conda
+ platform: osx-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2
hash:
- md5: ca6e04ac7262ecaec846e483d6fdc6c8
- sha256: 0959d015727ae5f55f385556a0a19b9f6036752ea05f78a99cb534803e325cab
+ md5: ccb34fb14960ad8b125962d3d79b31a9
+ sha256: 7a2d27a936ceee6942ea4d397f9c7d136f12549d86f7617e8b6bad51e01a941f
category: main
optional: false
-- name: markdown
- version: 3.5.1
+- name: libgcc-ng
+ version: 13.2.0
manager: conda
platform: linux-64
dependencies:
- importlib-metadata: '>=4.4'
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.1-pyhd8ed1ab_0.conda
+ _libgcc_mutex: '0.1'
+ _openmp_mutex: '>=4.5'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h807b86a_5.conda
hash:
- md5: 323495027ffa625701129acebf861412
- sha256: 35e8990504cf8dc7e2bb63efd855fb0a0d5c0d77bf79403235e757c24a83ec1d
+ md5: d4ff227c46917d3b4565302a2bbb276b
+ sha256: d32f78bfaac282cfe5205f46d558704ad737b8dbf71f9227788a5ca80facaba4
category: main
optional: false
-- name: prompt_toolkit
- version: 3.0.42
+- name: libgomp
+ version: 13.2.0
manager: conda
platform: linux-64
dependencies:
- prompt-toolkit: '>=3.0.42,<3.0.43.0a0'
- url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda
+ _libgcc_mutex: '0.1'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h807b86a_5.conda
hash:
- md5: 85a2189ecd2fcdd86e92b2d4ea8fe461
- sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d
+ md5: d211c42b9ce49aee3734fdc828731689
+ sha256: 0d3d4b1b0134283ea02d58e8eb5accf3655464cf7159abf098cc694002f8d34e
category: main
optional: false
-- name: pydantic
- version: 1.10.13
+- name: libnsl
+ version: 2.0.1
manager: conda
platform: linux-64
dependencies:
libgcc-ng: '>=12'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- typing-extensions: '>=4.2.0'
- url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-1.10.13-py311h459d7ec_1.conda
+ url: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda
hash:
- md5: 8a92f40420211897a35841861e7e8348
- sha256: f2d3a838fc90699c5dcd537aff10c78b33bd755232d0b21b26247cbf185cced7
+ md5: 30fd6e37fe21f86f4bd26d6ee73eeec7
+ sha256: 26d77a3bb4dceeedc2a41bd688564fe71bf2d149fdcf117049970bc02ff1add6
category: main
optional: false
-- name: pydantic-core
- version: 2.14.5
+- name: libpq
+ version: '16.2'
manager: conda
platform: linux-64
dependencies:
+ krb5: '>=1.21.2,<1.22.0a0'
libgcc-ng: '>=12'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- typing-extensions: '>=4.6.0'
- url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.14.5-py311h46250e7_0.conda
+ openssl: '>=3.2.1,<4.0a0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libpq-16.2-h33b98f1_0.conda
hash:
- md5: 9b2d1233d958079649cc8f91d814e04f
- sha256: c546a042316c34bf6b9c5e16da4e6993f6712554c0ac5ee3f49260260789c38f
+ md5: fe0e297faf462ee579c95071a5211665
+ sha256: 352748b0499a22e2a8e103f071b8d9357e1fb710c0aec0f79895d3ba03dccb03
category: main
optional: false
-- name: requests
- version: 2.31.0
+- name: libpq
+ version: '16.2'
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- certifi: '>=2017.4.17'
- charset-normalizer: '>=2,<4'
- idna: '>=2.5,<4'
- python: '>=3.7'
- urllib3: '>=1.21.1,<3'
- url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda
+ krb5: '>=1.21.2,<1.22.0a0'
+ openssl: '>=3.2.1,<4.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/libpq-16.2-ha925e61_0.conda
hash:
- md5: a30144e4156cdbb236f99ebb49828f8b
- sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad
+ md5: 8b81f4feaa3744271fcf2822ad1489f1
+ sha256: 537b3816ac66f12c56fc62a67d896703b68f7588a5d83ab98009731de82eb742
category: main
optional: false
-- name: rich
- version: 13.7.0
+- name: libsqlite
+ version: 3.45.2
manager: conda
platform: linux-64
dependencies:
- markdown-it-py: '>=2.2.0'
- pygments: '>=2.13.0,<3.0.0'
- python: '>=3.7.0'
- typing_extensions: '>=4.0.0,<5.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.0-pyhd8ed1ab_0.conda
+ libgcc-ng: '>=12'
+ libzlib: '>=1.2.13,<1.3.0a0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.2-h2797004_0.conda
hash:
- md5: d7a11d4f3024b2f4a6e0ae7377dd61e9
- sha256: 4bb25bf1f5664772b2c4c2e3878aa6e7dc2695f97e3da4ee8e47c51e179913bb
+ md5: 866983a220e27a80cb75e85cb30466a1
+ sha256: 8cdbeb7902729e319510a82d7c642402981818702b58812af265ef55d1315473
category: main
optional: false
-- name: ukkonen
- version: 1.0.1
+- name: libsqlite
+ version: 3.45.2
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- cffi: ''
- libgcc-ng: '>=12'
- libstdcxx-ng: '>=12'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.0.1-py311h9547e67_4.conda
+ libzlib: '>=1.2.13,<1.3.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.2-h92b6c6a_0.conda
hash:
- md5: 586da7df03b68640de14dc3e8bcbf76f
- sha256: c2d33e998f637b594632eba3727529171a06eb09896e36aa42f1ebcb03779472
+ md5: 086f56e13a96a6cfb1bf640505ae6b70
+ sha256: 320ec73a4e3dd377757a2595770b8137ec4583df4d7782472d76377cdbdc4543
category: main
optional: false
-- name: click-repl
- version: 0.3.0
+- name: libstdcxx-ng
+ version: 13.2.0
manager: conda
platform: linux-64
- dependencies:
- click: ''
- prompt_toolkit: ''
- python: '>=3.6'
- six: ''
- url: https://conda.anaconda.org/conda-forge/noarch/click-repl-0.3.0-pyhd8ed1ab_0.conda
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-h7e041cc_5.conda
hash:
- md5: 27eb8f68250666c1a19d1b6ec9d12c4e
- sha256: 69c16e0b89e1fb4fc444af4798ef1222b3075d074cbcbe70b9af793668200a14
+ md5: f6f6600d18a4047b54f803cf708b868a
+ sha256: a56c5b11f1e73a86e120e6141a42d9e935a99a2098491ac9e15347a1476ce777
category: main
optional: false
-- name: identify
- version: 2.5.33
+- name: libuuid
+ version: 2.38.1
manager: conda
platform: linux-64
dependencies:
- python: '>=3.6'
- ukkonen: ''
- url: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.33-pyhd8ed1ab_0.conda
+ libgcc-ng: '>=12'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda
hash:
- md5: 93c8f8ceb83827d88deeba796f07fba7
- sha256: ce2a64c18221af96226be23278d81f22ff9f64b3c047d8865590f6718915303f
+ md5: 40b61aab5c7ba9ff276c41cfffe6b80b
+ sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18
category: main
optional: false
-- name: oauthlib
- version: 3.2.2
+- name: libxcrypt
+ version: 4.4.36
manager: conda
platform: linux-64
dependencies:
- blinker: ''
- cryptography: ''
- pyjwt: '>=1.0.0'
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.2.2-pyhd8ed1ab_0.tar.bz2
+ libgcc-ng: '>=12'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda
hash:
- md5: 8f882b197fd9c4941a787926baea4868
- sha256: 0cfd5146a91d3974f4abfc2a45de890371d510a77238fe553e036ec8c031dc5b
+ md5: 5aa797f8787fe7a17d1b0821485b5adc
+ sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c
category: main
optional: false
-- name: pydantic-settings
- version: 2.1.0
+- name: libzlib
+ version: 1.2.13
manager: conda
platform: linux-64
dependencies:
- pydantic: '>=2.3.0'
- python: '>=3.8'
- python-dotenv: '>=0.21.0'
- url: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.1.0-pyhd8ed1ab_1.conda
+ libgcc-ng: '>=12'
+ url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda
hash:
- md5: 2a63052c1180846d4a6aaa9df7e113a3
- sha256: 2c80df34463dabec383b37dc19da48f84a1ea97f3d828d6d0dd220110da5f4e1
+ md5: f36c115f1ee199da648e0597ec2047ad
+ sha256: 370c7c5893b737596fd6ca0d9190c9715d89d888b8c88537ae1ef168c25e82e4
category: main
optional: false
-- name: pyopenssl
- version: 23.3.0
+- name: libzlib
+ version: 1.2.13
manager: conda
- platform: linux-64
- dependencies:
- cryptography: '>=41.0.5,<42'
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-23.3.0-pyhd8ed1ab_0.conda
+ platform: osx-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda
hash:
- md5: 7819533e674dbbc51468f3228b9b1bb6
- sha256: f7e04c4a49b1593140231d70801e2204e314e26d7141bfbdc8089d04114c0010
+ md5: 4a3ad23f6e16f99c04e166767193d700
+ sha256: fc58ad7f47ffea10df1f2165369978fba0a1cc32594aad778f5eec725f334867
category: main
optional: false
-- name: rich-click
- version: 1.7.2
+- name: loguru
+ version: 0.6.0
manager: conda
platform: linux-64
dependencies:
- click: '>=7,<9'
- python: '>=3.7'
- rich: '>=10'
- url: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.7.2-pyhd8ed1ab_0.conda
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/loguru-0.6.0-py311h38be061_2.tar.bz2
hash:
- md5: fe1eae76a71246959cefd09b5b00869b
- sha256: 4bfddbc5716a09bfea1c3345b1eed0ddb36d0e55f357afb60ca3e73c9231cc68
+ md5: 8495a2a957bbeacad2c25f277f407f24
+ sha256: 202d08801360bd4da179428107cb12ed31816d42acf5d5df179fb2aa55014a1a
category: main
optional: false
-- name: s3transfer
- version: 0.9.0
+- name: loguru
+ version: 0.6.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- botocore: '>=1.33.2,<2.0a.0'
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/s3transfer-0.9.0-pyhd8ed1ab_0.conda
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/osx-64/loguru-0.6.0-py311h6eed73b_2.tar.bz2
hash:
- md5: 27ad14e5fc6a13f05b90140debc72cd2
- sha256: c9fc315d830238113160471467259740593966bcf59f17287a0baeaf1f6a76d8
+ md5: fc9dde292b3ec1251e63aac5434cc47c
+ sha256: f74d200ffa50c455fbe631ca6564fe5b80c64ab314ec832528cfcdfad2a119d7
category: main
optional: false
-- name: boto3
- version: 1.34.2
+- name: markdown
+ version: 3.5.2
manager: conda
platform: linux-64
dependencies:
- botocore: '>=1.34.2,<1.35.0'
- jmespath: '>=0.7.1,<2.0.0'
- python: '>=3.8'
- s3transfer: '>=0.9.0,<0.10.0'
- url: https://conda.anaconda.org/conda-forge/noarch/boto3-1.34.2-pyhd8ed1ab_0.conda
+ importlib-metadata: '>=4.4'
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.2-pyhd8ed1ab_0.conda
hash:
- md5: 6f47ce30284317cb85960c4668cc5bd9
- sha256: c0444d9d386a1991fadca8b31b9dfc302e5d781b8a2d29faff2c47286eff477c
+ md5: db7b48fa4eeb0c21b2f3f5b1f7d9ebcf
+ sha256: fbc70dc01b361fe46e7b4e102e725f99ba60bf9903c2fa86b53ad6b70ded677a
category: main
optional: false
-- name: bump-my-version
- version: 0.9.3
+- name: markdown
+ version: 3.5.2
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- click: ''
- pydantic: <2.0.0
- python: '>=3.8'
- rich: ''
- rich-click: ''
- tomlkit: ''
- url: https://conda.anaconda.org/conda-forge/noarch/bump-my-version-0.9.3-pyhd8ed1ab_0.conda
+ python: '>=3.6'
+ importlib-metadata: '>=4.4'
+ url: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.2-pyhd8ed1ab_0.conda
hash:
- md5: 24f0c263af3783651f77b021a6ad97a8
- sha256: b5530371b54677cb72d93ae091052327b2c809a6066d85366af4f3f0728888eb
+ md5: db7b48fa4eeb0c21b2f3f5b1f7d9ebcf
+ sha256: fbc70dc01b361fe46e7b4e102e725f99ba60bf9903c2fa86b53ad6b70ded677a
category: main
optional: false
-- name: pre-commit
- version: 3.6.0
+- name: markdown-it-py
+ version: 3.0.0
manager: conda
platform: linux-64
dependencies:
- cfgv: '>=2.0.0'
- identify: '>=1.0.0'
- nodeenv: '>=0.11.1'
- python: '>=3.9'
- pyyaml: '>=5.1'
- virtualenv: '>=20.10.0'
- url: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.6.0-pyha770c72_0.conda
+ mdurl: '>=0.1,<1'
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda
hash:
- md5: 473a7cfca197da0a10cff3f6dded7d4b
- sha256: 7d1f4b4a2eb4946b5808769642c5f643788c3a9e090f1c02a6c63f8794fb3d54
+ md5: 93a8e71256479c62074356ef6ebf501b
+ sha256: c041b0eaf7a6af3344d5dd452815cdc148d6284fec25a4fa3f4263b3a021e962
category: main
optional: false
-- name: requests-oauthlib
- version: 1.3.1
+- name: markdown-it-py
+ version: 3.0.0
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- oauthlib: '>=3.0.0'
- python: '>=3.4'
- requests: '>=2.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/requests-oauthlib-1.3.1-pyhd8ed1ab_0.tar.bz2
+ python: '>=3.8'
+ mdurl: '>=0.1,<1'
+ url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda
hash:
- md5: 61b279f051eef9c89d58f4d813e75e04
- sha256: 889e3c1b84467b64046776db95dc4c5ea4dad5afaa5ec18ad811bd95c63286b0
+ md5: 93a8e71256479c62074356ef6ebf501b
+ sha256: c041b0eaf7a6af3344d5dd452815cdc148d6284fec25a4fa3f4263b3a021e962
category: main
optional: false
-- name: kombu
- version: 5.3.4
+- name: markupsafe
+ version: 2.1.5
manager: conda
platform: linux-64
dependencies:
- amqp: '>=5.1.1,<6.0.0'
- boto3: '>=1.26.143'
+ libgcc-ng: '>=12'
python: '>=3.11,<3.12.0a0'
python_abi: 3.11.*
- vine: ''
- url: https://conda.anaconda.org/conda-forge/linux-64/kombu-5.3.4-py311h38be061_0.conda
+ url: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-2.1.5-py311h459d7ec_0.conda
hash:
- md5: f087b47105e900808597549e7eaf4237
- sha256: 7c49b1464cfe67f79f083eadb578ebe5f5facda153be0fbfa1a24938f30476be
+ md5: a322b4185121935c871d201ae00ac143
+ sha256: 14912e557a6576e03f65991be89e9d289c6e301921b6ecfb4e7186ba974f453d
category: main
optional: false
-- name: celery
- version: 5.3.4
+- name: markupsafe
+ version: 2.1.5
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- backports.zoneinfo: '>=0.2.1'
- billiard: '>=4.1.0,<5.0'
- click: '>=8.1.2,<9.0'
- click-didyoumean: '>=0.3.0'
- click-plugins: '>=1.1.1'
- click-repl: '>=0.2.0'
- importlib-metadata: '>=3.6'
- kombu: '>=5.3.2,<6.0'
- python: '>=3.7'
- python-dateutil: '>=2.8.2'
- python-tzdata: '>=2022.7'
- pytz: '>=2021.3'
- vine: '>=5.0.0,<6.0'
- url: https://conda.anaconda.org/conda-forge/noarch/celery-5.3.4-pyhd8ed1ab_1.conda
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-2.1.5-py311he705e18_0.conda
hash:
- md5: 64a66acef34f7cca60b929b8228951f1
- sha256: b93109413da956e6e2a37b0a852ccb15a45f706c7ce718f9ea094c660b18b5e3
+ md5: 75abe7e2e3a0874a49d7c175115f443f
+ sha256: 83a2b764a4946a04e693a4dd8fe5a35bf093a378da9ce18bf0689cd5dcb3c3fe
category: main
optional: false
-- name: flask
- version: 2.2.5
+- name: mdurl
+ version: 0.1.2
manager: conda
platform: linux-64
dependencies:
- celery: '>=5.2.7'
- click: '>=8.0'
- importlib-metadata: '>=3.6.0'
- itsdangerous: '>=2.0'
- jinja2: '>=3.0'
- python: '>=3.7'
- werkzeug: '>=2.2.2'
- url: https://conda.anaconda.org/conda-forge/noarch/flask-2.2.5-pyhd8ed1ab_0.conda
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda
hash:
- md5: 66c558a28b9b47c1e2aa8e8cb80b9037
- sha256: 9356ae47278788439770eb9d05bfeb72c39a53a8b10a0e534b612f99b9c18e9b
+ md5: 776a8dd9e824f77abac30e6ef43a8f7a
+ sha256: 64073dfb6bb429d52fff30891877b48c7ec0f89625b1bf844905b66a81cce6e1
category: main
optional: false
-- name: flask-dance
- version: 7.0.0
+- name: mdurl
+ version: 0.1.2
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- flask: '>=2.0.3'
- oauthlib: '>=3.2'
- python: '>=3.7'
- requests: '>=2.0'
- requests-oauthlib: '>=1.0.0'
- urlobject: ''
- werkzeug: ''
- url: https://conda.anaconda.org/conda-forge/noarch/flask-dance-7.0.0-pyhd8ed1ab_0.conda
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda
hash:
- md5: a0007a17aa03b39c941f921f082afe9e
- sha256: 7f3b75ba7f321c9058e0adbd4113fe3bfad3fc28ea266fb42f7636091cd4ca34
+ md5: 776a8dd9e824f77abac30e6ef43a8f7a
+ sha256: 64073dfb6bb429d52fff30891877b48c7ec0f89625b1bf844905b66a81cce6e1
category: main
optional: false
-- name: flask-login
- version: 0.6.3
+- name: mypy
+ version: 1.7.1
manager: conda
platform: linux-64
dependencies:
- flask: '>=1.0.4'
- python: '>=3.7'
- werkzeug: '>=1.0.1'
- url: https://conda.anaconda.org/conda-forge/noarch/flask-login-0.6.3-pyhd8ed1ab_1.conda
+ libgcc-ng: '>=12'
+ mypy_extensions: '>=1.0.0'
+ psutil: '>=4.0'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ typing_extensions: '>=4.1.0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.7.1-py311h459d7ec_1.conda
hash:
- md5: 1d3523e7b18b38e4be992bf462d99e40
- sha256: 23ffed52801132e3e434c82a544ef1b77efbc025878a1a1cd0fbcc4c361cd9de
+ md5: 0a861b29266afe8c315ecdcb92f9e692
+ sha256: 8c9365ecf8e56666253f987ba83d1dcde141ef3d0f73300a92adf5aa63c8e5bd
category: main
optional: false
-- name: flask-sqlalchemy
- version: 3.0.3
+- name: mypy
+ version: 1.7.1
manager: conda
- platform: linux-64
+ platform: osx-64
dependencies:
- flask: '>=2.2'
- python: '>=3.7'
- sqlalchemy: '>=1.4.18'
- url: https://conda.anaconda.org/conda-forge/noarch/flask-sqlalchemy-3.0.3-pyhd8ed1ab_0.conda
+ mypy_extensions: '>=1.0.0'
+ psutil: '>=4.0'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ typing_extensions: '>=4.1.0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.7.1-py311he705e18_1.conda
hash:
- md5: 6a301e2aa76aef91787e15f59ab03390
- sha256: 460693607ab0e2feb600bb755851c0c19db8d6dbd1c7636904c8de6f2c63040d
+ md5: 153e0baec2f2d6c0bb6c9692f623ecdb
+ sha256: f9c25d9de38057167a10d4873e8ad7bcb9b9a8b5d1d3195421dac3445fb16b26
category: main
optional: false
-- name: flask-wtf
- version: 1.2.1
+- name: mypy_extensions
+ version: 1.0.0
manager: conda
platform: linux-64
dependencies:
- flask: ''
- itsdangerous: ''
- python: '>=3.8'
- wtforms: ''
- url: https://conda.anaconda.org/conda-forge/noarch/flask-wtf-1.2.1-pyhd8ed1ab_0.conda
- hash:
- md5: e7b75c25f98d7b55943466683e400529
- sha256: cee583240eec93d27f262f3bb8cdecf8334e502d81923295d98f378b15fe26d5
- category: main
- optional: false
-- name: bootstrap-flask
- version: 2.3.3
- manager: pip
- platform: linux-64
- dependencies:
- flask: '*'
- wtforms: '*'
- url: https://files.pythonhosted.org/packages/95/e4/7f3dd2dba1ef70ddbf1bf6a58ea8245c20b2d44bd81e8b37215e812f5d0e/Bootstrap_Flask-2.3.3-py2.py3-none-any.whl
- hash:
- sha256: 4c3d1f1b8ee19081dfc80e03aba5cb19cd92a8d54ba0ba98cee69acffded91d0
- category: main
- optional: false
-- name: wtforms-sqlalchemy
- version: '0.3'
- manager: pip
- platform: linux-64
- dependencies:
- wtforms: '>=1.0.5'
- sqlalchemy: '>=0.7.10'
- url: https://files.pythonhosted.org/packages/62/71/a5624ff63f4024d27489263b56e3ab6a5122087eb432d14617cfed90ec3d/WTForms_SQLAlchemy-0.3-py3-none-any.whl
- hash:
- sha256: 90195d7592bf256d82498c42c79d416832e4a4e6fbca4f1e745a018f66d26c47
- category: main
- optional: false
-- name: bzip2
- version: 1.0.8
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda
- hash:
- md5: 6097a6ca9ada32699b5fc4312dd6ef18
- sha256: 61fb2b488928a54d9472113e1280b468a309561caa54f33825a3593da390b242
- category: main
- optional: false
-- name: ca-certificates
- version: 2023.11.17
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2023.11.17-h8857fd0_0.conda
- hash:
- md5: c687e9d14c49e3d3946d50a413cdbf16
- sha256: 7e05d80a97beb7cb7492fae38584a68d51f338a5eddf73a14b5bd266597db90e
- category: main
- optional: false
-- name: libcxx
- version: 16.0.6
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/libcxx-16.0.6-hd57cbcb_0.conda
- hash:
- md5: 7d6972792161077908b62971802f289a
- sha256: 9063271847cf05f3a6cc6cae3e7f0ced032ab5f3a3c9d3f943f876f39c5c2549
- category: main
- optional: false
-- name: libexpat
- version: 2.5.0
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.5.0-hf0c8a7f_1.conda
- hash:
- md5: 6c81cb022780ee33435cca0127dd43c9
- sha256: 80024bd9f44d096c4cc07fb2bac76b5f1f7553390112dab3ad6acb16a05f0b96
- category: main
- optional: false
-- name: libffi
- version: 3.4.2
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2
- hash:
- md5: ccb34fb14960ad8b125962d3d79b31a9
- sha256: 7a2d27a936ceee6942ea4d397f9c7d136f12549d86f7617e8b6bad51e01a941f
- category: main
- optional: false
-- name: libzlib
- version: 1.2.13
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda
- hash:
- md5: 4a3ad23f6e16f99c04e166767193d700
- sha256: fc58ad7f47ffea10df1f2165369978fba0a1cc32594aad778f5eec725f334867
- category: main
- optional: false
-- name: python_abi
- version: '3.11'
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/python_abi-3.11-4_cp311.conda
- hash:
- md5: fef7a52f0eca6bae9e8e2e255bc86394
- sha256: f56dfe2a57b3b27bad3f9527f943548e8b2526e949d9d6fc0a383020d9359afe
- category: main
- optional: false
-- name: tzdata
- version: 2023c
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2023c-h71feb2d_0.conda
- hash:
- md5: 939e3e74d8be4dac89ce83b20de2492a
- sha256: 0449138224adfa125b220154408419ec37c06b0b49f63c5954724325903ecf55
- category: main
- optional: false
-- name: xz
- version: 5.2.6
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2
- hash:
- md5: a72f9d4ea13d55d745ff1ed594747f10
- sha256: eb09823f34cc2dd663c0ec4ab13f246f45dcd52e5b8c47b9864361de5204a1c8
- category: main
- optional: false
-- name: yaml
- version: 0.2.5
- manager: conda
- platform: osx-64
- dependencies: {}
- url: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2
+ python: '>=3.5'
+ url: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda
hash:
- md5: d7e08fcf8259d742156188e8762b4d20
- sha256: 5301417e2c8dea45b401ffee8df3957d2447d4ce80c83c5ff151fc6bfe1c4148
+ md5: 4eccaeba205f0aed9ac3a9ea58568ca3
+ sha256: f240217476e148e825420c6bc3a0c0efb08c0718b7042fae960400c02af858a3
category: main
optional: false
-- name: gmp
- version: 6.3.0
+- name: mypy_extensions
+ version: 1.0.0
manager: conda
platform: osx-64
dependencies:
- __osx: '>=10.9'
- libcxx: '>=16.0.6'
- url: https://conda.anaconda.org/conda-forge/osx-64/gmp-6.3.0-h93d8f39_0.conda
+ python: '>=3.5'
+ url: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda
hash:
- md5: a4ffd4bfd88659cbecbd36b61594bf0d
- sha256: 49443e6c41070e3967936c7f09b7686d3dd715f3351918c4edfd8072e1776013
+ md5: 4eccaeba205f0aed9ac3a9ea58568ca3
+ sha256: f240217476e148e825420c6bc3a0c0efb08c0718b7042fae960400c02af858a3
category: main
optional: false
-- name: libsqlite
- version: 3.44.2
+- name: ncurses
+ version: '6.4'
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- libzlib: '>=1.2.13,<1.3.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.44.2-h92b6c6a_0.conda
+ libgcc-ng: '>=12'
+ url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-h59595ed_2.conda
hash:
- md5: d4419f90019e6a2b152cd4d32f73a82f
- sha256: 8a317d2aa6352feba951ca09d5bf34f565f9dd10bb14ff842b8650baa321d781
+ md5: 7dbaa197d7ba6032caf7ae7f32c1efa0
+ sha256: 91cc03f14caf96243cead96c76fe91ab5925a695d892e83285461fb927dece5e
category: main
optional: false
- name: ncurses
@@ -1829,448 +1655,391 @@ package:
sha256: ea0fca66bbb52a1ef0687d466518fe120b5f279684effd6fd336a7b0dddc423a
category: main
optional: false
-- name: openssl
- version: 3.2.0
- manager: conda
- platform: osx-64
- dependencies:
- ca-certificates: ''
- url: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.2.0-hd75f5a5_1.conda
- hash:
- md5: 06cb561619487c88891839b9beb5244c
- sha256: 99161bf349f5dc80322f2a2c188588d11efa662566e4e19f2ac0a36d9fa3de25
- category: main
- optional: false
-- name: tk
- version: 8.6.13
- manager: conda
- platform: osx-64
- dependencies:
- libzlib: '>=1.2.13,<1.3.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda
- hash:
- md5: bf830ba5afc507c6232d4ef0fb1a882d
- sha256: 30412b2e9de4ff82d8c2a7e5d06a15f4f4fef1809a72138b6ccb53a33b26faf5
- category: main
- optional: false
-- name: libedit
- version: 3.1.20191231
- manager: conda
- platform: osx-64
- dependencies:
- ncurses: '>=6.2,<7.0.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20191231-h0678c8f_2.tar.bz2
- hash:
- md5: 6016a8a1d0e63cac3de2c352cd40208b
- sha256: dbd3c3f2eca1d21c52e4c03b21930bbce414c4592f8ce805801575b9e9256095
- category: main
- optional: false
-- name: readline
- version: '8.2'
+- name: nodeenv
+ version: 1.8.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- ncurses: '>=6.3,<7.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda
+ python: 2.7|>=3.7
+ setuptools: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.8.0-pyhd8ed1ab_0.conda
hash:
- md5: f17f77f2acf4d344734bda76829ce14e
- sha256: 41e7d30a097d9b060037f0c6a2b1d4c4ae7e942c06c943d23f9d481548478568
+ md5: 2a75b296096adabbabadd5e9782e5fcc
+ sha256: 1320306234552717149f36f825ddc7e27ea295f24829e9db4cc6ceaff0b032bd
category: main
optional: false
-- name: shellcheck
- version: 0.8.0
+- name: nodeenv
+ version: 1.8.0
manager: conda
platform: osx-64
dependencies:
- gmp: '>=6.2.1,<7.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/shellcheck-0.8.0-h7dd6a17_0.tar.bz2
+ setuptools: ''
+ python: 2.7|>=3.7
+ url: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.8.0-pyhd8ed1ab_0.conda
hash:
- md5: b5a30a0ff9f7b85fe4e3195bc12d4b66
- sha256: 9ae08b408c7c352be4dd927b50eb7c2b11d9053409f21c8ed608ac04636edcf6
+ md5: 2a75b296096adabbabadd5e9782e5fcc
+ sha256: 1320306234552717149f36f825ddc7e27ea295f24829e9db4cc6ceaff0b032bd
category: main
optional: false
-- name: krb5
- version: 1.21.2
+- name: oauthlib
+ version: 3.2.2
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- libcxx: '>=15.0.7'
- libedit: '>=3.1.20191231,<4.0a0'
- openssl: '>=3.1.2,<4.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.2-hb884880_0.conda
+ blinker: ''
+ cryptography: ''
+ pyjwt: '>=1.0.0'
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.2.2-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 80505a68783f01dc8d7308c075261b2f
- sha256: 081ae2008a21edf57c048f331a17c65d1ccb52d6ca2f87ee031a73eff4dc0fc6
+ md5: 8f882b197fd9c4941a787926baea4868
+ sha256: 0cfd5146a91d3974f4abfc2a45de890371d510a77238fe553e036ec8c031dc5b
category: main
optional: false
-- name: python
- version: 3.11.7
+- name: oauthlib
+ version: 3.2.2
manager: conda
platform: osx-64
dependencies:
- bzip2: '>=1.0.8,<2.0a0'
- libexpat: '>=2.5.0,<3.0a0'
- libffi: '>=3.4,<4.0a0'
- libsqlite: '>=3.44.2,<4.0a0'
- libzlib: '>=1.2.13,<1.3.0a0'
- ncurses: '>=6.4,<7.0a0'
- openssl: '>=3.2.0,<4.0a0'
- readline: '>=8.2,<9.0a0'
- tk: '>=8.6.13,<8.7.0a0'
- tzdata: ''
- xz: '>=5.2.6,<6.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.7-h9f0c242_0_cpython.conda
+ cryptography: ''
+ blinker: ''
+ python: '>=3.6'
+ pyjwt: '>=1.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.2.2-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 0c5df462c5510f1cc3fae7ba627d63d2
- sha256: 2ad1b68caa61682c6a893b0474f45354cda45e38185945e6b439aa18dff6e9fd
+ md5: 8f882b197fd9c4941a787926baea4868
+ sha256: 0cfd5146a91d3974f4abfc2a45de890371d510a77238fe553e036ec8c031dc5b
category: main
optional: false
-- name: backports.zoneinfo
- version: 0.2.1
+- name: openssl
+ version: 3.2.1
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/backports.zoneinfo-0.2.1-py311h6eed73b_8.conda
+ ca-certificates: ''
+ libgcc-ng: '>=12'
+ url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.2.1-hd590300_0.conda
hash:
- md5: 82f37234dbc0254423c109e9e21ce332
- sha256: f6064fc69833fed6d02738d29132bc87a6195098ec74257f53044de306694ff3
+ md5: 51a753e64a3027bd7e23a189b1f6e91e
+ sha256: c02c12bdb898daacf7eb3d09859f93ea8f285fd1a6132ff6ff0493ab52c7fe57
category: main
optional: false
-- name: billiard
- version: 4.1.0
+- name: openssl
+ version: 3.2.1
manager: conda
platform: osx-64
dependencies:
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/billiard-4.1.0-py311h2725bcf_1.conda
+ ca-certificates: ''
+ url: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.2.1-hd75f5a5_0.conda
hash:
- md5: 60ad2305d46ca7281d2a9a05dabf194f
- sha256: 3a8f8c8423cc3148c694084d78270a2dd32090de9e22d003d4fba0e9386a5b73
+ md5: 3033be9a59fd744172b03971b9ccd081
+ sha256: 20c1b1a34a1831c24d37ed1500ca07300171184af0c66598f3c5ca901634d713
category: main
optional: false
-- name: blinker
- version: 1.7.0
+- name: packaging
+ version: '24.0'
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.7.0-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda
hash:
- md5: 550da20b2c2e38be9cc44bb819fda5d5
- sha256: c8d72c2af4f57898dfd5e4c62ae67f7fea1490a37c8b6855460a170d61591177
+ md5: 248f521b64ce055e7feae3105e7abeb8
+ sha256: a390182d74c31dfd713c16db888c92c277feeb6d1fe96ff9d9c105f9564be48a
category: main
optional: false
-- name: brotli-python
- version: 1.1.0
+- name: packaging
+ version: '24.0'
manager: conda
platform: osx-64
dependencies:
- libcxx: '>=15.0.7'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py311hdf8f085_1.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda
hash:
- md5: 546fdccabb90492fbaf2da4ffb78f352
- sha256: 0f5e0a7de58006f349220365e32db521a1fe494c37ee455e5ecf05b8fe567dcc
+ md5: 248f521b64ce055e7feae3105e7abeb8
+ sha256: a390182d74c31dfd713c16db888c92c277feeb6d1fe96ff9d9c105f9564be48a
category: main
optional: false
-- name: certifi
- version: 2023.11.17
+- name: pip
+ version: '24.0'
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/certifi-2023.11.17-pyhd8ed1ab_0.conda
- hash:
- md5: 2011bcf45376341dd1d690263fdbc789
- sha256: afa22b77128a812cb57bc707c297d926561bd225a3d9dd74205d87a3b2d14a96
- category: main
- optional: false
-- name: cfgv
- version: 3.3.1
- manager: conda
- platform: osx-64
- dependencies:
- python: '>=3.6.1'
- url: https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_0.tar.bz2
+ setuptools: ''
+ wheel: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda
hash:
- md5: ebb5f5f7dc4f1a3780ef7ea7738db08c
- sha256: fbc03537a27ef756162c49b1d0608bf7ab12fa5e38ceb8563d6f4859e835ac5c
+ md5: f586ac1e56c8638b64f9c8122a7b8a67
+ sha256: b7c1c5d8f13e8cb491c4bd1d0d1896a4cf80fc47de01059ad77509112b664a4a
category: main
optional: false
-- name: charset-normalizer
- version: 3.3.2
+- name: pip
+ version: '24.0'
manager: conda
platform: osx-64
dependencies:
+ setuptools: ''
+ wheel: ''
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda
hash:
- md5: 7f4a9e3fcff3f6356ae99244a014da6a
- sha256: 20cae47d31fdd58d99c4d2e65fbdcefa0b0de0c84e455ba9d6356a4bdbc4b5b9
+ md5: f586ac1e56c8638b64f9c8122a7b8a67
+ sha256: b7c1c5d8f13e8cb491c4bd1d0d1896a4cf80fc47de01059ad77509112b664a4a
category: main
optional: false
-- name: click
- version: 8.1.7
+- name: platformdirs
+ version: 4.2.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- __unix: ''
python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda
- hash:
- md5: f3ad426304898027fc619827ff428eca
- sha256: f0016cbab6ac4138a429e28dbcb904a90305b34b3fe41a9b89d697c90401caec
- category: main
- optional: false
-- name: colorama
- version: 0.4.6
- manager: conda
- platform: osx-64
- dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.0-pyhd8ed1ab_0.conda
hash:
- md5: 3faab06a954c2a04039983f2c4a50d99
- sha256: 2c1b2e9755ce3102bca8d69e8f26e4f087ece73f50418186aee7c74bef8e1698
- category: main
- optional: false
-- name: distlib
- version: 0.3.8
- manager: conda
- platform: osx-64
- dependencies:
- python: 2.7|>=3.6
- url: https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.8-pyhd8ed1ab_0.conda
- hash:
- md5: db16c66b759a64dc5183d69cc3745a52
- sha256: 3ff11acdd5cc2f80227682966916e878e45ced94f59c402efb94911a5774e84e
+ md5: a0bc3eec34b0fab84be6b2da94e98e20
+ sha256: 2ebfb971236ab825dd79dd6086ea742a9901008ffb9c6222c1f2b5172a8039d3
category: main
optional: false
-- name: exceptiongroup
- version: 1.2.0
+- name: platformdirs
+ version: 4.2.0
manager: conda
platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_0.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.0-pyhd8ed1ab_0.conda
hash:
- md5: f6c211fee3c98229652b60a9a42ef363
- sha256: cf83dcaf9006015c8ccab3fc6770f478464a66a8769e1763ca5d7dff09d11d08
+ md5: a0bc3eec34b0fab84be6b2da94e98e20
+ sha256: 2ebfb971236ab825dd79dd6086ea742a9901008ffb9c6222c1f2b5172a8039d3
category: main
optional: false
-- name: filelock
- version: 3.13.1
+- name: pluggy
+ version: 1.4.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/filelock-3.13.1-pyhd8ed1ab_0.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.4.0-pyhd8ed1ab_0.conda
hash:
- md5: 0c1729b74a8152fde6a38ba0a2ab9f45
- sha256: 4d742d91412d1f163e5399d2b50c5d479694ebcd309127abb549ca3977f89d2b
+ md5: 139e9feb65187e916162917bb2484976
+ sha256: 6edfd2c41938ea772096c674809bfcf2ebb9bef7e82de6c7ea0b966b86bfb4d0
category: main
optional: false
-- name: greenlet
- version: 3.0.2
+- name: pluggy
+ version: 1.4.0
manager: conda
platform: osx-64
dependencies:
- __osx: '>=10.9'
- libcxx: '>=16.0.6'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/greenlet-3.0.2-py311hd39e593_0.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.4.0-pyhd8ed1ab_0.conda
hash:
- md5: 6005605b11c7db35cd5d4d04e645ecd3
- sha256: 1120b061eb3216f3c2fd4db8a2150c5185742941c1a66c1e05a8bb26bfa9d026
+ md5: 139e9feb65187e916162917bb2484976
+ sha256: 6edfd2c41938ea772096c674809bfcf2ebb9bef7e82de6c7ea0b966b86bfb4d0
category: main
optional: false
-- name: idna
- version: '3.6'
+- name: pre-commit
+ version: 3.6.2
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/idna-3.6-pyhd8ed1ab_0.conda
+ cfgv: '>=2.0.0'
+ identify: '>=1.0.0'
+ nodeenv: '>=0.11.1'
+ python: '>=3.9'
+ pyyaml: '>=5.1'
+ virtualenv: '>=20.10.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.6.2-pyha770c72_0.conda
hash:
- md5: 1a76f09108576397c41c0b0c5bd84134
- sha256: 6ee4c986d69ce61e60a20b2459b6f2027baeba153f0a64995fd3cb47c2cc7e07
+ md5: 61534ee57ffdf26d7b1b514d33daccc4
+ sha256: 8eb9f5965c37d2bbee9302e16cc7c5517ee06491986356112be13431a043681e
category: main
optional: false
-- name: iniconfig
- version: 2.0.0
+- name: pre-commit
+ version: 3.6.2
manager: conda
platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda
+ python: '>=3.9'
+ pyyaml: '>=5.1'
+ identify: '>=1.0.0'
+ nodeenv: '>=0.11.1'
+ cfgv: '>=2.0.0'
+ virtualenv: '>=20.10.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.6.2-pyha770c72_0.conda
hash:
- md5: f800d2da156d08e289b14e87e43c1ae5
- sha256: 38740c939b668b36a50ef455b077e8015b8c9cf89860d421b3fff86048f49666
+ md5: 61534ee57ffdf26d7b1b514d33daccc4
+ sha256: 8eb9f5965c37d2bbee9302e16cc7c5517ee06491986356112be13431a043681e
category: main
optional: false
-- name: invoke
- version: 2.0.0
+- name: prompt-toolkit
+ version: 3.0.42
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/invoke-2.0.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ wcwidth: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda
hash:
- md5: c282e4567f7b800a855f7092b3c44a5a
- sha256: 637e51d8df0159bae9d67f840a24a5fc7973d48fac09418b01e2fb6f3c03224b
+ md5: 0bf64bf10eee21f46ac83c161917fa86
+ sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16
category: main
optional: false
-- name: itsdangerous
- version: 2.1.2
+- name: prompt-toolkit
+ version: 3.0.42
manager: conda
platform: osx-64
dependencies:
+ wcwidth: ''
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.1.2-pyhd8ed1ab_0.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda
hash:
- md5: 3c3de74912f11d2b590184f03c7cd09b
- sha256: 31e3492686b4e92b53db9b48bc0eb03873b1caaf28629fee7d2d47627a2c56d3
+ md5: 0bf64bf10eee21f46ac83c161917fa86
+ sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16
category: main
optional: false
-- name: jmespath
- version: 1.0.1
+- name: prompt_toolkit
+ version: 3.0.42
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/jmespath-1.0.1-pyhd8ed1ab_0.tar.bz2
+ prompt-toolkit: '>=3.0.42,<3.0.43.0a0'
+ url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda
hash:
- md5: 2cfa3e1cf3fb51bb9b17acc5b5e9ea11
- sha256: 95ac5f9ee95fd4e34dc051746fc86016d3d4f6abefed113e2ede049d59ec2991
+ md5: 85a2189ecd2fcdd86e92b2d4ea8fe461
+ sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d
category: main
optional: false
-- name: libpq
- version: '16.1'
+- name: prompt_toolkit
+ version: 3.0.42
manager: conda
platform: osx-64
dependencies:
- krb5: '>=1.21.2,<1.22.0a0'
- openssl: '>=3.2.0,<4.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/libpq-16.1-ha925e61_7.conda
+ prompt-toolkit: '>=3.0.42,<3.0.43.0a0'
+ url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda
hash:
- md5: ad8be4619f57504e8c243e00ab315ad6
- sha256: addce7453b4ac80faf46ecec76db74d98f57d9711624df600399c56e147b7903
+ md5: 85a2189ecd2fcdd86e92b2d4ea8fe461
+ sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d
category: main
optional: false
-- name: loguru
- version: 0.6.0
+- name: psutil
+ version: 5.9.8
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
+ libgcc-ng: '>=12'
python: '>=3.11,<3.12.0a0'
python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/loguru-0.6.0-py311h6eed73b_2.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.8-py311h459d7ec_0.conda
hash:
- md5: fc9dde292b3ec1251e63aac5434cc47c
- sha256: f74d200ffa50c455fbe631ca6564fe5b80c64ab314ec832528cfcdfad2a119d7
+ md5: 9bc62d25dcf64eec484974a3123c9d57
+ sha256: 467788418a2c71fb3df9ac0a6282ae693d1070a6cb47cb59bdb529b53acaee1c
category: main
optional: false
-- name: markupsafe
- version: 2.1.3
+- name: psutil
+ version: 5.9.8
manager: conda
platform: osx-64
dependencies:
python: '>=3.11,<3.12.0a0'
python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-2.1.3-py311h2725bcf_1.conda
+ url: https://conda.anaconda.org/conda-forge/osx-64/psutil-5.9.8-py311he705e18_0.conda
hash:
- md5: 52ee86f482b552e547e2b1d6c01adf55
- sha256: 5a8f8caa89eeba6ea6e9e96d3e7c109b675bc3c6ed4b109b8931757da2411d48
+ md5: 31aa294c58b3058c179a7a9593e99e18
+ sha256: fcff83f4d265294b54821656a10be62421da377885ab2e9811a80eb76419b3fe
category: main
optional: false
-- name: mdurl
- version: 0.1.0
+- name: psycopg2
+ version: 2.9.9
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.0-pyhd8ed1ab_0.tar.bz2
+ libgcc-ng: '>=12'
+ libpq: '>=16.1,<17.0a0'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/psycopg2-2.9.9-py311h03dec38_0.conda
hash:
- md5: f8dab71fdc13b1bf29a01248b156d268
- sha256: c678b9194e025b1fb665bec30ee20aab93399203583875b1dcc0a3b52a8f5523
+ md5: 3cc2decd316838bce14d73818e0bf7a4
+ sha256: 4e78d9fe1799d028d9a2da3636a3a68a531aeca5d2c679d4fc78627a426b11cb
category: main
optional: false
-- name: mypy_extensions
- version: 1.0.0
+- name: psycopg2
+ version: 2.9.9
manager: conda
platform: osx-64
dependencies:
- python: '>=3.5'
- url: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda
+ libpq: '>=16.1,<17.0a0'
+ openssl: '>=3.2.0,<4.0a0'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/osx-64/psycopg2-2.9.9-py311h187f0af_0.conda
hash:
- md5: 4eccaeba205f0aed9ac3a9ea58568ca3
- sha256: f240217476e148e825420c6bc3a0c0efb08c0718b7042fae960400c02af858a3
+ md5: 2177c8943bbf9bfc45421ecaebd5be11
+ sha256: 73c0cf543b0ddd41993956969f665999f5801e027e3d3524604892baedbd2626
category: main
optional: false
-- name: packaging
- version: '23.2'
+- name: pycparser
+ version: '2.21'
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/packaging-23.2-pyhd8ed1ab_0.conda
+ python: 2.7.*|>=3.4
+ url: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 79002079284aa895f883c6b7f3f88fd6
- sha256: 69b3ace6cca2dab9047b2c24926077d81d236bef45329d264b394001e3c3e52f
+ md5: 076becd9e05608f8dc72757d5f3a91ff
+ sha256: 74c63fd03f1f1ea2b54e8bc529fd1a600aaafb24027b738d0db87909ee3a33dc
category: main
optional: false
-- name: platformdirs
- version: 4.1.0
+- name: pycparser
+ version: '2.21'
manager: conda
platform: osx-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.1.0-pyhd8ed1ab_0.conda
+ python: 2.7.*|>=3.4
+ url: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 45a5065664da0d1dfa8f8cd2eaf05ab9
- sha256: 9e4ff17ce802159ed31344eb913eaa877688226765b77947b102b42255a53853
+ md5: 076becd9e05608f8dc72757d5f3a91ff
+ sha256: 74c63fd03f1f1ea2b54e8bc529fd1a600aaafb24027b738d0db87909ee3a33dc
category: main
optional: false
-- name: pluggy
- version: 1.3.0
+- name: pydantic
+ version: 1.10.13
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.3.0-pyhd8ed1ab_0.conda
+ libgcc-ng: '>=12'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ typing-extensions: '>=4.2.0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-1.10.13-py311h459d7ec_1.conda
hash:
- md5: 2390bd10bed1f3fdc7a537fb5a447d8d
- sha256: 7bf2ad9d747e71f1e93d0863c2c8061dd0f2fe1e582f28d292abfb40264a2eb5
+ md5: 8a92f40420211897a35841861e7e8348
+ sha256: f2d3a838fc90699c5dcd537aff10c78b33bd755232d0b21b26247cbf185cced7
category: main
optional: false
-- name: psutil
- version: 5.9.7
+- name: pydantic
+ version: 1.10.13
manager: conda
platform: osx-64
dependencies:
python: '>=3.11,<3.12.0a0'
python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/psutil-5.9.7-py311he705e18_0.conda
+ typing-extensions: '>=4.2.0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-1.10.13-py311he705e18_1.conda
hash:
- md5: d99e96df7c4457d2b1b83d69491f2966
- sha256: 43ab1bbe0a13828c4996ae2e115e5ca991673700075f5754cdae06b661589762
+ md5: ca0cd7b41964ce9a7b80290ea85e22e9
+ sha256: c55ab5f7d182421a5c11f70afc32425fa192f1e40de5c301f685b25bdc3391a8
category: main
optional: false
-- name: pycparser
- version: '2.21'
+- name: pygments
+ version: 2.17.2
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: 2.7.*|>=3.4
- url: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/pygments-2.17.2-pyhd8ed1ab_0.conda
hash:
- md5: 076becd9e05608f8dc72757d5f3a91ff
- sha256: 74c63fd03f1f1ea2b54e8bc529fd1a600aaafb24027b738d0db87909ee3a33dc
+ md5: 140a7f159396547e9799aa98f9f0742e
+ sha256: af5f8867450dc292f98ea387d4d8945fc574284677c8f60eaa9846ede7387257
category: main
optional: false
- name: pygments
@@ -2285,22 +2054,60 @@ package:
sha256: af5f8867450dc292f98ea387d4d8945fc574284677c8f60eaa9846ede7387257
category: main
optional: false
+- name: pyjwt
+ version: 2.8.0
+ manager: conda
+ platform: linux-64
+ dependencies:
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/pyjwt-2.8.0-pyhd8ed1ab_1.conda
+ hash:
+ md5: 74f76d4868dbba5870f2cf1d9b12d8f3
+ sha256: d7cb7fbafd767e938db10820c76a9c16d91faf5a081842159cc185787879eb07
+ category: main
+ optional: false
- name: pyjwt
version: 2.8.0
manager: conda
platform: osx-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/pyjwt-2.8.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/pyjwt-2.8.0-pyhd8ed1ab_1.conda
+ hash:
+ md5: 74f76d4868dbba5870f2cf1d9b12d8f3
+ sha256: d7cb7fbafd767e938db10820c76a9c16d91faf5a081842159cc185787879eb07
+ category: main
+ optional: false
+- name: pyopenssl
+ version: 24.0.0
+ manager: conda
+ platform: linux-64
+ dependencies:
+ cryptography: '>=41.0.5,<43'
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-24.0.0-pyhd8ed1ab_0.conda
hash:
- md5: 912c0194f898fdb783021fd25f913c31
- sha256: 88ac94c42ade15113397e30d1831dd341399b5262fb5330b9240f915c33cd232
+ md5: b50aec2c744a5c493c09cce9e2e7533e
+ sha256: bacd1d38585f447e2809e7621283661da7c97cfa20f545edb0ac5838356ed87b
+ category: main
+ optional: false
+- name: pyopenssl
+ version: 24.0.0
+ manager: conda
+ platform: osx-64
+ dependencies:
+ python: '>=3.7'
+ cryptography: '>=41.0.5,<43'
+ url: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-24.0.0-pyhd8ed1ab_0.conda
+ hash:
+ md5: b50aec2c744a5c493c09cce9e2e7533e
+ sha256: bacd1d38585f447e2809e7621283661da7c97cfa20f545edb0ac5838356ed87b
category: main
optional: false
- name: pysocks
version: 1.7.1
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
__unix: ''
python: '>=3.8'
@@ -2310,396 +2117,458 @@ package:
sha256: a42f826e958a8d22e65b3394f437af7332610e43ee313393d1cf143f0a2d274b
category: main
optional: false
-- name: python-dotenv
- version: 1.0.0
+- name: pysocks
+ version: 1.7.1
manager: conda
platform: osx-64
dependencies:
+ __unix: ''
python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.0-pyhd8ed1ab_1.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2
+ hash:
+ md5: 2a7de29fb590ca14b5243c4c812c8025
+ sha256: a42f826e958a8d22e65b3394f437af7332610e43ee313393d1cf143f0a2d274b
+ category: main
+ optional: false
+- name: pytest
+ version: 7.4.4
+ manager: conda
+ platform: linux-64
+ dependencies:
+ colorama: ''
+ exceptiongroup: '>=1.0.0rc8'
+ iniconfig: ''
+ packaging: ''
+ pluggy: '>=0.12,<2.0'
+ python: '>=3.7'
+ tomli: '>=1.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/pytest-7.4.4-pyhd8ed1ab_0.conda
hash:
- md5: 111e7f9edd31865e2659fa9aad8ec8fd
- sha256: bc5663f224ff6d8a399ec6bd8517e0c0f87a69ead438f82e5ce5c30f00077586
+ md5: a9d145de8c5f064b5fa68fb34725d9f4
+ sha256: 8979721b7f86b183d21103f3ec2734783847d317c1b754f462f407efc7c60886
category: main
optional: false
-- name: python-tzdata
- version: '2023.3'
+- name: pytest
+ version: 7.4.4
manager: conda
platform: osx-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2023.3-pyhd8ed1ab_0.conda
+ packaging: ''
+ colorama: ''
+ iniconfig: ''
+ python: '>=3.7'
+ exceptiongroup: '>=1.0.0rc8'
+ tomli: '>=1.0.0'
+ pluggy: '>=0.12,<2.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/pytest-7.4.4-pyhd8ed1ab_0.conda
+ hash:
+ md5: a9d145de8c5f064b5fa68fb34725d9f4
+ sha256: 8979721b7f86b183d21103f3ec2734783847d317c1b754f462f407efc7c60886
+ category: main
+ optional: false
+- name: python
+ version: 3.11.8
+ manager: conda
+ platform: linux-64
+ dependencies:
+ bzip2: '>=1.0.8,<2.0a0'
+ ld_impl_linux-64: '>=2.36.1'
+ libexpat: '>=2.5.0,<3.0a0'
+ libffi: '>=3.4,<4.0a0'
+ libgcc-ng: '>=12'
+ libnsl: '>=2.0.1,<2.1.0a0'
+ libsqlite: '>=3.45.1,<4.0a0'
+ libuuid: '>=2.38.1,<3.0a0'
+ libxcrypt: '>=4.4.36'
+ libzlib: '>=1.2.13,<1.3.0a0'
+ ncurses: '>=6.4,<7.0a0'
+ openssl: '>=3.2.1,<4.0a0'
+ readline: '>=8.2,<9.0a0'
+ tk: '>=8.6.13,<8.7.0a0'
+ tzdata: ''
+ xz: '>=5.2.6,<6.0a0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.8-hab00c5b_0_cpython.conda
hash:
- md5: 2590495f608a63625e165915fb4e2e34
- sha256: 0108888507014fb24573c31e4deceb61c99e63d37776dddcadd7c89b2ecae0b6
+ md5: 2fdc314ee058eda0114738a9309d3683
+ sha256: f33559d7127b6a892854bc3b2b4be1406c3be9537d658cb13edae57c8c0b5a11
category: main
optional: false
-- name: pytz
- version: 2023.3.post1
+- name: python
+ version: 3.11.8
manager: conda
platform: osx-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda
+ bzip2: '>=1.0.8,<2.0a0'
+ libexpat: '>=2.5.0,<3.0a0'
+ libffi: '>=3.4,<4.0a0'
+ libsqlite: '>=3.45.1,<4.0a0'
+ libzlib: '>=1.2.13,<1.3.0a0'
+ ncurses: '>=6.4,<7.0a0'
+ openssl: '>=3.2.1,<4.0a0'
+ readline: '>=8.2,<9.0a0'
+ tk: '>=8.6.13,<8.7.0a0'
+ tzdata: ''
+ xz: '>=5.2.6,<6.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.8-h9f0c242_0_cpython.conda
hash:
- md5: c93346b446cd08c169d843ae5fc0da97
- sha256: 6b680e63d69aaf087cd43ca765a23838723ef59b0a328799e6363eb13f52c49e
+ md5: 22bda10a0f425564a538aed9a0e8a9df
+ sha256: 645dad20b46041ecd6a85eccbb3291fa1ad7921eea065c0081efff78c3d7e27a
category: main
optional: false
-- name: pyyaml
- version: 6.0.1
+- name: python-dateutil
+ version: 2.9.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- yaml: '>=0.2.5,<0.3.0a0'
- url: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py311h2725bcf_1.conda
+ python: '>=3.7'
+ six: '>=1.5'
+ url: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda
hash:
- md5: 9283f991b5e5856a99f8aabba9927df5
- sha256: 8ce2ba443414170a2570514d0ce6d03625a847e91af9763d48dc58c338e6f7f3
+ md5: 2cf4264fffb9e6eff6031c5b6884d61c
+ sha256: f3ceef02ac164a8d3a080d0d32f8e2ebe10dd29e3a685d240e38b3599e146320
category: main
optional: false
-- name: setuptools
- version: 68.2.2
+- name: python-dateutil
+ version: 2.9.0
manager: conda
platform: osx-64
dependencies:
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/setuptools-68.2.2-pyhd8ed1ab_0.conda
+ six: '>=1.5'
+ url: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda
hash:
- md5: fc2166155db840c634a1291a5c35a709
- sha256: 851901b1f8f2049edb36a675f0c3f9a98e1495ef4eb214761b048c6f696a06f7
+ md5: 2cf4264fffb9e6eff6031c5b6884d61c
+ sha256: f3ceef02ac164a8d3a080d0d32f8e2ebe10dd29e3a685d240e38b3599e146320
category: main
optional: false
-- name: six
- version: 1.16.0
+- name: python-tzdata
+ version: '2024.1'
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: ''
- url: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda
hash:
- md5: e5f25f8dbc060e9a8d912e432202afc2
- sha256: a85c38227b446f42c5b90d9b642f2c0567880c15d72492d8da074a59c8f91dd6
+ md5: 98206ea9954216ee7540f0c773f2104d
+ sha256: 9da9a849d53705dee450b83507df1ca8ffea5f83bd21a215202221f1c492f8ad
category: main
optional: false
-- name: tomli
- version: 2.0.1
+- name: python-tzdata
+ version: '2024.1'
manager: conda
platform: osx-64
dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda
hash:
- md5: 5844808ffab9ebdb694585b50ba02a96
- sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f
+ md5: 98206ea9954216ee7540f0c773f2104d
+ sha256: 9da9a849d53705dee450b83507df1ca8ffea5f83bd21a215202221f1c492f8ad
category: main
optional: false
-- name: tomlkit
- version: 0.12.3
+- name: python_abi
+ version: '3.11'
manager: conda
- platform: osx-64
- dependencies:
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.12.3-pyha770c72_0.conda
+ platform: linux-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-4_cp311.conda
hash:
- md5: 074d0ce7a6261ab8b497c3518796ef3e
- sha256: 53cc436ab92d38683df1320e4468a8b978428e800195bf1c8c2460e90b0bc117
+ md5: d786502c97404c94d7d58d258a445a65
+ sha256: 0be3ac1bf852d64f553220c7e6457e9c047dfb7412da9d22fbaa67e60858b3cf
category: main
optional: false
-- name: types-markdown
- version: 3.5.0.3
+- name: python_abi
+ version: '3.11'
manager: conda
platform: osx-64
- dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/types-markdown-3.5.0.3-pyhd8ed1ab_0.conda
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/python_abi-3.11-4_cp311.conda
hash:
- md5: 9a78be2f67528371edc1bf3f908530b8
- sha256: a64b305419e2f0d537c42aa9c30285e31e41b852904e85d25243f9bc9a4c6d2d
+ md5: fef7a52f0eca6bae9e8e2e255bc86394
+ sha256: f56dfe2a57b3b27bad3f9527f943548e8b2526e949d9d6fc0a383020d9359afe
category: main
optional: false
-- name: typing_extensions
- version: 4.9.0
+- name: pyyaml
+ version: 6.0.1
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.9.0-pyha770c72_0.conda
+ libgcc-ng: '>=12'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ yaml: '>=0.2.5,<0.3.0a0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda
hash:
- md5: a92a6440c3fe7052d63244f3aba2a4a7
- sha256: f3c5be8673bfd905c4665efcb27fa50192f24f84fa8eff2f19cba5d09753d905
+ md5: 52719a74ad130de8fb5d047dc91f247a
+ sha256: 28729ef1ffa7f6f9dfd54345a47c7faac5d34296d66a2b9891fb147f4efe1348
category: main
optional: false
-- name: urlobject
- version: 2.4.3
+- name: pyyaml
+ version: 6.0.1
manager: conda
platform: osx-64
dependencies:
- python: ''
- url: https://conda.anaconda.org/conda-forge/noarch/urlobject-2.4.3-py_1.tar.bz2
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ yaml: '>=0.2.5,<0.3.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py311h2725bcf_1.conda
hash:
- md5: 91140cccf570095e69d84b58075bc9b2
- sha256: 21354dad71b83bf6d0224f962565018c055f2d7f60205851491b9ff8f1d04936
+ md5: 9283f991b5e5856a99f8aabba9927df5
+ sha256: 8ce2ba443414170a2570514d0ce6d03625a847e91af9763d48dc58c338e6f7f3
category: main
optional: false
-- name: vine
- version: 5.0.0
+- name: readline
+ version: '8.2'
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/vine-5.0.0-pyhd8ed1ab_1.tar.bz2
+ libgcc-ng: '>=12'
+ ncurses: '>=6.3,<7.0a0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda
hash:
- md5: 7cb5b514698cfd164ad5103e58e1e201
- sha256: 53e1239bd2ef11f75d381ba6944d8339a247e42d088de87b9d9f751ddf7176bc
+ md5: 47d31b792659ce70f470b5c82fdfb7a4
+ sha256: 5435cf39d039387fbdc977b0a762357ea909a7694d9528ab40f005e9208744d7
category: main
optional: false
-- name: wcwidth
- version: 0.2.12
+- name: readline
+ version: '8.2'
manager: conda
platform: osx-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.12-pyhd8ed1ab_0.conda
+ ncurses: '>=6.3,<7.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda
hash:
- md5: bf4a1d1a97ca27b0b65bacd9e238b484
- sha256: ca757d0fc2dbd422af9d3238a8b4b630a6e11df3707a447bd89540656770d1d7
+ md5: f17f77f2acf4d344734bda76829ce14e
+ sha256: 41e7d30a097d9b060037f0c6a2b1d4c4ae7e942c06c943d23f9d481548478568
category: main
optional: false
-- name: wheel
- version: 0.42.0
+- name: requests
+ version: 2.31.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
+ certifi: '>=2017.4.17'
+ charset-normalizer: '>=2,<4'
+ idna: '>=2.5,<4'
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.42.0-pyhd8ed1ab_0.conda
+ urllib3: '>=1.21.1,<3'
+ url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda
hash:
- md5: 1cdea58981c5cbc17b51973bcaddcea7
- sha256: 80be0ccc815ce22f80c141013302839b0ed938a2edb50b846cf48d8a8c1cfa01
+ md5: a30144e4156cdbb236f99ebb49828f8b
+ sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad
category: main
optional: false
-- name: zipp
- version: 3.17.0
+- name: requests
+ version: 2.31.0
manager: conda
platform: osx-64
dependencies:
- python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ idna: '>=2.5,<4'
+ certifi: '>=2017.4.17'
+ charset-normalizer: '>=2,<4'
+ urllib3: '>=1.21.1,<3'
+ url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda
hash:
- md5: 2e4d6bc0b14e10f895fc6791a7d9b26a
- sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26
+ md5: a30144e4156cdbb236f99ebb49828f8b
+ sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad
category: main
optional: false
-- name: amqp
- version: 5.2.0
+- name: requests-oauthlib
+ version: 1.4.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.6'
- vine: 5.0.0
- url: https://conda.anaconda.org/conda-forge/noarch/amqp-5.2.0-pyhd8ed1ab_0.conda
+ oauthlib: '>=3.0.0'
+ python: '>=3.4'
+ requests: '>=2.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/requests-oauthlib-1.4.0-pyhd8ed1ab_0.conda
hash:
- md5: 7ab12cc04a0596a8ab937e9d211503cc
- sha256: 9993eb1df7e4a9a4e59c82a87495ab03762c94801f7c4bb8db922ca28681c126
+ md5: a55b220de8970208f583e38639cfbecc
+ sha256: 909ec1510bbb6fad9276534352025f428050a4deeea86e68d61c8c580938ac82
category: main
optional: false
-- name: cffi
- version: 1.16.0
+- name: requests-oauthlib
+ version: 1.4.0
manager: conda
platform: osx-64
dependencies:
- libffi: '>=3.4,<4.0a0'
- pycparser: ''
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py311hc0b63fd_0.conda
+ python: '>=3.4'
+ requests: '>=2.0.0'
+ oauthlib: '>=3.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/requests-oauthlib-1.4.0-pyhd8ed1ab_0.conda
hash:
- md5: 15d07b82223cac96af629e5e747ba27a
- sha256: 1f13a5fa7f310fdbd27f5eddceb9e62cfb10012c58a58c923dd6f51fa979748a
+ md5: a55b220de8970208f583e38639cfbecc
+ sha256: 909ec1510bbb6fad9276534352025f428050a4deeea86e68d61c8c580938ac82
category: main
optional: false
-- name: click-didyoumean
- version: 0.3.0
+- name: rich
+ version: 13.7.1
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- click: '>=7'
- python: '>=3.6.2,<4.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/click-didyoumean-0.3.0-pyhd8ed1ab_0.tar.bz2
+ markdown-it-py: '>=2.2.0'
+ pygments: '>=2.13.0,<3.0.0'
+ python: '>=3.7.0'
+ typing_extensions: '>=4.0.0,<5.0.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda
hash:
- md5: a49aa7bc1a82485f6a0a8849dcfefcad
- sha256: e1af96905976a83f5545b0914830e272415e2e66428165fdf178e73dc4bc9cff
+ md5: ba445bf767ae6f0d959ff2b40c20912b
+ sha256: 2b26d58aa59e46f933c3126367348651b0dab6e0bf88014e857415bb184a4667
category: main
optional: false
-- name: click-plugins
- version: 1.1.1
+- name: rich
+ version: 13.7.1
manager: conda
platform: osx-64
dependencies:
- python: ''
- click: '>=3.0'
- url: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2
+ python: '>=3.7.0'
+ typing_extensions: '>=4.0.0,<5.0.0'
+ pygments: '>=2.13.0,<3.0.0'
+ markdown-it-py: '>=2.2.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda
hash:
- md5: 4fd2c6b53934bd7d96d1f3fdaf99b79f
- sha256: ddef6e559dde6673ee504b0e29dd814d36e22b6b9b1f519fa856ee268905bf92
+ md5: ba445bf767ae6f0d959ff2b40c20912b
+ sha256: 2b26d58aa59e46f933c3126367348651b0dab6e0bf88014e857415bb184a4667
category: main
optional: false
-- name: gunicorn
- version: 21.2.0
+- name: rich-click
+ version: 1.7.4
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- packaging: ''
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- setuptools: '>=3.0'
- url: https://conda.anaconda.org/conda-forge/osx-64/gunicorn-21.2.0-py311h6eed73b_1.conda
+ click: '>=7,<9'
+ python: '>=3.7'
+ rich: '>=10'
+ url: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.7.4-pyhd8ed1ab_0.conda
hash:
- md5: f818ed3365dbee71c75368587fc976b3
- sha256: dd5e241c4f1ad7982ea6aa5bc2cb5c03ce35af6a73ecc1a86c4dbb621ed12c68
+ md5: a3e6556c7cfce33ba7dae23fb17d3303
+ sha256: 91e0b041cf663d4a8e27f1cf572d265d90fdf3a58fa6513bc41292572ca5462f
category: main
optional: false
-- name: importlib-metadata
- version: 7.0.0
+- name: rich-click
+ version: 1.7.4
manager: conda
platform: osx-64
dependencies:
- python: '>=3.8'
- zipp: '>=0.5'
- url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.0.0-pyha770c72_0.conda
+ python: '>=3.7'
+ click: '>=7,<9'
+ rich: '>=10'
+ url: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.7.4-pyhd8ed1ab_0.conda
hash:
- md5: a941237cd06538837b25cd245fcd25d8
- sha256: 9731e82a00d36b182dc515e31723e711ac82890bb1ca86c6a17a4b471135564f
+ md5: a3e6556c7cfce33ba7dae23fb17d3303
+ sha256: 91e0b041cf663d4a8e27f1cf572d265d90fdf3a58fa6513bc41292572ca5462f
category: main
optional: false
-- name: jinja2
- version: 3.1.2
+- name: s3transfer
+ version: 0.10.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.7'
- markupsafe: '>=2.0'
- url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.2-pyhd8ed1ab_1.tar.bz2
+ botocore: '>=1.33.2,<2.0a.0'
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/s3transfer-0.10.0-pyhd8ed1ab_0.conda
hash:
- md5: c8490ed5c70966d232fdd389d0dbed37
- sha256: b045faba7130ab263db6a8fdc96b1a3de5fcf85c4a607c5f11a49e76851500b5
+ md5: 2d52125a7fe49248ce5e883fed6c935a
+ sha256: 5f1fccbbc0460971f12dda7ab0465d8f6037486042d156b611881e57d218ce95
category: main
optional: false
-- name: markdown-it-py
- version: 3.0.0
+- name: s3transfer
+ version: 0.10.0
manager: conda
platform: osx-64
dependencies:
python: '>=3.8'
- mdurl: '>=0.1,<1'
- url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda
+ botocore: '>=1.33.2,<2.0a.0'
+ url: https://conda.anaconda.org/conda-forge/noarch/s3transfer-0.10.0-pyhd8ed1ab_0.conda
hash:
- md5: 93a8e71256479c62074356ef6ebf501b
- sha256: c041b0eaf7a6af3344d5dd452815cdc148d6284fec25a4fa3f4263b3a021e962
+ md5: 2d52125a7fe49248ce5e883fed6c935a
+ sha256: 5f1fccbbc0460971f12dda7ab0465d8f6037486042d156b611881e57d218ce95
category: main
optional: false
-- name: mypy
- version: 1.7.1
+- name: setuptools
+ version: 69.1.1
manager: conda
- platform: osx-64
- dependencies:
- mypy_extensions: '>=1.0.0'
- psutil: '>=4.0'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- typing_extensions: '>=4.1.0'
- url: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.7.1-py311he705e18_1.conda
+ platform: linux-64
+ dependencies:
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.1.1-pyhd8ed1ab_0.conda
hash:
- md5: 153e0baec2f2d6c0bb6c9692f623ecdb
- sha256: f9c25d9de38057167a10d4873e8ad7bcb9b9a8b5d1d3195421dac3445fb16b26
+ md5: 576de899521b7d43674ba3ef6eae9142
+ sha256: 7a6dca60efcaa42d0ebb784950bc16230a968256cb5048a4441cb34653b5ec58
category: main
optional: false
-- name: nodeenv
- version: 1.8.0
+- name: setuptools
+ version: 69.1.1
manager: conda
platform: osx-64
dependencies:
- setuptools: ''
- python: 2.7|>=3.7
- url: https://conda.anaconda.org/conda-forge/noarch/nodeenv-1.8.0-pyhd8ed1ab_0.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.1.1-pyhd8ed1ab_0.conda
hash:
- md5: 2a75b296096adabbabadd5e9782e5fcc
- sha256: 1320306234552717149f36f825ddc7e27ea295f24829e9db4cc6ceaff0b032bd
+ md5: 576de899521b7d43674ba3ef6eae9142
+ sha256: 7a6dca60efcaa42d0ebb784950bc16230a968256cb5048a4441cb34653b5ec58
category: main
optional: false
-- name: pip
- version: 23.3.2
+- name: shellcheck
+ version: 0.8.0
manager: conda
- platform: osx-64
- dependencies:
- setuptools: ''
- wheel: ''
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/pip-23.3.2-pyhd8ed1ab_0.conda
+ platform: linux-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/linux-64/shellcheck-0.8.0-ha770c72_0.tar.bz2
hash:
- md5: 8591c748f98dcc02253003533bc2e4b1
- sha256: 29096d1d53c61aeef518729add2f405df86b3629d1d738a35b15095e6a02eeed
+ md5: 0276737172793e3ec3dbc1631840ead7
+ sha256: dfeecf516522c4b040ef9e4c6ec9c204d2b09f985f114c6a655522ed6407c27f
category: main
optional: false
-- name: prompt-toolkit
- version: 3.0.42
+- name: shellcheck
+ version: 0.8.0
manager: conda
platform: osx-64
dependencies:
- wcwidth: ''
- python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda
+ gmp: '>=6.2.1,<7.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/shellcheck-0.8.0-h7dd6a17_0.tar.bz2
hash:
- md5: 0bf64bf10eee21f46ac83c161917fa86
- sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16
+ md5: b5a30a0ff9f7b85fe4e3195bc12d4b66
+ sha256: 9ae08b408c7c352be4dd927b50eb7c2b11d9053409f21c8ed608ac04636edcf6
category: main
optional: false
-- name: psycopg2
- version: 2.9.9
+- name: six
+ version: 1.16.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- libpq: '>=16.1,<17.0a0'
- openssl: '>=3.2.0,<4.0a0'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/psycopg2-2.9.9-py311h187f0af_0.conda
+ python: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2
hash:
- md5: 2177c8943bbf9bfc45421ecaebd5be11
- sha256: 73c0cf543b0ddd41993956969f665999f5801e027e3d3524604892baedbd2626
+ md5: e5f25f8dbc060e9a8d912e432202afc2
+ sha256: a85c38227b446f42c5b90d9b642f2c0567880c15d72492d8da074a59c8f91dd6
category: main
optional: false
-- name: pytest
- version: 7.4.3
+- name: six
+ version: 1.16.0
manager: conda
platform: osx-64
dependencies:
- packaging: ''
- colorama: ''
- iniconfig: ''
- python: '>=3.7'
- exceptiongroup: '>=1.0.0rc8'
- tomli: '>=1.0.0'
- pluggy: '>=0.12,<2.0'
- url: https://conda.anaconda.org/conda-forge/noarch/pytest-7.4.3-pyhd8ed1ab_0.conda
+ python: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2
hash:
- md5: 5bdca0aca30b0ee62bb84854e027eae0
- sha256: 14e948e620ec87d9e62a8d9c21d40084b4805a939cfee322be7d457379dc96a0
+ md5: e5f25f8dbc060e9a8d912e432202afc2
+ sha256: a85c38227b446f42c5b90d9b642f2c0567880c15d72492d8da074a59c8f91dd6
category: main
optional: false
-- name: python-dateutil
- version: 2.8.2
+- name: sqlalchemy
+ version: 1.4.49
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.6'
- six: '>=1.5'
- url: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2
+ greenlet: '!=0.4.17'
+ libgcc-ng: '>=12'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/sqlalchemy-1.4.49-py311h459d7ec_1.conda
hash:
- md5: dd999d1cc9f79e67dbb855c8924c7984
- sha256: 54d7785c7678166aa45adeaccfc1d2b8c3c799ca2dc05d4a82bb39b1968bd7da
+ md5: 17392bcb4ceac1b2c95db9d54b4ac018
+ sha256: 542dea4823e2e1283936fbd25c9f3fa960ec6df2dd54589b192b4dac68af7295
category: main
optional: false
- name: sqlalchemy
@@ -2716,198 +2585,187 @@ package:
sha256: 39569dfc13e742e1b61fcc92948e02bc7f361d05bb5100e5226251b70fcdf1af
category: main
optional: false
-- name: typing-extensions
- version: 4.9.0
+- name: tk
+ version: 8.6.13
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- typing_extensions: 4.9.0
- url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.9.0-hd8ed1ab_0.conda
+ libgcc-ng: '>=12'
+ libzlib: '>=1.2.13,<1.3.0a0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda
hash:
- md5: c16524c1b7227dc80b36b4fa6f77cc86
- sha256: d795c1eb1db4ea147f01ece74e5a504d7c2e8d5ee8c11ec987884967dd938f9c
+ md5: d453b98d9c83e71da0741bb0ff4d76bc
+ sha256: e0569c9caa68bf476bead1bed3d79650bb080b532c64a4af7d8ca286c08dea4e
category: main
optional: false
-- name: urllib3
- version: 1.26.18
+- name: tk
+ version: 8.6.13
manager: conda
platform: osx-64
dependencies:
- python: '>=3.7'
- brotli-python: '>=1.0.9'
- pysocks: '>=1.5.6,<2.0,!=1.5.7'
- url: https://conda.anaconda.org/conda-forge/noarch/urllib3-1.26.18-pyhd8ed1ab_0.conda
+ libzlib: '>=1.2.13,<1.3.0a0'
+ url: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda
hash:
- md5: bf61cfd2a7f212efba378167a07d4a6a
- sha256: 1cc0bab65a6ad0f5a8bd7657760a4fb4e670d30377f9dab88b792977cb3687e7
+ md5: bf830ba5afc507c6232d4ef0fb1a882d
+ sha256: 30412b2e9de4ff82d8c2a7e5d06a15f4f4fef1809a72138b6ccb53a33b26faf5
category: main
optional: false
-- name: virtualenv
- version: 20.25.0
+- name: tomli
+ version: 2.0.1
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.8'
- distlib: <1,>=0.3.7
- filelock: <4,>=3.12.2
- platformdirs: <5,>=3.9.1
- url: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.25.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2
hash:
- md5: c119653cba436d8183c27bf6d190e587
- sha256: 50827c3721a9dbf973b568709d4381add2a6552fa562f26a385c5edc16a534af
+ md5: 5844808ffab9ebdb694585b50ba02a96
+ sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f
category: main
optional: false
-- name: werkzeug
- version: 2.2.3
+- name: tomli
+ version: 2.0.1
manager: conda
platform: osx-64
dependencies:
python: '>=3.7'
- markupsafe: '>=2.1.1'
- url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-2.2.3-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2
hash:
- md5: 94dea682ba9d8e091e1f46872886fb1f
- sha256: 38f68541580b74ed91396a67766fb96088f7b161bfd203675ed7a257d642e2e3
+ md5: 5844808ffab9ebdb694585b50ba02a96
+ sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f
category: main
optional: false
-- name: wtforms
- version: 3.0.1
+- name: tomlkit
+ version: 0.12.4
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- markupsafe: ''
python: '>=3.7'
- url: https://conda.anaconda.org/conda-forge/noarch/wtforms-3.0.1-pyhd8ed1ab_0.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.12.4-pyha770c72_0.conda
hash:
- md5: 62a19155ee3896566849634586c1813d
- sha256: fc6bc71fc1bd5966ad024a1c828652b9a1ceee06ea514a94968b9b53492e3abe
+ md5: 37c47ea93ef00dd80d880fc4ba21256a
+ sha256: 8d45c266bf919788abacd9828f4a2101d7216f6d4fc7c8d3417034fe0d795a18
category: main
optional: false
-- name: annotated-types
- version: 0.6.0
+- name: tomlkit
+ version: 0.12.4
manager: conda
platform: osx-64
dependencies:
python: '>=3.7'
- typing-extensions: '>=4.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.6.0-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.12.4-pyha770c72_0.conda
hash:
- md5: 997c29372bdbe2afee073dff71f35923
- sha256: 3a2c98154d95cfd54daba6b7d507d31f5ba07ac2ad955c44eb041b66563193cd
+ md5: 37c47ea93ef00dd80d880fc4ba21256a
+ sha256: 8d45c266bf919788abacd9828f4a2101d7216f6d4fc7c8d3417034fe0d795a18
category: main
optional: false
-- name: botocore
- version: 1.34.2
+- name: types-markdown
+ version: 3.5.0.20240311
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.8'
- python-dateutil: '>=2.1,<3.0.0'
- jmespath: '>=0.7.1,<2.0.0'
- urllib3: '>=1.25.4,<1.27'
- url: https://conda.anaconda.org/conda-forge/noarch/botocore-1.34.2-pyhd8ed1ab_0.conda
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/types-markdown-3.5.0.20240311-pyhd8ed1ab_0.conda
hash:
- md5: 90d807074ce872ffb1e20ea0e7c76c10
- sha256: e404de75c98ee31d06b52c631078df97f77e50ebcb644758c22ec86fcca2d6c4
+ md5: 01e9f6ef2d980874b9a4e5a6d32443fa
+ sha256: 65502afa9cd2d7377e5f2fdaff0f415f060a3aefcaa81c4969fae4ad50c31361
category: main
optional: false
-- name: cryptography
- version: 41.0.7
+- name: types-markdown
+ version: 3.5.0.20240311
manager: conda
platform: osx-64
dependencies:
- cffi: '>=1.12'
- openssl: '>=3.1.4,<4.0a0'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- url: https://conda.anaconda.org/conda-forge/osx-64/cryptography-41.0.7-py311h48c7838_1.conda
+ python: '>=3.6'
+ url: https://conda.anaconda.org/conda-forge/noarch/types-markdown-3.5.0.20240311-pyhd8ed1ab_0.conda
hash:
- md5: 65293feff96135571de02c047ecbd5a2
- sha256: f4c5e683386acf06cfa85805d264c9cd540361ec6e86740cb03312e560aa706a
+ md5: 01e9f6ef2d980874b9a4e5a6d32443fa
+ sha256: 65502afa9cd2d7377e5f2fdaff0f415f060a3aefcaa81c4969fae4ad50c31361
category: main
optional: false
-- name: markdown
- version: 3.5.1
+- name: typing-extensions
+ version: 4.10.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.6'
- importlib-metadata: '>=4.4'
- url: https://conda.anaconda.org/conda-forge/noarch/markdown-3.5.1-pyhd8ed1ab_0.conda
+ typing_extensions: 4.10.0
+ url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.10.0-hd8ed1ab_0.conda
hash:
- md5: 323495027ffa625701129acebf861412
- sha256: 35e8990504cf8dc7e2bb63efd855fb0a0d5c0d77bf79403235e757c24a83ec1d
+ md5: 091683b9150d2ebaa62fd7e2c86433da
+ sha256: 0698fe2c4e555fb44c27c60f7a21fa0eea7f5bf8186ad109543c5b056e27f96a
category: main
optional: false
-- name: prompt_toolkit
- version: 3.0.42
+- name: typing-extensions
+ version: 4.10.0
manager: conda
platform: osx-64
dependencies:
- prompt-toolkit: '>=3.0.42,<3.0.43.0a0'
- url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda
+ typing_extensions: 4.10.0
+ url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.10.0-hd8ed1ab_0.conda
hash:
- md5: 85a2189ecd2fcdd86e92b2d4ea8fe461
- sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d
+ md5: 091683b9150d2ebaa62fd7e2c86433da
+ sha256: 0698fe2c4e555fb44c27c60f7a21fa0eea7f5bf8186ad109543c5b056e27f96a
category: main
optional: false
-- name: pydantic
- version: 1.10.13
+- name: typing_extensions
+ version: 4.10.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- typing-extensions: '>=4.2.0'
- url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-1.10.13-py311he705e18_1.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.10.0-pyha770c72_0.conda
hash:
- md5: ca0cd7b41964ce9a7b80290ea85e22e9
- sha256: c55ab5f7d182421a5c11f70afc32425fa192f1e40de5c301f685b25bdc3391a8
+ md5: 16ae769069b380646c47142d719ef466
+ sha256: 4be24d557897b2f6609f5d5f7c437833c62f4d4a96581e39530067e96a2d0451
category: main
optional: false
-- name: pydantic-core
- version: 2.14.5
+- name: typing_extensions
+ version: 4.10.0
manager: conda
platform: osx-64
dependencies:
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- typing-extensions: '>=4.6.0'
- url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.14.5-py311h5e0f0e4_0.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.10.0-pyha770c72_0.conda
hash:
- md5: 915ef17e91fbe6c5a2d2ea502e112ae7
- sha256: d79248cd5511c1153981b7fdcad4ef72a17985e604488a3ad1f242e2cd1e2622
+ md5: 16ae769069b380646c47142d719ef466
+ sha256: 4be24d557897b2f6609f5d5f7c437833c62f4d4a96581e39530067e96a2d0451
category: main
optional: false
-- name: requests
- version: 2.31.0
+- name: tzdata
+ version: 2024a
manager: conda
- platform: osx-64
- dependencies:
- python: '>=3.7'
- idna: '>=2.5,<4'
- certifi: '>=2017.4.17'
- charset-normalizer: '>=2,<4'
- urllib3: '>=1.21.1,<3'
- url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda
+ platform: linux-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda
hash:
- md5: a30144e4156cdbb236f99ebb49828f8b
- sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad
+ md5: 161081fc7cec0bfda0d86d7cb595f8d8
+ sha256: 7b2b69c54ec62a243eb6fba2391b5e443421608c3ae5dbff938ad33ca8db5122
category: main
optional: false
-- name: rich
- version: 13.7.0
+- name: tzdata
+ version: 2024a
manager: conda
platform: osx-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda
+ hash:
+ md5: 161081fc7cec0bfda0d86d7cb595f8d8
+ sha256: 7b2b69c54ec62a243eb6fba2391b5e443421608c3ae5dbff938ad33ca8db5122
+ category: main
+ optional: false
+- name: ukkonen
+ version: 1.0.1
+ manager: conda
+ platform: linux-64
dependencies:
- python: '>=3.7.0'
- typing_extensions: '>=4.0.0,<5.0.0'
- pygments: '>=2.13.0,<3.0.0'
- markdown-it-py: '>=2.2.0'
- url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.0-pyhd8ed1ab_0.conda
+ cffi: ''
+ libgcc-ng: '>=12'
+ libstdcxx-ng: '>=12'
+ python: '>=3.11,<3.12.0a0'
+ python_abi: 3.11.*
+ url: https://conda.anaconda.org/conda-forge/linux-64/ukkonen-1.0.1-py311h9547e67_4.conda
hash:
- md5: d7a11d4f3024b2f4a6e0ae7377dd61e9
- sha256: 4bb25bf1f5664772b2c4c2e3878aa6e7dc2695f97e3da4ee8e47c51e179913bb
+ md5: 586da7df03b68640de14dc3e8bcbf76f
+ sha256: c2d33e998f637b594632eba3727529171a06eb09896e36aa42f1ebcb03779472
category: main
optional: false
- name: ukkonen
@@ -2925,283 +2783,292 @@ package:
sha256: b273782a1277042a54e12411beebd378d2a2a69e503bcf147766e98628e91c91
category: main
optional: false
-- name: click-repl
- version: 0.3.0
+- name: urllib3
+ version: 2.0.7
+ manager: conda
+ platform: linux-64
+ dependencies:
+ brotli-python: '>=1.0.9'
+ pysocks: '>=1.5.6,<2.0,!=1.5.7'
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.0.7-pyhd8ed1ab_0.conda
+ hash:
+ md5: 270e71c14d37074b1d066ee21cf0c4a6
+ sha256: 9fe14735dde74278c6f1710cbe883d5710fc98501a96031dec6849a8d8a1bb11
+ category: main
+ optional: false
+- name: urllib3
+ version: 2.0.7
manager: conda
platform: osx-64
dependencies:
- six: ''
- click: ''
- prompt_toolkit: ''
- python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/click-repl-0.3.0-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ brotli-python: '>=1.0.9'
+ pysocks: '>=1.5.6,<2.0,!=1.5.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.0.7-pyhd8ed1ab_0.conda
+ hash:
+ md5: 270e71c14d37074b1d066ee21cf0c4a6
+ sha256: 9fe14735dde74278c6f1710cbe883d5710fc98501a96031dec6849a8d8a1bb11
+ category: main
+ optional: false
+- name: urlobject
+ version: 2.4.3
+ manager: conda
+ platform: linux-64
+ dependencies:
+ python: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/urlobject-2.4.3-py_1.tar.bz2
+ hash:
+ md5: 91140cccf570095e69d84b58075bc9b2
+ sha256: 21354dad71b83bf6d0224f962565018c055f2d7f60205851491b9ff8f1d04936
+ category: main
+ optional: false
+- name: urlobject
+ version: 2.4.3
+ manager: conda
+ platform: osx-64
+ dependencies:
+ python: ''
+ url: https://conda.anaconda.org/conda-forge/noarch/urlobject-2.4.3-py_1.tar.bz2
hash:
- md5: 27eb8f68250666c1a19d1b6ec9d12c4e
- sha256: 69c16e0b89e1fb4fc444af4798ef1222b3075d074cbcbe70b9af793668200a14
+ md5: 91140cccf570095e69d84b58075bc9b2
+ sha256: 21354dad71b83bf6d0224f962565018c055f2d7f60205851491b9ff8f1d04936
category: main
optional: false
-- name: identify
- version: 2.5.33
+- name: vine
+ version: 5.1.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- ukkonen: ''
python: '>=3.6'
- url: https://conda.anaconda.org/conda-forge/noarch/identify-2.5.33-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/vine-5.1.0-pyhd8ed1ab_0.conda
hash:
- md5: 93c8f8ceb83827d88deeba796f07fba7
- sha256: ce2a64c18221af96226be23278d81f22ff9f64b3c047d8865590f6718915303f
+ md5: af71debe5f1819b065c0ba2b062ae81c
+ sha256: 95a819731659de391ee084d68a1bdee56a5a16d0db95783c6cf115638d372215
category: main
optional: false
-- name: oauthlib
- version: 3.2.2
+- name: vine
+ version: 5.1.0
manager: conda
platform: osx-64
dependencies:
- cryptography: ''
- blinker: ''
python: '>=3.6'
- pyjwt: '>=1.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/oauthlib-3.2.2-pyhd8ed1ab_0.tar.bz2
+ url: https://conda.anaconda.org/conda-forge/noarch/vine-5.1.0-pyhd8ed1ab_0.conda
hash:
- md5: 8f882b197fd9c4941a787926baea4868
- sha256: 0cfd5146a91d3974f4abfc2a45de890371d510a77238fe553e036ec8c031dc5b
+ md5: af71debe5f1819b065c0ba2b062ae81c
+ sha256: 95a819731659de391ee084d68a1bdee56a5a16d0db95783c6cf115638d372215
category: main
optional: false
-- name: pydantic-settings
- version: 2.1.0
+- name: virtualenv
+ version: 20.25.1
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
+ distlib: <1,>=0.3.7
+ filelock: <4,>=3.12.2
+ platformdirs: <5,>=3.9.1
python: '>=3.8'
- python-dotenv: '>=0.21.0'
- pydantic: '>=2.3.0'
- url: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.1.0-pyhd8ed1ab_1.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.25.1-pyhd8ed1ab_0.conda
hash:
- md5: 2a63052c1180846d4a6aaa9df7e113a3
- sha256: 2c80df34463dabec383b37dc19da48f84a1ea97f3d828d6d0dd220110da5f4e1
+ md5: 8797a4e26be36880a603aba29c785352
+ sha256: 1ced4445cf72cd9dc344ad04bdaf703a08cc428c8c46e4bda928ad79786ee153
category: main
optional: false
-- name: pyopenssl
- version: 23.3.0
+- name: virtualenv
+ version: 20.25.1
manager: conda
platform: osx-64
dependencies:
- python: '>=3.7'
- cryptography: '>=41.0.5,<42'
- url: https://conda.anaconda.org/conda-forge/noarch/pyopenssl-23.3.0-pyhd8ed1ab_0.conda
+ python: '>=3.8'
+ distlib: <1,>=0.3.7
+ filelock: <4,>=3.12.2
+ platformdirs: <5,>=3.9.1
+ url: https://conda.anaconda.org/conda-forge/noarch/virtualenv-20.25.1-pyhd8ed1ab_0.conda
hash:
- md5: 7819533e674dbbc51468f3228b9b1bb6
- sha256: f7e04c4a49b1593140231d70801e2204e314e26d7141bfbdc8089d04114c0010
+ md5: 8797a4e26be36880a603aba29c785352
+ sha256: 1ced4445cf72cd9dc344ad04bdaf703a08cc428c8c46e4bda928ad79786ee153
category: main
optional: false
-- name: rich-click
- version: 1.7.2
+- name: wcwidth
+ version: 0.2.13
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.7'
- click: '>=7,<9'
- rich: '>=10'
- url: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.7.2-pyhd8ed1ab_0.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda
hash:
- md5: fe1eae76a71246959cefd09b5b00869b
- sha256: 4bfddbc5716a09bfea1c3345b1eed0ddb36d0e55f357afb60ca3e73c9231cc68
+ md5: 68f0738df502a14213624b288c60c9ad
+ sha256: b6cd2fee7e728e620ec736d8dfee29c6c9e2adbd4e695a31f1d8f834a83e57e3
category: main
optional: false
-- name: s3transfer
- version: 0.9.0
+- name: wcwidth
+ version: 0.2.13
manager: conda
platform: osx-64
dependencies:
python: '>=3.8'
- botocore: '>=1.33.2,<2.0a.0'
- url: https://conda.anaconda.org/conda-forge/noarch/s3transfer-0.9.0-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda
hash:
- md5: 27ad14e5fc6a13f05b90140debc72cd2
- sha256: c9fc315d830238113160471467259740593966bcf59f17287a0baeaf1f6a76d8
+ md5: 68f0738df502a14213624b288c60c9ad
+ sha256: b6cd2fee7e728e620ec736d8dfee29c6c9e2adbd4e695a31f1d8f834a83e57e3
category: main
optional: false
-- name: boto3
- version: 1.34.2
+- name: werkzeug
+ version: 2.2.3
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.8'
- jmespath: '>=0.7.1,<2.0.0'
- s3transfer: '>=0.9.0,<0.10.0'
- botocore: '>=1.34.2,<1.35.0'
- url: https://conda.anaconda.org/conda-forge/noarch/boto3-1.34.2-pyhd8ed1ab_0.conda
+ markupsafe: '>=2.1.1'
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-2.2.3-pyhd8ed1ab_0.conda
hash:
- md5: 6f47ce30284317cb85960c4668cc5bd9
- sha256: c0444d9d386a1991fadca8b31b9dfc302e5d781b8a2d29faff2c47286eff477c
+ md5: 94dea682ba9d8e091e1f46872886fb1f
+ sha256: 38f68541580b74ed91396a67766fb96088f7b161bfd203675ed7a257d642e2e3
category: main
optional: false
-- name: bump-my-version
- version: 0.9.3
+- name: werkzeug
+ version: 2.2.3
manager: conda
platform: osx-64
dependencies:
- click: ''
- rich: ''
- tomlkit: ''
- rich-click: ''
- python: '>=3.8'
- pydantic: <2.0.0
- url: https://conda.anaconda.org/conda-forge/noarch/bump-my-version-0.9.3-pyhd8ed1ab_0.conda
+ python: '>=3.7'
+ markupsafe: '>=2.1.1'
+ url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-2.2.3-pyhd8ed1ab_0.conda
hash:
- md5: 24f0c263af3783651f77b021a6ad97a8
- sha256: b5530371b54677cb72d93ae091052327b2c809a6066d85366af4f3f0728888eb
+ md5: 94dea682ba9d8e091e1f46872886fb1f
+ sha256: 38f68541580b74ed91396a67766fb96088f7b161bfd203675ed7a257d642e2e3
category: main
optional: false
-- name: pre-commit
- version: 3.6.0
+- name: wheel
+ version: 0.42.0
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.9'
- pyyaml: '>=5.1'
- identify: '>=1.0.0'
- nodeenv: '>=0.11.1'
- cfgv: '>=2.0.0'
- virtualenv: '>=20.10.0'
- url: https://conda.anaconda.org/conda-forge/noarch/pre-commit-3.6.0-pyha770c72_0.conda
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.42.0-pyhd8ed1ab_0.conda
hash:
- md5: 473a7cfca197da0a10cff3f6dded7d4b
- sha256: 7d1f4b4a2eb4946b5808769642c5f643788c3a9e090f1c02a6c63f8794fb3d54
+ md5: 1cdea58981c5cbc17b51973bcaddcea7
+ sha256: 80be0ccc815ce22f80c141013302839b0ed938a2edb50b846cf48d8a8c1cfa01
category: main
optional: false
-- name: requests-oauthlib
- version: 1.3.1
+- name: wheel
+ version: 0.42.0
manager: conda
platform: osx-64
dependencies:
- python: '>=3.4'
- requests: '>=2.0.0'
- oauthlib: '>=3.0.0'
- url: https://conda.anaconda.org/conda-forge/noarch/requests-oauthlib-1.3.1-pyhd8ed1ab_0.tar.bz2
+ python: '>=3.7'
+ url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.42.0-pyhd8ed1ab_0.conda
hash:
- md5: 61b279f051eef9c89d58f4d813e75e04
- sha256: 889e3c1b84467b64046776db95dc4c5ea4dad5afaa5ec18ad811bd95c63286b0
+ md5: 1cdea58981c5cbc17b51973bcaddcea7
+ sha256: 80be0ccc815ce22f80c141013302839b0ed938a2edb50b846cf48d8a8c1cfa01
category: main
optional: false
-- name: kombu
- version: 5.3.4
+- name: wtforms
+ version: 3.1.2
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- amqp: '>=5.1.1,<6.0.0'
- boto3: '>=1.26.143'
- python: '>=3.11,<3.12.0a0'
- python_abi: 3.11.*
- vine: ''
- url: https://conda.anaconda.org/conda-forge/osx-64/kombu-5.3.4-py311h6eed73b_0.conda
+ markupsafe: ''
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/wtforms-3.1.2-pyhd8ed1ab_0.conda
hash:
- md5: d3dbbb66857aea7968bf38186bbf970c
- sha256: 249eded4ed2933f29e90e98632a2e50b74d20c0829cf9d302b19fb478c07cdd2
+ md5: 1e60bfa73e13b1ca9c439c6938664ab4
+ sha256: 6d3ae74038e34945daf8e091b7fa85741162c0db6e989da4d0f8164d84a4cbce
category: main
optional: false
-- name: celery
- version: 5.3.4
+- name: wtforms
+ version: 3.1.2
manager: conda
platform: osx-64
dependencies:
- python: '>=3.7'
- backports.zoneinfo: '>=0.2.1'
- pytz: '>=2021.3'
- python-dateutil: '>=2.8.2'
- importlib-metadata: '>=3.6'
- vine: '>=5.0.0,<6.0'
- click-plugins: '>=1.1.1'
- click-repl: '>=0.2.0'
- billiard: '>=4.1.0,<5.0'
- click: '>=8.1.2,<9.0'
- click-didyoumean: '>=0.3.0'
- python-tzdata: '>=2022.7'
- kombu: '>=5.3.2,<6.0'
- url: https://conda.anaconda.org/conda-forge/noarch/celery-5.3.4-pyhd8ed1ab_1.conda
+ markupsafe: ''
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/wtforms-3.1.2-pyhd8ed1ab_0.conda
hash:
- md5: 64a66acef34f7cca60b929b8228951f1
- sha256: b93109413da956e6e2a37b0a852ccb15a45f706c7ce718f9ea094c660b18b5e3
+ md5: 1e60bfa73e13b1ca9c439c6938664ab4
+ sha256: 6d3ae74038e34945daf8e091b7fa85741162c0db6e989da4d0f8164d84a4cbce
category: main
optional: false
-- name: flask
- version: 2.2.5
+- name: xz
+ version: 5.2.6
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.7'
- jinja2: '>=3.0'
- click: '>=8.0'
- importlib-metadata: '>=3.6.0'
- itsdangerous: '>=2.0'
- werkzeug: '>=2.2.2'
- celery: '>=5.2.7'
- url: https://conda.anaconda.org/conda-forge/noarch/flask-2.2.5-pyhd8ed1ab_0.conda
+ libgcc-ng: '>=12'
+ url: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2
hash:
- md5: 66c558a28b9b47c1e2aa8e8cb80b9037
- sha256: 9356ae47278788439770eb9d05bfeb72c39a53a8b10a0e534b612f99b9c18e9b
+ md5: 2161070d867d1b1204ea749c8eec4ef0
+ sha256: 03a6d28ded42af8a347345f82f3eebdd6807a08526d47899a42d62d319609162
category: main
optional: false
-- name: flask-dance
- version: 7.0.0
+- name: xz
+ version: 5.2.6
manager: conda
platform: osx-64
- dependencies:
- werkzeug: ''
- urlobject: ''
- python: '>=3.7'
- requests-oauthlib: '>=1.0.0'
- requests: '>=2.0'
- flask: '>=2.0.3'
- oauthlib: '>=3.2'
- url: https://conda.anaconda.org/conda-forge/noarch/flask-dance-7.0.0-pyhd8ed1ab_0.conda
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2
hash:
- md5: a0007a17aa03b39c941f921f082afe9e
- sha256: 7f3b75ba7f321c9058e0adbd4113fe3bfad3fc28ea266fb42f7636091cd4ca34
+ md5: a72f9d4ea13d55d745ff1ed594747f10
+ sha256: eb09823f34cc2dd663c0ec4ab13f246f45dcd52e5b8c47b9864361de5204a1c8
category: main
optional: false
-- name: flask-login
- version: 0.6.3
+- name: yaml
+ version: 0.2.5
manager: conda
- platform: osx-64
+ platform: linux-64
dependencies:
- python: '>=3.7'
- flask: '>=1.0.4'
- werkzeug: '>=1.0.1'
- url: https://conda.anaconda.org/conda-forge/noarch/flask-login-0.6.3-pyhd8ed1ab_1.conda
+ libgcc-ng: '>=9.4.0'
+ url: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2
hash:
- md5: 1d3523e7b18b38e4be992bf462d99e40
- sha256: 23ffed52801132e3e434c82a544ef1b77efbc025878a1a1cd0fbcc4c361cd9de
+ md5: 4cb3ad778ec2d5a7acbdf254eb1c42ae
+ sha256: a4e34c710eeb26945bdbdaba82d3d74f60a78f54a874ec10d373811a5d217535
category: main
optional: false
-- name: flask-sqlalchemy
- version: 3.0.3
+- name: yaml
+ version: 0.2.5
manager: conda
platform: osx-64
+ dependencies: {}
+ url: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2
+ hash:
+ md5: d7e08fcf8259d742156188e8762b4d20
+ sha256: 5301417e2c8dea45b401ffee8df3957d2447d4ce80c83c5ff151fc6bfe1c4148
+ category: main
+ optional: false
+- name: zipp
+ version: 3.17.0
+ manager: conda
+ platform: linux-64
dependencies:
- python: '>=3.7'
- flask: '>=2.2'
- sqlalchemy: '>=1.4.18'
- url: https://conda.anaconda.org/conda-forge/noarch/flask-sqlalchemy-3.0.3-pyhd8ed1ab_0.conda
+ python: '>=3.8'
+ url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda
hash:
- md5: 6a301e2aa76aef91787e15f59ab03390
- sha256: 460693607ab0e2feb600bb755851c0c19db8d6dbd1c7636904c8de6f2c63040d
+ md5: 2e4d6bc0b14e10f895fc6791a7d9b26a
+ sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26
category: main
optional: false
-- name: flask-wtf
- version: 1.2.1
+- name: zipp
+ version: 3.17.0
manager: conda
platform: osx-64
dependencies:
- flask: ''
- itsdangerous: ''
- wtforms: ''
python: '>=3.8'
- url: https://conda.anaconda.org/conda-forge/noarch/flask-wtf-1.2.1-pyhd8ed1ab_0.conda
+ url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda
hash:
- md5: e7b75c25f98d7b55943466683e400529
- sha256: cee583240eec93d27f262f3bb8cdecf8334e502d81923295d98f378b15fe26d5
+ md5: 2e4d6bc0b14e10f895fc6791a7d9b26a
+ sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26
+ category: main
+ optional: false
+- name: bootstrap-flask
+ version: 2.3.3
+ manager: pip
+ platform: linux-64
+ dependencies:
+ flask: '*'
+ wtforms: '*'
+ url: https://files.pythonhosted.org/packages/95/e4/7f3dd2dba1ef70ddbf1bf6a58ea8245c20b2d44bd81e8b37215e812f5d0e/Bootstrap_Flask-2.3.3-py2.py3-none-any.whl
+ hash:
+ sha256: 4c3d1f1b8ee19081dfc80e03aba5cb19cd92a8d54ba0ba98cee69acffded91d0
category: main
optional: false
- name: bootstrap-flask
@@ -3216,6 +3083,42 @@ package:
sha256: 4c3d1f1b8ee19081dfc80e03aba5cb19cd92a8d54ba0ba98cee69acffded91d0
category: main
optional: false
+- name: flask-pydantic
+ version: 0.10.0
+ manager: pip
+ platform: linux-64
+ dependencies:
+ flask: '*'
+ pydantic: '>=1.7'
+ url: https://files.pythonhosted.org/packages/9e/a8/89b0d85e2b76a10bb1987050c8d3fd5160b8749574807f4502525cba5988/Flask_Pydantic-0.10.0-py3-none-any.whl
+ hash:
+ sha256: a52e12d5c3d9f53c06edb4a138973d2bf6dea968269bcedc67751403ca70e856
+ category: main
+ optional: false
+- name: flask-pydantic
+ version: 0.10.0
+ manager: pip
+ platform: osx-64
+ dependencies:
+ flask: '*'
+ pydantic: '>=1.7'
+ url: https://files.pythonhosted.org/packages/9e/a8/89b0d85e2b76a10bb1987050c8d3fd5160b8749574807f4502525cba5988/Flask_Pydantic-0.10.0-py3-none-any.whl
+ hash:
+ sha256: a52e12d5c3d9f53c06edb4a138973d2bf6dea968269bcedc67751403ca70e856
+ category: main
+ optional: false
+- name: wtforms-sqlalchemy
+ version: '0.3'
+ manager: pip
+ platform: linux-64
+ dependencies:
+ wtforms: '>=1.0.5'
+ sqlalchemy: '>=0.7.10'
+ url: https://files.pythonhosted.org/packages/62/71/a5624ff63f4024d27489263b56e3ab6a5122087eb432d14617cfed90ec3d/WTForms_SQLAlchemy-0.3-py3-none-any.whl
+ hash:
+ sha256: 90195d7592bf256d82498c42c79d416832e4a4e6fbca4f1e745a018f66d26c47
+ category: main
+ optional: false
- name: wtforms-sqlalchemy
version: '0.3'
manager: pip
diff --git a/doc/how-to/development.md b/doc/how-to/development.md
index dc8554b3..451ec6d4 100644
--- a/doc/how-to/development.md
+++ b/doc/how-to/development.md
@@ -88,6 +88,8 @@ docker compose logs -f
In dev this will initialize a PostgreSQL DB that is preserved in the `_db/` directory.
In NSIDC deployment environments we deploy the db on a separate host using the
[usaon-benefit-tool-db project](https://github.com/nsidc/usaon-benefit-tool-db).
+
+**The dev credentials are specified in `compose.dev.yml`.**
:::
Run `./scripts/invoke_in_container.sh db.init`
@@ -145,3 +147,74 @@ See
[our documentation on third-party services](/reference/third-party-service-dependencies.md)
for more, but the way they are currently set up should allow for development on
`localhost`.
+
+
+### Coding concerns
+
+#### Adding a new route
+
+* Create the new route function in a module under `/routes/`
+* Should the route be restricted to only logged-in users? If so, decorate with
+ `@login_required`.
+* If you need to create a new module and blueprint, don't forget to register the
+ blueprint in `/__init__.py`
+
+
+#### REST API design
+
+* Use `.../form` endpoints for HTMX to get user interface elements.
+ * This is valuable for using HTMX to help with separation of user interface
+ concerns; e.g. instead of designing a page with multiple forms, design form
+ endpoints and HTMX elements on the page which use those endpoints to display the
+ returned forms in a modal.
+ * Use `GET resources/form` route to serve a form to add a new resource to collection
+ "resources".
+ * That form will `POST resources` to request the resource to be created.
+ * Use `GET resource//form` route to serve a form to edit a "resource".
+ * That form will `PUT resource/` to request the resource to be updated.
+* Use consistent HTTP response codes:
+ * `200`: Successfully returned page or successfully updated resource
+ * `201`: Create resource
+ * `202`: Successfully deleted resource
+ * ...
+* Avoid redirections after operations, e.g. after a delete, don't `302`. Instead,
+ `202` and pass an `HX-Redirect` header to inform HTMX, if used on the client side,
+ what to do.
+* Use separate route functions for separate verbs/methods! Otherwise there can be
+ excessive conditional logic inside route functions.
+
+
+#### Flask route design and naming
+
+Most importantly, **keep it simple**! Constructing route strings can be confusing
+otherwise.
+
+* Use HTTP verbs to name basic endpoint functions (`get`, `post`, `delete`, etc.).
+ Resist the honorable temptation to write descriptive route function names. Instead of
+ `view_project_data_products`, stick with `get`. Then the resultant route identifier
+ might be `project.data_products.get` instead of
+ `project.data_products.view_project_data_products`.
+ * Form-serving routes are an exception; see the "REST API design" section above.
+* Use nested routes. This pushes the responsibility for route registry down the route
+ hierarchy instead of requiring every blueprint to be registered in `__init__.py`.
+
+
+#### Flask template design and naming
+
+##### Macros
+
+* Macros live in `templates/macros/`
+* Macros that output HTML should be prefixed with `render_`. The codebase is currently
+ not in compliance with this.
+
+
+### Debugging
+
+#### HTMX routes
+
+When you put a `breakpoint()` in a route that returns a partial to HTMX and try to test
+in the browser, HTMX will swallow the debugger response, treating it like a failure.
+
+You can directly visit the route in question with your browser to bypass this and access
+the Flask debugger! However, the HTMX Javascript won't load, so you can't really use
+this to debug forms.
diff --git a/doc/notes/TODO.md b/doc/notes/TODO.md
index 10806c7f..aa736ce0 100644
--- a/doc/notes/TODO.md
+++ b/doc/notes/TODO.md
@@ -2,6 +2,18 @@
title: "TODO"
---
+
+## Type checking
+
+* The data models don't seem to be being type checked as expected. E.g. Passing the
+ wrong field name doesn't trigger the type checker.
+
+
+## Dependencies
+
+* SQLAlchemy -> 2.0. NOTE: Remove the mypy plugin during migration!
+
+
## Templates
* Should Jinja templates have a `.html` or `.j2` extension?
diff --git a/doc/reference/data_model.md b/doc/reference/data_model.md
index cadb5423..d1495522 100644
--- a/doc/reference/data_model.md
+++ b/doc/reference/data_model.md
@@ -1,16 +1,6 @@
```mermaid
erDiagram
-%% Dynamic operational data:
-survey {
- uuid id PK
- int response_id FK
- str title
- str created_by FK
- datetime created_timestamp
- str notes "nullable"
-}
-
user {
string id PK "user identifier"
string role FK
@@ -19,12 +9,19 @@ user {
string affiliation "?"
}
-response {
+role {
+ string id PK "name"
+}
+
+%% Dynamic operational data:
+assessment {
uuid id PK
- seq version PK
+ %% seq version PK
- string expert_user_id FK
- string application_object_id FK
+ str title
+ str description
+
+ string assignee FK
array tags
@@ -34,102 +31,62 @@ response {
}
-response_observing_system {
- int response_id FK
- string id PK
- string object_id FK
+assessment_node {
+ int id PK "SK"
+ int assessment_id FK
+ int node_id FK
- enum type
- string url
- string author_name
- string author_email
- string funding_country
- string funding_agency
- string references_citations
- string notes "nullable"
}
-%% This name is confusing, but "observational" _is_ a type of observing system
-response_observing_system_observational {
- int response_id PK
- string response_observing_system_id FK
+link {
+ int source_assessment_node_id PK "FK"
+ int target_assessment_node_id PK "FK"
- string platform
- string sensor
+ %% TODO identify which rating
+ int rating
}
-response_observing_system_research {
- int response_id PK
- string response_observing_system_id FK
-
-
- string intermediate_product
-}
-
-response_observing_system_data_product {
- int response_id PK
- string observing_system_id PK
- string data_product_id PK
-
- int observing_system_contribution_to_data_product_rating "0-100"
- int satisfaction_rating "0-100"
- string rationale "nullable"
- string needed_improvements "nullable"
-}
-
-response_data_product {
+%% AKA node library
+node {
int id PK
- int response_id FK
-
- str name
- int satisfaction_rating "0-100"
-}
-
-response_data_product_application {
- string response_data_product_id FK
- string response_application_id PK
-
- int data_product_contribution_to_application_rating "0-100"
- int satisfaction_rating "0-100"
- string rationale "nullable"
- string needed_improvements "nullable"
-}
-response_application {
- int id PK
+ enum type
- int response_id FK
- string name
-}
+ str description
+ %% not implemented in the app
+ %% str tags
+ str version
-response_application_societal_benefit_area {
- int response_application_id FK
- string response_societal_benefit_area_id FK
+ string created_by FK
+ datetime created
+ datetime updated
- int application_contribution_to_sociateal_benefit_area_rating "0-100"
}
+node_other{
+ int node_id PK "FK"
+ %% str societal_benefit_area_id FK "UK"
-response_object {
- string id PK "name"
- string type FK
- TODO TODO "more fields?"
+ enum type
+ str short_name
+ str full_name
+ str organization
+ str funder
+ str funding_country
+ str website
+ str contact_information
+ str persistent_identifier
+ boolean hypothetical
}
-
-analysis {
- string id PK "name"
- string analyst_user_id FK
- string description
-}
-analysis_response {
- string analysis_id PK
- string response_id PK
+node_societal_benefit_area {
+ int node_id PK "FK"
+ str societal_benefit_area_id FK "UK"
}
%% Static reference data:
-response_object_type {
+node_type {
string id PK "name"
}
societal_benefit_area {
@@ -143,52 +100,29 @@ societal_benefit_key_objective {
string id PK "name"
string societal_benefit_subarea_id FK
}
-role {
- string id PK "name"
-}
-
%% Relationships
-survey }|--|| user: ""
+
+assessment }|--|| user: ""
user }|--|| role: ""
+node }|--|| user: ""
+
-response }|--o{ survey: ""
-response }o--|| user: ""
-response }o--|| response_object: ""
+assessment_node ||--|{ link: "points from"
+assessment_node ||--|{ link: "points to"
-response ||--o{ response_observing_system: ""
-response ||--o{ response_data_product: ""
-response ||--o{ response_application: ""
-response ||--o{ response_application_societal_benefit_area: ""
+node ||--|{ assessment_node: ""
+assessment ||--|{ assessment_node: ""
-response_observing_system }|--|| response_object: ""
-response_observing_system ||--o| response_observing_system_observational: ""
-response_observing_system ||--o| response_observing_system_research: ""
+node ||--o| node_societal_benefit_area: ""
+node_societal_benefit_area |o--|| societal_benefit_area: ""
-response_data_product }|--|| response_object: ""
-response_application }|--|| response_object: ""
+node }o--|| node_type: ""
+node ||--|| node_other: ""
societal_benefit_area ||--|{ societal_benefit_subarea: ""
societal_benefit_subarea ||--|{ societal_benefit_key_objective: ""
-
-response_application_societal_benefit_area ||--|| societal_benefit_area: ""
-
-response_object }|--|| response_object_type: ""
-
-analysis }|--|| user: ""
-
-%% Associative relationships (i.e. relationships with data)
-response_observing_system ||--|{ response_observing_system_data_product: ""
-response_data_product ||--|{ response_observing_system_data_product: ""
-
-response_data_product ||--|{ response_data_product_application: ""
-response_application ||--|{ response_data_product_application: ""
-
-response_application ||--|{ response_application_societal_benefit_area: ""
-
-response }|--o{ analysis_response: ""
-analysis }|--o{ analysis_response: ""
```
diff --git a/environment.yml b/environment.yml
index b2e7cdc1..ffaeab94 100644
--- a/environment.yml
+++ b/environment.yml
@@ -45,3 +45,4 @@ dependencies:
# TODO: Get these on conda-forge
- wtforms-sqlalchemy
- bootstrap-flask ~=2.3.0
+ - flask-pydantic ~=0.10.0
diff --git a/pyproject.toml b/pyproject.toml
index a0e8dc03..3b492f9e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -22,7 +22,7 @@ warn_unused_configs = true
warn_unreachable = true
# disallow_untyped_defs = true
# disallow_incomplete_defs = true
-# struct = true
+# strict = true
[[tool.mypy.overrides]]
module = [
@@ -31,6 +31,7 @@ module = [
"flask_wtf.*",
"flask_dance.*",
"flask_login.*",
+ "flask_pydantic.*",
"wtforms.*",
"wtforms_sqlalchemy.*",
]
diff --git a/tasks/db.py b/tasks/db.py
index 6310e385..c94d952f 100644
--- a/tasks/db.py
+++ b/tasks/db.py
@@ -4,8 +4,16 @@
@task(aliases=('recreate',))
-def init(ctx, *, load=True):
- """Drop and recreate all database tables, loading them by default."""
+def init(ctx, *, reference_data=True):
+ """Drop and recreate all database tables, loading them by default.
+
+ TODO: Enable loading test data. Currently doesn't work with error `Instance
+ is not bound to a Session`. Works fine when directly running load_test_data.
+
+ ```python
+ def init(ctx, *, reference_data=True, test_data=False):
+ ```
+ """
if not in_container():
print(
'Please run from the container context using'
@@ -23,10 +31,12 @@ def init(ctx, *, load=True):
print('Recreating tables...')
recreate_tables_()
- if load:
- print('Loading reference tables...')
+ if reference_data:
load_reference_data(ctx)
+ # if test_data:
+ # load_test_data(ctx)
+
@task()
def load_reference_data(ctx):
@@ -44,4 +54,25 @@ def load_reference_data(ctx):
app = create_app()
with app.app_context():
+ print('Loading reference tables...')
populate_reference_data()
+
+
+@task()
+def load_test_data(ctx):
+ """Populate operational tables with test data."""
+ if not in_container():
+ print(
+ 'Please run from the container context using'
+ ' `scripts/invoke_in_container.sh`',
+ )
+ return
+
+ from usaon_benefit_tool import create_app
+ from usaon_benefit_tool.util.db.setup import populate_test_data
+
+ app = create_app()
+
+ with app.app_context():
+ print('Loading test data...')
+ populate_test_data()
diff --git a/usaon_benefit_tool/__init__.py b/usaon_benefit_tool/__init__.py
index 676c4a18..0f69178a 100644
--- a/usaon_benefit_tool/__init__.py
+++ b/usaon_benefit_tool/__init__.py
@@ -13,9 +13,11 @@
from werkzeug.middleware.proxy_fix import ProxyFix
from usaon_benefit_tool.constants import repo
+from usaon_benefit_tool.constants.sankey import DUMMY_NODE_ID
from usaon_benefit_tool.constants.version import VERSION
from usaon_benefit_tool.util.db.connect import db_connstr
from usaon_benefit_tool.util.envvar import envvar_is_true
+from usaon_benefit_tool.util.flask_jsglue import JSGlue
__version__: Final[str] = VERSION
@@ -38,8 +40,25 @@ def create_app():
"""Create and configure the app."""
# TODO: enable override config to test_config
# https://flask.palletsprojects.com/en/2.3.x/tutorial/factory/
+ _monkeypatch()
app = Flask(__name__)
+ _setup_config(app)
+ _setup_proxy_support(app)
+
+ db.init_app(app)
+
+ Bootstrap5(app)
+ JSGlue(app)
+
+ _setup_login(app)
+ _register_blueprints(app)
+ _register_template_helpers(app)
+
+ return app
+
+
+def _setup_config(app) -> None:
app.config['SECRET_KEY'] = os.environ.get('FLASK_SECRET_KEY', 'youcanneverguess')
app.config['SQLALCHEMY_DATABASE_URI'] = db_connstr(app)
app.config['BOOTSTRAP_BOOTSWATCH_THEME'] = 'cosmo'
@@ -52,13 +71,13 @@ def create_app():
# DEV ONLY: Disable login
app.config['LOGIN_DISABLED'] = envvar_is_true("USAON_BENEFIT_TOOL_LOGIN_DISABLED")
+
+def _setup_proxy_support(app) -> None:
if envvar_is_true("USAON_BENEFIT_TOOL_PROXY"):
app.wsgi_app = ProxyFix(app.wsgi_app, x_prefix=1) # type: ignore
- db.init_app(app)
-
- Bootstrap5(app)
+def _setup_login(app) -> None:
login_manager = LoginManager()
login_manager.login_view = "login.login"
login_manager.init_app(app)
@@ -86,44 +105,10 @@ def before_request():
if time.time() >= token['expires_at']:
del s['google_oauth_token']
- from usaon_benefit_tool.routes.login import google_bp, login_bp
- from usaon_benefit_tool.routes.logout import logout_bp
- from usaon_benefit_tool.routes.root import root_bp
- from usaon_benefit_tool.routes.survey import response_bp, survey_bp
- from usaon_benefit_tool.routes.survey.applications import application_bp
- from usaon_benefit_tool.routes.survey.data_products import data_product_bp
- from usaon_benefit_tool.routes.survey.observing_systems import observing_system_bp
- from usaon_benefit_tool.routes.survey.relationships.application_societal_benefit_area import (
- application_societal_benefit_area_bp,
- )
- from usaon_benefit_tool.routes.survey.relationships.data_product_application import (
- data_product_application_bp,
- )
- from usaon_benefit_tool.routes.survey.relationships.observing_system_data_product import (
- observing_system_data_product_bp,
- )
- from usaon_benefit_tool.routes.survey.sbas import societal_benefit_area_bp
- from usaon_benefit_tool.routes.surveys import surveys_bp
- from usaon_benefit_tool.routes.user import user_bp
- from usaon_benefit_tool.routes.users import users_bp
-
- app.register_blueprint(root_bp)
- app.register_blueprint(surveys_bp)
- app.register_blueprint(survey_bp)
- app.register_blueprint(user_bp)
- app.register_blueprint(users_bp)
- app.register_blueprint(login_bp)
- app.register_blueprint(logout_bp)
- app.register_blueprint(google_bp, url_prefix="/google_oauth")
- app.register_blueprint(response_bp)
- app.register_blueprint(observing_system_bp)
- app.register_blueprint(societal_benefit_area_bp)
- app.register_blueprint(application_bp)
- app.register_blueprint(data_product_bp)
- app.register_blueprint(observing_system_data_product_bp)
- app.register_blueprint(data_product_application_bp)
- app.register_blueprint(application_societal_benefit_area_bp)
+def _register_template_helpers(app) -> None:
+ # TODO: Consider context processors instead?
+ # https://flask.palletsprojects.com/en/2.3.x/templating/#context-processors
app.jinja_env.globals.update(
__version__=__version__,
sqla_inspect=sqla_inspect,
@@ -131,6 +116,9 @@ def before_request():
doc_url=repo.DOC_URL,
discuss_url=repo.DISCUSS_URL,
current_year=repo.CURRENT_YEAR,
+ constants={
+ "DUMMY_NODE_ID": DUMMY_NODE_ID,
+ },
)
md = Markdown(extensions=['fenced_code'])
@@ -139,4 +127,37 @@ def before_request():
dateformat=lambda date: date.strftime("%Y-%m-%d %H:%M%Z"),
)
- return app
+
+def _register_blueprints(app) -> None:
+ # TODO: Extract function register_blueprints
+ from usaon_benefit_tool.routes.assessment import assessment_bp
+ from usaon_benefit_tool.routes.assessments import assessments_bp
+ from usaon_benefit_tool.routes.login import google_bp, login_bp
+ from usaon_benefit_tool.routes.logout import logout_bp
+ from usaon_benefit_tool.routes.node import node_bp
+ from usaon_benefit_tool.routes.nodes import nodes_bp
+ from usaon_benefit_tool.routes.root import root_bp
+ from usaon_benefit_tool.routes.user import user_bp
+ from usaon_benefit_tool.routes.users import users_bp
+
+ app.register_blueprint(root_bp)
+
+ app.register_blueprint(user_bp)
+ app.register_blueprint(users_bp)
+ app.register_blueprint(login_bp)
+ app.register_blueprint(logout_bp)
+ app.register_blueprint(google_bp, url_prefix="/google_oauth")
+
+ app.register_blueprint(assessments_bp)
+ app.register_blueprint(assessment_bp)
+
+ app.register_blueprint(nodes_bp)
+ app.register_blueprint(node_bp)
+
+
+def _monkeypatch():
+ import wtforms_sqlalchemy
+
+ from usaon_benefit_tool.util.monkeypatch.wtforms_sqlalchemy import model_fields
+
+ wtforms_sqlalchemy.orm.model_fields = model_fields
diff --git a/usaon_benefit_tool/_types.py b/usaon_benefit_tool/_types.py
index fe9c693c..d8dfcb10 100644
--- a/usaon_benefit_tool/_types.py
+++ b/usaon_benefit_tool/_types.py
@@ -1,7 +1,16 @@
from enum import Enum
-class ObservingSystemType(Enum):
- observational = 'observational'
- research = 'research'
- other = 'other'
+# FIXME: We're inheriting from `str` to make this JSON serializable for flask-pydantic.
+# Undo this once the lib fixes it.
+# https://github.com/bauerji/flask-pydantic/issues/54
+class NodeType(str, Enum):
+ OBSERVING_SYSTEM = 'observing_system'
+ DATA_PRODUCT = 'data_product'
+ APPLICATION = 'application'
+ SOCIETAL_BENEFIT_AREA = 'societal_benefit_area'
+
+
+class NodeTypeDiscriminator(Enum):
+ OTHER = "other"
+ SOCIETAL_BENEFIT_AREA = "sba"
diff --git a/usaon_benefit_tool/constants/sankey.py b/usaon_benefit_tool/constants/sankey.py
new file mode 100644
index 00000000..d3a428a4
--- /dev/null
+++ b/usaon_benefit_tool/constants/sankey.py
@@ -0,0 +1,3 @@
+from typing import Final
+
+DUMMY_NODE_ID: Final = "__DUMMY__"
diff --git a/usaon_benefit_tool/constants/status.py b/usaon_benefit_tool/constants/status.py
index 4af73990..26459d58 100644
--- a/usaon_benefit_tool/constants/status.py
+++ b/usaon_benefit_tool/constants/status.py
@@ -1,10 +1,9 @@
from typing import Final
-# Note STATUSES[0] is the default value
-# Keep that in mind when altering the list
-STATUSES: Final[list[str]] = [
- 'work in progress',
- 'published',
- 'closed',
- 'archived',
-]
+# NOTE: element 0 is the default value. Keep that in mind when altering the list.
+ASSESSMENT_STATUSES: Final[dict[str, str]] = {
+ 'work in progress': 'The assessment is not done yet',
+ 'published': 'The assessment is complete and visible to the public',
+ 'closed': 'TODO',
+ 'archived': 'TODO',
+}
diff --git a/usaon_benefit_tool/forms.py b/usaon_benefit_tool/forms.py
index e6f465d0..840f1826 100644
--- a/usaon_benefit_tool/forms.py
+++ b/usaon_benefit_tool/forms.py
@@ -1,10 +1,4 @@
-"""Forms corresponding to database models.
-
-TODO: What can we do to improve syncing between models and forms? Consider
-wtforms-sqlalchemy? Consider designing a custom class or type that can represent
-everything needed to construct column and field instances, and functions for converting
-objects of that class to appropriate field/column?
-"""
+"""Forms corresponding to database models."""
from functools import partial
from flask_wtf import FlaskForm
@@ -18,36 +12,22 @@
from usaon_benefit_tool import db
from usaon_benefit_tool.models.tables import (
- ResponseApplication,
- ResponseApplicationSocietalBenefitArea,
- ResponseDataProduct,
- ResponseDataProductApplication,
- ResponseObservingSystem,
- ResponseObservingSystemDataProduct,
- ResponseSocietalBenefitArea,
- Survey,
+ Assessment,
+ AssessmentNode,
+ Link,
+ Node,
+ NodeSubtypeOther,
+ NodeSubtypeSocietalBenefitArea,
User,
)
-common_response_object_fields = [
- 'short_name',
- 'full_name',
- 'organization',
- 'funder',
- 'funding_country',
- 'website',
- 'description',
- 'contact_name',
- 'contact_title',
- 'contact_email',
- 'tags',
- 'version',
-]
-
-app_response_object_fields = [
- *common_response_object_fields,
- 'performance_criteria',
- 'performance_rating',
+node_exclude = [
+ 'assessment_nodes',
+ 'created_by_id',
+ 'created_by',
+ 'created_timestamp',
+ 'updated_timestamp',
+ 'type',
]
@@ -66,6 +46,10 @@ def conv_String(self, field_args, **extra):
return super().conv_String(field_args, **extra)
+def get_node_label(node: Node) -> str:
+ return f"Object #{node.id} ({node.type.value}): {node.title}"
+
+
model_form = partial(
model_form,
converter=CustomModelConverter(),
@@ -78,56 +62,42 @@ def conv_String(self, field_args, **extra):
BaseModel: DeclarativeMeta = db.Model
FORMS_BY_MODEL: dict[BaseModel, FlaskForm] = {
- User: model_form(
- User,
- only=['orcid', 'biography', 'affiliation', 'role'],
- field_args={'role': {'get_label': 'id'}},
+ Assessment: model_form(Assessment, only=['title', 'description']),
+ AssessmentNode: model_form(
+ AssessmentNode,
+ only=['node'],
+ field_args={
+ 'node': {'get_label': get_node_label},
+ },
),
- Survey: model_form(Survey, only=['title', 'description']),
- # Response entities ("nodes" from Sankey diagram perspective)
- # TODO: Restrict "rating" values to correct range
- ResponseObservingSystem: model_form(
- ResponseObservingSystem,
- only=common_response_object_fields,
+ Link: model_form(
+ Link,
+ field_args={
+ 'source_assessment_node': {'get_label': lambda an: get_node_label(an.node)},
+ 'target_assessment_node': {'get_label': lambda an: get_node_label(an.node)},
+ },
),
- ResponseDataProduct: model_form(
- ResponseDataProduct,
- only=common_response_object_fields,
+ NodeSubtypeOther: model_form(
+ NodeSubtypeOther,
+ exclude=node_exclude,
),
- ResponseApplication: model_form(
- ResponseApplication,
- only=app_response_object_fields,
+ NodeSubtypeSocietalBenefitArea: model_form(
+ NodeSubtypeSocietalBenefitArea,
+ exclude=[*node_exclude, "societal_benefit_area_id"],
+ exclude_fk=False,
+ field_args={
+ 'societal_benefit_area': {'get_label': 'id'},
+ },
),
- ResponseSocietalBenefitArea: model_form(
- ResponseSocietalBenefitArea,
- only=['societal_benefit_area'],
- field_args={'societal_benefit_area': {'get_label': 'id'}},
- ),
- # Response relationships ("edges" from Sankey diagram perspective)
- ResponseObservingSystemDataProduct: model_form(
- ResponseObservingSystemDataProduct,
- only=[
- 'criticality_rating',
- 'performance_rating',
- 'rationale',
- 'needed_improvements',
- ],
- ),
- ResponseDataProductApplication: model_form(
- ResponseDataProductApplication,
- only=[
- 'criticality_rating',
- 'performance_rating',
- 'rationale',
- 'needed_improvements',
- ],
- ),
- ResponseApplicationSocietalBenefitArea: model_form(
- ResponseApplicationSocietalBenefitArea,
- only=['performance_rating'],
+ User: model_form(
+ User,
+ only=['orcid', 'biography', 'affiliation', 'role'],
+ # Helps drop-down display the correct user-facing string
+ field_args={'role': {'get_label': 'id'}},
),
}
+
# HACK: Add a submit button so bootstrap-flask's render_form macro can work
# TODO: Make this less hacky
for form in FORMS_BY_MODEL.values():
- form.submit_button = SubmitField('submit')
+ form.submit_button = SubmitField('Submit')
diff --git a/usaon_benefit_tool/models/tables.py b/usaon_benefit_tool/models/tables.py
index 2e84dac2..8478d7a8 100644
--- a/usaon_benefit_tool/models/tables.py
+++ b/usaon_benefit_tool/models/tables.py
@@ -1,4 +1,4 @@
-"""The VTA survey data model.
+"""The Value Tree Analysis assessment data model.
WARNING: The type-checker can't save you from yourself in this file; there are many
magic strings that need to match class names at runtime.
@@ -9,75 +9,28 @@
"""
from datetime import datetime
-from functools import cache
-from typing import Final, NotRequired
+from typing import ClassVar
from flask_login import UserMixin, current_user
-from sqlalchemy import CheckConstraint
+from sqlalchemy import CheckConstraint, case
from sqlalchemy.ext.declarative import DeclarativeMeta
from sqlalchemy.orm import relationship
from sqlalchemy.schema import Column, ForeignKey, Index, UniqueConstraint
-from sqlalchemy.types import Boolean, DateTime, Enum, Integer, SmallInteger, String
-from typing_extensions import TypedDict
+from sqlalchemy.types import Boolean, DateTime, Enum, Integer, String
from usaon_benefit_tool import db
-from usaon_benefit_tool._types import ObservingSystemType
-from usaon_benefit_tool.constants.status import STATUSES
+from usaon_benefit_tool._types import NodeType, NodeTypeDiscriminator
+from usaon_benefit_tool.constants.status import ASSESSMENT_STATUSES
# Workaround for missing type stubs for flask-sqlalchemy:
# https://github.com/dropbox/sqlalchemy-stubs/issues/76#issuecomment-595839159
+# TODO: Consider adding updated_timestamp there
BaseModel: DeclarativeMeta = db.Model
-class IORelationship(TypedDict):
- input: NotRequired[BaseModel]
- output: NotRequired[BaseModel]
-
-
-class IORelationshipMixin:
- """Provide a dictionary of input and/or output models related to this entity.
-
- TODO: Could use a clearer name. We may want to also have a mixin for models
- representing relationships instead of entities.
- """
-
- @classmethod
- @cache
- def __io__(cls) -> IORelationship:
- """Return dictionary of any IO relationships this model has.
-
- TODO: Fix and remove type-ignore comments.
- """
- io: IORelationship = {}
- if hasattr(cls, 'input_relationships'):
- io['input'] = cls.input_relationships.mapper.class_ # type: ignore
- if hasattr(cls, 'output_relationships'):
- io['output'] = cls.output_relationships.mapper.class_ # type: ignore
-
- if io == {}:
- raise RuntimeError(
- 'Please only use IORelationshipMixin on a model with'
- ' input_relationships or output_relationships',
- )
-
- return io
-
-
-class ResponseObjectFieldMixin:
- """Provide shared fields between all relationship objects to reduce repetition."""
-
- short_name = Column(String(256), nullable=False)
- full_name = Column(String(256), nullable=True)
- organization = Column(String(256), nullable=False)
- funder = Column(String(256), nullable=False)
- funding_country = Column(String(256), nullable=False)
- website = Column(String(256), nullable=True)
- description = Column(String(512), nullable=True)
- contact_name = Column(String(256), nullable=False)
- contact_title = Column(String(256), nullable=True)
- contact_email = Column(String(256), nullable=False)
- tags = Column(String, nullable=False)
- version = Column(String(64), nullable=True)
+####################
+# Association tables
+####################
class User(BaseModel, UserMixin):
@@ -101,7 +54,7 @@ class User(BaseModel, UserMixin):
nullable=False,
)
orcid = Column(
- String(64), # how long are orcids?
+ String(64), # TODO: Exactly how long are orcids? Validator?
nullable=True,
)
role_id = Column(
@@ -118,40 +71,47 @@ class User(BaseModel, UserMixin):
String,
nullable=True,
)
+
role = relationship('Role')
- responses = relationship(
- 'Response',
+ # TODO: Rename "created_assessments"? Add "filled_assessments"?
+ assessments = relationship(
+ 'Assessment',
back_populates='created_by',
)
- surveys = relationship(
- 'Survey',
+ nodes = relationship(
+ 'Node',
back_populates='created_by',
)
-class Survey(BaseModel):
- __tablename__ = 'survey'
+class Assessment(BaseModel):
+ __tablename__ = 'assessment'
id = Column(
Integer,
primary_key=True,
autoincrement=True,
)
- response_id = Column(
- Integer,
- ForeignKey('response.id'),
+ title = Column(
+ String(128),
+ nullable=False,
+ )
+
+ description = Column(
+ String(512),
nullable=True,
)
- title = Column(
- String(128),
+ private = Column(
+ Boolean,
nullable=False,
+ default=False,
)
status_id = Column(
String,
ForeignKey('status.id'),
- default=STATUSES[0],
+ default=next(iter(ASSESSMENT_STATUSES.keys())),
nullable=False,
)
@@ -167,36 +127,71 @@ class Survey(BaseModel):
nullable=False,
default=datetime.now,
)
-
- description = Column(
- String(512),
- nullable=True,
- )
-
- private = Column(
- Boolean,
+ updated_timestamp = Column(
+ DateTime,
nullable=False,
- default=False,
+ default=datetime.now,
+ onupdate=datetime.now,
)
- response = relationship(
- 'Response',
- back_populates='survey',
- )
created_by = relationship(
'User',
- back_populates='surveys',
+ back_populates='assessments',
+ )
+ status = relationship(
+ 'AssessmentStatus',
+ back_populates="assessments",
+ )
+ assessment_nodes = relationship(
+ 'AssessmentNode',
+ back_populates="assessment",
)
- status = relationship('Status')
+ # TODO: Re-enable this convenience relationship which passes through the association
+ # table. Disabled to enable defining AssessmentNode table in a consistent way; to
+ # make this work it seems you need to use the Table() constructor, but that was
+ # causing problems with constructing a relationship to Links table.
+ # nodes = relationship(
+ # 'Node',
+ # secondary=assessment_node,
+ # back_populates='assessments',
+ # )
-class Response(BaseModel):
- __tablename__ = 'response'
+class Node(BaseModel):
+ """The "Node Library"."""
+
+ __tablename__ = 'node'
id = Column(
Integer,
primary_key=True,
autoincrement=True,
)
+ type = Column(
+ Enum(NodeType),
+ nullable=False,
+ )
+ __mapper_args__: ClassVar = {
+ # 'polymorphic_identity': 'none', # TODO: Do we need this?
+ 'polymorphic_on': case(
+ [
+ (
+ type == NodeType.SOCIETAL_BENEFIT_AREA,
+ NodeTypeDiscriminator.SOCIETAL_BENEFIT_AREA.value,
+ ),
+ ],
+ else_=NodeTypeDiscriminator.OTHER.value,
+ ),
+ }
+
+ title = Column(String(128), nullable=False)
+ short_name = Column(String(256), nullable=False)
+ description = Column(String(512), nullable=True)
+
+ # TODO: Implement tags!
+ # tags = Column(String, nullable=False)
+ # TODO: Implement versioning!
+ # version = Column(String(64), nullable=True)
+
created_by_id = Column(
Integer,
ForeignKey('user.id'),
@@ -212,232 +207,138 @@ class Response(BaseModel):
DateTime,
nullable=False,
default=datetime.now,
+ onupdate=datetime.now,
)
- survey = relationship(
- 'Survey',
- back_populates='response',
- )
created_by = relationship(
'User',
- back_populates='responses',
- )
- observing_systems = relationship(
- 'ResponseObservingSystem',
- back_populates='response',
+ back_populates='nodes',
)
- data_products = relationship(
- 'ResponseDataProduct',
- back_populates='response',
- )
- applications = relationship(
- 'ResponseApplication',
- back_populates='response',
- )
- societal_benefit_areas = relationship(
- 'ResponseSocietalBenefitArea',
- back_populates='response',
+ assessment_nodes = relationship(
+ 'AssessmentNode',
+ back_populates="node",
)
+ # TODO: Re-enable this convenience relationship which passes through the association
+ # table. Disabled to enable defining AssessmentNode table in a consistent way; to
+ # make this work it seems you need to use the Table() constructor, but that was
+ # causing problems with constructing a relationship to Links table.
+ # assessments = relationship(
+ # 'Assessment',
+ # secondary=assessment_node,
+ # back_populates='nodes',
+ # )
-class ResponseObservingSystem(BaseModel, IORelationshipMixin, ResponseObjectFieldMixin):
- __tablename__ = 'response_observing_system'
- __table_args__ = (UniqueConstraint('short_name', 'response_id'),)
- id = Column(
- Integer,
- primary_key=True,
- autoincrement=True,
- )
- response_id = Column(
- Integer,
- ForeignKey('response.id'),
- nullable=False,
- )
+class NodeSubtypeOther(Node):
+ """Fields that are used for all node types except societal benefit area."""
- type = Column(
- Enum(ObservingSystemType),
- nullable=False,
- )
-
- __mapper_args__: Final[dict] = {
- 'polymorphic_identity': ObservingSystemType.other,
- 'polymorphic_on': type,
+ __tablename__ = "node_subtype_other"
+ __mapper_args__: ClassVar = {
+ 'polymorphic_identity': NodeTypeDiscriminator.OTHER.value,
}
- response = relationship(
- 'Response',
- back_populates='observing_systems',
- )
- output_relationships = relationship(
- 'ResponseObservingSystemDataProduct',
- back_populates='observing_system',
- cascade="all, delete",
- )
-
-
-class ResponseObservingSystemObservational(BaseModel):
- __tablename__ = 'response_observing_system_observational'
- __mapper_args__: Final[dict] = {
- 'polymorphic_identity': ObservingSystemType.observational,
- }
-
- response_observing_system_id = Column(
+ node_id = Column(
Integer,
- ForeignKey('response_observing_system.id'),
+ ForeignKey('node.id'),
primary_key=True,
+ nullable=False,
)
- platform = Column(String(256), nullable=False)
- sensor = Column(String(256), nullable=False)
-
-
-class ResponseObservingSystemResearch(BaseModel):
- __tablename__ = 'response_observing_system_research'
- __mapper_args__: Final[dict] = {
- 'polymorphic_identity': ObservingSystemType.research,
- }
+ organization = Column(String(256), nullable=False)
+ funder = Column(String(256), nullable=False)
+ funding_country = Column(String(256), nullable=False)
+ # TODO: do we need multiple website fields?
+ website = Column(String(256), nullable=True)
+ contact_information = Column(String(256), nullable=False)
+ persistent_identifier = Column(String(256), nullable=True)
+ hypothetical = Column(Boolean)
- response_observing_system_id = Column(
- Integer,
- ForeignKey('response_observing_system.id'),
- primary_key=True,
- )
- intermediate_product = Column(String(256), nullable=False)
+class NodeSubtypeSocietalBenefitArea(Node):
+ """Fields that are specific to societal benefit area type nodes."""
+ __tablename__ = "node_subtype_societal_benefit_area"
+ __table_args__ = (UniqueConstraint('societal_benefit_area_id'),)
+ __mapper_args__: ClassVar = {
+ 'polymorphic_identity': NodeTypeDiscriminator.SOCIETAL_BENEFIT_AREA.value,
+ }
-class ResponseDataProduct(BaseModel, IORelationshipMixin, ResponseObjectFieldMixin):
- __tablename__ = 'response_data_product'
- __table_args__ = (UniqueConstraint('short_name', 'response_id'),)
- id = Column(
+ node_id = Column(
Integer,
+ ForeignKey('node.id'),
primary_key=True,
- autoincrement=True,
+ nullable=False,
)
- response_id = Column(
- Integer,
- ForeignKey('response.id'),
+ societal_benefit_area_id = Column(
+ String,
+ ForeignKey('societal_benefit_area.id'),
nullable=False,
)
- response = relationship(
- 'Response',
- back_populates='data_products',
- )
- input_relationships = relationship(
- 'ResponseObservingSystemDataProduct',
- back_populates='data_product',
- cascade="all, delete",
- )
- output_relationships = relationship(
- 'ResponseDataProductApplication',
- back_populates='data_product',
- cascade="all, delete",
- )
+ # TODO: Relationship to societal benefit area table? How would we make a similar
+ # relationship for the other node types?
+ societal_benefit_area = relationship("SocietalBenefitArea")
-class ResponseApplication(BaseModel, IORelationshipMixin, ResponseObjectFieldMixin):
- __tablename__ = 'response_application'
- __table_args__ = (UniqueConstraint('short_name', 'response_id'),)
- id = Column(
- Integer,
- primary_key=True,
- autoincrement=True,
- )
- response_id = Column(
- Integer,
- ForeignKey('response.id'),
- nullable=False,
- )
+class AssessmentNode(BaseModel):
+ """An instance of a Node in the Node Library for use in an Assessment."""
- performance_criteria = Column(
- String(256),
- )
- performance_rating = Column(
- Integer,
- CheckConstraint(
- 'performance_rating>0 and performance_rating<101',
- name='0-100',
+ __tablename__ = "assessment_node"
+ __table_args__ = (
+ UniqueConstraint('assessment_id', 'node_id'),
+ Index(
+ f'idx_{__tablename__}',
+ 'assessment_id',
+ 'node_id',
+ unique=True, # TODO: Do we need this?
),
- nullable=False,
)
- response = relationship(
- 'Response',
- back_populates='applications',
- )
- input_relationships = relationship(
- 'ResponseDataProductApplication',
- back_populates='application',
- cascade="all, delete",
- )
- output_relationships = relationship(
- 'ResponseApplicationSocietalBenefitArea',
- back_populates='application',
- cascade="all, delete",
- )
-
-
-class ResponseSocietalBenefitArea(BaseModel, IORelationshipMixin):
- __tablename__ = 'response_societal_benefit_area'
- __table_args__ = (UniqueConstraint('societal_benefit_area_id', 'response_id'),)
+ # TODO: If/when we make this a pure associative entity, do we need a surrogate ID?
id = Column(
Integer,
primary_key=True,
- autoincrement=True,
)
- response_id = Column(
+ assessment_id = Column(
Integer,
- ForeignKey('response.id'),
+ ForeignKey('assessment.id'),
nullable=False,
)
-
- societal_benefit_area_id = Column(
- String(256),
- ForeignKey('societal_benefit_area.id'),
+ node_id = Column(
+ Integer,
+ ForeignKey('node.id'),
nullable=False,
)
- response = relationship(
- 'Response',
- back_populates='societal_benefit_areas',
- )
- societal_benefit_area = relationship('SocietalBenefitArea')
- input_relationships = relationship(
- 'ResponseApplicationSocietalBenefitArea',
- back_populates='societal_benefit_area',
- cascade="all, delete",
- )
+ # TODO: Special case for applications, they have performance_criteria and
+ # performance_rating.
+ assessment = relationship(Assessment)
+ node = relationship(Node)
-# Association tables
-class Status(BaseModel):
- __tablename__ = 'status'
- id = Column(
- String,
- primary_key=True,
- nullable=False,
+ input_links = relationship(
+ "Link",
+ foreign_keys="Link.target_assessment_node_id",
+ back_populates="target_assessment_node",
)
-
-
-class Role(BaseModel):
- __tablename__ = 'role'
- id = Column(
- String,
- primary_key=True,
- nullable=False,
+ output_links = relationship(
+ "Link",
+ foreign_keys="Link.source_assessment_node_id",
+ back_populates="source_assessment_node",
)
-class ResponseObservingSystemDataProduct(BaseModel):
- __tablename__ = 'response_observing_system_data_product'
+class Link(BaseModel):
+ """A link between two nodes _in an assessment_."""
+
+ __tablename__ = 'link'
__table_args__ = (
- UniqueConstraint('response_observing_system_id', 'response_data_product_id'),
+ UniqueConstraint('source_assessment_node_id', 'target_assessment_node_id'),
Index(
f'idx_{__tablename__}',
- 'response_observing_system_id',
- 'response_data_product_id',
- unique=True,
+ 'source_assessment_node_id',
+ 'target_assessment_node_id',
+ unique=True, # TODO: Do we need this?
),
)
id = Column(
@@ -445,153 +346,70 @@ class ResponseObservingSystemDataProduct(BaseModel):
autoincrement=True,
primary_key=True,
)
- response_observing_system_id = Column(
+ source_assessment_node_id = Column(
Integer,
- ForeignKey('response_observing_system.id'),
- index=True,
+ ForeignKey('assessment_node.id'),
+ nullable=False,
)
- response_data_product_id = Column(
+ target_assessment_node_id = Column(
Integer,
- ForeignKey('response_data_product.id'),
- index=True,
- )
-
- criticality_rating = Column(
- SmallInteger,
- CheckConstraint(
- 'criticality_rating>=0 and criticality_rating<=100',
- name='c0-100',
- ),
+ ForeignKey('assessment_node.id'),
nullable=False,
)
+
performance_rating = Column(
- SmallInteger,
+ Integer,
CheckConstraint(
- 'performance_rating>=0 and performance_rating<=100',
+ 'performance_rating>0 and performance_rating<101',
name='0-100',
),
nullable=False,
)
- rationale = Column(String(512), nullable=True)
- needed_improvements = Column(String(512), nullable=True)
- observing_system = relationship(
- 'ResponseObservingSystem',
- back_populates='output_relationships',
+ source_assessment_node = relationship(
+ AssessmentNode,
+ foreign_keys=[source_assessment_node_id],
+ back_populates='output_links',
)
- data_product = relationship(
- 'ResponseDataProduct',
- back_populates='input_relationships',
+ target_assessment_node = relationship(
+ AssessmentNode,
+ foreign_keys=[target_assessment_node_id],
+ back_populates='input_links',
)
-class ResponseDataProductApplication(BaseModel):
- __tablename__ = 'response_data_product_application'
- __table_args__ = (
- UniqueConstraint('response_data_product_id', 'response_application_id'),
- Index(
- f'idx_{__tablename__}',
- 'response_data_product_id',
- 'response_application_id',
- unique=True,
- ),
- )
- id = Column(
- Integer,
- autoincrement=True,
- primary_key=True,
- )
+##################
+# Reference tables
+##################
- response_data_product_id = Column(
- Integer,
- ForeignKey('response_data_product.id'),
- index=True,
- )
- response_application_id = Column(
- Integer,
- ForeignKey('response_application.id'),
- index=True,
- )
- criticality_rating = Column(
- SmallInteger,
- CheckConstraint(
- 'criticality_rating>=0 and criticality_rating<=100',
- name='c0-100',
- ),
- nullable=False,
- )
- performance_rating = Column(
- SmallInteger,
- CheckConstraint(
- 'performance_rating>=0 and performance_rating<=100',
- name='0-100',
- ),
+# TODO: Is this "association" or "reference"
+class Role(BaseModel):
+ __tablename__ = 'role'
+ id = Column(
+ String,
+ primary_key=True,
nullable=False,
)
- rationale = Column(String(512), nullable=True)
- needed_improvements = Column(String(512), nullable=True)
-
- data_product = relationship(
- 'ResponseDataProduct',
- back_populates='output_relationships',
- )
- application = relationship(
- 'ResponseApplication',
- back_populates='input_relationships',
- )
-class ResponseApplicationSocietalBenefitArea(BaseModel):
- __tablename__ = 'response_application_societal_benefit_area'
- __table_args__ = (
- UniqueConstraint(
- 'response_application_id',
- 'response_societal_benefit_area_id',
- ),
- Index(
- 'idx_{__tablename__}',
- 'response_application_id',
- 'response_societal_benefit_area_id',
- unique=True,
- ),
- )
+class AssessmentStatus(BaseModel):
+ __tablename__ = 'status'
id = Column(
- Integer,
- autoincrement=True,
+ String,
primary_key=True,
)
- response_application_id = Column(
- Integer,
- ForeignKey('response_application.id'),
- index=True,
- )
- response_societal_benefit_area_id = Column(
- Integer,
- ForeignKey('response_societal_benefit_area.id'),
- index=True,
- )
-
- performance_rating = Column(
- SmallInteger,
- CheckConstraint(
- 'performance_rating>=0 and performance_rating<=100',
- name='0-100',
- ),
+ description = Column(
+ String,
nullable=False,
)
- application = relationship(
- 'ResponseApplication',
- back_populates='output_relationships',
- )
- societal_benefit_area = relationship(
- 'ResponseSocietalBenefitArea',
- back_populates='input_relationships',
+ assessments = relationship(
+ Assessment,
+ back_populates='status',
)
-# Reference tables
class SocietalBenefitArea(BaseModel):
__tablename__ = 'societal_benefit_area'
id = Column(
diff --git a/usaon_benefit_tool/routes/assessment/__init__.py b/usaon_benefit_tool/routes/assessment/__init__.py
new file mode 100644
index 00000000..b20706f5
--- /dev/null
+++ b/usaon_benefit_tool/routes/assessment/__init__.py
@@ -0,0 +1,47 @@
+from flask import Blueprint, render_template
+from flask_login import login_required
+
+from usaon_benefit_tool import db
+from usaon_benefit_tool.models.tables import Assessment
+
+# from usaon_benefit_tool.routes.assessment.link import assessment_link_bp
+from usaon_benefit_tool.routes.assessment.links import assessment_links_bp
+
+# from usaon_benefit_tool.routes.assessment.node import assessment_node_bp
+from usaon_benefit_tool.routes.assessment.nodes import (
+ assessment_nodes_bp,
+)
+from usaon_benefit_tool.util.sankey import sankey
+
+assessment_bp = Blueprint(
+ 'assessment',
+ __name__,
+ url_prefix='/assessment/',
+)
+assessment_bp.register_blueprint(assessment_links_bp)
+# assessment_bp.register_blueprint(assessment_link_bp)
+assessment_bp.register_blueprint(assessment_nodes_bp)
+# assessment_bp.register_blueprint(assessment_node_bp)
+
+
+@assessment_bp.route('')
+@login_required
+def get(assessment_id: str):
+ """Display the assessment overview."""
+ assessment = db.get_or_404(Assessment, assessment_id)
+ return render_template(
+ 'assessment/overview.html',
+ assessment=assessment,
+ sankey_series=sankey(assessment),
+ )
+
+
+@assessment_bp.route('/user_guide', methods=['GET'])
+@login_required
+def user_guide(assessment_id: str):
+ """Display the assessment user guide."""
+ assessment = db.get_or_404(Assessment, assessment_id)
+ return render_template(
+ 'assessment/user_guide.html',
+ assessment=assessment,
+ )
diff --git a/usaon_benefit_tool/routes/assessment/links.py b/usaon_benefit_tool/routes/assessment/links.py
new file mode 100644
index 00000000..e4d43662
--- /dev/null
+++ b/usaon_benefit_tool/routes/assessment/links.py
@@ -0,0 +1,50 @@
+from flask import Blueprint, Response, render_template, request, url_for
+from flask_login import login_required
+
+from usaon_benefit_tool import db
+from usaon_benefit_tool.forms import FORMS_BY_MODEL
+from usaon_benefit_tool.models.tables import Link
+
+assessment_links_bp = Blueprint('links', __name__, url_prefix='/links')
+Form = FORMS_BY_MODEL[Link]
+
+
+@assessment_links_bp.route('', methods=['POST'])
+@login_required
+def post(assessment_id: str):
+ """Add an entry to the assessment's link collection."""
+ assessment_link = Link()
+ form = Form(request.form, obj=assessment_link)
+
+ if form.validate():
+ form.populate_obj(assessment_link)
+ db.session.add(assessment_link)
+ db.session.commit()
+
+ return Response(
+ status=201,
+ headers={
+ 'HX-Redirect': url_for(
+ 'assessment.get',
+ assessment_id=assessment_id,
+ ),
+ },
+ )
+
+
+@assessment_links_bp.route('/form', methods=['GET'])
+@login_required
+def form(assessment_id: str):
+ """Return a form to add an entry to the assessment's link collection."""
+ assessment_link = Link()
+ form = Form(obj=assessment_link)
+ form_attrs = (
+ f"hx-post={url_for('assessment.links.post', assessment_id=assessment_id)}"
+ )
+
+ return render_template(
+ 'partials/modal_form.html',
+ title="Add a link",
+ form_attrs=form_attrs,
+ form=form,
+ )
diff --git a/usaon_benefit_tool/routes/assessment/nodes.py b/usaon_benefit_tool/routes/assessment/nodes.py
new file mode 100644
index 00000000..b22c2d8f
--- /dev/null
+++ b/usaon_benefit_tool/routes/assessment/nodes.py
@@ -0,0 +1,67 @@
+from flask import Blueprint, Response, render_template, request, url_for
+from flask_login import login_required
+
+from usaon_benefit_tool import db
+from usaon_benefit_tool.forms import FORMS_BY_MODEL
+from usaon_benefit_tool.models.tables import AssessmentNode
+
+assessment_nodes_bp = Blueprint('nodes', __name__, url_prefix='/nodes')
+Form = FORMS_BY_MODEL[AssessmentNode]
+
+
+# @assessment_nodes_bp.route('', methods=['GET'])
+# @login_required
+# def get(assessment_id: str):
+# """Return a page for managing data products associated with a assessment."""
+# assessment = db.get_or_404(Assessment, assessment_id)
+# assessment_data_product = AssessmentDataProduct(assessment_id=assessment.id)
+#
+# form = Form(obj=assessment_data_product)
+# return render_template(
+# 'assessment/nodes.html',
+# form=form,
+# assessment=assessment,
+# nodes=assessment.nodes,
+# sankey_series=sankey_subset(assessment, AssessmentDataProduct),
+# )
+
+
+@assessment_nodes_bp.route('', methods=['POST'])
+@login_required
+def post(assessment_id: str):
+ """Add an entry to the assessment's node collection."""
+ assessment_node = AssessmentNode(assessment_id=assessment_id)
+ form = Form(request.form, obj=assessment_node)
+
+ if form.validate():
+ form.populate_obj(assessment_node)
+ db.session.add(assessment_node)
+ db.session.commit()
+
+ return Response(
+ status=201,
+ headers={
+ 'HX-Redirect': url_for(
+ 'assessment.get',
+ assessment_id=assessment_id,
+ ),
+ },
+ )
+
+
+@assessment_nodes_bp.route('/form', methods=['GET'])
+@login_required
+def form(assessment_id: str):
+ """Return a form to add an entry to the assessment's nodes collection."""
+ assessment_node = AssessmentNode(assessment_id=assessment_id)
+ form = Form(obj=assessment_node)
+ form_attrs = (
+ f"hx-post={url_for('assessment.nodes.post', assessment_id=assessment_id)}"
+ )
+
+ return render_template(
+ 'partials/modal_form.html',
+ title="Add a node",
+ form_attrs=form_attrs,
+ form=form,
+ )
diff --git a/usaon_benefit_tool/routes/assessments.py b/usaon_benefit_tool/routes/assessments.py
new file mode 100644
index 00000000..7a0ba498
--- /dev/null
+++ b/usaon_benefit_tool/routes/assessments.py
@@ -0,0 +1,42 @@
+from flask import (
+ Blueprint,
+ redirect,
+ render_template,
+ request,
+ url_for,
+)
+from flask_login import login_required
+
+from usaon_benefit_tool import db
+from usaon_benefit_tool.forms import FORMS_BY_MODEL
+from usaon_benefit_tool.models.tables import Assessment
+
+assessments_bp = Blueprint('assessments', __name__, url_prefix='/assessments')
+
+
+@assessments_bp.route('', methods=["GET"])
+@login_required
+def get():
+ assessments = Assessment.query.order_by(Assessment.created_timestamp).all()
+ form = FORMS_BY_MODEL[Assessment](obj=Assessment())
+ return render_template('assessments.html', assessments=assessments, form=form)
+
+
+@assessments_bp.route('', methods=["POST"])
+@login_required
+def post():
+ assessment = Assessment()
+ form = FORMS_BY_MODEL[Assessment](request.form, obj=assessment)
+
+ if not form.validate():
+ # FIXME: Handle this case! Return an error code and let HTMX handle it?
+ # breakpoint()
+ raise RuntimeError("FIXME")
+
+ # Insert to DB
+ form.populate_obj(assessment)
+
+ db.session.add(assessment)
+ db.session.commit()
+
+ return redirect(url_for('assessment.get', assessment_id=assessment.id))
diff --git a/usaon_benefit_tool/routes/node/__init__.py b/usaon_benefit_tool/routes/node/__init__.py
new file mode 100644
index 00000000..5e2142a5
--- /dev/null
+++ b/usaon_benefit_tool/routes/node/__init__.py
@@ -0,0 +1,80 @@
+from flask import Blueprint, Response, render_template, request, url_for
+from flask_login import login_required
+
+from usaon_benefit_tool import db
+from usaon_benefit_tool.forms import FORMS_BY_MODEL
+from usaon_benefit_tool.models.tables import Node
+
+# TODO: Separate endpoints for each type of node? /node/data_product/...
+# Or /node/?type=data_product or /node/', methods=['GET'])
-@login_required
-def view_response(survey_id: str):
- """View or create response to a survey."""
- # Anyone should be able to view a survey
- # Only admins or respondents should be able to create a response.
- survey = db.get_or_404(Survey, survey_id)
-
- return render_template(
- 'survey/user_guide.html',
- survey=survey,
- response=survey.response,
- sankey_series=sankey(survey.response),
- )
-
-
-@survey_bp.route('/new', methods=['GET', 'POST'])
-@login_required
-def new_survey():
- Form = FORMS_BY_MODEL[Survey]
- survey = Survey()
-
- if request.method == 'POST':
- form = Form(request.form, obj=survey)
-
- if form.validate():
- # Insert to DB
- # TODO: We don't need a response concept!
- form.populate_obj(survey)
-
- response = Response()
- survey.response = response
-
- db.session.add(survey)
- db.session.add(response)
- db.session.commit()
-
- return redirect(url_for('survey.view_survey', survey_id=survey.id))
-
- form = Form(obj=survey)
- return render_template('new_survey.html', form=form)
-
-
-@survey_bp.route('/')
-@login_required
-def view_survey(survey_id: str):
- # Fetch survey by id
- survey = db.get_or_404(Survey, survey_id)
-
- return render_template(
- 'survey/overview.html',
- survey=survey,
- sankey_series=sankey(survey.response) if survey.response else [],
- )
diff --git a/usaon_benefit_tool/routes/survey/applications.py b/usaon_benefit_tool/routes/survey/applications.py
deleted file mode 100644
index b6b5093a..00000000
--- a/usaon_benefit_tool/routes/survey/applications.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from flask import Blueprint, redirect, render_template, request, url_for
-from flask_login import login_required
-
-from usaon_benefit_tool import db
-from usaon_benefit_tool.forms import FORMS_BY_MODEL
-from usaon_benefit_tool.models.tables import ResponseApplication, Survey
-from usaon_benefit_tool.util.authorization import limit_response_editors
-from usaon_benefit_tool.util.sankey import applications_sankey
-
-application_bp = Blueprint(
- 'application',
- __name__,
- url_prefix='/response//applications',
-)
-
-
-@application_bp.route('', methods=['GET', 'POST'])
-@login_required
-def view_response_applications(survey_id: int):
- """View and add to applications associated with a response."""
- Form = FORMS_BY_MODEL[ResponseApplication]
- survey = db.get_or_404(Survey, survey_id)
- response_application = ResponseApplication(response_id=survey.response_id)
-
- if request.method == 'POST':
- limit_response_editors()
- form = Form(request.form, obj=response_application)
-
- if form.validate():
- form.populate_obj(response_application)
- db.session.add(response_application)
- db.session.commit()
-
- return redirect(
- url_for('application.view_response_applications', survey_id=survey.id),
- )
-
- form = Form(obj=response_application)
- return render_template(
- 'survey/applications.html',
- form=form,
- survey=survey,
- response=survey.response,
- applications=survey.response.applications,
- sankey_series=applications_sankey(survey.response),
- )
-
-
-@application_bp.route('/', methods=['DELETE'])
-@login_required
-def delete_response_application(survey_id: int, response_application_id: int):
- """Delete application response object from survey."""
- survey = db.get_or_404(Survey, survey_id)
- response_application = db.get_or_404(ResponseApplication, response_application_id)
- db.session.delete(response_application)
- db.session.commit()
-
- return redirect(
- url_for('application.view_response_applications', survey_id=survey.id),
- code=303,
- )
diff --git a/usaon_benefit_tool/routes/survey/data_products.py b/usaon_benefit_tool/routes/survey/data_products.py
deleted file mode 100644
index d321a212..00000000
--- a/usaon_benefit_tool/routes/survey/data_products.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from flask import Blueprint, redirect, render_template, request, url_for
-from flask_login import login_required
-
-from usaon_benefit_tool import db
-from usaon_benefit_tool.forms import FORMS_BY_MODEL
-from usaon_benefit_tool.models.tables import ResponseDataProduct, Survey
-from usaon_benefit_tool.util.authorization import limit_response_editors
-from usaon_benefit_tool.util.sankey import data_products_sankey
-
-data_product_bp = Blueprint(
- 'data_product',
- __name__,
- url_prefix='/response//data_products',
-)
-
-
-@data_product_bp.route('', methods=['GET', 'POST'])
-@login_required
-def view_response_data_products(survey_id: str):
- """View and add to data products associated with a response."""
- Form = FORMS_BY_MODEL[ResponseDataProduct]
- survey = db.get_or_404(Survey, survey_id)
- response_data_product = ResponseDataProduct(response_id=survey.response_id)
-
- if request.method == 'POST':
- limit_response_editors()
- form = Form(request.form, obj=response_data_product)
-
- if form.validate():
- form.populate_obj(response_data_product)
- db.session.add(response_data_product)
- db.session.commit()
-
- return redirect(
- url_for('data_product.view_response_data_products', survey_id=survey.id),
- )
-
- form = Form(obj=response_data_product)
- return render_template(
- 'survey/data_products.html',
- form=form,
- survey=survey,
- response=survey.response,
- data_products=survey.response.data_products,
- sankey_series=data_products_sankey(survey.response),
- )
-
-
-@data_product_bp.route('/', methods=['DELETE'])
-@login_required
-def delete_response_data_product(survey_id: int, response_data_product_id: int):
- """Delete data product response object from survey."""
- survey = db.get_or_404(Survey, survey_id)
- response_data_product = db.get_or_404(ResponseDataProduct, response_data_product_id)
- db.session.delete(response_data_product)
- db.session.commit()
-
- return redirect(
- url_for('data_product.view_response_data_products', survey_id=survey.id),
- code=303,
- )
diff --git a/usaon_benefit_tool/routes/survey/observing_systems.py b/usaon_benefit_tool/routes/survey/observing_systems.py
deleted file mode 100644
index 23d942d7..00000000
--- a/usaon_benefit_tool/routes/survey/observing_systems.py
+++ /dev/null
@@ -1,68 +0,0 @@
-from flask import Blueprint, redirect, render_template, request, url_for
-from flask_login import login_required
-
-from usaon_benefit_tool import db
-from usaon_benefit_tool._types import ObservingSystemType
-from usaon_benefit_tool.forms import FORMS_BY_MODEL
-from usaon_benefit_tool.models.tables import ResponseObservingSystem, Survey
-from usaon_benefit_tool.util.authorization import limit_response_editors
-
-observing_system_bp = Blueprint(
- 'obs',
- __name__,
- url_prefix='/response//observing_systems',
-)
-
-
-@observing_system_bp.route('', methods=['GET', 'POST'])
-@login_required
-def view_response_observing_systems(survey_id: str):
- """View and add to observing systems associated with a response."""
- Form = FORMS_BY_MODEL[ResponseObservingSystem]
- survey = db.get_or_404(Survey, survey_id)
- response_observing_system = ResponseObservingSystem(
- response_id=survey.response_id,
- type=ObservingSystemType.other,
- )
-
- if request.method == 'POST':
- limit_response_editors()
- form = Form(request.form, obj=response_observing_system)
-
- if form.validate():
- form.populate_obj(response_observing_system)
- db.session.add(response_observing_system)
- db.session.commit()
-
- redirect_url = url_for(
- 'obs.view_response_observing_systems',
- survey_id=survey.id,
- )
- return redirect(redirect_url)
-
- form = Form(obj=response_observing_system)
- return render_template(
- 'survey/observing_systems.html',
- form=form,
- survey=survey,
- response=survey.response,
- observing_systems=survey.response.observing_systems,
- )
-
-
-@observing_system_bp.route('/', methods=['DELETE'])
-@login_required
-def delete_response_observing_system(survey_id: int, response_observing_system_id: int):
- """Delete observing system response object from survey."""
- survey = db.get_or_404(Survey, survey_id)
- response_observing_system = db.get_or_404(
- ResponseObservingSystem,
- response_observing_system_id,
- )
- db.session.delete(response_observing_system)
- db.session.commit()
-
- return redirect(
- url_for('obs.view_response_observing_systems', survey_id=survey.id),
- code=303,
- )
diff --git a/usaon_benefit_tool/routes/survey/relationships/application_societal_benefit_area.py b/usaon_benefit_tool/routes/survey/relationships/application_societal_benefit_area.py
deleted file mode 100644
index ab9195c9..00000000
--- a/usaon_benefit_tool/routes/survey/relationships/application_societal_benefit_area.py
+++ /dev/null
@@ -1,263 +0,0 @@
-from flask import Blueprint, Request, redirect, render_template, request, url_for
-from wtforms import FormField
-
-from usaon_benefit_tool import db
-from usaon_benefit_tool.forms import FORMS_BY_MODEL
-from usaon_benefit_tool.models.tables import (
- ResponseApplication,
- ResponseApplicationSocietalBenefitArea,
- ResponseSocietalBenefitArea,
- Survey,
-)
-from usaon_benefit_tool.util.authorization import limit_response_editors
-from usaon_benefit_tool.util.superform import SuperForm
-
-
-def _update_super_form(
- super_form: type[SuperForm],
- /,
- *,
- societal_benefit_area_id: int | None,
- application_id: int | None,
-) -> None:
- """Populate the form of forms with sub-forms depending on provided IDs.
-
- When an ID for an object is not provided, we need to gather information from the
- user to create that object.
-
- TODO: Better function name.
- """
- if societal_benefit_area_id is None:
- super_form.societal_benefit_area = FormField(
- FORMS_BY_MODEL[ResponseSocietalBenefitArea],
- )
-
- if application_id is None:
- super_form.application = FormField(FORMS_BY_MODEL[ResponseApplication])
-
-
-def _update_relationship(
- relationship: ResponseSocietalBenefitArea,
- *,
- societal_benefit_area_id: int | None,
- application_id: int | None,
-) -> None:
- """Populate the relationship with any known identifiers.
-
- TODO: Better function name.
- """
- if societal_benefit_area_id:
- relationship.response_societal_benefit_area_id = societal_benefit_area_id
-
- if application_id:
- relationship.response_application_id = application_id
-
-
-def _response_societal_benefit_area(
- *,
- societal_benefit_area_id: int | None,
- response_id: int,
-) -> ResponseSocietalBenefitArea:
- """Return a SBA db object (or 404)."""
- if societal_benefit_area_id is not None:
- response_societal_benefit_area = db.get_or_404(
- ResponseSocietalBenefitArea,
- societal_benefit_area_id,
- )
- else:
- response_societal_benefit_area = ResponseSocietalBenefitArea(
- response_id=response_id,
- )
-
- return response_societal_benefit_area
-
-
-def _response_application(
- *,
- application_id: int | None,
- response_id: int,
-) -> ResponseApplication:
- """Return an application db object (or 404)."""
- if application_id is not None:
- response_application = db.get_or_404(ResponseApplication, application_id)
- else:
- response_application = ResponseApplication(response_id=response_id)
-
- return response_application
-
-
-def _response_application_societal_benefit_area(
- *,
- societal_benefit_area_id: int | None,
- application_id: int | None,
-) -> ResponseApplicationSocietalBenefitArea:
- """Return a relationship db object.
-
- Returned object may be transient or persistent depending on whether a match exists
- in the db.
- """
- if societal_benefit_area_id and application_id:
- # If not found, will be `None`
- response_application_societal_benefit_area = (
- db.session.query(ResponseApplicationSocietalBenefitArea)
- .filter(
- ResponseApplicationSocietalBenefitArea.response_societal_benefit_area_id
- == societal_benefit_area_id
- and ResponseApplicationSocietalBenefitArea.response_application_id
- == application_id,
- )
- .one_or_none()
- )
- else:
- response_application_societal_benefit_area = None
-
- if response_application_societal_benefit_area is not None:
- return response_application_societal_benefit_area
- else:
- return ResponseApplicationSocietalBenefitArea()
-
-
-def _request_args(request: Request) -> tuple[int | None, int | None]:
- societal_benefit_area_id: int | str | None = request.args.get(
- 'societal_benefit_area_id',
- )
- if societal_benefit_area_id is not None:
- societal_benefit_area_id = int(societal_benefit_area_id)
-
- application_id: int | str | None = request.args.get('application_id')
- if application_id is not None:
- application_id = int(application_id)
-
- return societal_benefit_area_id, application_id
-
-
-application_societal_benefit_area_bp = Blueprint(
- 'application_societal_benefit_area',
- __name__,
- url_prefix='/response//application_societal_benefit_area_relationships',
-)
-
-
-@application_societal_benefit_area_bp.route(
- '',
- methods=['GET', 'POST'],
-)
-def view_response_application_societal_benefit_area_relationships(survey_id: str):
- """View and add application/SBA relationships to a response.
-
- TODO: Refactor this whole pile of stuff. Less string magic. Less cyclomatic
- complexity.
- """
- societal_benefit_area_id, application_id = _request_args(request)
- survey = db.get_or_404(Survey, survey_id)
-
- class ApplicationSocietalBenefitAreaForm(SuperForm):
- """Combine all necessary forms into one super-form.
-
- NOTE: Additional class attributes are added dynamically below.
- """
-
- relationship = FormField(FORMS_BY_MODEL[ResponseApplicationSocietalBenefitArea])
-
- response_application_societal_benefit_area = (
- _response_application_societal_benefit_area(
- societal_benefit_area_id=societal_benefit_area_id,
- application_id=application_id,
- )
- )
-
- response_societal_benefit_area = _response_societal_benefit_area(
- societal_benefit_area_id=societal_benefit_area_id,
- response_id=survey.response_id,
- )
-
- response_application = _response_application(
- application_id=application_id,
- response_id=survey.response_id,
- )
-
- _update_super_form(
- ApplicationSocietalBenefitAreaForm,
- societal_benefit_area_id=societal_benefit_area_id,
- application_id=application_id,
- )
- _update_relationship(
- response_application_societal_benefit_area,
- societal_benefit_area_id=societal_benefit_area_id,
- application_id=application_id,
- )
-
- form_obj: dict[
- str,
- ResponseSocietalBenefitArea
- | ResponseApplication
- | ResponseApplicationSocietalBenefitArea,
- ] = {
- 'societal_benefit_area': response_societal_benefit_area,
- 'application': response_application,
- # NOTE: Logic below depends on relationship being last in this dict
- 'relationship': response_application_societal_benefit_area,
- }
-
- if request.method == 'POST':
- limit_response_editors()
- form = ApplicationSocietalBenefitAreaForm(request.form, obj=form_obj)
-
- if form.validate():
- # Add only submitted sub-forms into the db session
- for key, obj in form_obj.items():
- if hasattr(form, key):
- form[key].form.populate_obj(obj)
- db.session.add(obj)
-
- # Update the relationship object with the ids of any new entities
- if type(obj) is not ResponseApplicationSocietalBenefitArea:
- # Get the db object's new ID
- db.session.flush()
- db.session.refresh(obj)
-
- # Update the relationship db object
- setattr(
- response_application_societal_benefit_area,
- f'response_{key}_id',
- obj.id,
- )
-
- db.session.commit()
-
- return redirect(url_for('sba.view_response_sbas', survey_id=survey.id))
-
- form = ApplicationSocietalBenefitAreaForm(obj=form_obj)
- return render_template(
- 'survey/relationships/application_societal_benefit_area.html',
- form=form,
- survey=survey,
- societal_benefit_area=response_societal_benefit_area,
- societal_benefit_areas=survey.response.societal_benefit_areas,
- application=response_application,
- applications=survey.response.applications,
- relationship=response_application_societal_benefit_area,
- )
-
-
-@application_societal_benefit_area_bp.route(
- '/',
- methods=['DELETE'],
-)
-def delete_response_application_societal_benefit_area_relationship(
- survey_id: int,
- response_application_societal_benefit_area_id: int,
-):
- """Delete application/data product relationship."""
- survey = db.get_or_404(Survey, survey_id)
- response_application_societal_benefit_area = db.get_or_404(
- ResponseApplicationSocietalBenefitArea,
- response_application_societal_benefit_area_id,
- )
- db.session.delete(response_application_societal_benefit_area)
- db.session.commit()
-
- return redirect(
- url_for('sba.view_response_sbas', survey_id=survey.id),
- code=303,
- )
diff --git a/usaon_benefit_tool/routes/survey/relationships/data_product_application.py b/usaon_benefit_tool/routes/survey/relationships/data_product_application.py
deleted file mode 100644
index 7264f1ad..00000000
--- a/usaon_benefit_tool/routes/survey/relationships/data_product_application.py
+++ /dev/null
@@ -1,252 +0,0 @@
-from flask import Blueprint, Request, redirect, render_template, request, url_for
-from wtforms import FormField
-
-from usaon_benefit_tool import db
-from usaon_benefit_tool.forms import FORMS_BY_MODEL
-from usaon_benefit_tool.models.tables import (
- ResponseApplication,
- ResponseDataProduct,
- ResponseDataProductApplication,
- Survey,
-)
-from usaon_benefit_tool.util.authorization import limit_response_editors
-from usaon_benefit_tool.util.superform import SuperForm
-
-
-def _update_super_form(
- super_form: type[SuperForm],
- /,
- *,
- data_product_id: int | None,
- application_id: int | None,
-) -> None:
- """Populate the form of forms with sub-forms depending on provided IDs.
-
- When an ID for an object is not provided, we need to gather information from the
- user to create that object.
-
- TODO: Better function name.
- """
- if data_product_id is None:
- super_form.data_product = FormField(FORMS_BY_MODEL[ResponseDataProduct])
-
- if application_id is None:
- super_form.application = FormField(FORMS_BY_MODEL[ResponseApplication])
-
-
-def _update_relationship(
- relationship: ResponseDataProductApplication,
- *,
- data_product_id: int | None,
- application_id: int | None,
-) -> None:
- """Populate the relationship with any known identifiers.
-
- TODO: Better function name.
- """
- if data_product_id:
- relationship.response_data_product_id = data_product_id
-
- if application_id:
- relationship.response_application_id = application_id
-
-
-def _response_data_product(
- *,
- data_product_id: int | None,
- response_id: int,
-) -> ResponseDataProduct:
- """Return a data product db object (or 404)."""
- if data_product_id is not None:
- response_data_product = db.get_or_404(ResponseDataProduct, data_product_id)
- else:
- response_data_product = ResponseDataProduct(response_id=response_id)
-
- return response_data_product
-
-
-def _response_application(
- *,
- application_id: int | None,
- response_id: int,
-) -> ResponseApplication:
- """Return an application db object (or 404)."""
- if application_id is not None:
- response_application = db.get_or_404(ResponseApplication, application_id)
- else:
- response_application = ResponseApplication(response_id=response_id)
-
- return response_application
-
-
-def _response_data_product_application(
- *,
- data_product_id: int | None,
- application_id: int | None,
-) -> ResponseDataProductApplication:
- """Return a relationship db object.
-
- Returned object may be transient or persistent depending on whether a match exists
- in the db.
- """
- if data_product_id and application_id:
- response_data_product_application = (
- db.session.query(ResponseDataProductApplication)
- .filter(
- ResponseDataProductApplication.response_data_product_id
- == data_product_id
- and ResponseDataProductApplication.response_application_id
- == application_id,
- )
- .one_or_none()
- )
- else:
- response_data_product_application = None
-
- if response_data_product_application is not None:
- return response_data_product_application
- else:
- return ResponseDataProductApplication()
-
-
-def _request_args(request: Request) -> tuple[int | None, int | None]:
- data_product_id: int | str | None = request.args.get('data_product_id')
- if data_product_id is not None:
- data_product_id = int(data_product_id)
-
- application_id: int | str | None = request.args.get('application_id')
- if application_id is not None:
- application_id = int(application_id)
-
- return data_product_id, application_id
-
-
-# NOTE: consider making this a child of response_bp
-data_product_application_bp = Blueprint(
- 'data_product_application',
- __name__,
- url_prefix='/response//data_product_application_relationships',
-)
-
-
-@data_product_application_bp.route(
- '',
- methods=['GET', 'POST'],
-)
-def view_response_data_product_application_relationships(survey_id: str):
- """View and add application/dataproduct relationships to a response.
-
- TODO: Refactor this whole pile of stuff. Less string magic. Less cyclomatic
- complexity.
- """
- data_product_id, application_id = _request_args(request)
- survey = db.get_or_404(Survey, survey_id)
-
- class ResponseDataProductApplicationForm(SuperForm):
- """Combine all necessary forms into one super-form.
-
- NOTE: Additional class attributes are added dynamically below.
- """
-
- relationship = FormField(FORMS_BY_MODEL[ResponseDataProductApplication])
-
- response_data_product_application = _response_data_product_application(
- data_product_id=data_product_id,
- application_id=application_id,
- )
-
- response_data_product = _response_data_product(
- data_product_id=data_product_id,
- response_id=survey.response_id,
- )
-
- response_application = _response_application(
- application_id=application_id,
- response_id=survey.response_id,
- )
-
- _update_super_form(
- ResponseDataProductApplicationForm,
- data_product_id=data_product_id,
- application_id=application_id,
- )
- _update_relationship(
- response_data_product_application,
- data_product_id=data_product_id,
- application_id=application_id,
- )
-
- form_obj: dict[
- str,
- ResponseDataProduct | ResponseApplication | ResponseDataProductApplication,
- ] = {
- 'data_product': response_data_product,
- 'application': response_application,
- # NOTE: Logic below depends on relationship being last in this dict
- 'relationship': response_data_product_application,
- }
-
- if request.method == 'POST':
- limit_response_editors()
- form = ResponseDataProductApplicationForm(request.form, obj=form_obj)
-
- if form.validate():
- # Add only submitted sub-forms into the db session
- for key, obj in form_obj.items():
- if hasattr(form, key):
- form[key].form.populate_obj(obj)
- db.session.add(obj)
-
- # Update the relationship object with the ids of any new entities
- if type(obj) is not ResponseDataProductApplication:
- # Get the db object's new ID
- db.session.flush()
- db.session.refresh(obj)
-
- # Update the relationship db object
- setattr(
- response_data_product_application,
- f'response_{key}_id',
- obj.id,
- )
-
- db.session.commit()
-
- return redirect(
- url_for('application.view_response_applications', survey_id=survey.id),
- )
-
- form = ResponseDataProductApplicationForm(obj=form_obj)
- return render_template(
- 'survey/relationships/data_product_application.html',
- form=form,
- survey=survey,
- data_product=response_data_product,
- data_products=survey.response.data_products,
- application=response_application,
- applications=survey.response.applications,
- relationship=response_data_product_application,
- )
-
-
-@data_product_application_bp.route(
- '/',
- methods=['DELETE'],
-)
-def delete_response_data_product_application_relationships(
- survey_id: int,
- response_data_product_application_id: int,
-):
- """Delete application/data product relationship."""
- survey = db.get_or_404(Survey, survey_id)
- response_data_product_application = db.get_or_404(
- ResponseDataProductApplication,
- response_data_product_application_id,
- )
- db.session.delete(response_data_product_application)
- db.session.commit()
-
- return redirect(
- url_for('application.view_response_applications', survey_id=survey.id),
- code=303,
- )
diff --git a/usaon_benefit_tool/routes/survey/relationships/observing_system_data_product.py b/usaon_benefit_tool/routes/survey/relationships/observing_system_data_product.py
deleted file mode 100644
index 0c07a47f..00000000
--- a/usaon_benefit_tool/routes/survey/relationships/observing_system_data_product.py
+++ /dev/null
@@ -1,260 +0,0 @@
-from flask import Blueprint, Request, redirect, render_template, request, url_for
-from wtforms import FormField
-
-from usaon_benefit_tool import db
-from usaon_benefit_tool.forms import FORMS_BY_MODEL
-from usaon_benefit_tool.models.tables import (
- ResponseDataProduct,
- ResponseObservingSystem,
- ResponseObservingSystemDataProduct,
- Survey,
-)
-from usaon_benefit_tool.util.authorization import limit_response_editors
-from usaon_benefit_tool.util.superform import SuperForm
-
-
-def _update_super_form(
- super_form: type[SuperForm],
- /,
- *,
- data_product_id: int | None,
- observing_system_id: int | None,
-) -> None:
- """Populate the form of forms with sub-forms depending on provided IDs.
-
- When an ID for an object is not provided, we need to gather information from the
- user to create that object.
-
- TODO: Better function name.
- """
- if observing_system_id is None:
- super_form.observing_system = FormField(FORMS_BY_MODEL[ResponseObservingSystem])
-
- if data_product_id is None:
- super_form.data_product = FormField(FORMS_BY_MODEL[ResponseDataProduct])
-
-
-def _update_relationship(
- relationship: ResponseObservingSystemDataProduct,
- *,
- observing_system_id: int | None,
- data_product_id: int | None,
-) -> None:
- """Populate the relationship with any known identifiers.
-
- TODO: Better function name.
- """
- if observing_system_id:
- relationship.response_observing_system_id = observing_system_id
-
- if data_product_id:
- relationship.response_data_product_id = data_product_id
-
-
-# may not need to be internal
-def _response_data_product(
- *,
- data_product_id: int | None,
- response_id: int,
-) -> ResponseDataProduct:
- """Return a data product db object (or 404)."""
- if data_product_id is not None:
- response_data_product = db.get_or_404(ResponseDataProduct, data_product_id)
- else:
- response_data_product = ResponseDataProduct(response_id=response_id)
-
- return response_data_product
-
-
-def _response_observing_system(
- *,
- observing_system_id: int | None,
- response_id: int,
-) -> ResponseObservingSystem:
- """Return an observing system db object (or 404)."""
- if observing_system_id is not None:
- response_observing_system = db.get_or_404(
- ResponseObservingSystem,
- observing_system_id,
- )
- else:
- response_observing_system = ResponseObservingSystem(response_id=response_id)
-
- return response_observing_system
-
-
-def _response_observing_system_data_product(
- *,
- observing_system_id: int | None,
- data_product_id: int | None,
-) -> ResponseObservingSystemDataProduct:
- """Return a relationship db object.
-
- Returned object may be transient or persistent depending on whether a match exists
- in the db.
- """
- if data_product_id and observing_system_id:
- # If not found, will be `None`
- response_observing_system_data_product = (
- db.session.query(ResponseObservingSystemDataProduct)
- .filter(
- ResponseObservingSystemDataProduct.response_data_product_id
- == data_product_id
- and ResponseObservingSystemDataProduct.response_observing_system_id
- == observing_system_id,
- )
- .one_or_none()
- )
- else:
- response_observing_system_data_product = None
-
- if response_observing_system_data_product is not None:
- return response_observing_system_data_product
- else:
- return ResponseObservingSystemDataProduct()
-
-
-def _request_args(request: Request) -> tuple[int | None, int | None]:
- data_product_id: int | str | None = request.args.get('data_product_id')
- if data_product_id is not None:
- data_product_id = int(data_product_id)
-
- observing_system_id: int | str | None = request.args.get('observing_system_id')
- if observing_system_id is not None:
- observing_system_id = int(observing_system_id)
-
- return data_product_id, observing_system_id
-
-
-observing_system_data_product_bp = Blueprint(
- 'observing_system_data_product',
- __name__,
- url_prefix='/response//observing_system_data_product_relationships',
-)
-
-
-@observing_system_data_product_bp.route(
- '',
- methods=['GET', 'POST'],
-)
-def view_response_observing_system_data_product_relationships(survey_id: str):
- """View and add observing system/dataproduct relationships to a response.
-
- TODO: Refactor this whole pile of stuff. Less string magic. Less cyclomatic
- complexity.
- """
- data_product_id, observing_system_id = _request_args(request)
- survey = db.get_or_404(Survey, survey_id)
-
- class ObservingSystemDataProductForm(SuperForm):
- """Combine all necessary forms into one super-form.
-
- NOTE: Additional class attributes are added dynamically below.
- """
-
- relationship = FormField(FORMS_BY_MODEL[ResponseObservingSystemDataProduct])
-
- response_observing_system_data_product = _response_observing_system_data_product(
- data_product_id=data_product_id,
- observing_system_id=observing_system_id,
- )
-
- response_data_product = _response_data_product(
- data_product_id=data_product_id,
- response_id=survey.response_id,
- )
-
- response_observing_system = _response_observing_system(
- observing_system_id=observing_system_id,
- response_id=survey.response_id,
- )
-
- _update_super_form(
- ObservingSystemDataProductForm,
- observing_system_id=observing_system_id,
- data_product_id=data_product_id,
- )
- _update_relationship(
- response_observing_system_data_product,
- observing_system_id=observing_system_id,
- data_product_id=data_product_id,
- )
-
- form_obj: dict[
- str,
- ResponseObservingSystem
- | ResponseDataProduct
- | ResponseObservingSystemDataProduct,
- ] = {
- 'observing_system': response_observing_system,
- 'data_product': response_data_product,
- # NOTE: Logic below depends on relationship being last in this dict
- 'relationship': response_observing_system_data_product,
- }
-
- if request.method == 'POST':
- limit_response_editors()
- form = ObservingSystemDataProductForm(request.form, obj=form_obj)
-
- if form.validate():
- # Add only submitted sub-forms into the db session
- for key, obj in form_obj.items():
- if hasattr(form, key):
- form[key].form.populate_obj(obj)
- db.session.add(obj)
-
- # Update the relationship object with the ids of any new entities
- if type(obj) is not ResponseObservingSystemDataProduct:
- # Get the db object's new ID
- db.session.flush()
- db.session.refresh(obj)
-
- # Update the relationship db object
- setattr(
- response_observing_system_data_product,
- f'response_{key}_id',
- obj.id,
- )
-
- db.session.commit()
-
- return redirect(
- url_for('data_product.view_response_data_products', survey_id=survey.id),
- )
-
- form = ObservingSystemDataProductForm(obj=form_obj)
- return render_template(
- 'survey/relationships/observing_system_data_product.html',
- form=form,
- survey=survey,
- observing_system=response_observing_system,
- observing_systems=survey.response.observing_systems,
- data_product=response_data_product,
- data_products=survey.response.data_products,
- relationship=response_observing_system_data_product,
- )
-
-
-@observing_system_data_product_bp.route(
- '/',
- methods=['DELETE'],
-)
-def delete_response_observing_system_data_product_relationship(
- survey_id: int,
- response_observing_system_data_product_id: int,
-):
- """Delete data product/observing system relationship."""
- survey = db.get_or_404(Survey, survey_id)
- response_observing_system_data_product = db.get_or_404(
- ResponseObservingSystemDataProduct,
- response_observing_system_data_product_id,
- )
- db.session.delete(response_observing_system_data_product)
- db.session.commit()
- # TODO: figure out why this isn't working
- # flash('You have deleted this relationship')
-
- return redirect(
- url_for('data_product.view_response_data_products', survey_id=survey.id),
- code=303,
- )
diff --git a/usaon_benefit_tool/routes/survey/sbas.py b/usaon_benefit_tool/routes/survey/sbas.py
deleted file mode 100644
index 6acf07d9..00000000
--- a/usaon_benefit_tool/routes/survey/sbas.py
+++ /dev/null
@@ -1,74 +0,0 @@
-from flask import Blueprint, redirect, render_template, request, url_for
-from flask_login import login_required
-
-from usaon_benefit_tool import db
-from usaon_benefit_tool.forms import FORMS_BY_MODEL
-from usaon_benefit_tool.models.tables import (
- ResponseSocietalBenefitArea,
- SocietalBenefitArea,
- Survey,
-)
-from usaon_benefit_tool.util.authorization import limit_response_editors
-from usaon_benefit_tool.util.sankey import societal_benefit_areas_sankey
-
-societal_benefit_area_bp = Blueprint(
- 'sba',
- __name__,
- url_prefix='/response//societal_benefit_areas',
-)
-
-
-@societal_benefit_area_bp.route('', methods=['GET', 'POST'])
-@login_required
-def view_response_sbas(survey_id: str):
- """View and add to observing systems associated with a response."""
- sbas = SocietalBenefitArea.query.all()
- Form = FORMS_BY_MODEL[ResponseSocietalBenefitArea]
- survey = db.get_or_404(Survey, survey_id)
- # show the list of available SBAs
- response_societal_benefit_area = ResponseSocietalBenefitArea(
- response_id=survey.response_id,
- )
-
- if request.method == 'POST':
- limit_response_editors()
- form = Form(request.form, obj=response_societal_benefit_area)
-
- if form.validate():
- form.populate_obj(response_societal_benefit_area)
- db.session.add(response_societal_benefit_area)
- db.session.commit()
-
- return redirect(url_for('sba.view_response_sbas', survey_id=survey.id))
-
- form = Form(obj=response_societal_benefit_area)
- return render_template(
- 'survey/sbas.html',
- form=form,
- survey=survey,
- sbas=sbas,
- response=survey.response,
- societal_benefit_areas=survey.response.societal_benefit_areas,
- sankey_series=societal_benefit_areas_sankey(survey.response),
- )
-
-
-@societal_benefit_area_bp.route(
- '/',
- methods=['DELETE'],
-)
-@login_required
-def delete_response_sba(survey_id: int, response_societal_benefit_area_id: int):
- """Delete societal benefit area response object from survey."""
- survey = db.get_or_404(Survey, survey_id)
- response_sba = db.get_or_404(
- ResponseSocietalBenefitArea,
- response_societal_benefit_area_id,
- )
- db.session.delete(response_sba)
- db.session.commit()
-
- return redirect(
- url_for('sba.view_response_sbas', survey_id=survey.id),
- code=303,
- )
diff --git a/usaon_benefit_tool/routes/surveys.py b/usaon_benefit_tool/routes/surveys.py
deleted file mode 100644
index 9e8f46fe..00000000
--- a/usaon_benefit_tool/routes/surveys.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from flask import Blueprint, render_template
-from flask_login import login_required
-
-from usaon_benefit_tool.models.tables import Survey
-
-surveys_bp = Blueprint('surveys', __name__, url_prefix='/surveys')
-
-
-@surveys_bp.route('')
-@login_required
-def view_surveys():
- surveys = Survey.query.order_by(Survey.created_timestamp).all()
- return render_template('surveys.html', surveys=surveys)
diff --git a/usaon_benefit_tool/static/style.css b/usaon_benefit_tool/static/style.css
index 8925922b..9ae56050 100644
--- a/usaon_benefit_tool/static/style.css
+++ b/usaon_benefit_tool/static/style.css
@@ -4,6 +4,13 @@
margin-bottom: 0;
}
+a {
+ text-decoration: none;
+}
+a:hover {
+ text-decoration: underline;
+}
+
/* Footer stuff */
body {
diff --git a/usaon_benefit_tool/templates/assessment/_data_product.html b/usaon_benefit_tool/templates/assessment/_data_product.html
new file mode 100644
index 00000000..7f3c726e
--- /dev/null
+++ b/usaon_benefit_tool/templates/assessment/_data_product.html
@@ -0,0 +1,37 @@
+{% from 'bootstrap5/form.html' import render_form %}
+{% from 'macros/buttons.j2' import delete_button_htmx %}
+
+{# Construct POST or PUT request depending on whether a data product id was passed #}
+{% set edit = assessment_data_product_id is not undefined %}
+{% set
+ htmxQueryAttr = 'hx-put=' ~ url_for("assessment.data_product.put", assessment_id=assessment_id, assessment_data_product_id=assessment_data_product_id)
+ if edit else 'hx-post=' ~ url_for("assessment.data_products.post", assessment_id=assessment_id)
+%}
+{% set endpoint = "assessment.data_product.edit" if edit else "assessment.data_products.post" %}
+
+
diff --git a/usaon_benefit_tool/templates/survey/base.html b/usaon_benefit_tool/templates/assessment/base.html
similarity index 54%
rename from usaon_benefit_tool/templates/survey/base.html
rename to usaon_benefit_tool/templates/assessment/base.html
index 660e5091..761461fc 100644
--- a/usaon_benefit_tool/templates/survey/base.html
+++ b/usaon_benefit_tool/templates/assessment/base.html
@@ -6,9 +6,9 @@
{% block content %}
- {% block title %}Project #{{survey.id}}: {{survey.title}}{% endblock %}
+ {% block title %}Assessment #{{assessment.id}}: {{assessment.title}}{% endblock %}
{{ help_icon(
- "Created: "~survey.response.created_timestamp | dateformat~" Last updated: "~survey.response.updated_timestamp | dateformat,
+ "Created: " ~ assessment.created_timestamp | dateformat ~ " Last updated: " ~ assessment.updated_timestamp | dateformat,
html="true",
)}}
@@ -17,45 +17,47 @@
{{ render_nav_pill_item(
- 'survey.view_survey',
- 'Overview',
- survey_id=survey.id,
+ 'assessment.user_guide',
+ 'User guide',
+ assessment_id=assessment.id,
) }}
{{ render_nav_pill_item(
- 'response.view_response',
- 'User guide',
- survey_id=survey.id,
+ 'assessment.get',
+ 'Overview',
+ assessment_id=assessment.id,
) }}
+ {#
{{ render_nav_pill_item(
'obs.view_response_observing_systems',
'Observing systems',
- survey_id=survey.id,
+ assessment_id=assessment.id,
_icon='pencil',
- _badge=survey.response.observing_systems | length | string,
+ _badge=assessment.response.observing_systems | length | string,
) }}
{{ render_nav_pill_item(
'data_product.view_response_data_products',
'Data products',
- survey_id=survey.id,
+ assessment_id=assessment.id,
_icon='pencil',
- _badge=survey.response.data_products | length | string,
+ _badge=assessment.response.data_products | length | string,
) }}
{{ render_nav_pill_item(
'application.view_response_applications',
'Applications',
- survey_id=survey.id,
+ assessment_id=assessment.id,
_icon='pencil',
- _badge=survey.response.applications | length | string,
+ _badge=assessment.response.applications | length | string,
) }}
{{ render_nav_pill_item(
'sba.view_response_sbas',
'Societal Benefit Areas',
- survey_id=survey.id,
+ assessment_id=assessment.id,
_icon='pencil',
- _badge=survey.response.societal_benefit_areas | length | string,
+ _badge=assessment.response.societal_benefit_areas | length | string,
) }}
+ #}
diff --git a/usaon_benefit_tool/templates/survey/overview.html b/usaon_benefit_tool/templates/assessment/edit.html
similarity index 59%
rename from usaon_benefit_tool/templates/survey/overview.html
rename to usaon_benefit_tool/templates/assessment/edit.html
index 7f51dc0d..7507c2b3 100644
--- a/usaon_benefit_tool/templates/survey/overview.html
+++ b/usaon_benefit_tool/templates/assessment/edit.html
@@ -1,4 +1,4 @@
-{% extends 'survey/base.html' %}
+{% extends 'assessment/base.html' %}
{% from 'bootstrap5/utils.html' import render_icon %}
{% from 'macros/javascript_highcharts.j2' import display_sankey %}
@@ -6,9 +6,8 @@
{{super()}}
Description
- {{survey.description}}
+ {{assessment.description}}
-
- {{ display_sankey(sankey_series, survey_title=survey.title)}}
+ {{ display_sankey(sankey_series, assessment=assessment)}}
{% endblock %}
diff --git a/usaon_benefit_tool/templates/assessment/overview.html b/usaon_benefit_tool/templates/assessment/overview.html
new file mode 100644
index 00000000..7730babe
--- /dev/null
+++ b/usaon_benefit_tool/templates/assessment/overview.html
@@ -0,0 +1,65 @@
+{% extends 'assessment/base.html' %}
+{% from 'bootstrap5/utils.html' import render_icon %}
+{% from 'macros/javascript_highcharts.j2' import display_sankey %}
+{% from 'macros/buttons.j2' import create_button %}
+
+{% block content %}
+ {{super()}}
+
+ Description
+ {{assessment.description}}
+
+
+
+ {{ render_icon("plus-circle-fill") }} Add node
+
+
+ {{ render_icon("plus-circle-fill") }} Add link
+
+
+
+ {{ display_sankey(sankey_series, assessment=assessment)}}
+
+
+ {# NOTE: This div has HTMX configuration because it can be used by
+ Highcharts callbacks to open a modal for viewing or editing a Highcharts
+ node/link. Highcharts will call `htmx.trigger("#this-div-id",
+ "modalOpened")` after setting the `hx-get` attribute on this div with
+ the correct URL to fetch the needed form. This is a bit complex, but it
+ helps simplify the UI by promoting separation of concerns (a new endpoint
+ is created to take responsibility to display the form, and HTMX is
+ responsible for fetching and submitting right form). This helps prevent
+ one big Jinja template for a unified diagram editing interface that
+ must display at least 4 different kinds of forms.
+ #}
+
+
+
+{% endblock %}
diff --git a/usaon_benefit_tool/templates/survey/user_guide.html b/usaon_benefit_tool/templates/assessment/user_guide.html
similarity index 76%
rename from usaon_benefit_tool/templates/survey/user_guide.html
rename to usaon_benefit_tool/templates/assessment/user_guide.html
index e4e835c3..f4c084fd 100644
--- a/usaon_benefit_tool/templates/survey/user_guide.html
+++ b/usaon_benefit_tool/templates/assessment/user_guide.html
@@ -1,4 +1,4 @@
-{% extends 'survey/base.html' %}
+{% extends 'assessment/base.html' %}
{% block content %}
diff --git a/usaon_benefit_tool/templates/assessments.html b/usaon_benefit_tool/templates/assessments.html
new file mode 100644
index 00000000..dd209bb8
--- /dev/null
+++ b/usaon_benefit_tool/templates/assessments.html
@@ -0,0 +1,83 @@
+{% extends 'base.html' %}
+{% from 'bootstrap5/utils.html' import render_icon %}
+{% from 'macros/badges/private.j2' import private_badge %}
+{% from 'macros/forms/new_assessment.j2' import new_assessment_form %}
+
+
+{% block content %}
+ {% block title %}Assessments{% endblock %}
+
+ {% if current_user.role_id=='admin' %}
+
+ {{ render_icon("plus-circle-fill") }} New
+
+
+
+
+
+ {{ new_assessment_form(form) }}
+
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+ {% if current_user.role_id=='admin' %}
+ #
+ {% endif %}
+
+ Title
+
+ {% if current_user.role_id=='admin' %}
+ Created by
+ Created time
+ Updated time
+ {% endif %}
+
+ Status
+
+
+
+
+
+
+
+ {% for assessment in assessments %}
+
+ {% if current_user.role_id=='admin' %}
+ {{assessment.id}}
+ {% endif %}
+
+
+ {{assessment.title}}
+
+
+ {% if current_user.role_id=='admin' %}
+ {{assessment.created_by.email}}
+ {{assessment.created_timestamp | dateformat}}
+ {{assessment.updated_timestamp | dateformat}}
+ {% endif %}
+
+ {{assessment.status.id}}
+ {{private_badge(assessment.private)}}
+
+ {% endfor %}
+
+
+
+
+{% endblock %}
diff --git a/usaon_benefit_tool/templates/base.html b/usaon_benefit_tool/templates/base.html
index e830f877..89d7db2e 100644
--- a/usaon_benefit_tool/templates/base.html
+++ b/usaon_benefit_tool/templates/base.html
@@ -8,6 +8,18 @@
{% block title %}{% endblock %} - US AON Benefit Tool
{{ bootstrap.load_css() }}
+ {# TODO:
+ Can the version of HTMX we include be managed as a dependency like
+ bootstrap?
+ #}
+
+ {{ JSGlue.include() }}
+ {# TODO:
+ The best practice is to load bootstrap right before
@@ -73,7 +85,6 @@
{% block scripts %}
- {{ bootstrap.load_js() }}
{{ add_javascript__remove() }}
diff --git a/usaon_benefit_tool/templates/home.md b/usaon_benefit_tool/templates/home.md
index e9c40afa..e60098a3 100644
--- a/usaon_benefit_tool/templates/home.md
+++ b/usaon_benefit_tool/templates/home.md
@@ -4,8 +4,8 @@
### Actions
-* [View our library of projects]({{ url_for("surveys.view_surveys") }}).
-* [Edit or update your own project]({{ url_for("surveys.view_surveys") }}).
+* [View our library of assessments]({{ url_for("assessments.get") }}).
+* [Edit or update your own assessment]({{ url_for("assessments.get") }}).
* If you'd like to create a new evaluation please email: [hazel@iarpccollaborations.org](mailto:hazel@iarpccollaborations.org)
* Our [data management plan](https://docs.google.com/document/d/13DLX3A__M60xMgFbQqk2NMAjZzahn5FZcvB3fWSVRck/edit?usp=sharing)
includes information about how any information you add to the tool will be stored and may be shared.
diff --git a/usaon_benefit_tool/templates/jsglue/js_bridge.js b/usaon_benefit_tool/templates/jsglue/js_bridge.js
new file mode 100644
index 00000000..b89a6608
--- /dev/null
+++ b/usaon_benefit_tool/templates/jsglue/js_bridge.js
@@ -0,0 +1,113 @@
+{# Provide `{{namespace}}.url_for` JS function (default `Flask.url_for()`).
+
+Vendored from https://github.com/stewartpark/Flask-JSGlue; appears abandoned.
+Applied changes to work with modern versions of these dependencies.
+
+Copyright 2022 Stewart Park
+License: BSD 3-clause
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#}
+var {{ namespace }} = new(function () {
+ 'use strict';
+ return {
+ '_endpoints': {{ rules|safe }},
+ 'url_for': function (endpoint, rule) {
+ if (typeof rule === "undefined") rule = {};
+ else if (typeof(rule) !== "object") {
+ // rule *must* be an Object, anything else is wrong
+ throw {name: "ValueError", message: "type for 'rule' must be Object, got: " + typeof(rule)};
+ }
+
+ var has_everything = false,
+ url = "";
+
+ var is_absolute = false,
+ has_anchor = false,
+ has_scheme;
+ var anchor = "",
+ scheme = "";
+
+ if (rule['_external'] === true) {
+ is_absolute = true;
+ scheme = location.protocol.split(':')[0];
+ delete rule['_external'];
+ }
+
+ if ('_scheme' in rule) {
+ if (is_absolute) {
+ scheme = rule['_scheme'];
+ delete rule['_scheme'];
+ } else {
+ throw {
+ name: "ValueError",
+ message: "_scheme is set without _external."
+ };
+ }
+ }
+
+ if ('_anchor' in rule) {
+ has_anchor = true;
+ anchor = rule['_anchor'];
+ delete rule['_anchor'];
+ }
+
+ for (var i in this._endpoints) {
+ if (endpoint == this._endpoints[i][0]) {
+ var url = '';
+ var j = 0;
+ var has_everything = true;
+ var used = {};
+ for (var j = 0; j < this._endpoints[i][2].length; j++) {
+ var t = rule[this._endpoints[i][2][j]];
+ if (typeof t === "undefined") {
+ has_everything = false;
+ break;
+ }
+ url += this._endpoints[i][1][j] + t;
+ used[this._endpoints[i][2][j]] = true;
+ }
+ if (has_everything) {
+ if (this._endpoints[i][2].length != this._endpoints[i][1].length)
+ url += this._endpoints[i][1][j];
+
+ var first = true;
+ for (var r in rule) {
+ if (r[0] != '_' && !(r in used)) {
+ if (first) {
+ url += '?';
+ first = false;
+ } else {
+ url += '&';
+ }
+ url += r + '=' + rule[r];
+ }
+ }
+ if (has_anchor) {
+ url += "#" + anchor;
+ }
+
+ if (is_absolute) {
+ return scheme + "://" + location.host + url;
+ } else {
+ return url;
+ }
+ }
+ }
+ }
+
+ throw {
+ name: 'BuildError',
+ message: "Endpoint '" + endpoint + "' does not exist or you have passed incorrect parameters " + JSON.stringify(rule)
+ };
+ }
+ };
+});
diff --git a/usaon_benefit_tool/templates/macros/buttons.j2 b/usaon_benefit_tool/templates/macros/buttons.j2
index 345b5da5..7271b914 100644
--- a/usaon_benefit_tool/templates/macros/buttons.j2
+++ b/usaon_benefit_tool/templates/macros/buttons.j2
@@ -1,5 +1,18 @@
{% from 'bootstrap5/utils.html' import render_icon %}
+{% macro delete_button_htmx(endpoint, text) -%}
+ {% set text = text | default('Delete') %}
+
+
+ {{render_icon('trash3-fill')}} {{text}}
+
+{%- endmacro -%}
+
{% macro delete_button(endpoint, text) -%}
{# CRITICAL: The "remove()" JS function must be available. #}
{% set text = text | default('Delete') %}
@@ -21,12 +34,12 @@
class="btn btn-success text-nowrap"
role="button"
/>
+ {# TODO: Sparkles? :) #}
{{ render_icon("plus-circle-fill") }} {{text}}
{%- endmacro -%}
-
{% macro edit_button(endpoint, text) -%}
{% set text = text | default('Edit') %}
diff --git a/usaon_benefit_tool/templates/macros/forms/form_fields.j2 b/usaon_benefit_tool/templates/macros/forms/form_fields.j2
new file mode 100644
index 00000000..099ae03e
--- /dev/null
+++ b/usaon_benefit_tool/templates/macros/forms/form_fields.j2
@@ -0,0 +1,35 @@
+{% from 'bootstrap5/form.html' import render_hidden_errors, render_field %}
+
+{% macro render_form_fields(
+ form,
+ form_type="basic",
+ horizontal_columns=('lg', 2, 10),
+ button_map={},
+ button_style="",
+ button_size="",
+ form_group_classes=''
+) %}
+ {#-
+ Render a form without the
+{%- endmacro -%}
diff --git a/usaon_benefit_tool/templates/macros/javascript_highcharts.j2 b/usaon_benefit_tool/templates/macros/javascript_highcharts.j2
index e7e5b326..2ced724e 100644
--- a/usaon_benefit_tool/templates/macros/javascript_highcharts.j2
+++ b/usaon_benefit_tool/templates/macros/javascript_highcharts.j2
@@ -1,6 +1,52 @@
-{% macro add_javascript__highcharts(sankey_series, survey_title) -%}
-
+{% macro add_javascript__highcharts(sankey_series, assessment) -%}
{% endmacro %}
-{% macro display_sankey(sankey_series, survey_title) -%}
+{% macro display_sankey(sankey_series, assessment) -%}
{% include 'includes/highcharts.html' %}
Diagram
@@ -42,6 +124,6 @@
- {{ add_javascript__highcharts(sankey_series, survey_title) }}
+ {{ add_javascript__highcharts(sankey_series=sankey_series, assessment=assessment) }}
{% endif %}
{% endmacro %}
diff --git a/usaon_benefit_tool/templates/macros/nav_buttons.j2 b/usaon_benefit_tool/templates/macros/nav_buttons.j2
index 81f8aabb..e2fc85bc 100644
--- a/usaon_benefit_tool/templates/macros/nav_buttons.j2
+++ b/usaon_benefit_tool/templates/macros/nav_buttons.j2
@@ -1,8 +1,9 @@
{% macro nav_buttons(current_user) -%}
{% from "bootstrap5/nav.html" import render_nav_item %}
- {{ render_nav_item("root.root", "Home", _use_li=True)}}
- {{ render_nav_item("surveys.view_surveys", "Projects", _use_li=True)}}
+ {{ render_nav_item("assessments.get", "Assessments", _use_li=True)}}
+ {# NB: The user-facing term for "nodes" is "objects" #}
+ {{ render_nav_item("nodes.get", "Object library", _use_li=True)}}
{%- endmacro -%}
diff --git a/usaon_benefit_tool/templates/new_survey.html b/usaon_benefit_tool/templates/new_survey.html
deleted file mode 100644
index aac2d899..00000000
--- a/usaon_benefit_tool/templates/new_survey.html
+++ /dev/null
@@ -1,33 +0,0 @@
-{% extends 'base.html' %}
-
-
-{% block content %}
-
- {% block title %}New Project{% endblock %}
-
-
-
-{% endblock %}
diff --git a/usaon_benefit_tool/templates/node.html b/usaon_benefit_tool/templates/node.html
new file mode 100644
index 00000000..7975ffa2
--- /dev/null
+++ b/usaon_benefit_tool/templates/node.html
@@ -0,0 +1,20 @@
+{% extends 'base.html' %}
+{% from 'macros/forms/form_fields.j2' import render_form_fields %}
+{% from 'macros/buttons.j2' import delete_button_htmx %}
+{% from 'macros/help_icon.j2' import help_icon %}
+
+{% block content %}
+
+ {% block title %}Object #{{node.id}}: {{node.title}}{% endblock %}
+ {{ help_icon(
+ "Created: " ~ node.created_timestamp | dateformat ~ " Last updated: " ~ node.updated_timestamp | dateformat,
+ html="true",
+ )}}
+
+
+
+{% endblock %}
diff --git a/usaon_benefit_tool/templates/nodes.html b/usaon_benefit_tool/templates/nodes.html
new file mode 100644
index 00000000..8667b10b
--- /dev/null
+++ b/usaon_benefit_tool/templates/nodes.html
@@ -0,0 +1,129 @@
+{% extends 'base.html' %}
+{% from 'bootstrap5/utils.html' import render_icon %}
+{% from 'macros/badges/private.j2' import private_badge %}
+{% from 'macros/buttons.j2' import edit_button, delete_button_htmx %}
+
+
+{% block content %}
+ {% block title %}Object library{% endblock %}
+
+ {% if current_user.role_id=='admin' %}
+ {# TODO: _DRY!_ #}
+
+ {{ render_icon("plus-circle-fill") }} New observing system
+
+
+ {{ render_icon("plus-circle-fill") }} New data product
+
+
+ {{ render_icon("plus-circle-fill") }} New application
+
+
+ {{ render_icon("plus-circle-fill") }} New societal benefit area
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+ {% if current_user.role_id=='admin' %}
+ #
+ {% endif %}
+
+ Title
+ Object type
+
+ {% if current_user.role_id=='admin' %}
+ Created by
+ Created time
+ Updated time
+ {% endif %}
+
+
+
+
+
+ {% for node in nodes %}
+
+
+ {% if current_user.role_id=='admin' %}
+ {{node.id}}
+ {% endif %}
+
+
+
+ {{node.title}}
+
+
+
+
+ {{node.type.value}}
+
+
+ {% if current_user.role_id=='admin' %}
+ {{node.created_by.email}}
+ {{node.created_timestamp | dateformat}}
+ {{node.updated_timestamp | dateformat}}
+
+ {{delete_button_htmx(
+ 'node.delete',
+ 'Delete object',
+ node_id=node.id,
+ )}}
+
+ {% endif %}
+
+
+ {% endfor %}
+
+
+
+
+{% endblock %}
diff --git a/usaon_benefit_tool/templates/partials/modal_form.html b/usaon_benefit_tool/templates/partials/modal_form.html
new file mode 100644
index 00000000..6df3592b
--- /dev/null
+++ b/usaon_benefit_tool/templates/partials/modal_form.html
@@ -0,0 +1,14 @@
+{% from 'macros/forms/form_fields.j2' import render_form_fields %}
+
+
diff --git a/usaon_benefit_tool/templates/survey/applications.html b/usaon_benefit_tool/templates/survey/applications.html
deleted file mode 100644
index ee035aa2..00000000
--- a/usaon_benefit_tool/templates/survey/applications.html
+++ /dev/null
@@ -1,97 +0,0 @@
-{% extends 'survey/base.html' %}
-{% from 'bootstrap5/form.html' import render_form %}
-{% from 'bootstrap5/utils.html' import render_icon %}
-{% from 'macros/buttons.j2' import delete_button, create_button %}
-{% from 'macros/javascript_highcharts.j2' import display_sankey %}
-
-{% block content %}
- {{super()}}
-
- Applications
-
-
-
-
-
- Name
- Data products related
-
-
- Name
- Performance Rating
- Criticality Rating
- Edit Relationships
-
- {% for application in response.applications %}
-
- {{application.short_name}}
- {{delete_button(
- 'application.delete_response_application',
- 'Delete object',
- survey_id=survey.id,
- response_application_id=application.id,
- )}}
-
-
- {% if not application.input_relationships %}
- None
-
- {% endif %}
-
- {% for input_relationship in application.input_relationships %}
- {{input_relationship.data_product.short_name}}
- {% endfor %}
-
-
-
-
-
- {% for input_relationship in application.input_relationships %}
- {{input_relationship.performance_rating}}
- {% endfor %}
-
-
-
-
- {% for input_relationship in application.input_relationships %}
- {{input_relationship.criticality_rating}}
- {% endfor %}
-
-
-
- {{create_button(
- 'data_product_application.view_response_data_product_application_relationships',
- 'New relationship',
- survey_id=survey.id,
- application_id=application.id,
- )}}
- {% for input_relationship in application.input_relationships %}
-
- {{delete_button(
- 'data_product_application.delete_response_data_product_application_relationships',
- 'Delete relationship',
- survey_id=survey.id,
- response_data_product_application_id=input_relationship.id,
- )}}
-
-
- {% endfor %}
-
-
- {% endfor %}
-
-
-
- {{ display_sankey(sankey_series) }}
-
-
- {% if not current_user.role_id not in ['admin', 'respondent'] %}
- Add application
-
-
- {% endif %}
-
-{% endblock %}
diff --git a/usaon_benefit_tool/templates/survey/data_products.html b/usaon_benefit_tool/templates/survey/data_products.html
deleted file mode 100644
index eb5600b0..00000000
--- a/usaon_benefit_tool/templates/survey/data_products.html
+++ /dev/null
@@ -1,94 +0,0 @@
-{% extends 'survey/base.html' %}
-{% from 'bootstrap5/form.html' import render_form %}
-{% from 'bootstrap5/utils.html' import render_icon %}
-{% from 'macros/buttons.j2' import delete_button, create_button %}
-{% from 'macros/javascript_highcharts.j2' import display_sankey %}
-
-{% block content %}
- {{super()}}
-
- Data products
-
-
-
-
-
- Name
- Related Observing Systems
-
-
- Name
- Performance Rating
- Criticality Rating
- Edit Relationships
-
- {% for data_product in response.data_products %}
-
- {{data_product.short_name}}
- {{delete_button(
- 'data_product.delete_response_data_product',
- 'Delete object',
- survey_id=survey.id,
- response_data_product_id=data_product.id,
- )}}
-
-
- {% if not data_product.input_relationships %}
- None
-
- {% endif %}
-
- {% for input_relationship in data_product.input_relationships %}
- {{input_relationship.observing_system.short_name}}
- {% endfor %}
-
-
-
-
- {% for input_relationship in data_product.input_relationships %}
- {{input_relationship.performance_rating}}
- {% endfor %}
-
-
-
-
- {% for input_relationship in data_product.input_relationships %}
- {{input_relationship.criticality_rating}}
- {% endfor %}
-
-
-
- {{create_button(
- 'observing_system_data_product.view_response_observing_system_data_product_relationships',
- 'New relationship',
- survey_id=survey.id,
- data_product_id=data_product.id,
- )}}
- {% for input_relationship in data_product.input_relationships %}
-
- {{delete_button(
- 'observing_system_data_product.delete_response_observing_system_data_product_relationship',
- 'Delete relationship',
- survey_id=survey.id,
- response_observing_system_data_product_id=input_relationship.id,
- )}}
-
- {% endfor %}
-
-
- {% endfor %}
-
-
-
- {{ display_sankey(sankey_series) }}
-
-
-
- {% if not current_user.role_id not in ['admin', 'respondent'] %}
- Add data product
-
- {% endif %}
-
-{% endblock %}
diff --git a/usaon_benefit_tool/templates/survey/observing_systems.html b/usaon_benefit_tool/templates/survey/observing_systems.html
deleted file mode 100644
index 6ffcffa2..00000000
--- a/usaon_benefit_tool/templates/survey/observing_systems.html
+++ /dev/null
@@ -1,39 +0,0 @@
-{% extends 'survey/base.html' %}
-{% from 'bootstrap5/form.html' import render_form %}
-{% from 'bootstrap5/utils.html' import render_icon %}
-{% from 'macros/buttons.j2' import delete_button %}
-
-
-{% block content %}
-
- {{super()}}
-
- Observing systems
-
-
-
- Name
-
- {% for observing_system in response.observing_systems %}
-
- {{observing_system.short_name}}
- {{delete_button(
- 'obs.delete_response_observing_system',
- 'Delete object',
- survey_id=survey.id,
- response_observing_system_id=observing_system.id,
- )}}
-
-
- {% endfor %}
-
-
-
- {% if not current_user.role_id not in ['admin', 'respondent'] %}
- Add observing system
-
- {% endif %}
-{% endblock %}
diff --git a/usaon_benefit_tool/templates/survey/relationships/application_societal_benefit_area.html b/usaon_benefit_tool/templates/survey/relationships/application_societal_benefit_area.html
deleted file mode 100644
index 4025e3cb..00000000
--- a/usaon_benefit_tool/templates/survey/relationships/application_societal_benefit_area.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{% extends 'survey/base.html' %}
-{% from 'bootstrap5/form.html' import render_form %}
-
-
-{% block content %}
-
- {{super()}}
-
- {% if not current_user.role_id=='analyst' %}
- Application <-> Societal Benefit Area relationship
-
-
-
-
-
- {% else %}
- You do not have permissions to add relationships.
- {% endif %}
-
-
-{% endblock %}
diff --git a/usaon_benefit_tool/templates/survey/relationships/data_product_application.html b/usaon_benefit_tool/templates/survey/relationships/data_product_application.html
deleted file mode 100644
index 16845189..00000000
--- a/usaon_benefit_tool/templates/survey/relationships/data_product_application.html
+++ /dev/null
@@ -1,65 +0,0 @@
-{% extends 'survey/base.html' %}
-{% from 'bootstrap5/form.html' import render_form, render_field %}
-
-
-{% block content %}
-
- {{super()}}
-
- {% if not current_user.role_id=='analyst' %}
- Data Product <-> Application relationship
-
-
-
-
-
-
-
- {% else %}
- You do not have permissions to add relationships.
- {% endif %}
-
-
-{% endblock %}
diff --git a/usaon_benefit_tool/templates/survey/relationships/observing_system_data_product.html b/usaon_benefit_tool/templates/survey/relationships/observing_system_data_product.html
deleted file mode 100644
index 72077a67..00000000
--- a/usaon_benefit_tool/templates/survey/relationships/observing_system_data_product.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{% extends 'survey/base.html' %}
-{% from 'bootstrap5/form.html' import render_form %}
-
-
-{% block content %}
-
- {{super()}}
-
- {% if not current_user.role_id=='analyst' %}
- Observing System <-> Data Product relationship
-
-
-
-
-