From 29ca95f076ce76387deaacc66fb39799a70f605a Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 10:12:46 +0100 Subject: [PATCH 01/11] Generate "conf/requirements.txt" and install via this file --- Makefile | 3 + conf/requirements.txt | 214 ++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 1 + scripts/_common.sh | 6 +- scripts/install | 5 +- scripts/upgrade | 13 ++- 6 files changed, 227 insertions(+), 15 deletions(-) create mode 100644 conf/requirements.txt diff --git a/Makefile b/Makefile index 2edd58a..4e3c59a 100644 --- a/Makefile +++ b/Makefile @@ -16,13 +16,16 @@ check-poetry: fi install-poetry: ## install or update poetry + pip3 install -U pip pip3 install -U poetry + poetry run pip install -U pip install: check-poetry ## install project via poetry poetry install update: install-poetry ## update the sources and installation poetry update + poetry export -f requirements.txt --output conf/requirements.txt local-test: check-poetry ## Run local_test.py to run the project locally poetry run ./local_test.py diff --git a/conf/requirements.txt b/conf/requirements.txt new file mode 100644 index 0000000..19b9892 --- /dev/null +++ b/conf/requirements.txt @@ -0,0 +1,214 @@ +bleach==3.2.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:9f8ccbeb6183c6e6cddea37592dfb0167485c1e3b13b3363bc325aa8bda3adbd \ + --hash=sha256:52b5919b81842b1854196eaae5ca29679a2f2e378905c346d3ca8227c2c66080 +bx-py-utils==18; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:72a6090822544603e3a7547ce07f0120ae67940ca2ec4590ac907b3b09ad70ca \ + --hash=sha256:195ea1b3d5d277354ea33e34ec3ebd4fc2a6e8d94d646ede902f80527f06ec75 +certifi==2020.12.5; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830 \ + --hash=sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c +chardet==4.0.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5 \ + --hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa +colorama==0.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" and sys_platform == "win32" \ + --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2 \ + --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b +colorlog==4.6.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:edd5ada5de03e880e42b2526f8be5570fd9b692f8eb7cf6b1fdcac3e3fb23976 \ + --hash=sha256:54e5f153419c22afc283c130c4201db19a3dbd83221a0f4657d5ee66234a2ea4 +defusedxml==0.6.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93 \ + --hash=sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5 +diff-match-patch==20200713; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:da6f5a01aa586df23dfc89f3827e1cafbb5420be9d87769eeb079ddfd9477a18 \ + --hash=sha256:8bf9d9c4e059d917b5c6312bac0c137971a32815ddbda9c682b949f2986b4d34 +django-admin-sortable2==0.7.7; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:65c8a02300e178b4a02c904b6f4dce6e528c58f5ecab3907dfba3540da51b862 +django-axes==5.10.0; python_version >= "3.7" and python_version < "4.0" and python_full_version < "4.0.0" \ + --hash=sha256:8a62cd4cc78ef08007e8102def34be83832995eb6e3e0c814d605741b82a2796 \ + --hash=sha256:3c81ddca8a9d7fd0019cb440f711cc873c3039546f7eacb3f2ec616bf0ec1b32 +django-ckeditor==6.0.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:29fd1a333cb9741ac2c3fd4e427a5c00115ed33a2389716a09af7656022dcdde \ + --hash=sha256:cc2d377f1bdcd4ca1540caeebe85f7e2cd006198d57328ef6c718d3eaa5a0846 +django-dbbackup==3.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:bb109735cae98b64ad084e5b461b7aca2d7b39992f10c9ed9435e3ebb6fb76c8 +django-debug-toolbar==3.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:84e2607d900dbd571df0a2acf380b47c088efb787dce9805aefeb407341961d2 \ + --hash=sha256:9e5a25d0c965f7e686f6a8ba23613ca9ca30184daa26487706d4829f5cfb697a +django-import-export==2.4.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:401d76eca0a5c6cf43bffed16c06e509b9044ce8f6bcff264b776e3952830f1a \ + --hash=sha256:7610f6efff797d65f56c03ba34444507c0b0ccdffe9346c168b9894fc349c55e +django-ipware==3.0.2; python_version >= "3.7" and python_version < "4.0" and python_full_version < "4.0.0" \ + --hash=sha256:c7df8e1410a8e5d6b1fbae58728402ea59950f043c3582e033e866f0f0cf5e94 +django-js-asset==1.2.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:c163ae80d2e0b22d8fb598047cd0dcef31f81830e127cfecae278ad574167260 \ + --hash=sha256:8ec12017f26eec524cab436c64ae73033368a372970af4cf42d9354fcb166bdd +django-processinfo==1.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:3cacad233a5428a5cc6292eafbfddd97948d8d1e4f47e47175a7fcdfcee90f12 \ + --hash=sha256:08aefdf7285d1eaa595e46570bcc12f2dfd9e24594d524246110614819076b6c +django-redis==4.12.1; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:306589c7021e6468b2656edc89f62b8ba67e8d5a1c8877e2688042263daa7a63 \ + --hash=sha256:1133b26b75baa3664164c3f44b9d5d133d1b8de45d94d79f38d1adc5b1d502e5 +django-reversion-compare==0.13.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:db7c82ade287e172a9e84d6666b1df0b673eb97ab8a81a8cb52212f359e17f9b \ + --hash=sha256:087d6951462692e0a477a84e5460d606661be6ea2224e40dc9eded193ab7b928 +django-reversion==3.0.8; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:49e9930f90322dc6a2754dd26144285cfcc1c5bd0c1c39ca95d5602c5054ae32 \ + --hash=sha256:9cfadeec2df37cb53d795ab79f6792f9eed8e70363dcf3a275dc19a58b971a8f +django-tagulous==1.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:9bc9d1d066c486fac1a3ec351531e440bc239c459b043e9180d99d7846e45fd6 \ + --hash=sha256:de2a56ed92374b79358275ac0b7910af2c3d2823f44a847bef91ca9e456353ba +django-tools==0.48.3; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:08ed2ae606067f49c2c3949055227a826c8b880e5816114925eca386cf1823af \ + --hash=sha256:40444fa16b703b7c6960a800ba76aad42472c9aa70040d549a4d91dbb47a5ddb +django-ynh==0.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:db75d5d9f0b1744187168a1b815272cd8c86c9ecb0fd77c58517e82a2cd9b09b \ + --hash=sha256:955dc29f55c449e116876c7c920dc8451157bae2a246b1375822f5e47d4c6fd4 +django==2.2.17; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "4.0" \ + --hash=sha256:558cb27930defd9a6042133258caf797b2d1dee233959f537e3dc475cb49bd7c \ + --hash=sha256:cf5370a4d7765a9dd6d42a7b96b53c74f9446cd38209211304b210fe0404b861 +et-xmlfile==1.0.1; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:614d9722d572f6246302c4491846d2c393c199cfa4edc9af593437691683335b +gunicorn==20.0.4; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c \ + --hash=sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626 +icdiff==1.9.1; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:66972dd03318da55280991db375d3ef6b66d948c67af96c1ebdb21587e86655e +idna==2.10; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 \ + --hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 +jdcal==1.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:1abf1305fce18b4e8aa248cf8fe0c56ce2032392bc64bbd61b5dff2a19ec8bba \ + --hash=sha256:472872e096eb8df219c23f2689fc336668bdb43d194094b5cc1707e1640acfc8 +markuppy==1.14; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f +odfpy==1.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0 \ + --hash=sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec +openpyxl==3.0.5; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:f7d666b569f729257082cf7ddc56262431878f602dcc2bc3980775c59439cdab \ + --hash=sha256:18e11f9a650128a12580a58e3daba14e00a11d9e907c554a17ea016bf1a2c71b +packaging==20.8; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858 \ + --hash=sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093 +pillow==8.0.1; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3 \ + --hash=sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302 \ + --hash=sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c \ + --hash=sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11 \ + --hash=sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e \ + --hash=sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3 \ + --hash=sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09 \ + --hash=sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae \ + --hash=sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a \ + --hash=sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8 \ + --hash=sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0 \ + --hash=sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039 \ + --hash=sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11 \ + --hash=sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72 \ + --hash=sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792 \ + --hash=sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015 \ + --hash=sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271 \ + --hash=sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7 \ + --hash=sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5 \ + --hash=sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce \ + --hash=sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3 \ + --hash=sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544 \ + --hash=sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140 \ + --hash=sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021 \ + --hash=sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6 \ + --hash=sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb \ + --hash=sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8 \ + --hash=sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e +pprintpp==0.4.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \ + --hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403 +psycopg2-binary==2.8.6; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.4.0" \ + --hash=sha256:11b9c0ebce097180129e422379b824ae21c8f2a6596b159c7659e2e5a00e1aa0 \ + --hash=sha256:d14b140a4439d816e3b1229a4a525df917d6ea22a0771a2a78332273fd9528a4 \ + --hash=sha256:1fabed9ea2acc4efe4671b92c669a213db744d2af8a9fc5d69a8e9bc14b7a9db \ + --hash=sha256:f5ab93a2cb2d8338b1674be43b442a7f544a0971da062a5da774ed40587f18f5 \ + --hash=sha256:b4afc542c0ac0db720cf516dd20c0846f71c248d2b3d21013aa0d4ef9c71ca25 \ + --hash=sha256:e74a55f6bad0e7d3968399deb50f61f4db1926acf4a6d83beaaa7df986f48b1c \ + --hash=sha256:0deac2af1a587ae12836aa07970f5cb91964f05a7c6cdb69d8425ff4c15d4e2c \ + --hash=sha256:ad20d2eb875aaa1ea6d0f2916949f5c08a19c74d05b16ce6ebf6d24f2c9f75d1 \ + --hash=sha256:950bc22bb56ee6ff142a2cb9ee980b571dd0912b0334aa3fe0fe3788d860bea2 \ + --hash=sha256:b8a3715b3c4e604bcc94c90a825cd7f5635417453b253499664f784fc4da0152 \ + --hash=sha256:d1b4ab59e02d9008efe10ceabd0b31e79519da6fb67f7d8e8977118832d0f449 \ + --hash=sha256:ac0c682111fbf404525dfc0f18a8b5f11be52657d4f96e9fcb75daf4f3984859 \ + --hash=sha256:7d92a09b788cbb1aec325af5fcba9fed7203897bbd9269d5691bb1e3bce29550 \ + --hash=sha256:aaa4213c862f0ef00022751161df35804127b78adf4a2755b9f991a507e425fd \ + --hash=sha256:c2507d796fca339c8fb03216364cca68d87e037c1f774977c8fc377627d01c71 \ + --hash=sha256:ee69dad2c7155756ad114c02db06002f4cded41132cc51378e57aad79cc8e4f4 \ + --hash=sha256:e82aba2188b9ba309fd8e271702bd0d0fc9148ae3150532bbb474f4590039ffb \ + --hash=sha256:d5227b229005a696cc67676e24c214740efd90b148de5733419ac9aaba3773da \ + --hash=sha256:a0eb43a07386c3f1f1ebb4dc7aafb13f67188eab896e7397aa1ee95a9c884eb2 \ + --hash=sha256:e1f57aa70d3f7cc6947fd88636a481638263ba04a742b4a37dd25c373e41491a \ + --hash=sha256:833709a5c66ca52f1d21d41865a637223b368c0ee76ea54ca5bad6f2526c7679 \ + --hash=sha256:ba28584e6bca48c59eecbf7efb1576ca214b47f05194646b081717fa628dfddf \ + --hash=sha256:6a32f3a4cb2f6e1a0b15215f448e8ce2da192fd4ff35084d80d5e39da683e79b \ + --hash=sha256:0e4dc3d5996760104746e6cfcdb519d9d2cd27c738296525d5867ea695774e67 \ + --hash=sha256:cec7e622ebc545dbb4564e483dd20e4e404da17ae07e06f3e780b2dacd5cee66 \ + --hash=sha256:ba381aec3a5dc29634f20692349d73f2d21f17653bda1decf0b52b11d694541f \ + --hash=sha256:a0c50db33c32594305b0ef9abc0cb7db13de7621d2cadf8392a1d9b3c437ef77 \ + --hash=sha256:2dac98e85565d5688e8ab7bdea5446674a83a3945a8f416ad0110018d1501b94 \ + --hash=sha256:bd1be66dde2b82f80afb9459fc618216753f67109b859a361cf7def5c7968729 \ + --hash=sha256:8cd0fb36c7412996859cb4606a35969dd01f4ea34d9812a141cd920c3b18be77 \ + --hash=sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83 \ + --hash=sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52 \ + --hash=sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd \ + --hash=sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056 \ + --hash=sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6 +pyinventory==0.8.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:f772cdae9d34f77a31a943f796a02bf706bba1f4ff7b2ecba87afc96234a64c2 \ + --hash=sha256:c3badc4db1d488d49fd693536ba3c93b84bf880841d109e9bce9e2be864ce9e0 +pyparsing==2.4.7; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \ + --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 +python-stdnum==1.14; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:fd3a92b8ec82a159c41dbaa3c5397934d090090c92b04e346412e0fd7e6a1b1c \ + --hash=sha256:6389a1e7658e39c37e4f10b42d7a51ce620e031bdeae05158519c218e14ff3b5 +pytz==2020.5; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4 \ + --hash=sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5 +pyyaml==5.3.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f \ + --hash=sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76 \ + --hash=sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2 \ + --hash=sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c \ + --hash=sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2 \ + --hash=sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648 \ + --hash=sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a \ + --hash=sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf \ + --hash=sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97 \ + --hash=sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee \ + --hash=sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a \ + --hash=sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e \ + --hash=sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d +redis==3.5.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24 \ + --hash=sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2 +requests==2.25.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e \ + --hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 +six==1.15.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \ + --hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 +sqlparse==0.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0 \ + --hash=sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8 +tablib==3.0.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:41aa40981cddd7ec4d1fabeae7c38d271601b306386bd05b5c3bcae13e5aeb20 \ + --hash=sha256:f83cac08454f225a34a305daa20e2110d5e6335135d505f93bc66583a5f9c10d +urllib3==1.26.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473 \ + --hash=sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08 +webencodings==0.5.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ + --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 +xlrd==2.0.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \ + --hash=sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd \ + --hash=sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88 +xlwt==1.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e \ + --hash=sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88 diff --git a/pyproject.toml b/pyproject.toml index 026a1d2..103fa6f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ license = "GPL" [tool.poetry.dependencies] python = ">=3.7,<4.0.0" pyinventory = "*" +django_ynh = "*" [tool.poetry.dev-dependencies] diff --git a/scripts/_common.sh b/scripts/_common.sh index 47f796e..826fe53 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -25,15 +25,11 @@ log_file="${log_path}/pyinventory.log" #================================================= # dependencies used by the app -pkg_dependencies="build-essential python3-dev python3-pip python3-venv git \ - postgresql postgresql-contrib" +pkg_dependencies="build-essential python3-dev python3-pip python3-venv git postgresql postgresql-contrib" # PyInventory's version for PIP and settings file pyinventory_version="0.8.2" -# Extra python packages: -pypi_extras="django-redis" - #================================================= # Redis HELPERS #================================================= diff --git a/scripts/install b/scripts/install index e8e6c72..4aece0f 100755 --- a/scripts/install +++ b/scripts/install @@ -104,6 +104,7 @@ ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell ynh_script_progression --message="Install PyInventory using PIP..." --weight=80 python3 -m venv "${final_path}/venv" +cp ../conf/requirements.txt "$final_path/requirements.txt" chown -R "$app" "$final_path" #run source in a 'sub shell' @@ -112,9 +113,7 @@ chown -R "$app" "$final_path" source "${final_path}/venv/bin/activate" set -o nounset ynh_exec_as $app $final_path/venv/bin/pip install --upgrade pip - ynh_exec_as $app $final_path/venv/bin/pip install --upgrade setuptools wheel psycopg2-binary - ynh_exec_as $app $final_path/venv/bin/pip install --upgrade pyinventory=="$pyinventory_version" - ynh_exec_as $app $final_path/venv/bin/pip install --upgrade ${pypi_extras} + ynh_exec_as $app $final_path/venv/bin/pip install -r "$final_path/requirements.txt" ) #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 3523f15..4295ece 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -89,17 +89,16 @@ ynh_add_systemd_config --service="$app" --template="pyinventory.service" ynh_script_progression --message="Install pyinventory using PIP..." --weight=15 python3 -m venv "${final_path}/venv" +cp ../conf/requirements.txt "$final_path/requirements.txt" chown -R "$app" "$final_path" #run source in a 'sub shell' ( - set +o nounset - source "${final_path}/venv/bin/activate" - set -o nounset - ynh_exec_as $app $final_path/venv/bin/pip install --upgrade pip - ynh_exec_as $app $final_path/venv/bin/pip install --upgrade setuptools wheel psycopg2-binary - ynh_exec_as $app $final_path/venv/bin/pip install --upgrade pyinventory=="$pyinventory_version" - ynh_exec_as $app $final_path/venv/bin/pip install --upgrade ${pypi_extras} + set +o nounset + source "${final_path}/venv/bin/activate" + set -o nounset + ynh_exec_as $app $final_path/venv/bin/pip install --upgrade pip + ynh_exec_as $app $final_path/venv/bin/pip install -r "$final_path/requirements.txt" ) #================================================= From 53509495600b51a1f5011f672f8d8cd385066539 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 12:51:24 +0100 Subject: [PATCH 02/11] Bugfix nginx.conf --- conf/nginx.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/nginx.conf b/conf/nginx.conf index 65adebf..729b72d 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -12,7 +12,7 @@ location __PATH__/static/ { # expires 30d; #} -location / { +location __PATH__/ { # https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf # this is needed if you have file import via upload enabled @@ -30,5 +30,5 @@ location / { proxy_connect_timeout 30; proxy_redirect off; - proxy_pass http://127.0.0.1:__PORT__/; + proxy_pass http://127.0.0.1:__PORT__; } From 465bf8b8eb7e268b1c38f91ba50857f595db0244 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 12:52:08 +0100 Subject: [PATCH 03/11] rename settings/urls --- conf/manage.py | 2 +- conf/{ynh_pyinventory_settings.py => settings.py} | 0 conf/{ynh_urls.py => urls.py} | 0 conf/wsgi.py | 4 ++-- 4 files changed, 3 insertions(+), 3 deletions(-) rename conf/{ynh_pyinventory_settings.py => settings.py} (100%) rename conf/{ynh_urls.py => urls.py} (100%) diff --git a/conf/manage.py b/conf/manage.py index 944c2a6..c0f3ae6 100755 --- a/conf/manage.py +++ b/conf/manage.py @@ -5,7 +5,7 @@ import sys def main(): - os.environ['DJANGO_SETTINGS_MODULE'] = 'ynh_pyinventory_settings' + os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) diff --git a/conf/ynh_pyinventory_settings.py b/conf/settings.py similarity index 100% rename from conf/ynh_pyinventory_settings.py rename to conf/settings.py diff --git a/conf/ynh_urls.py b/conf/urls.py similarity index 100% rename from conf/ynh_urls.py rename to conf/urls.py diff --git a/conf/wsgi.py b/conf/wsgi.py index 34badf7..6158012 100644 --- a/conf/wsgi.py +++ b/conf/wsgi.py @@ -2,7 +2,7 @@ WSGI config """ import os -os.environ['DJANGO_SETTINGS_MODULE'] = 'ynh_pyinventory_settings' +os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' from django.core.wsgi import get_wsgi_application -application = get_wsgi_application() \ No newline at end of file +application = get_wsgi_application() From cca6eef925c0645bbf2335a419c77d95688f998d Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 12:52:44 +0100 Subject: [PATCH 04/11] cleanup Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4e3c59a..e9ae7ae 100644 --- a/Makefile +++ b/Makefile @@ -18,12 +18,12 @@ check-poetry: install-poetry: ## install or update poetry pip3 install -U pip pip3 install -U poetry - poetry run pip install -U pip install: check-poetry ## install project via poetry poetry install -update: install-poetry ## update the sources and installation +update: install-poetry ## update the sources and installation and generate "conf/requirements.txt" + poetry run pip install -U pip poetry update poetry export -f requirements.txt --output conf/requirements.txt From add1026c119893b70ecd1e7ea3bef0be56a25843 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 13:58:40 +0100 Subject: [PATCH 05/11] Refactor to use django_ynh --- .gitignore | 2 + Makefile | 15 +++- README.md | 6 +- conf/create_superuser.py | 46 ---------- conf/gunicorn.conf.py | 1 + conf/manage.py | 1 + conf/requirements.txt | 8 +- conf/settings.py | 40 +++++---- conf/setup_user.py | 8 ++ conf/urls.py | 2 - conf/wsgi.py | 6 +- conf/ynh_authenticate.py | 185 --------------------------------------- local_test.py | 149 +++---------------------------- manifest.json | 2 +- pyproject.toml | 67 +++++++++++++- scripts/_common.sh | 3 - scripts/change_url | 4 +- scripts/install | 24 +++-- scripts/upgrade | 44 +++++----- 19 files changed, 173 insertions(+), 440 deletions(-) delete mode 100644 conf/create_superuser.py create mode 100644 conf/setup_user.py delete mode 100644 conf/ynh_authenticate.py mode change 100755 => 100644 local_test.py diff --git a/.gitignore b/.gitignore index d18d5cc..04228fa 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ __pycache__ secret.txt /local_test/ /poetry.lock +/coverage.xml +/htmlcov/ diff --git a/Makefile b/Makefile index e9ae7ae..01bfae7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ SHELL := /bin/bash +MAX_LINE_LENGTH := 119 all: help @@ -27,8 +28,18 @@ update: install-poetry ## update the sources and installation and generate "con poetry update poetry export -f requirements.txt --output conf/requirements.txt -local-test: check-poetry ## Run local_test.py to run the project locally - poetry run ./local_test.py +lint: ## Run code formatters and linter + poetry run flynt --fail-on-change --line_length=${MAX_LINE_LENGTH} . + poetry run isort --check-only . + poetry run flake8 . + +fix-code-style: ## Fix code formatting + poetry run flynt --line_length=${MAX_LINE_LENGTH} . + poetry run black --verbose --safe --line-length=${MAX_LINE_LENGTH} --skip-string-normalization . + poetry run isort . + +local-test: install ## Run local_test.py to run the project locally + poetry run python3 ./local_test.py local-diff-settings: ## Run "manage.py diffsettings" with local test poetry run python3 local_test/opt_yunohost/manage.py diffsettings diff --git a/README.md b/README.md index 410294a..83ffac6 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Pull requests welcome ;) ## Settings and upgrades -Almost everything related to PyInventory's configuration is handled in a `"../conf/ynh_pyinventory_settings.py"` file. +Almost everything related to PyInventory's configuration is handled in a `"../conf/settings.py"` file. You can edit the file `$final_path/local_settings.py` to enable or disable features. # Miscellaneous @@ -100,13 +100,13 @@ drwxr-xr-x 3 root root 3 Dec 8 08:36 .. -rw-r--r-- 1 pyinventory pyinventory 171 Dec 8 08:39 secret.txt drwxr-xr-x 6 pyinventory pyinventory 6 Dec 8 08:37 venv -rw-r--r-- 1 pyinventory pyinventory 115 Dec 8 08:39 wsgi.py --rw-r--r-- 1 pyinventory pyinventory 4737 Dec 8 08:39 ynh_pyinventory_settings.py +-rw-r--r-- 1 pyinventory pyinventory 4737 Dec 8 08:39 settings.py root@yunohost:~# cd /opt/yunohost/pyinventory/ root@yunohost:/opt/yunohost/pyinventory# source venv/bin/activate (venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py check PyInventory v0.8.2 (Django v2.2.17) -DJANGO_SETTINGS_MODULE='ynh_pyinventory_settings' +DJANGO_SETTINGS_MODULE='settings' PROJECT_PATH:/opt/yunohost/pyinventory/venv/lib/python3.7/site-packages BASE_PATH:/opt/yunohost/pyinventory System check identified no issues (0 silenced). diff --git a/conf/create_superuser.py b/conf/create_superuser.py deleted file mode 100644 index 21cb858..0000000 --- a/conf/create_superuser.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import os -import sys - - -def main(): - os.environ['DJANGO_SETTINGS_MODULE'] = 'ynh_pyinventory_settings' - - parser = argparse.ArgumentParser( - description='Create or update Django super user.' - ) - parser.add_argument('--username') - parser.add_argument('--email') - parser.add_argument('--password') - - args = parser.parse_args() - username = args.username - email = args.email or '' - password = args.password - - import django - django.setup() - - from django.contrib.auth import get_user_model - User = get_user_model() - user = User.objects.filter(username=username).first() - if user: - print('Update existing user and set his password.', file=sys.stderr) - user.is_active = True - user.is_staff = True - user.is_superuser = True - user.set_password(password) - user.email = email - user.save() - else: - print('Create new super user', file=sys.stderr) - User.objects.create_superuser( - username=username, - email=email, - password=password - ) - - -if __name__ == '__main__': - main() diff --git a/conf/gunicorn.conf.py b/conf/gunicorn.conf.py index fde7958..bcab967 100644 --- a/conf/gunicorn.conf.py +++ b/conf/gunicorn.conf.py @@ -3,6 +3,7 @@ """ import multiprocessing + bind = '127.0.0.1:__PORT__' # https://docs.gunicorn.org/en/latest/settings.html#workers diff --git a/conf/manage.py b/conf/manage.py index c0f3ae6..a85e3b1 100755 --- a/conf/manage.py +++ b/conf/manage.py @@ -7,6 +7,7 @@ import sys def main(): os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' from django.core.management import execute_from_command_line + execute_from_command_line(sys.argv) diff --git a/conf/requirements.txt b/conf/requirements.txt index 19b9892..204e24c 100644 --- a/conf/requirements.txt +++ b/conf/requirements.txt @@ -1,7 +1,7 @@ bleach==3.2.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ --hash=sha256:9f8ccbeb6183c6e6cddea37592dfb0167485c1e3b13b3363bc325aa8bda3adbd \ --hash=sha256:52b5919b81842b1854196eaae5ca29679a2f2e378905c346d3ca8227c2c66080 -bx-py-utils==18; python_version >= "3.7" and python_full_version < "4.0.0" \ +bx-py-utils==18; python_version >= "3.6" and python_full_version < "4.0.0" \ --hash=sha256:72a6090822544603e3a7547ce07f0120ae67940ca2ec4590ac907b3b09ad70ca \ --hash=sha256:195ea1b3d5d277354ea33e34ec3ebd4fc2a6e8d94d646ede902f80527f06ec75 certifi==2020.12.5; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ @@ -61,9 +61,9 @@ django-tagulous==1.1.0; python_version >= "3.7" and python_full_version < "4.0.0 django-tools==0.48.3; python_version >= "3.7" and python_full_version < "4.0.0" \ --hash=sha256:08ed2ae606067f49c2c3949055227a826c8b880e5816114925eca386cf1823af \ --hash=sha256:40444fa16b703b7c6960a800ba76aad42472c9aa70040d549a4d91dbb47a5ddb -django-ynh==0.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \ - --hash=sha256:db75d5d9f0b1744187168a1b815272cd8c86c9ecb0fd77c58517e82a2cd9b09b \ - --hash=sha256:955dc29f55c449e116876c7c920dc8451157bae2a246b1375822f5e47d4c6fd4 +django-ynh==0.1.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:2efa30444f67252bbb7601e1b5631ce93ddf72a70b2216bb61363990de78ad4f \ + --hash=sha256:711b0f9ac183b2507a58cf644081aafefdc025ce585f6a8dad427ca3baf55a19 django==2.2.17; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "4.0" \ --hash=sha256:558cb27930defd9a6042133258caf797b2d1dee233959f537e3dc475cb49bd7c \ --hash=sha256:cf5370a4d7765a9dd6d42a7b96b53c74f9446cd38209211304b210fe0404b861 diff --git a/conf/settings.py b/conf/settings.py index 5127053..e6090ca 100644 --- a/conf/settings.py +++ b/conf/settings.py @@ -11,9 +11,11 @@ from pathlib import Path as __Path +from django_ynh.secret_key import get_or_create_secret as __get_or_create_secret from inventory_project.settings.base import * # noqa -DEBUG = False + +DEBUG = False # Don't turn DEBUG on in production! # ----------------------------------------------------------------------------- @@ -31,40 +33,41 @@ PATH_URL = PATH_URL.strip('/') # ----------------------------------------------------------------------------- -ROOT_URLCONF = 'ynh_urls' # /opt/yunohost/pyinventory/ynh_urls.py +ROOT_URLCONF = 'urls' # /opt/yunohost/pyinventory/ynh_urls.py -# ----------------------------------------------------------------------------- +# Function that will be called to finalize a user profile: +YNH_SETUP_USER = 'setup_user.setup_project_user' + +SECRET_KEY = __get_or_create_secret(FINAL_HOME_PATH / 'secret.txt') # /opt/yunohost/$app/secret.txt + +INSTALLED_APPS.append('django_ynh') + +MIDDLEWARE.insert( + MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1, + # login a user via HTTP_REMOTE_USER header from SSOwat: + 'django_ynh.sso_auth.auth_middleware.SSOwatRemoteUserMiddleware', +) # Keep ModelBackend around for per-user permissions and superuser AUTHENTICATION_BACKENDS = ( 'axes.backends.AxesBackend', # AxesBackend should be the first backend! - + # # Authenticate via SSO and nginx 'HTTP_REMOTE_USER' header: - 'ynh_authenticate.RemoteUserBackend', - + 'django_ynh.sso_auth.auth_backend.SSOwatUserBackend', + # # Fallback to normal Django model backend: 'django.contrib.auth.backends.ModelBackend', ) + LOGIN_REDIRECT_URL = None LOGIN_URL = '/yunohost/sso/' LOGOUT_REDIRECT_URL = '/yunohost/sso/' # /yunohost/sso/?action=logout -# ----------------------------------------------------------------------------- -# https://docs.djangoproject.com/en/2.2/howto/auth-remote-user/ -# Add RemoteUserMiddleware after AuthenticationMiddleware - -MIDDLEWARE.insert( - MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1, - 'ynh_authenticate.RemoteUserMiddleware', -) - # ----------------------------------------------------------------------------- -ADMINS = ( - ('__ADMIN__', '__ADMINMAIL__'), -) +ADMINS = (('__ADMIN__', '__ADMINMAIL__'),) MANAGERS = ADMINS @@ -170,6 +173,7 @@ LOGGING = { 'django': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, 'axes': {'handlers': ['log_file', 'mail_admins'], 'level': 'WARNING', 'propagate': False}, 'django_tools': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, + 'django_ynh': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, 'inventory': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, }, } diff --git a/conf/setup_user.py b/conf/setup_user.py new file mode 100644 index 0000000..5d820de --- /dev/null +++ b/conf/setup_user.py @@ -0,0 +1,8 @@ +def setup_project_user(user): + """ + All users used the Django admin, so we need to set the "staff" user flag. + Called from django_ynh.sso_auth + """ + user.is_staff = True + user.save() + return user diff --git a/conf/urls.py b/conf/urls.py index bd1d685..c012497 100644 --- a/conf/urls.py +++ b/conf/urls.py @@ -23,9 +23,7 @@ if settings.PATH_URL: urlpatterns = [ # path(f'{settings.PATH_URL}/debug/', debug_view), path(f'{settings.PATH_URL}/', admin.site.urls), - path(f'{settings.PATH_URL}/ckeditor/', include('ckeditor_uploader.urls')), - # MEDIA_URL contains the "PATH_URL" already: path(settings.MEDIA_URL.lstrip('/'), include('django_tools.serve_media_app.urls')), ] diff --git a/conf/wsgi.py b/conf/wsgi.py index 6158012..018a0cc 100644 --- a/conf/wsgi.py +++ b/conf/wsgi.py @@ -2,7 +2,11 @@ WSGI config """ import os + + os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' -from django.core.wsgi import get_wsgi_application +from django.core.wsgi import get_wsgi_application # noqa + + application = get_wsgi_application() diff --git a/conf/ynh_authenticate.py b/conf/ynh_authenticate.py deleted file mode 100644 index 1f3d03c..0000000 --- a/conf/ynh_authenticate.py +++ /dev/null @@ -1,185 +0,0 @@ -""" - * remote user authentication backend - * remote user middleware - - Note: SSOwat/nginx add authentication headers: - - 'HTTP_AUTHORIZATION': 'Basic XXXXXXXXXXXXXXXX=' - 'HTTP_AUTH_USER': 'username' - 'HTTP_REMOTE_USER': 'username' - - Basic auth contains "{username}:{plaintext-password}" - - and we get SSOwat cookies like: - - 'HTTP_COOKIE': 'SSOwAuthUser=username; ' - 'SSOwAuthHash=593876aa66...99e69f88af1e; ' - 'SSOwAuthExpire=1609227697.998; ' - - * Login a user via HTTP_REMOTE_USER header, but check also username in: - * SSOwAuthUser - * HTTP_AUTH_USER - * HTTP_AUTHORIZATION (Basic auth) - * Create new users - * Update Email, First / Last name for existing users -""" -import base64 -import logging - -from axes.exceptions import AxesBackendPermissionDenied -from django.contrib.auth.backends import RemoteUserBackend as OriginRemoteUserBackend -from django.contrib.auth.middleware import RemoteUserMiddleware as OriginRemoteUserMiddleware -from django.core.exceptions import ValidationError -from inventory.permissions import get_or_create_normal_user_group - -logger = logging.getLogger(__name__) - - -def update_user_profile(request): - """ - Update existing user information: - * Email - * First / Last name - """ - user = request.user - assert user.is_authenticated - - update_fields = [] - - if not user.password: - # Empty password is not valid, so we can't save the model, because of full_clean() call - logger.info('Set unusable password for user: %s', user) - user.set_unusable_password() - update_fields.append('password') - - email = request.META.get('HTTP_EMAIL') - if email and user.email != email: - logger.info('Update email: %r -> %r', user.email, email) - user.email = email - update_fields.append('email') - - raw_username = request.META.get('HTTP_NAME') - if raw_username: - if ' ' in raw_username: - first_name, last_name = raw_username.split(' ', 1) - else: - first_name = '' - last_name = raw_username - - if user.first_name != first_name: - logger.info('Update first name: %r -> %r', user.first_name, first_name) - user.first_name = first_name - update_fields.append('first_name') - - if user.last_name != last_name: - logger.info('Update last name: %r -> %r', user.last_name, last_name) - user.last_name = last_name - update_fields.append('last_name') - - if update_fields: - try: - user.full_clean() - except ValidationError: - logger.exception('Can not update user: %s', user) - else: - user.save(update_fields=update_fields) - - -class RemoteUserMiddleware(OriginRemoteUserMiddleware): - """ - Middleware to login a user HTTP_REMOTE_USER header. - Use Django Axes if something is wrong. - Update exising user informations. - """ - header = 'HTTP_REMOTE_USER' - force_logout_if_no_header = True - - def process_request(self, request): - # Keep the information if the user is already logged in - was_authenticated = request.user.is_authenticated - - super().process_request(request) # login remote user - - if not request.user.is_authenticated: - # Not logged in -> nothing to verify here - return - - # Check SSOwat cookie informations: - try: - username = request.COOKIES['SSOwAuthUser'] - except KeyError: - logger.error('SSOwAuthUser cookie missing!') - - # emits a signal indicating user login failed, which is processed by - # axes.signals.log_user_login_failed which logs and flags the failed request. - raise AxesBackendPermissionDenied('Cookie missing') - - logger.info('SSOwat username from cookies: %r', username) - if username != request.user.username: - raise AxesBackendPermissionDenied('Wrong username') - - # Compare with HTTP_AUTH_USER - try: - username = request.META['HTTP_AUTH_USER'] - except KeyError: - logger.error('HTTP_AUTH_USER missing!') - raise AxesBackendPermissionDenied('No HTTP_AUTH_USER') - - if username != request.user.username: - raise AxesBackendPermissionDenied('Wrong HTTP_AUTH_USER username') - - # Also check 'HTTP_AUTHORIZATION', but only the username ;) - try: - auth = request.META['HTTP_AUTHORIZATION'] - except KeyError: - logger.error('HTTP_AUTHORIZATION missing!') - raise AxesBackendPermissionDenied('No HTTP_AUTHORIZATION') - - scheme, creds = auth.split(' ', 1) - if scheme.lower() != 'basic': - logger.error('HTTP_AUTHORIZATION with %r not supported', scheme) - raise AxesBackendPermissionDenied('HTTP_AUTHORIZATION scheme not supported') - - creds = str(base64.b64decode(creds), encoding='utf-8') - username = creds.split(':', 1)[0] - if username != request.user.username: - raise AxesBackendPermissionDenied('Wrong HTTP_AUTHORIZATION username') - - if not was_authenticated: - # First request, after login -> update user informations - logger.info('Remote used was logged in') - update_user_profile(request) - - -class RemoteUserBackend(OriginRemoteUserBackend): - """ - Authentication backend via SSO/nginx header - """ - create_unknown_user = True - - def authenticate(self, request, remote_user): - logger.info('Remote user authenticate: %r', remote_user) - return super().authenticate(request, remote_user) - - def configure_user(self, request, user): - """ - Configure a user after creation and return the updated user. - Setup a normal, non-superuser - """ - logger.warning('Configure user %s', user) - - user.set_unusable_password() # Always login via SSO - user.is_staff = True - user.is_superuser = False - user.save() - - pyinventory_user_group = get_or_create_normal_user_group()[0] - user.groups.set([pyinventory_user_group]) - - update_user_profile(request) - - return user - - def user_can_authenticate(self, user): - logger.warning('Remote user login: %s', user) - return True diff --git a/local_test.py b/local_test.py old mode 100755 new mode 100644 index 3430c3f..305294d --- a/local_test.py +++ b/local_test.py @@ -1,154 +1,29 @@ -#!/usr/bin/env python3 - """ - Start PyInventory in YunoHost setup locally. - Note: - You can only run this script, if you are in a activated PyInventory venv! + Build a "local_test" YunoHost installation and start the Django dev. server against it. + + Run via: + make local-test + see README for details ;) """ - -import os -import shlex -import subprocess -import sys from pathlib import Path -os.environ['DJANGO_SETTINGS_MODULE'] = 'ynh_pyinventory_settings' try: - import inventory_project # noqa + from django_ynh.local_test import create_local_test except ImportError as err: - raise ImportError( - 'Couldn\'t import PyInventory. Did you ' - 'forget to activate a virtual environment?' - ) from err + raise ImportError('Did you forget to activate a virtual environment?') from err - -BASE_PATH = Path(__file__).parent.absolute() -TEST_PATH = BASE_PATH / 'local_test' -CONF_PATH = BASE_PATH / 'conf' - -FINAL_HOME_PATH = TEST_PATH / 'opt_yunohost' -FINAL_WWW_PATH = TEST_PATH / 'var_www' -LOG_FILE = TEST_PATH / 'var_log_pyinventory.log' - -MANAGE_PY_FILE = CONF_PATH / 'manage.py' -CREATE_SUPERUSER_FILE = CONF_PATH / 'create_superuser.py' -SETTINGS_FILE = CONF_PATH / 'ynh_pyinventory_settings.py' -URLS_FILE = CONF_PATH / 'ynh_urls.py' - -REPLACES = { - '__FINAL_HOME_PATH__': str(FINAL_HOME_PATH), - '__FINAL_WWW_PATH__': str(FINAL_WWW_PATH), - '__LOG_FILE__': str(TEST_PATH / 'var_log_pyinventory.log'), - - '__PATH_URL__': 'app_path', - '__DOMAIN__': '127.0.0.1', - - 'django.db.backends.postgresql': 'django.db.backends.sqlite3', - "'NAME': '__APP__',": f"'NAME': '{TEST_PATH / 'test_db.sqlite'}',", - - 'django_redis.cache.RedisCache': 'django.core.cache.backends.dummy.DummyCache', - - 'DEBUG = False': 'DEBUG = True', - - # Just use the default logging setup from PyInventory project: - 'LOGGING = {': 'HACKED_DEACTIVATED_LOGGING = {', -} - - -def verbose_check_call(command, verbose=True, **kwargs): - """ 'verbose' version of subprocess.check_call() """ - if verbose: - print('_' * 100) - msg = f'Call: {command!r}' - verbose_kwargs = ', '.join(f'{k}={v!r}' for k, v in sorted(kwargs.items())) - if verbose_kwargs: - msg += f' (kwargs: {verbose_kwargs})' - print(f'{msg}\n', flush=True) - - env = os.environ.copy() - env['PYTHONUNBUFFERED'] = '1' - - popenargs = shlex.split(command) - subprocess.check_call( - popenargs, - universal_newlines=True, - env=env, - **kwargs - ) - - -def call_manage_py(args): - verbose_check_call( - command=f'{sys.executable} manage.py {args}', - cwd=FINAL_HOME_PATH, - ) - - -def copy_patch(src_file, replaces=None): - dst_file = FINAL_HOME_PATH / src_file.name - print(f'{src_file.relative_to(BASE_PATH)} -> {dst_file.relative_to(BASE_PATH)}') - - with src_file.open('r') as f: - content = f.read() - - if replaces: - for old, new in replaces.items(): - content = content.replace(old, new) - - with dst_file.open('w') as f: - f.write(content) +BASE_PATH = Path(__file__).parent def main(): - print('-' * 100) - - assert BASE_PATH.is_dir() - assert CONF_PATH.is_dir() - assert SETTINGS_FILE.is_file() - assert URLS_FILE.is_file() - - for p in (TEST_PATH, FINAL_HOME_PATH, FINAL_WWW_PATH): - if p.is_dir(): - print(f'Already exists: "{p.relative_to(BASE_PATH)}", ok.') - else: - print(f'Create: "{p.relative_to(BASE_PATH)}"') - p.mkdir(parents=True, exist_ok=True) - - LOG_FILE.touch(exist_ok=True) - - # conf/manage.py -> local_test/manage.py - copy_patch(src_file=MANAGE_PY_FILE) - - # conf/create_superuser.py -> local_test/opt_yunohost/create_superuser.py - copy_patch(src_file=CREATE_SUPERUSER_FILE) - - # conf/ynh_pyinventory_settings.py -> local_test/ynh_pyinventory_settings.py - copy_patch(src_file=SETTINGS_FILE, replaces=REPLACES) - - # conf/ynh_urls.py -> local_test/ynh_urls.py - copy_patch(src_file=URLS_FILE, replaces=REPLACES) - - with Path(FINAL_HOME_PATH / 'local_settings.py').open('w') as f: - f.write('# Only for local test run\n') - f.write('SERVE_FILES=True # used in src/inventory_project/urls.py\n') - - # call "local_test/manage.py" via subprocess: - call_manage_py('check --deploy') - call_manage_py('migrate --no-input') - call_manage_py('collectstatic --no-input') - - verbose_check_call( - command=f'{sys.executable} create_superuser.py --username="test" --password="test"', - cwd=FINAL_HOME_PATH, + create_local_test( + django_settings_path=BASE_PATH / 'conf' / 'settings.py', + destination=BASE_PATH / 'local_test', + runserver=True, ) - try: - call_manage_py('runserver --nostatic') - except KeyboardInterrupt: - print('\nBye ;)') - if __name__ == '__main__': main() diff --git a/manifest.json b/manifest.json index 167d761..de98baa 100644 --- a/manifest.json +++ b/manifest.json @@ -5,7 +5,7 @@ "description": { "en": "Web based management to catalog things including state and location etc." }, - "version": "0.8.2~ynh4", + "version": "0.8.2~ynh5", "url": "https://github.com/jedie/PyInventory", "license": "GPL-3.0", "maintainer": { diff --git a/pyproject.toml b/pyproject.toml index 103fa6f..0fadb29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pyinventory_ynh" -version = "0.8.2~ynh4" +version = "0.8.2~ynh5" description = "Test pyinventory_ynh via local_test.py" authors = ["JensDiemer "] license = "GPL" @@ -11,7 +11,72 @@ pyinventory = "*" django_ynh = "*" [tool.poetry.dev-dependencies] +bx_py_utils = "*" +isort = "*" +flake8 = "*" +flynt = "*" +black = "*" +pyupgrade = "*" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" + + +[tool.isort] +# https://pycqa.github.io/isort/docs/configuration/config_files/#pyprojecttoml-preferred-format +atomic=true +line_length=120 +case_sensitive=false +skip_glob=["*/htmlcov/*","*/migrations/*"] +multi_line_output=3 +include_trailing_comma=true +known_first_party=["inventory"] +no_lines_before="LOCALFOLDER" +default_section="THIRDPARTY" +sections=["FUTURE","STDLIB","THIRDPARTY","FIRSTPARTY","LOCALFOLDER"] +lines_after_imports=2 + + +[tool.pytest.ini_options] +# https://docs.pytest.org/en/latest/customize.html#pyproject-toml +minversion = "6.0" +norecursedirs = ".* .git __pycache__ conf coverage* dist htmlcov" +# sometimes helpfull "addopts" arguments: +# -vv +# --verbose +# --capture=no +# --trace-config +# --full-trace +# -p no:warnings +addopts = """ + --import-mode=importlib + --reuse-db + --nomigrations + --cov=. + --cov-report term-missing + --cov-report html + --cov-report xml + --no-cov-on-fail + --showlocals + --doctest-modules + --failed-first + --last-failed-no-failures all + --new-first +""" + + +[tool.tox] +# https://tox.readthedocs.io/en/latest/example/basic.html#pyproject-toml-tox-legacy-ini +legacy_tox_ini = """ +[tox] +isolated_build = True +envlist = py39,py38,py37 +skip_missing_interpreters = True + +[testenv] +passenv = * +whitelist_externals = make +commands = + make pytest +""" diff --git a/scripts/_common.sh b/scripts/_common.sh index 826fe53..dc3de28 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -27,9 +27,6 @@ log_file="${log_path}/pyinventory.log" # dependencies used by the app pkg_dependencies="build-essential python3-dev python3-pip python3-venv git postgresql postgresql-contrib" -# PyInventory's version for PIP and settings file -pyinventory_version="0.8.2" - #================================================= # Redis HELPERS #================================================= diff --git a/scripts/change_url b/scripts/change_url index 4fbcb36..2b32057 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -116,10 +116,10 @@ fi ynh_script_progression --message="Modify PyInventory's config file..." # save old settings file -settings="$final_path/ynh_pyinventory_settings.py" +settings="$final_path/settings.py" ynh_backup_if_checksum_is_different --file="$settings" -cp "../conf/ynh_pyinventory_settings.py" "$settings" +cp "../conf/settings.py" "$settings" ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings" ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings" diff --git a/scripts/install b/scripts/install index 4aece0f..c309ec8 100755 --- a/scripts/install +++ b/scripts/install @@ -101,7 +101,7 @@ ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell #================================================= # PIP INSTALLATION #================================================= -ynh_script_progression --message="Install PyInventory using PIP..." --weight=80 +ynh_script_progression --message="Install project via pip..." --weight=80 python3 -m venv "${final_path}/venv" cp ../conf/requirements.txt "$final_path/requirements.txt" @@ -119,10 +119,7 @@ chown -R "$app" "$final_path" #================================================= # copy config files # ================================================ -ynh_script_progression --message="Create pyinventory configuration file..." - -cp ../conf/create_superuser.py "$final_path/create_superuser.py" -chmod +x "$final_path/create_superuser.py" +ynh_script_progression --message="Create project configuration files..." gunicorn_conf="$final_path/gunicorn.conf.py" cp "../conf/gunicorn.conf.py" "$gunicorn_conf" @@ -134,10 +131,8 @@ ynh_store_file_checksum --file="$gunicorn_conf" cp ../conf/manage.py "$final_path/manage.py" chmod +x "$final_path/manage.py" -cp ../conf/wsgi.py "$final_path/wsgi.py" - -settings="$final_path/ynh_pyinventory_settings.py" -cp "../conf/ynh_pyinventory_settings.py" "$settings" +settings="$final_path/settings.py" +cp "../conf/settings.py" "$settings" ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings" ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings" @@ -156,10 +151,11 @@ ynh_store_file_checksum --file="$settings" ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db" -touch "$final_path/local_settings.py" +cp ../conf/setup_user.py "$final_path/setup_user.py" +cp ../conf/urls.py "$final_path/urls.py" +cp ../conf/wsgi.py "$final_path/wsgi.py" -cp "../conf/ynh_authenticate.py" "$final_path/ynh_authenticate.py" -cp "../conf/ynh_urls.py" "$final_path/ynh_urls.py" +touch "$final_path/local_settings.py" #================================================= # MIGRATE / COLLECTSTATIC / CREATEADMIN @@ -177,7 +173,9 @@ ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight ./manage.py migrate --no-input ./manage.py collectstatic --no-input - ./create_superuser.py --username="$admin" --email="$admin_mail" --password="pyinventory" + + # Create/update Django superuser (set unusable password, because auth done via SSOwat): + ./manage.py create_superuser --username="$admin" --email="$admin_mail" # Check the configuration # This may fail in some cases with errors, etc., but the app works and the user can fix issues later. diff --git a/scripts/upgrade b/scripts/upgrade index 4295ece..e45aba9 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -83,10 +83,9 @@ ynh_script_progression --message="Configuring a systemd service..." ynh_add_systemd_config --service="$app" --template="pyinventory.service" #================================================= -# UPGRADE PYINVENTORY +# UPGRADE VENV #================================================= - -ynh_script_progression --message="Install pyinventory using PIP..." --weight=15 +ynh_script_progression --message="Upgrade project via pip..." --weight=80 python3 -m venv "${final_path}/venv" cp ../conf/requirements.txt "$final_path/requirements.txt" @@ -94,21 +93,17 @@ chown -R "$app" "$final_path" #run source in a 'sub shell' ( - set +o nounset - source "${final_path}/venv/bin/activate" - set -o nounset - ynh_exec_as $app $final_path/venv/bin/pip install --upgrade pip - ynh_exec_as $app $final_path/venv/bin/pip install -r "$final_path/requirements.txt" + set +o nounset + source "${final_path}/venv/bin/activate" + set -o nounset + ynh_exec_as $app $final_path/venv/bin/pip install --upgrade pip + ynh_exec_as $app $final_path/venv/bin/pip install -r "$final_path/requirements.txt" ) #================================================= # copy config files # ================================================ -ynh_script_progression --message="Create pyinventory configuration file..." - -ynh_backup_if_checksum_is_different --file="$final_path/create_superuser.py" -cp ../conf/create_superuser.py "$final_path/create_superuser.py" -chmod +x "$final_path/create_superuser.py" +ynh_script_progression --message="Create project configuration files..." gunicorn_conf="$final_path/gunicorn.conf.py" ynh_backup_if_checksum_is_different --file="$gunicorn_conf" @@ -122,14 +117,11 @@ ynh_backup_if_checksum_is_different --file="$final_path/manage.py" cp ../conf/manage.py "$final_path/manage.py" chmod +x "$final_path/manage.py" -ynh_backup_if_checksum_is_different --file="$final_path/wsgi.py" -cp ../conf/wsgi.py "$final_path/wsgi.py" - # save old settings file -settings="$final_path/ynh_pyinventory_settings.py" +settings="$final_path/settings.py" ynh_backup_if_checksum_is_different --file="$settings" -cp "../conf/ynh_pyinventory_settings.py" "$settings" +cp "../conf/settings.py" "$settings" ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings" ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings" @@ -146,10 +138,16 @@ ynh_replace_string --match_string="__PATH_URL__" --replace_string="$path_url" -- # Recalculate and store the config file checksum into the app settings ynh_store_file_checksum --file="$settings" -touch "$final_path/local_settings.py" +ynh_backup_if_checksum_is_different --file="$final_path/setup_user.py" +cp ../conf/setup_user.py "$final_path/setup_user.py" -cp "../conf/ynh_authenticate.py" "$final_path/ynh_authenticate.py" -cp "../conf/ynh_urls.py" "$final_path/ynh_urls.py" +ynh_backup_if_checksum_is_different --file="$final_path/urls.py" +cp ../conf/urls.py "$final_path/urls.py" + +ynh_backup_if_checksum_is_different --file="$final_path/wsgi.py" +cp ../conf/wsgi.py "$final_path/wsgi.py" + +touch "$final_path/local_settings.py" #================================================= # MIGRATE PYINVENTORY @@ -167,7 +165,9 @@ ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight ./manage.py migrate --no-input ./manage.py collectstatic --no-input - ./create_superuser.py --username="$admin" --email="$admin_mail" --password="pyinventory" + + # Create/update Django superuser (set unusable password, because auth done via SSOwat): + ./manage.py create_superuser --username="$admin" --email="$admin_mail" # Check the configuration # This may fail in some cases with errors, etc., but the app works and the user can fix issues later. From 5c6087fb44ac77cf55c2998649bc5a1e2b81cef1 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 13:58:51 +0100 Subject: [PATCH 06/11] add pytests --- .github/workflows/pytest.yml | 41 ++++++++++ Makefile | 9 +++ pyproject.toml | 5 ++ run_pytest.py | 25 ++++++ tests/__init__.py | 0 tests/test_django_project.py | 145 +++++++++++++++++++++++++++++++++++ tests/test_lint.py | 13 ++++ tests/test_project_setup.py | 43 +++++++++++ tests/test_utils.py | 8 ++ 9 files changed, 289 insertions(+) create mode 100644 .github/workflows/pytest.yml create mode 100644 run_pytest.py create mode 100644 tests/__init__.py create mode 100644 tests/test_django_project.py create mode 100644 tests/test_lint.py create mode 100644 tests/test_project_setup.py create mode 100644 tests/test_utils.py diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml new file mode 100644 index 0000000..e190805 --- /dev/null +++ b/.github/workflows/pytest.yml @@ -0,0 +1,41 @@ +name: pytest + +on: + schedule: + - cron: '0 8 * * *' + push: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + max-parallel: 2 + matrix: + python-version: [3.9, 3.8, 3.7] + steps: + - uses: actions/checkout@v1 + - name: 'Set up Python ${{ matrix.python-version }}' + uses: actions/setup-python@v1 + with: + python-version: '${{ matrix.python-version }}' + + - name: 'Install package' + run: | + pip3 install poetry + make install + + - name: 'List installed packages' + run: | + poetry run pip freeze + + - name: 'Run tests with Python v${{ matrix.python-version }}' + run: | + make pytest + + - name: 'Upload coverage report' + run: bash <(curl -s https://codecov.io/bash) + + - name: 'Run linters' + if: matrix.python-version == '3.8' + run: | + make lint diff --git a/Makefile b/Makefile index 01bfae7..3692cc4 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,15 @@ fix-code-style: ## Fix code formatting poetry run black --verbose --safe --line-length=${MAX_LINE_LENGTH} --skip-string-normalization . poetry run isort . +tox-listenvs: check-poetry ## List all tox test environments + poetry run tox --listenvs + +tox: check-poetry ## Run pytest via tox with all environments + poetry run tox + +pytest: install ## Run pytest + poetry run python3 ./run_pytest.py + local-test: install ## Run local_test.py to run the project locally poetry run python3 ./local_test.py diff --git a/pyproject.toml b/pyproject.toml index 0fadb29..cc73f64 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,11 @@ django_ynh = "*" [tool.poetry.dev-dependencies] bx_py_utils = "*" +tox = "*" +pytest = "*" +pytest-cov = "*" +pytest-django = "*" +coveralls = "*" isort = "*" flake8 = "*" flynt = "*" diff --git a/run_pytest.py b/run_pytest.py new file mode 100644 index 0000000..a398526 --- /dev/null +++ b/run_pytest.py @@ -0,0 +1,25 @@ +""" + Run pytest against local test creation +""" + +from pathlib import Path + + +try: + from django_ynh.pytest_helper import run_pytest +except ImportError as err: + raise ImportError('Did you forget to activate a virtual environment?') from err + + +BASE_PATH = Path(__file__).parent + + +def main(): + run_pytest( + django_settings_path=BASE_PATH / 'conf' / 'settings.py', + destination=BASE_PATH / 'local_test', + ) + + +if __name__ == '__main__': + main() diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_django_project.py b/tests/test_django_project.py new file mode 100644 index 0000000..73fa685 --- /dev/null +++ b/tests/test_django_project.py @@ -0,0 +1,145 @@ +from axes.models import AccessLog +from bx_py_utils.test_utils.html_assertion import HtmlAssertionMixin +from django.conf import settings +from django.contrib.auth.models import User +from django.test import override_settings +from django.test.testcases import TestCase +from django.urls import NoReverseMatch +from django.urls.base import reverse +from django_ynh.test_utils import generate_basic_auth +from django_ynh.views import request_media_debug_view + +import inventory + + +@override_settings(DEBUG=False) +class DjangoYnhTestCase(HtmlAssertionMixin, TestCase): + def setUp(self): + super().setUp() + + # Always start a fresh session: + self.client = self.client_class() + + def test_settings(self): + assert settings.PATH_URL == 'app_path' + + assert str(settings.FINAL_HOME_PATH).endswith('/local_test/opt_yunohost') + assert str(settings.FINAL_WWW_PATH).endswith('/local_test/var_www') + assert str(settings.LOG_FILE).endswith('/local_test/var_log_django_ynh.log') + + assert settings.ROOT_URLCONF == 'urls' + + def test_urls(self): + assert reverse('admin:index') == '/app_path/' + + # The django_ynh debug view should not be avaiable: + with self.assertRaises(NoReverseMatch): + reverse(request_media_debug_view) + + # Serve user uploads via django_tools.serve_media_app: + assert settings.MEDIA_URL == '/app_path/media/' + assert reverse('serve_media_app:serve-media', kwargs={'user_token': 'token', 'path': 'foo/bar/'}) == ( + '/app_path/media/token/foo/bar/' + ) + + def test_auth(self): + response = self.client.get('/app_path/') + self.assertRedirects(response, expected_url='/app_path/login/?next=/app_path/') + + def test_create_unknown_user(self): + assert User.objects.count() == 0 + + self.client.cookies['SSOwAuthUser'] = 'test' + + response = self.client.get( + path='/app_path/', + HTTP_REMOTE_USER='test', + HTTP_AUTH_USER='test', + HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', + ) + + assert User.objects.count() == 1 + user = User.objects.first() + assert user.username == 'test' + assert user.is_active is True + assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler + assert user.is_superuser is False + + self.assert_html_parts( + response, + parts=( + f'Site administration | PyInventory v{inventory.__version__}', + 'test', + ), + ) + + def test_wrong_auth_user(self): + assert User.objects.count() == 0 + assert AccessLog.objects.count() == 0 + + self.client.cookies['SSOwAuthUser'] = 'test' + + response = self.client.get( + path='/app_path/', + HTTP_REMOTE_USER='test', + HTTP_AUTH_USER='foobar', # <<< wrong user name + HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', + ) + + assert User.objects.count() == 1 + user = User.objects.first() + assert user.username == 'test' + assert user.is_active is True + assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler + assert user.is_superuser is False + + assert AccessLog.objects.count() == 1 + + assert response.status_code == 403 # Forbidden + + def test_wrong_cookie(self): + assert User.objects.count() == 0 + assert AccessLog.objects.count() == 0 + + self.client.cookies['SSOwAuthUser'] = 'foobar' # <<< wrong user name + + response = self.client.get( + path='/app_path/', + HTTP_REMOTE_USER='test', + HTTP_AUTH_USER='test', + HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', + ) + + assert User.objects.count() == 1 + user = User.objects.first() + assert user.username == 'test' + assert user.is_active is True + assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler + assert user.is_superuser is False + + assert AccessLog.objects.count() == 1 + + assert response.status_code == 403 # Forbidden + + def test_wrong_authorization_user(self): + assert User.objects.count() == 0 + + self.client.cookies['SSOwAuthUser'] = 'test' + + response = self.client.get( + path='/app_path/', + HTTP_REMOTE_USER='test', + HTTP_AUTH_USER='test', + HTTP_AUTHORIZATION=generate_basic_auth(username='foobar', password='test123'), # <<< wrong user name + ) + + assert User.objects.count() == 1 + user = User.objects.first() + assert user.username == 'test' + assert user.is_active is True + assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler + assert user.is_superuser is False + + assert AccessLog.objects.count() == 1 + + assert response.status_code == 403 # Forbidden diff --git a/tests/test_lint.py b/tests/test_lint.py new file mode 100644 index 0000000..003dc76 --- /dev/null +++ b/tests/test_lint.py @@ -0,0 +1,13 @@ +import shutil +import subprocess +from pathlib import Path + + +BASE_PATH = Path(__file__).parent.parent + + +def test_lint(): + assert Path(BASE_PATH, 'Makefile').is_file() + make_bin = shutil.which('make') + assert make_bin is not None + subprocess.check_call([make_bin, 'lint'], cwd=BASE_PATH) diff --git a/tests/test_project_setup.py b/tests/test_project_setup.py new file mode 100644 index 0000000..f5a6651 --- /dev/null +++ b/tests/test_project_setup.py @@ -0,0 +1,43 @@ +import os +import shutil +import subprocess +from pathlib import Path + +import inventory + + +PACKAGE_ROOT = Path(__file__).parent.parent + + +def assert_file_contains_string(file_path, string): + with file_path.open('r') as f: + for line in f: + if string in line: + return + raise AssertionError(f'File {file_path} does not contain {string!r} !') + + +def test_version(): + version = inventory.__version__ + + if 'dev' not in version and 'rc' not in version: + version_string = f'v{version}' + + assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'README.md'), string=version_string) + + assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'version = "{version}~ynh') + assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'manifest.json'), string=f'"version": "{version}~ynh') + + +def test_poetry_check(): + poerty_bin = shutil.which('poetry') + + output = subprocess.check_output( + [poerty_bin, 'check'], + universal_newlines=True, + env=os.environ, + stderr=subprocess.STDOUT, + cwd=str(PACKAGE_ROOT), + ) + print(output) + assert output == 'All set!\n' diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..a9927a7 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,8 @@ +from unittest.case import TestCase + +from django_ynh.test_utils import generate_basic_auth + + +class TestUtilsTestCase(TestCase): + def test_generate_basic_auth(self): + assert generate_basic_auth(username='test', password='test123') == 'basic dGVzdDp0ZXN0MTIz' From 6aeaa4e03966626b754c4e3595bac5ac3d175e15 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 13:59:16 +0100 Subject: [PATCH 07/11] commit poetry.lock, too --- .gitignore | 1 - poetry.lock | 1484 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1484 insertions(+), 1 deletion(-) create mode 100644 poetry.lock diff --git a/.gitignore b/.gitignore index 04228fa..28e1b61 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,5 @@ __pycache__ secret.txt /local_test/ -/poetry.lock /coverage.xml /htmlcov/ diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..bca3c54 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,1484 @@ +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "astor" +version = "0.8.1" +description = "Read/rewrite/write Python ASTs" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "attrs" +version = "20.3.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] + +[[package]] +name = "black" +version = "20.8b1" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +appdirs = "*" +click = ">=7.1.2" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.6,<1" +regex = ">=2020.1.8" +toml = ">=0.10.1" +typed-ast = ">=1.4.0" +typing-extensions = ">=3.7.4" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + +[[package]] +name = "bleach" +version = "3.2.1" +description = "An easy safelist-based HTML-sanitizing tool." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +packaging = "*" +six = ">=1.9.0" +webencodings = "*" + +[[package]] +name = "bx-py-utils" +version = "18" +description = "Various Python / Django utility functions" +category = "main" +optional = false +python-versions = ">=3.6,<4.0.0" + +[package.dependencies] +django = "*" +python-stdnum = "*" + +[[package]] +name = "certifi" +version = "2020.12.5" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "chardet" +version = "4.0.0" +description = "Universal encoding detector for Python 2 and 3" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "click" +version = "7.1.2" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "colorlog" +version = "4.6.2" +description = "Log formatting with colors!" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} + +[[package]] +name = "coverage" +version = "5.3.1" +description = "Code coverage measurement for Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +toml = ["toml"] + +[[package]] +name = "coveralls" +version = "2.2.0" +description = "Show coverage stats online via coveralls.io" +category = "dev" +optional = false +python-versions = ">= 3.5" + +[package.dependencies] +coverage = ">=4.1,<6.0" +docopt = ">=0.6.1" +requests = ">=1.0.0" + +[package.extras] +yaml = ["PyYAML (>=3.10)"] + +[[package]] +name = "defusedxml" +version = "0.6.0" +description = "XML bomb protection for Python stdlib modules" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "diff-match-patch" +version = "20200713" +description = "Repackaging of Google's Diff Match and Patch libraries. Offers robust algorithms to perform the operations required for synchronizing plain text." +category = "main" +optional = false +python-versions = ">=2.7" + +[[package]] +name = "distlib" +version = "0.3.1" +description = "Distribution utilities" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "django" +version = "2.2.17" +description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +pytz = "*" +sqlparse = ">=0.2.2" + +[package.extras] +argon2 = ["argon2-cffi (>=16.1.0)"] +bcrypt = ["bcrypt"] + +[[package]] +name = "django-admin-sortable2" +version = "0.7.7" +description = "Generic drag-and-drop sorting for the List, the Stacked- and the Tabular-Inlines Views in the Django Admin" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +Django = ">=1.8,<3.2" + +[[package]] +name = "django-axes" +version = "5.10.0" +description = "Keep track of failed login attempts in Django-powered sites." +category = "main" +optional = false +python-versions = "~=3.6" + +[package.dependencies] +django = ">=2.0" +django-ipware = ">=3,<4" + +[[package]] +name = "django-ckeditor" +version = "6.0.0" +description = "Django admin CKEditor integration." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +django-js-asset = ">=1.2.2" + +[[package]] +name = "django-dbbackup" +version = "3.3.0" +description = "Management commands to help backup and restore a project database and media" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +Django = ">=1.5" +pytz = "*" +six = "*" + +[[package]] +name = "django-debug-toolbar" +version = "3.2" +description = "A configurable set of panels that display various debug information about the current request/response." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +Django = ">=2.2" +sqlparse = ">=0.2.0" + +[[package]] +name = "django-import-export" +version = "2.4.0" +description = "Django application and library for importing and exporting data with included admin integration." +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +diff-match-patch = "*" +Django = ">=2.0" +tablib = {version = ">=0.14.0", extras = ["html", "ods", "xls", "xlsx", "yaml"]} + +[[package]] +name = "django-ipware" +version = "3.0.2" +description = "A Django utility application that returns client's real IP address" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "django-js-asset" +version = "1.2.2" +description = "script tag with additional attributes for django.forms.Media" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "django-processinfo" +version = "1.0.2" +description = "Django application to collect information about the running server processes." +category = "main" +optional = false +python-versions = ">=3.7,<4.0.0" + +[package.dependencies] +Django = "*" + +[[package]] +name = "django-redis" +version = "4.12.1" +description = "Full featured redis cache backend for Django." +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +Django = ">=2.2" +redis = ">=3.0.0" + +[[package]] +name = "django-reversion" +version = "3.0.8" +description = "An extension to the Django web framework that provides version control for model instances." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +django = ">=1.11" + +[[package]] +name = "django-reversion-compare" +version = "0.13.0" +description = "history compare for django-reversion" +category = "main" +optional = false +python-versions = ">=3.7,<4.0.0" + +[package.dependencies] +diff-match-patch = "*" +django-reversion = "*" + +[[package]] +name = "django-tagulous" +version = "1.1.0" +description = "Fabulous Tagging for Django" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +Django = ">=2.2" + +[package.extras] +dev = ["tox", "jasmine"] +devdb = ["psycopg2", "mysqlclient"] +i18n = ["unidecode"] + +[[package]] +name = "django-tools" +version = "0.48.3" +description = "miscellaneous tools for django" +category = "main" +optional = false +python-versions = ">=3.6,<4.0.0" + +[package.dependencies] +bleach = "*" +django = "*" +icdiff = "*" +pprintpp = "*" + +[[package]] +name = "django-ynh" +version = "0.1.2" +description = "Glue code to package django projects as yunohost apps." +category = "main" +optional = false +python-versions = ">=3.7,<4.0.0" + +[package.dependencies] +django = "*" +django-axes = "*" +django-redis = "*" +gunicorn = "*" +psycopg2-binary = "*" + +[[package]] +name = "docopt" +version = "0.6.2" +description = "Pythonic argument parser, that will make you smile" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "et-xmlfile" +version = "1.0.1" +description = "An implementation of lxml.xmlfile for the standard library" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "filelock" +version = "3.0.12" +description = "A platform independent file lock." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "flake8" +version = "3.8.4" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.6.0a1,<2.7.0" +pyflakes = ">=2.2.0,<2.3.0" + +[[package]] +name = "flynt" +version = "0.58" +description = "CLI tool to convert a python project's %-formatted strings to f-strings." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +astor = "*" + +[[package]] +name = "gunicorn" +version = "20.0.4" +description = "WSGI HTTP Server for UNIX" +category = "main" +optional = false +python-versions = ">=3.4" + +[package.extras] +eventlet = ["eventlet (>=0.9.7)"] +gevent = ["gevent (>=0.13)"] +setproctitle = ["setproctitle"] +tornado = ["tornado (>=0.2)"] + +[[package]] +name = "icdiff" +version = "1.9.1" +description = "improved colored diff" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "idna" +version = "2.10" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "importlib-metadata" +version = "3.3.0" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] + +[[package]] +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "isort" +version = "5.6.4" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + +[package.extras] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +requirements_deprecated_finder = ["pipreqs", "pip-api"] +colors = ["colorama (>=0.4.3,<0.5.0)"] + +[[package]] +name = "jdcal" +version = "1.4.1" +description = "Julian dates from proleptic Gregorian and Julian calendars." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "markuppy" +version = "1.14" +description = "An HTML/XML generator" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "odfpy" +version = "1.4.1" +description = "Python API and tools to manipulate OpenDocument files" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +defusedxml = "*" + +[[package]] +name = "openpyxl" +version = "3.0.5" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +category = "main" +optional = false +python-versions = ">=3.6," + +[package.dependencies] +et-xmlfile = "*" +jdcal = "*" + +[[package]] +name = "packaging" +version = "20.8" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.0.2" + +[[package]] +name = "pathspec" +version = "0.8.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pillow" +version = "8.0.1" +description = "Python Imaging Library (Fork)" +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +name = "pprintpp" +version = "0.4.0" +description = "A drop-in replacement for pprint that's actually pretty" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "psycopg2-binary" +version = "2.8.6" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +category = "main" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" + +[[package]] +name = "py" +version = "1.10.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pycodestyle" +version = "2.6.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyflakes" +version = "2.2.0" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyinventory" +version = "0.8.2" +description = "Web based management to catalog things including state and location etc. using Python/Django." +category = "main" +optional = false +python-versions = ">=3.7,<4.0.0" + +[package.dependencies] +bx_py_utils = "*" +colorama = "*" +colorlog = "*" +django = ">=2.2.0,<2.3.0" +django-admin-sortable2 = "*" +django-axes = "*" +django-ckeditor = "*" +django-dbbackup = "*" +django-debug-toolbar = "*" +django-import-export = "*" +django-processinfo = "*" +django-reversion-compare = "*" +django-tagulous = "*" +django-tools = ">=0.48.2" +gunicorn = "*" +pillow = "*" +requests = "*" + +[package.extras] +docker = ["docker-compose"] +postgres = ["psycopg2-binary"] + +[[package]] +name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "pytest" +version = "6.2.1" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<1.0.0a1" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "2.10.1" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +coverage = ">=4.4" +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pytest-django" +version = "4.1.0" +description = "A Django plugin for pytest." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +pytest = ">=5.4.0" + +[package.extras] +docs = ["sphinx", "sphinx-rtd-theme"] +testing = ["django", "django-configurations (>=2.0)"] + +[[package]] +name = "python-stdnum" +version = "1.14" +description = "Python module to handle standardized numbers and codes" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +soap = ["zeep"] +soap-alt = ["suds"] +soap-fallback = ["pysimplesoap"] + +[[package]] +name = "pytz" +version = "2020.5" +description = "World timezone definitions, modern and historical" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "pyupgrade" +version = "2.7.4" +description = "A tool to automatically upgrade syntax for newer versions." +category = "dev" +optional = false +python-versions = ">=3.6.1" + +[package.dependencies] +tokenize-rt = ">=3.2.0" + +[[package]] +name = "pyyaml" +version = "5.3.1" +description = "YAML parser and emitter for Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "redis" +version = "3.5.3" +description = "Python client for Redis key-value store" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +hiredis = ["hiredis (>=0.1.3)"] + +[[package]] +name = "regex" +version = "2020.11.13" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "requests" +version = "2.25.1" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<5" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] + +[[package]] +name = "six" +version = "1.15.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "sqlparse" +version = "0.4.1" +description = "A non-validating SQL parser." +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "tablib" +version = "3.0.0" +description = "Format agnostic tabular data library (XLS, JSON, YAML, CSV)" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +markuppy = {version = "*", optional = true, markers = "extra == \"html\""} +odfpy = {version = "*", optional = true, markers = "extra == \"ods\""} +openpyxl = {version = ">=2.6.0", optional = true, markers = "extra == \"xlsx\""} +pyyaml = {version = "*", optional = true, markers = "extra == \"yaml\""} +xlrd = {version = "*", optional = true, markers = "extra == \"xls\""} +xlwt = {version = "*", optional = true, markers = "extra == \"xls\""} + +[package.extras] +all = ["markuppy", "odfpy", "openpyxl (>=2.6.0)", "pandas", "pyyaml", "tabulate", "xlrd", "xlwt"] +cli = ["tabulate"] +html = ["markuppy"] +ods = ["odfpy"] +pandas = ["pandas"] +xls = ["xlrd", "xlwt"] +xlsx = ["openpyxl (>=2.6.0)"] +yaml = ["pyyaml"] + +[[package]] +name = "tokenize-rt" +version = "4.0.0" +description = "A wrapper around the stdlib `tokenize` which roundtrips." +category = "dev" +optional = false +python-versions = ">=3.6.1" + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "tox" +version = "3.12.1" +description = "tox is a generic virtualenv management and test command line tool" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +filelock = ">=3.0.0,<4" +pluggy = ">=0.3.0,<1" +py = ">=1.4.17,<2" +six = ">=1.0.0,<2" +toml = ">=0.9.4" +virtualenv = ">=14.0.0" + +[package.extras] +docs = ["sphinx (>=2.0.0,<3)", "towncrier (>=18.5.0)", "pygments-github-lexers (>=0.0.5)", "sphinxcontrib-autoprogram (>=0.1.5)"] +testing = ["freezegun (>=0.3.11,<1)", "pathlib2 (>=2.3.3,<3)", "pytest (>=3.0.0,<5)", "pytest-cov (>=2.5.1,<3)", "pytest-mock (>=1.10.0,<2)", "pytest-xdist (>=1.22.2,<2)", "pytest-randomly (>=1.2.3,<2)", "flaky (>=3.4.0,<4)", "psutil (>=5.6.1,<6)"] + +[[package]] +name = "typed-ast" +version = "1.4.1" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "typing-extensions" +version = "3.7.4.3" +description = "Backported and Experimental Type Hints for Python 3.5+" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "urllib3" +version = "1.26.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "virtualenv" +version = "20.2.2" +description = "Virtual Python Environment builder" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +appdirs = ">=1.4.3,<2" +distlib = ">=0.3.1,<1" +filelock = ">=3.0.0,<4" +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +six = ">=1.9.0,<2" + +[package.extras] +docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] +testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "xlrd" +version = "2.0.1" +description = "Library for developers to extract data from Microsoft Excel (tm) .xls spreadsheet files" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.extras] +build = ["wheel", "twine"] +docs = ["sphinx"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "xlwt" +version = "1.3.0" +description = "Library to create spreadsheet files compatible with MS Excel 97/2000/XP/2003 XLS files, on any platform, with Python 2.6, 2.7, 3.3+" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "zipp" +version = "3.4.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] + +[metadata] +lock-version = "1.1" +python-versions = ">=3.7,<4.0.0" +content-hash = "206d7e10d1b6d7d258b18819d1966ef15e601db154a6632541f40615191d80f7" + +[metadata.files] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +astor = [ + {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, + {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, +] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, + {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, +] +black = [ + {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, +] +bleach = [ + {file = "bleach-3.2.1-py2.py3-none-any.whl", hash = "sha256:9f8ccbeb6183c6e6cddea37592dfb0167485c1e3b13b3363bc325aa8bda3adbd"}, + {file = "bleach-3.2.1.tar.gz", hash = "sha256:52b5919b81842b1854196eaae5ca29679a2f2e378905c346d3ca8227c2c66080"}, +] +bx-py-utils = [ + {file = "bx_py_utils-18-py3-none-any.whl", hash = "sha256:72a6090822544603e3a7547ce07f0120ae67940ca2ec4590ac907b3b09ad70ca"}, + {file = "bx_py_utils-18.tar.gz", hash = "sha256:195ea1b3d5d277354ea33e34ec3ebd4fc2a6e8d94d646ede902f80527f06ec75"}, +] +certifi = [ + {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, + {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, +] +chardet = [ + {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, + {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, +] +click = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +colorlog = [ + {file = "colorlog-4.6.2-py2.py3-none-any.whl", hash = "sha256:edd5ada5de03e880e42b2526f8be5570fd9b692f8eb7cf6b1fdcac3e3fb23976"}, + {file = "colorlog-4.6.2.tar.gz", hash = "sha256:54e5f153419c22afc283c130c4201db19a3dbd83221a0f4657d5ee66234a2ea4"}, +] +coverage = [ + {file = "coverage-5.3.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fabeeb121735d47d8eab8671b6b031ce08514c86b7ad8f7d5490a7b6dcd6267d"}, + {file = "coverage-5.3.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7e4d159021c2029b958b2363abec4a11db0ce8cd43abb0d9ce44284cb97217e7"}, + {file = "coverage-5.3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:378ac77af41350a8c6b8801a66021b52da8a05fd77e578b7380e876c0ce4f528"}, + {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e448f56cfeae7b1b3b5bcd99bb377cde7c4eb1970a525c770720a352bc4c8044"}, + {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:cc44e3545d908ecf3e5773266c487ad1877be718d9dc65fc7eb6e7d14960985b"}, + {file = "coverage-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:08b3ba72bd981531fd557f67beee376d6700fba183b167857038997ba30dd297"}, + {file = "coverage-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:8dacc4073c359f40fcf73aede8428c35f84639baad7e1b46fce5ab7a8a7be4bb"}, + {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ee2f1d1c223c3d2c24e3afbb2dd38be3f03b1a8d6a83ee3d9eb8c36a52bee899"}, + {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9a9d4ff06804920388aab69c5ea8a77525cf165356db70131616acd269e19b36"}, + {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:782a5c7df9f91979a7a21792e09b34a658058896628217ae6362088b123c8500"}, + {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:fda29412a66099af6d6de0baa6bd7c52674de177ec2ad2630ca264142d69c6c7"}, + {file = "coverage-5.3.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:f2c6888eada180814b8583c3e793f3f343a692fc802546eed45f40a001b1169f"}, + {file = "coverage-5.3.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8f33d1156241c43755137288dea619105477961cfa7e47f48dbf96bc2c30720b"}, + {file = "coverage-5.3.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b239711e774c8eb910e9b1ac719f02f5ae4bf35fa0420f438cdc3a7e4e7dd6ec"}, + {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:f54de00baf200b4539a5a092a759f000b5f45fd226d6d25a76b0dff71177a714"}, + {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:be0416074d7f253865bb67630cf7210cbc14eb05f4099cc0f82430135aaa7a3b"}, + {file = "coverage-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:c46643970dff9f5c976c6512fd35768c4a3819f01f61169d8cdac3f9290903b7"}, + {file = "coverage-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9a4f66259bdd6964d8cf26142733c81fb562252db74ea367d9beb4f815478e72"}, + {file = "coverage-5.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6e5174f8ca585755988bc278c8bb5d02d9dc2e971591ef4a1baabdf2d99589b"}, + {file = "coverage-5.3.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3911c2ef96e5ddc748a3c8b4702c61986628bb719b8378bf1e4a6184bbd48fe4"}, + {file = "coverage-5.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c5ec71fd4a43b6d84ddb88c1df94572479d9a26ef3f150cef3dacefecf888105"}, + {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f51dbba78d68a44e99d484ca8c8f604f17e957c1ca09c3ebc2c7e3bbd9ba0448"}, + {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:a2070c5affdb3a5e751f24208c5c4f3d5f008fa04d28731416e023c93b275277"}, + {file = "coverage-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:535dc1e6e68fad5355f9984d5637c33badbdc987b0c0d303ee95a6c979c9516f"}, + {file = "coverage-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:a4857f7e2bc6921dbd487c5c88b84f5633de3e7d416c4dc0bb70256775551a6c"}, + {file = "coverage-5.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fac3c432851038b3e6afe086f777732bcf7f6ebbfd90951fa04ee53db6d0bcdd"}, + {file = "coverage-5.3.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cd556c79ad665faeae28020a0ab3bda6cd47d94bec48e36970719b0b86e4dcf4"}, + {file = "coverage-5.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a66ca3bdf21c653e47f726ca57f46ba7fc1f260ad99ba783acc3e58e3ebdb9ff"}, + {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ab110c48bc3d97b4d19af41865e14531f300b482da21783fdaacd159251890e8"}, + {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e52d3d95df81c8f6b2a1685aabffadf2d2d9ad97203a40f8d61e51b70f191e4e"}, + {file = "coverage-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:fa10fee7e32213f5c7b0d6428ea92e3a3fdd6d725590238a3f92c0de1c78b9d2"}, + {file = "coverage-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ce6f3a147b4b1a8b09aae48517ae91139b1b010c5f36423fa2b866a8b23df879"}, + {file = "coverage-5.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:93a280c9eb736a0dcca19296f3c30c720cb41a71b1f9e617f341f0a8e791a69b"}, + {file = "coverage-5.3.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3102bb2c206700a7d28181dbe04d66b30780cde1d1c02c5f3c165cf3d2489497"}, + {file = "coverage-5.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8ffd4b204d7de77b5dd558cdff986a8274796a1e57813ed005b33fd97e29f059"}, + {file = "coverage-5.3.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a607ae05b6c96057ba86c811d9c43423f35e03874ffb03fbdcd45e0637e8b631"}, + {file = "coverage-5.3.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:3a3c3f8863255f3c31db3889f8055989527173ef6192a283eb6f4db3c579d830"}, + {file = "coverage-5.3.1-cp38-cp38-win32.whl", hash = "sha256:ff1330e8bc996570221b450e2d539134baa9465f5cb98aff0e0f73f34172e0ae"}, + {file = "coverage-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:3498b27d8236057def41de3585f317abae235dd3a11d33e01736ffedb2ef8606"}, + {file = "coverage-5.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ceb499d2b3d1d7b7ba23abe8bf26df5f06ba8c71127f188333dddcf356b4b63f"}, + {file = "coverage-5.3.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:3b14b1da110ea50c8bcbadc3b82c3933974dbeea1832e814aab93ca1163cd4c1"}, + {file = "coverage-5.3.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:76b2775dda7e78680d688daabcb485dc87cf5e3184a0b3e012e1d40e38527cc8"}, + {file = "coverage-5.3.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:cef06fb382557f66d81d804230c11ab292d94b840b3cb7bf4450778377b592f4"}, + {file = "coverage-5.3.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f61319e33222591f885c598e3e24f6a4be3533c1d70c19e0dc59e83a71ce27d"}, + {file = "coverage-5.3.1-cp39-cp39-win32.whl", hash = "sha256:cc6f8246e74dd210d7e2b56c76ceaba1cc52b025cd75dbe96eb48791e0250e98"}, + {file = "coverage-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:2757fa64e11ec12220968f65d086b7a29b6583d16e9a544c889b22ba98555ef1"}, + {file = "coverage-5.3.1-pp36-none-any.whl", hash = "sha256:723d22d324e7997a651478e9c5a3120a0ecbc9a7e94071f7e1954562a8806cf3"}, + {file = "coverage-5.3.1-pp37-none-any.whl", hash = "sha256:c89b558f8a9a5a6f2cfc923c304d49f0ce629c3bd85cb442ca258ec20366394c"}, + {file = "coverage-5.3.1.tar.gz", hash = "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b"}, +] +coveralls = [ + {file = "coveralls-2.2.0-py2.py3-none-any.whl", hash = "sha256:2301a19500b06649d2ec4f2858f9c69638d7699a4c63027c5d53daba666147cc"}, + {file = "coveralls-2.2.0.tar.gz", hash = "sha256:b990ba1f7bc4288e63340be0433698c1efe8217f78c689d254c2540af3d38617"}, +] +defusedxml = [ + {file = "defusedxml-0.6.0-py2.py3-none-any.whl", hash = "sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93"}, + {file = "defusedxml-0.6.0.tar.gz", hash = "sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5"}, +] +diff-match-patch = [ + {file = "diff-match-patch-20200713.tar.gz", hash = "sha256:da6f5a01aa586df23dfc89f3827e1cafbb5420be9d87769eeb079ddfd9477a18"}, + {file = "diff_match_patch-20200713-py3-none-any.whl", hash = "sha256:8bf9d9c4e059d917b5c6312bac0c137971a32815ddbda9c682b949f2986b4d34"}, +] +distlib = [ + {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, + {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"}, +] +django = [ + {file = "Django-2.2.17-py3-none-any.whl", hash = "sha256:558cb27930defd9a6042133258caf797b2d1dee233959f537e3dc475cb49bd7c"}, + {file = "Django-2.2.17.tar.gz", hash = "sha256:cf5370a4d7765a9dd6d42a7b96b53c74f9446cd38209211304b210fe0404b861"}, +] +django-admin-sortable2 = [ + {file = "django-admin-sortable2-0.7.7.tar.gz", hash = "sha256:65c8a02300e178b4a02c904b6f4dce6e528c58f5ecab3907dfba3540da51b862"}, +] +django-axes = [ + {file = "django-axes-5.10.0.tar.gz", hash = "sha256:8a62cd4cc78ef08007e8102def34be83832995eb6e3e0c814d605741b82a2796"}, + {file = "django_axes-5.10.0-py3-none-any.whl", hash = "sha256:3c81ddca8a9d7fd0019cb440f711cc873c3039546f7eacb3f2ec616bf0ec1b32"}, +] +django-ckeditor = [ + {file = "django-ckeditor-6.0.0.tar.gz", hash = "sha256:29fd1a333cb9741ac2c3fd4e427a5c00115ed33a2389716a09af7656022dcdde"}, + {file = "django_ckeditor-6.0.0-py2.py3-none-any.whl", hash = "sha256:cc2d377f1bdcd4ca1540caeebe85f7e2cd006198d57328ef6c718d3eaa5a0846"}, +] +django-dbbackup = [ + {file = "django-dbbackup-3.3.0.tar.gz", hash = "sha256:bb109735cae98b64ad084e5b461b7aca2d7b39992f10c9ed9435e3ebb6fb76c8"}, +] +django-debug-toolbar = [ + {file = "django-debug-toolbar-3.2.tar.gz", hash = "sha256:84e2607d900dbd571df0a2acf380b47c088efb787dce9805aefeb407341961d2"}, + {file = "django_debug_toolbar-3.2-py3-none-any.whl", hash = "sha256:9e5a25d0c965f7e686f6a8ba23613ca9ca30184daa26487706d4829f5cfb697a"}, +] +django-import-export = [ + {file = "django-import-export-2.4.0.tar.gz", hash = "sha256:401d76eca0a5c6cf43bffed16c06e509b9044ce8f6bcff264b776e3952830f1a"}, + {file = "django_import_export-2.4.0-py3-none-any.whl", hash = "sha256:7610f6efff797d65f56c03ba34444507c0b0ccdffe9346c168b9894fc349c55e"}, +] +django-ipware = [ + {file = "django-ipware-3.0.2.tar.gz", hash = "sha256:c7df8e1410a8e5d6b1fbae58728402ea59950f043c3582e033e866f0f0cf5e94"}, +] +django-js-asset = [ + {file = "django-js-asset-1.2.2.tar.gz", hash = "sha256:c163ae80d2e0b22d8fb598047cd0dcef31f81830e127cfecae278ad574167260"}, + {file = "django_js_asset-1.2.2-py2.py3-none-any.whl", hash = "sha256:8ec12017f26eec524cab436c64ae73033368a372970af4cf42d9354fcb166bdd"}, +] +django-processinfo = [ + {file = "django-processinfo-1.0.2.tar.gz", hash = "sha256:3cacad233a5428a5cc6292eafbfddd97948d8d1e4f47e47175a7fcdfcee90f12"}, + {file = "django_processinfo-1.0.2-py3-none-any.whl", hash = "sha256:08aefdf7285d1eaa595e46570bcc12f2dfd9e24594d524246110614819076b6c"}, +] +django-redis = [ + {file = "django-redis-4.12.1.tar.gz", hash = "sha256:306589c7021e6468b2656edc89f62b8ba67e8d5a1c8877e2688042263daa7a63"}, + {file = "django_redis-4.12.1-py3-none-any.whl", hash = "sha256:1133b26b75baa3664164c3f44b9d5d133d1b8de45d94d79f38d1adc5b1d502e5"}, +] +django-reversion = [ + {file = "django-reversion-3.0.8.tar.gz", hash = "sha256:49e9930f90322dc6a2754dd26144285cfcc1c5bd0c1c39ca95d5602c5054ae32"}, + {file = "django_reversion-3.0.8-py3-none-any.whl", hash = "sha256:9cfadeec2df37cb53d795ab79f6792f9eed8e70363dcf3a275dc19a58b971a8f"}, +] +django-reversion-compare = [ + {file = "django-reversion-compare-0.13.0.tar.gz", hash = "sha256:db7c82ade287e172a9e84d6666b1df0b673eb97ab8a81a8cb52212f359e17f9b"}, + {file = "django_reversion_compare-0.13.0-py3-none-any.whl", hash = "sha256:087d6951462692e0a477a84e5460d606661be6ea2224e40dc9eded193ab7b928"}, +] +django-tagulous = [ + {file = "django-tagulous-1.1.0.tar.gz", hash = "sha256:9bc9d1d066c486fac1a3ec351531e440bc239c459b043e9180d99d7846e45fd6"}, + {file = "django_tagulous-1.1.0-py3-none-any.whl", hash = "sha256:de2a56ed92374b79358275ac0b7910af2c3d2823f44a847bef91ca9e456353ba"}, +] +django-tools = [ + {file = "django-tools-0.48.3.tar.gz", hash = "sha256:08ed2ae606067f49c2c3949055227a826c8b880e5816114925eca386cf1823af"}, + {file = "django_tools-0.48.3-py3-none-any.whl", hash = "sha256:40444fa16b703b7c6960a800ba76aad42472c9aa70040d549a4d91dbb47a5ddb"}, +] +django-ynh = [ + {file = "django_ynh-0.1.2-py3-none-any.whl", hash = "sha256:2efa30444f67252bbb7601e1b5631ce93ddf72a70b2216bb61363990de78ad4f"}, + {file = "django_ynh-0.1.2.tar.gz", hash = "sha256:711b0f9ac183b2507a58cf644081aafefdc025ce585f6a8dad427ca3baf55a19"}, +] +docopt = [ + {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, +] +et-xmlfile = [ + {file = "et_xmlfile-1.0.1.tar.gz", hash = "sha256:614d9722d572f6246302c4491846d2c393c199cfa4edc9af593437691683335b"}, +] +filelock = [ + {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, + {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, +] +flake8 = [ + {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, + {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, +] +flynt = [ + {file = "flynt-0.58-py3-none-any.whl", hash = "sha256:0630c2f80ae9afa3c7e75b64cd3cc2c2c8fecd8ad87802a168598abe22824699"}, + {file = "flynt-0.58.tar.gz", hash = "sha256:7b74e02a7f902986e819b11d185078b701dc58ce00441dba5f151a7f560ff4da"}, +] +gunicorn = [ + {file = "gunicorn-20.0.4-py2.py3-none-any.whl", hash = "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c"}, + {file = "gunicorn-20.0.4.tar.gz", hash = "sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626"}, +] +icdiff = [ + {file = "icdiff-1.9.1.tar.gz", hash = "sha256:66972dd03318da55280991db375d3ef6b66d948c67af96c1ebdb21587e86655e"}, +] +idna = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] +importlib-metadata = [ + {file = "importlib_metadata-3.3.0-py3-none-any.whl", hash = "sha256:bf792d480abbd5eda85794e4afb09dd538393f7d6e6ffef6e9f03d2014cf9450"}, + {file = "importlib_metadata-3.3.0.tar.gz", hash = "sha256:5c5a2720817414a6c41f0a49993908068243ae02c1635a228126519b509c8aed"}, +] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] +isort = [ + {file = "isort-5.6.4-py3-none-any.whl", hash = "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7"}, + {file = "isort-5.6.4.tar.gz", hash = "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58"}, +] +jdcal = [ + {file = "jdcal-1.4.1-py2.py3-none-any.whl", hash = "sha256:1abf1305fce18b4e8aa248cf8fe0c56ce2032392bc64bbd61b5dff2a19ec8bba"}, + {file = "jdcal-1.4.1.tar.gz", hash = "sha256:472872e096eb8df219c23f2689fc336668bdb43d194094b5cc1707e1640acfc8"}, +] +markuppy = [ + {file = "MarkupPy-1.14.tar.gz", hash = "sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f"}, +] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +odfpy = [ + {file = "odfpy-1.4.1-py2.7.egg", hash = "sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0"}, + {file = "odfpy-1.4.1.tar.gz", hash = "sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec"}, +] +openpyxl = [ + {file = "openpyxl-3.0.5-py2.py3-none-any.whl", hash = "sha256:f7d666b569f729257082cf7ddc56262431878f602dcc2bc3980775c59439cdab"}, + {file = "openpyxl-3.0.5.tar.gz", hash = "sha256:18e11f9a650128a12580a58e3daba14e00a11d9e907c554a17ea016bf1a2c71b"}, +] +packaging = [ + {file = "packaging-20.8-py2.py3-none-any.whl", hash = "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858"}, + {file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"}, +] +pathspec = [ + {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, + {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, +] +pillow = [ + {file = "Pillow-8.0.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c"}, + {file = "Pillow-8.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11"}, + {file = "Pillow-8.0.1-cp36-cp36m-win32.whl", hash = "sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e"}, + {file = "Pillow-8.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3"}, + {file = "Pillow-8.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a"}, + {file = "Pillow-8.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8"}, + {file = "Pillow-8.0.1-cp37-cp37m-win32.whl", hash = "sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0"}, + {file = "Pillow-8.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039"}, + {file = "Pillow-8.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792"}, + {file = "Pillow-8.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015"}, + {file = "Pillow-8.0.1-cp38-cp38-win32.whl", hash = "sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271"}, + {file = "Pillow-8.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7"}, + {file = "Pillow-8.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3"}, + {file = "Pillow-8.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544"}, + {file = "Pillow-8.0.1-cp39-cp39-win32.whl", hash = "sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140"}, + {file = "Pillow-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021"}, + {file = "Pillow-8.0.1-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6"}, + {file = "Pillow-8.0.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb"}, + {file = "Pillow-8.0.1-pp37-pypy37_pp73-win32.whl", hash = "sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8"}, + {file = "Pillow-8.0.1.tar.gz", hash = "sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +pprintpp = [ + {file = "pprintpp-0.4.0-py2.py3-none-any.whl", hash = "sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d"}, + {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, +] +psycopg2-binary = [ + {file = "psycopg2-binary-2.8.6.tar.gz", hash = "sha256:11b9c0ebce097180129e422379b824ae21c8f2a6596b159c7659e2e5a00e1aa0"}, + {file = "psycopg2_binary-2.8.6-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:d14b140a4439d816e3b1229a4a525df917d6ea22a0771a2a78332273fd9528a4"}, + {file = "psycopg2_binary-2.8.6-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1fabed9ea2acc4efe4671b92c669a213db744d2af8a9fc5d69a8e9bc14b7a9db"}, + {file = "psycopg2_binary-2.8.6-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f5ab93a2cb2d8338b1674be43b442a7f544a0971da062a5da774ed40587f18f5"}, + {file = "psycopg2_binary-2.8.6-cp27-cp27m-win32.whl", hash = "sha256:b4afc542c0ac0db720cf516dd20c0846f71c248d2b3d21013aa0d4ef9c71ca25"}, + {file = "psycopg2_binary-2.8.6-cp27-cp27m-win_amd64.whl", hash = "sha256:e74a55f6bad0e7d3968399deb50f61f4db1926acf4a6d83beaaa7df986f48b1c"}, + {file = "psycopg2_binary-2.8.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:0deac2af1a587ae12836aa07970f5cb91964f05a7c6cdb69d8425ff4c15d4e2c"}, + {file = "psycopg2_binary-2.8.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ad20d2eb875aaa1ea6d0f2916949f5c08a19c74d05b16ce6ebf6d24f2c9f75d1"}, + {file = "psycopg2_binary-2.8.6-cp34-cp34m-win32.whl", hash = "sha256:950bc22bb56ee6ff142a2cb9ee980b571dd0912b0334aa3fe0fe3788d860bea2"}, + {file = "psycopg2_binary-2.8.6-cp34-cp34m-win_amd64.whl", hash = "sha256:b8a3715b3c4e604bcc94c90a825cd7f5635417453b253499664f784fc4da0152"}, + {file = "psycopg2_binary-2.8.6-cp35-cp35m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:d1b4ab59e02d9008efe10ceabd0b31e79519da6fb67f7d8e8977118832d0f449"}, + {file = "psycopg2_binary-2.8.6-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:ac0c682111fbf404525dfc0f18a8b5f11be52657d4f96e9fcb75daf4f3984859"}, + {file = "psycopg2_binary-2.8.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7d92a09b788cbb1aec325af5fcba9fed7203897bbd9269d5691bb1e3bce29550"}, + {file = "psycopg2_binary-2.8.6-cp35-cp35m-win32.whl", hash = "sha256:aaa4213c862f0ef00022751161df35804127b78adf4a2755b9f991a507e425fd"}, + {file = "psycopg2_binary-2.8.6-cp35-cp35m-win_amd64.whl", hash = "sha256:c2507d796fca339c8fb03216364cca68d87e037c1f774977c8fc377627d01c71"}, + {file = "psycopg2_binary-2.8.6-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:ee69dad2c7155756ad114c02db06002f4cded41132cc51378e57aad79cc8e4f4"}, + {file = "psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:e82aba2188b9ba309fd8e271702bd0d0fc9148ae3150532bbb474f4590039ffb"}, + {file = "psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d5227b229005a696cc67676e24c214740efd90b148de5733419ac9aaba3773da"}, + {file = "psycopg2_binary-2.8.6-cp36-cp36m-win32.whl", hash = "sha256:a0eb43a07386c3f1f1ebb4dc7aafb13f67188eab896e7397aa1ee95a9c884eb2"}, + {file = "psycopg2_binary-2.8.6-cp36-cp36m-win_amd64.whl", hash = "sha256:e1f57aa70d3f7cc6947fd88636a481638263ba04a742b4a37dd25c373e41491a"}, + {file = "psycopg2_binary-2.8.6-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:833709a5c66ca52f1d21d41865a637223b368c0ee76ea54ca5bad6f2526c7679"}, + {file = "psycopg2_binary-2.8.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ba28584e6bca48c59eecbf7efb1576ca214b47f05194646b081717fa628dfddf"}, + {file = "psycopg2_binary-2.8.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6a32f3a4cb2f6e1a0b15215f448e8ce2da192fd4ff35084d80d5e39da683e79b"}, + {file = "psycopg2_binary-2.8.6-cp37-cp37m-win32.whl", hash = "sha256:0e4dc3d5996760104746e6cfcdb519d9d2cd27c738296525d5867ea695774e67"}, + {file = "psycopg2_binary-2.8.6-cp37-cp37m-win_amd64.whl", hash = "sha256:cec7e622ebc545dbb4564e483dd20e4e404da17ae07e06f3e780b2dacd5cee66"}, + {file = "psycopg2_binary-2.8.6-cp38-cp38-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:ba381aec3a5dc29634f20692349d73f2d21f17653bda1decf0b52b11d694541f"}, + {file = "psycopg2_binary-2.8.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a0c50db33c32594305b0ef9abc0cb7db13de7621d2cadf8392a1d9b3c437ef77"}, + {file = "psycopg2_binary-2.8.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2dac98e85565d5688e8ab7bdea5446674a83a3945a8f416ad0110018d1501b94"}, + {file = "psycopg2_binary-2.8.6-cp38-cp38-win32.whl", hash = "sha256:bd1be66dde2b82f80afb9459fc618216753f67109b859a361cf7def5c7968729"}, + {file = "psycopg2_binary-2.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:8cd0fb36c7412996859cb4606a35969dd01f4ea34d9812a141cd920c3b18be77"}, + {file = "psycopg2_binary-2.8.6-cp39-cp39-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83"}, + {file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52"}, + {file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd"}, + {file = "psycopg2_binary-2.8.6-cp39-cp39-win32.whl", hash = "sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056"}, + {file = "psycopg2_binary-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6"}, +] +py = [ + {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, + {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, +] +pycodestyle = [ + {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, + {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, +] +pyflakes = [ + {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, + {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, +] +pyinventory = [ + {file = "PyInventory-0.8.2-py3-none-any.whl", hash = "sha256:f772cdae9d34f77a31a943f796a02bf706bba1f4ff7b2ecba87afc96234a64c2"}, + {file = "PyInventory-0.8.2.tar.gz", hash = "sha256:c3badc4db1d488d49fd693536ba3c93b84bf880841d109e9bce9e2be864ce9e0"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] +pytest = [ + {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, + {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, +] +pytest-cov = [ + {file = "pytest-cov-2.10.1.tar.gz", hash = "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e"}, + {file = "pytest_cov-2.10.1-py2.py3-none-any.whl", hash = "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191"}, +] +pytest-django = [ + {file = "pytest-django-4.1.0.tar.gz", hash = "sha256:26f02c16d36fd4c8672390deebe3413678d89f30720c16efb8b2a6bf63b9041f"}, + {file = "pytest_django-4.1.0-py3-none-any.whl", hash = "sha256:10e384e6b8912ded92db64c58be8139d9ae23fb8361e5fc139d8e4f8fc601bc2"}, +] +python-stdnum = [ + {file = "python-stdnum-1.14.tar.gz", hash = "sha256:fd3a92b8ec82a159c41dbaa3c5397934d090090c92b04e346412e0fd7e6a1b1c"}, + {file = "python_stdnum-1.14-py2.py3-none-any.whl", hash = "sha256:6389a1e7658e39c37e4f10b42d7a51ce620e031bdeae05158519c218e14ff3b5"}, +] +pytz = [ + {file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"}, + {file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"}, +] +pyupgrade = [ + {file = "pyupgrade-2.7.4-py2.py3-none-any.whl", hash = "sha256:ab2f47377e977bec8dd41db634fde35bce78fedd2be0e8b189fe687f23fb1d85"}, + {file = "pyupgrade-2.7.4.tar.gz", hash = "sha256:e57057ccef3fd8e8fad5ba9f365c1288a076271a222ccb502d865c0d8fe16c3a"}, +] +pyyaml = [ + {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, + {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, + {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, + {file = "PyYAML-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a"}, + {file = "PyYAML-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e"}, + {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, +] +redis = [ + {file = "redis-3.5.3-py2.py3-none-any.whl", hash = "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24"}, + {file = "redis-3.5.3.tar.gz", hash = "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2"}, +] +regex = [ + {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6"}, + {file = "regex-2020.11.13-cp36-cp36m-win32.whl", hash = "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e"}, + {file = "regex-2020.11.13-cp36-cp36m-win_amd64.whl", hash = "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884"}, + {file = "regex-2020.11.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538"}, + {file = "regex-2020.11.13-cp37-cp37m-win32.whl", hash = "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4"}, + {file = "regex-2020.11.13-cp37-cp37m-win_amd64.whl", hash = "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444"}, + {file = "regex-2020.11.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b"}, + {file = "regex-2020.11.13-cp38-cp38-win32.whl", hash = "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c"}, + {file = "regex-2020.11.13-cp38-cp38-win_amd64.whl", hash = "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683"}, + {file = "regex-2020.11.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c"}, + {file = "regex-2020.11.13-cp39-cp39-win32.whl", hash = "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f"}, + {file = "regex-2020.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d"}, + {file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"}, +] +requests = [ + {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, + {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, +] +six = [ + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, +] +sqlparse = [ + {file = "sqlparse-0.4.1-py3-none-any.whl", hash = "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0"}, + {file = "sqlparse-0.4.1.tar.gz", hash = "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8"}, +] +tablib = [ + {file = "tablib-3.0.0-py3-none-any.whl", hash = "sha256:41aa40981cddd7ec4d1fabeae7c38d271601b306386bd05b5c3bcae13e5aeb20"}, + {file = "tablib-3.0.0.tar.gz", hash = "sha256:f83cac08454f225a34a305daa20e2110d5e6335135d505f93bc66583a5f9c10d"}, +] +tokenize-rt = [ + {file = "tokenize_rt-4.0.0-py2.py3-none-any.whl", hash = "sha256:c47d3bd00857c24edefccdd6dc99c19d4ceed77c5971a3e2fac007fb0c02e39d"}, + {file = "tokenize_rt-4.0.0.tar.gz", hash = "sha256:07d5f88b6a953612159b160129bcf9425677c8d062b0cb83250968ba803e1c64"}, +] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] +tox = [ + {file = "tox-3.12.1-py2.py3-none-any.whl", hash = "sha256:f5c8e446b51edd2ea97df31d4ded8c8b72e7d6c619519da6bb6084b9dd5770f9"}, + {file = "tox-3.12.1.tar.gz", hash = "sha256:f87fd33892a2df0950e5e034def9468988b8d008c7e9416be665fcc0dd45b14f"}, +] +typed-ast = [ + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, + {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, + {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, +] +typing-extensions = [ + {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, + {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, + {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, +] +urllib3 = [ + {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"}, + {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, +] +virtualenv = [ + {file = "virtualenv-20.2.2-py2.py3-none-any.whl", hash = "sha256:54b05fc737ea9c9ee9f8340f579e5da5b09fb64fd010ab5757eb90268616907c"}, + {file = "virtualenv-20.2.2.tar.gz", hash = "sha256:b7a8ec323ee02fb2312f098b6b4c9de99559b462775bc8fe3627a73706603c1b"}, +] +webencodings = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] +xlrd = [ + {file = "xlrd-2.0.1-py2.py3-none-any.whl", hash = "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd"}, + {file = "xlrd-2.0.1.tar.gz", hash = "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88"}, +] +xlwt = [ + {file = "xlwt-1.3.0-py2.py3-none-any.whl", hash = "sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e"}, + {file = "xlwt-1.3.0.tar.gz", hash = "sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88"}, +] +zipp = [ + {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"}, + {file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"}, +] From 8e81bd12eac321f7e5112956810cf797e14c1459 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 14:36:09 +0100 Subject: [PATCH 08/11] update to pyinventory==0.8.3 --- conf/requirements.txt | 8 +++---- manifest.json | 2 +- poetry.lock | 47 +++++++++++++++++++------------------ pyproject.toml | 4 ++-- tests/test_project_setup.py | 1 + 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/conf/requirements.txt b/conf/requirements.txt index 204e24c..b3ed098 100644 --- a/conf/requirements.txt +++ b/conf/requirements.txt @@ -10,7 +10,7 @@ certifi==2020.12.5; python_version >= "3.7" and python_full_version < "3.0.0" or chardet==4.0.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ --hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5 \ --hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa -colorama==0.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" and sys_platform == "win32" \ +colorama==0.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or python_version >= "3.7" and python_full_version < "4.0.0" and sys_platform == "win32" and python_full_version >= "3.5.0" \ --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2 \ --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b colorlog==4.6.2; python_version >= "3.7" and python_full_version < "4.0.0" \ @@ -159,9 +159,9 @@ psycopg2-binary==2.8.6; python_version >= "3.7" and python_full_version < "3.0.0 --hash=sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd \ --hash=sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056 \ --hash=sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6 -pyinventory==0.8.2; python_version >= "3.7" and python_full_version < "4.0.0" \ - --hash=sha256:f772cdae9d34f77a31a943f796a02bf706bba1f4ff7b2ecba87afc96234a64c2 \ - --hash=sha256:c3badc4db1d488d49fd693536ba3c93b84bf880841d109e9bce9e2be864ce9e0 +pyinventory==0.8.3; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:03f028a508b9a4e303b5561083476b5c7099914c792b66f20d94f034a8b0db50 \ + --hash=sha256:e7a09820b2aaf1d17e9ca6896e83e69999cce99d7d399141648e0d303cef10c7 pyparsing==2.4.7; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \ --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 diff --git a/manifest.json b/manifest.json index de98baa..cca703a 100644 --- a/manifest.json +++ b/manifest.json @@ -5,7 +5,7 @@ "description": { "en": "Web based management to catalog things including state and location etc." }, - "version": "0.8.2~ynh5", + "version": "0.8.3~ynh1", "url": "https://github.com/jedie/PyInventory", "license": "GPL-3.0", "maintainer": { diff --git a/poetry.lock b/poetry.lock index bca3c54..793d22f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -453,19 +453,18 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "3.3.0" +version = "2.1.1" description = "Read metadata from Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +docs = ["sphinx", "rst.linker"] +testing = ["packaging", "pep517", "unittest2", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -626,7 +625,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyinventory" -version = "0.8.2" +version = "0.8.3" description = "Web based management to catalog things including state and location etc. using Python/Django." category = "main" optional = false @@ -634,7 +633,6 @@ python-versions = ">=3.7,<4.0.0" [package.dependencies] bx_py_utils = "*" -colorama = "*" colorlog = "*" django = ">=2.2.0,<2.3.0" django-admin-sortable2 = "*" @@ -852,23 +850,26 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tox" -version = "3.12.1" +version = "3.20.1" description = "tox is a generic virtualenv management and test command line tool" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.dependencies] -filelock = ">=3.0.0,<4" -pluggy = ">=0.3.0,<1" -py = ">=1.4.17,<2" -six = ">=1.0.0,<2" +colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} +filelock = ">=3.0.0" +importlib-metadata = {version = ">=0.12,<3", markers = "python_version < \"3.8\""} +packaging = ">=14" +pluggy = ">=0.12.0" +py = ">=1.4.17" +six = ">=1.14.0" toml = ">=0.9.4" -virtualenv = ">=14.0.0" +virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" [package.extras] -docs = ["sphinx (>=2.0.0,<3)", "towncrier (>=18.5.0)", "pygments-github-lexers (>=0.0.5)", "sphinxcontrib-autoprogram (>=0.1.5)"] -testing = ["freezegun (>=0.3.11,<1)", "pathlib2 (>=2.3.3,<3)", "pytest (>=3.0.0,<5)", "pytest-cov (>=2.5.1,<3)", "pytest-mock (>=1.10.0,<2)", "pytest-xdist (>=1.22.2,<2)", "pytest-randomly (>=1.2.3,<2)", "flaky (>=3.4.0,<4)", "psutil (>=5.6.1,<6)"] +docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] +testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)", "pytest-xdist (>=1.22.2)"] [[package]] name = "typed-ast" @@ -962,7 +963,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = ">=3.7,<4.0.0" -content-hash = "206d7e10d1b6d7d258b18819d1966ef15e601db154a6632541f40615191d80f7" +content-hash = "d708bf66cd5d0ffa06e20cbb38d38f868a39a251761cffce542df913cfa46505" [metadata.files] appdirs = [ @@ -1170,8 +1171,8 @@ idna = [ {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] importlib-metadata = [ - {file = "importlib_metadata-3.3.0-py3-none-any.whl", hash = "sha256:bf792d480abbd5eda85794e4afb09dd538393f7d6e6ffef6e9f03d2014cf9450"}, - {file = "importlib_metadata-3.3.0.tar.gz", hash = "sha256:5c5a2720817414a6c41f0a49993908068243ae02c1635a228126519b509c8aed"}, + {file = "importlib_metadata-2.1.1-py2.py3-none-any.whl", hash = "sha256:c2d6341ff566f609e89a2acb2db190e5e1d23d5409d6cc8d2fe34d72443876d4"}, + {file = "importlib_metadata-2.1.1.tar.gz", hash = "sha256:b8de9eff2b35fb037368f28a7df1df4e6436f578fa74423505b6c6a778d5b5dd"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -1300,8 +1301,8 @@ pyflakes = [ {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, ] pyinventory = [ - {file = "PyInventory-0.8.2-py3-none-any.whl", hash = "sha256:f772cdae9d34f77a31a943f796a02bf706bba1f4ff7b2ecba87afc96234a64c2"}, - {file = "PyInventory-0.8.2.tar.gz", hash = "sha256:c3badc4db1d488d49fd693536ba3c93b84bf880841d109e9bce9e2be864ce9e0"}, + {file = "PyInventory-0.8.3-py3-none-any.whl", hash = "sha256:03f028a508b9a4e303b5561083476b5c7099914c792b66f20d94f034a8b0db50"}, + {file = "PyInventory-0.8.3.tar.gz", hash = "sha256:e7a09820b2aaf1d17e9ca6896e83e69999cce99d7d399141648e0d303cef10c7"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, @@ -1418,8 +1419,8 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tox = [ - {file = "tox-3.12.1-py2.py3-none-any.whl", hash = "sha256:f5c8e446b51edd2ea97df31d4ded8c8b72e7d6c619519da6bb6084b9dd5770f9"}, - {file = "tox-3.12.1.tar.gz", hash = "sha256:f87fd33892a2df0950e5e034def9468988b8d008c7e9416be665fcc0dd45b14f"}, + {file = "tox-3.20.1-py2.py3-none-any.whl", hash = "sha256:42ce19ce5dc2f6d6b1fdc5666c476e1f1e2897359b47e0aa3a5b774f335d57c2"}, + {file = "tox-3.20.1.tar.gz", hash = "sha256:4321052bfe28f9d85082341ca8e233e3ea901fdd14dab8a5d3fbd810269fbaf6"}, ] typed-ast = [ {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, diff --git a/pyproject.toml b/pyproject.toml index cc73f64..46856b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,13 +1,13 @@ [tool.poetry] name = "pyinventory_ynh" -version = "0.8.2~ynh5" +version = "0.8.3~ynh1" description = "Test pyinventory_ynh via local_test.py" authors = ["JensDiemer "] license = "GPL" [tool.poetry.dependencies] python = ">=3.7,<4.0.0" -pyinventory = "*" +pyinventory = "==0.8.3" django_ynh = "*" [tool.poetry.dev-dependencies] diff --git a/tests/test_project_setup.py b/tests/test_project_setup.py index f5a6651..827ce28 100644 --- a/tests/test_project_setup.py +++ b/tests/test_project_setup.py @@ -26,6 +26,7 @@ def test_version(): assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'README.md'), string=version_string) assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'version = "{version}~ynh') + assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'pyinventory = "=={version}"') assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'manifest.json'), string=f'"version": "{version}~ynh') From e3138f0ed59c240ca80a2509bb529c66f0fa69b5 Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 14:48:04 +0100 Subject: [PATCH 09/11] add link to https://github.com/YunoHost-Apps/django_ynh --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83ffac6..2acfaef 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ You can edit the file `$final_path/local_settings.py` to enable or disable featu ## SSO authentication -[SSOwat](https://github.com/YunoHost/SSOwat) is fully supported: +[SSOwat](https://github.com/YunoHost/SSOwat) is fully supported via [django_ynh](https://github.com/YunoHost-Apps/django_ynh): * First user (`$YNH_APP_ARG_ADMIN`) will be created as Django's super user * All new users will be created as normal users From 4e8746cfaab966764ca2570b322bc515cfde5e1e Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Tue, 29 Dec 2020 14:48:41 +0100 Subject: [PATCH 10/11] fix tests: we didn't have version information in README ;) --- tests/test_project_setup.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test_project_setup.py b/tests/test_project_setup.py index 827ce28..ec62036 100644 --- a/tests/test_project_setup.py +++ b/tests/test_project_setup.py @@ -20,11 +20,6 @@ def assert_file_contains_string(file_path, string): def test_version(): version = inventory.__version__ - if 'dev' not in version and 'rc' not in version: - version_string = f'v{version}' - - assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'README.md'), string=version_string) - assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'version = "{version}~ynh') assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'pyinventory = "=={version}"') assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'manifest.json'), string=f'"version": "{version}~ynh') From fc4b166980e7d7688c783a0aea0bb9039671c0cb Mon Sep 17 00:00:00 2001 From: JensDiemer Date: Wed, 30 Dec 2020 09:58:41 +0100 Subject: [PATCH 11/11] fix linting by addning flake8 config file --- .flake8 | 7 +++++++ .gitignore | 1 + 2 files changed, 8 insertions(+) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..6ad2ff9 --- /dev/null +++ b/.flake8 @@ -0,0 +1,7 @@ +# +# Move to pyproject.toml after: https://gitlab.com/pycqa/flake8/-/issues/428 +# +[flake8] +exclude = .pytest_cache, .tox, dist, htmlcov, local_test +ignore = F405 +max-line-length = 119 diff --git a/.gitignore b/.gitignore index 28e1b61..d4aff27 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .* !.github !.editorconfig +!.flake8 !.gitignore __pycache__ secret.txt