From dce1d86e93077b8f85cc1b733d5712ff26fc4c5b Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Tue, 6 Jul 2021 10:34:57 -0400 Subject: [PATCH 01/11] commit changes before looking at something else --- crc/api/workflow_sync.py | 1 + crc/models/workflow.py | 1 + 2 files changed, 2 insertions(+) diff --git a/crc/api/workflow_sync.py b/crc/api/workflow_sync.py index e094fff9..8ab6e703 100644 --- a/crc/api/workflow_sync.py +++ b/crc/api/workflow_sync.py @@ -159,6 +159,7 @@ def create_or_update_local_spec(remote,workflow_spec_id): localcategory.name = specdict['category']['name'] localcategory.display_name = specdict['category']['display_name'] localcategory.display_order = specdict['category']['display_order'] + localcategory.library = False session.add(localcategory) localspec.category = localcategory diff --git a/crc/models/workflow.py b/crc/models/workflow.py index 5b1c49f6..f6604ce6 100644 --- a/crc/models/workflow.py +++ b/crc/models/workflow.py @@ -15,6 +15,7 @@ class WorkflowSpecCategoryModel(db.Model): name = db.Column(db.String) display_name = db.Column(db.String) display_order = db.Column(db.Integer) + library = db.Column(db.Boolean) class WorkflowSpecCategoryModelSchema(SQLAlchemyAutoSchema): From 79c69037ddf12c8804158a73df62baabeb59b2cf Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Thu, 8 Jul 2021 08:57:40 -0400 Subject: [PATCH 02/11] Filter out Library categories from the list returned --- crc/services/study_service.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crc/services/study_service.py b/crc/services/study_service.py index 3aa12fed..922daa64 100644 --- a/crc/services/study_service.py +++ b/crc/services/study_service.py @@ -242,7 +242,8 @@ class StudyService(object): def get_categories(): """Returns a list of category objects, in the correct order.""" cat_models = db.session.query(WorkflowSpecCategoryModel) \ - .order_by(WorkflowSpecCategoryModel.display_order).all() + .order_by(WorkflowSpecCategoryModel.display_order) \ + .filter((WorkflowSpecCategoryModel.library == None)|(WorkflowSpecCategoryModel.library ==False)).all() categories = [] for cat_model in cat_models: categories.append(Category(cat_model)) From 245549545764d6f24b33c7674be0a991c97b34cc Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Thu, 22 Jul 2021 10:20:34 -0400 Subject: [PATCH 03/11] got library side working - still need to have parent working --- Pipfile | 17 +- Pipfile.lock | 1360 -------------------------- crc/api.yml | 79 ++ crc/api/workflow.py | 53 +- crc/api/workflow_sync.py | 1 - crc/models/workflow.py | 31 +- crc/services/study_service.py | 3 +- crc/services/workflow_service.py | 5 + migrations/versions/a931e2b7b070_.py | 35 + migrations/versions/b0f38c78db40_.py | 28 + 10 files changed, 239 insertions(+), 1373 deletions(-) delete mode 100644 Pipfile.lock create mode 100644 migrations/versions/a931e2b7b070_.py create mode 100644 migrations/versions/b0f38c78db40_.py diff --git a/Pipfile b/Pipfile index ffed64df..87b295c9 100644 --- a/Pipfile +++ b/Pipfile @@ -10,7 +10,6 @@ coverage = "*" [packages] alembic = "*" -connexion = {extras = ["swagger-ui"],version = "*"} coverage = "*" docxtpl = "*" flask = "*" @@ -36,11 +35,8 @@ pyjwt = "*" python-dateutil = "*" recommonmark = "*" requests = "*" -sentry-sdk = {extras = ["flask"],version = "==0.14.4"} sphinx = "*" swagger-ui-bundle = "*" -spiffworkflow = {git = "https://github.com/sartography/SpiffWorkflow.git"} -# spiffworkflow = {editable = true, path = "./../SpiffWorkflow"} webtest = "*" werkzeug = "*" xlrd = "*" @@ -50,4 +46,15 @@ python-levenshtein = "*" apscheduler = "*" [requires] -python_version = "3.8" +python_version = "3.9" + +[packages.connexion] +extras = [ "swagger-ui",] +version = "*" + +[packages.sentry-sdk] +extras = [ "flask",] +version = "==0.14.4" + +[packages.spiffworkflow] +git = "https://github.com/sartography/SpiffWorkflow.git" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index f0f34a2e..00000000 --- a/Pipfile.lock +++ /dev/null @@ -1,1360 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "2d74273fabb4ccda79f76e59ed2595d68a72eaa4a56bd4e04d0e7fbd9489039e" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.8" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "alabaster": { - "hashes": [ - "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", - "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02" - ], - "version": "==0.7.12" - }, - "alembic": { - "hashes": [ - "sha256:a21fedebb3fb8f6bbbba51a11114f08c78709377051384c9c5ead5705ee93a51", - "sha256:e78be5b919f5bb184e3e0e2dd1ca986f2362e29a2bc933c446fe89f39dbe4e9c" - ], - "index": "pypi", - "version": "==1.6.5" - }, - "amqp": { - "hashes": [ - "sha256:03e16e94f2b34c31f8bf1206d8ddd3ccaa4c315f7f6a1879b7b1210d229568c2", - "sha256:493a2ac6788ce270a2f6a765b017299f60c1998f5a8617908ee9be082f7300fb" - ], - "markers": "python_version >= '3.6'", - "version": "==5.0.6" - }, - "aniso8601": { - "hashes": [ - "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f", - "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973" - ], - "version": "==9.0.1" - }, - "apscheduler": { - "hashes": [ - "sha256:1cab7f2521e107d07127b042155b632b7a1cd5e02c34be5a28ff62f77c900c6a", - "sha256:c06cc796d5bb9eb3c4f77727f6223476eb67749e7eea074d1587550702a7fbe3" - ], - "index": "pypi", - "version": "==3.7.0" - }, - "attrs": { - "hashes": [ - "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", - "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.2.0" - }, - "babel": { - "hashes": [ - "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9", - "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.9.1" - }, - "bcrypt": { - "hashes": [ - "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29", - "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7", - "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34", - "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55", - "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6", - "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1", - "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d" - ], - "markers": "python_version >= '3.6'", - "version": "==3.2.0" - }, - "beautifulsoup4": { - "hashes": [ - "sha256:4c98143716ef1cb40bf7f39a8e3eec8f8b009509e74904ba3a7b315431577e35", - "sha256:84729e322ad1d5b4d25f805bfa05b902dd96450f43842c4e99067d5e1369eb25", - "sha256:fff47e031e34ec82bf17e00da8f592fe7de69aeea38be00523c04623c04fb666" - ], - "version": "==4.9.3" - }, - "billiard": { - "hashes": [ - "sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547", - "sha256:87103ea78fa6ab4d5c751c4909bcff74617d985de7fa8b672cf8618afd5a875b" - ], - "version": "==3.6.4.0" - }, - "blinker": { - "hashes": [ - "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6" - ], - "version": "==1.4" - }, - "celery": { - "hashes": [ - "sha256:8d9a3de9162965e97f8e8cc584c67aad83b3f7a267584fa47701ed11c3e0d4b0", - "sha256:9dab2170b4038f7bf10ef2861dbf486ddf1d20592290a1040f7b7a1259705d42" - ], - "markers": "python_version >= '3.6'", - "version": "==5.1.2" - }, - "certifi": { - "hashes": [ - "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee", - "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8" - ], - "version": "==2021.5.30" - }, - "cffi": { - "hashes": [ - "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813", - "sha256:04c468b622ed31d408fea2346bec5bbffba2cc44226302a0de1ade9f5ea3d373", - "sha256:06d7cd1abac2ffd92e65c0609661866709b4b2d82dd15f611e602b9b188b0b69", - "sha256:06db6321b7a68b2bd6df96d08a5adadc1fa0e8f419226e25b2a5fbf6ccc7350f", - "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06", - "sha256:0f861a89e0043afec2a51fd177a567005847973be86f709bbb044d7f42fc4e05", - "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea", - "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee", - "sha256:1bf1ac1984eaa7675ca8d5745a8cb87ef7abecb5592178406e55858d411eadc0", - "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396", - "sha256:24a570cd11895b60829e941f2613a4f79df1a27344cbbb82164ef2e0116f09c7", - "sha256:24ec4ff2c5c0c8f9c6b87d5bb53555bf267e1e6f70e52e5a9740d32861d36b6f", - "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73", - "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315", - "sha256:293e7ea41280cb28c6fcaaa0b1aa1f533b8ce060b9e701d78511e1e6c4a1de76", - "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1", - "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49", - "sha256:3c3f39fa737542161d8b0d680df2ec249334cd70a8f420f71c9304bd83c3cbed", - "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892", - "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482", - "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058", - "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5", - "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53", - "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045", - "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3", - "sha256:681d07b0d1e3c462dd15585ef5e33cb021321588bebd910124ef4f4fb71aef55", - "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5", - "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e", - "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c", - "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369", - "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827", - "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053", - "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa", - "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4", - "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322", - "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132", - "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62", - "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa", - "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0", - "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396", - "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e", - "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991", - "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6", - "sha256:cc5a8e069b9ebfa22e26d0e6b97d6f9781302fe7f4f2b8776c3e1daea35f1adc", - "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1", - "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406", - "sha256:df5052c5d867c1ea0b311fb7c3cd28b19df469c056f7fdcfe88c7473aa63e333", - "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d", - "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c" - ], - "version": "==1.14.5" - }, - "chardet": { - "hashes": [ - "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", - "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.0.0" - }, - "click": { - "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==7.1.2" - }, - "click-didyoumean": { - "hashes": [ - "sha256:112229485c9704ff51362fe34b2d4f0b12fc71cc20f6d2b3afabed4b8bfa6aeb" - ], - "version": "==0.0.3" - }, - "click-plugins": { - "hashes": [ - "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b", - "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8" - ], - "version": "==1.1.1" - }, - "click-repl": { - "hashes": [ - "sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b", - "sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8" - ], - "version": "==0.2.0" - }, - "clickclick": { - "hashes": [ - "sha256:4efb13e62353e34c5eef7ed6582c4920b418d7dedc86d819e22ee089ba01802c", - "sha256:c8f33e6d9ec83f68416dd2136a7950125bd256ec39ccc9a85c6e280a16be2bb5" - ], - "version": "==20.10.2" - }, - "commonmark": { - "hashes": [ - "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60", - "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9" - ], - "version": "==0.9.1" - }, - "configparser": { - "hashes": [ - "sha256:85d5de102cfe6d14a5172676f09d19c465ce63d6019cf0a4ef13385fc535e828", - "sha256:af59f2cdd7efbdd5d111c1976ecd0b82db9066653362f0962d7bf1d3ab89a1fa" - ], - "markers": "python_version >= '3.6'", - "version": "==5.0.2" - }, - "connexion": { - "extras": [ - "swagger-ui" - ], - "hashes": [ - "sha256:1ccfac57d4bb7adf4295ba6f5e48f5a1f66057df6a0713417766c9b5235182ee", - "sha256:5439e9659a89c4380d93a07acfbf3380d70be4130574de8881e5f0dfec7ad0e2" - ], - "index": "pypi", - "version": "==2.7.0" - }, - "coverage": { - "hashes": [ - "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c", - "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6", - "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45", - "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a", - "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03", - "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529", - "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a", - "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a", - "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2", - "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6", - "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759", - "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53", - "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a", - "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4", - "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff", - "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502", - "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793", - "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb", - "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905", - "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821", - "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b", - "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81", - "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0", - "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b", - "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3", - "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184", - "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701", - "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a", - "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82", - "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638", - "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5", - "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083", - "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6", - "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90", - "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465", - "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a", - "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3", - "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e", - "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066", - "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf", - "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b", - "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae", - "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669", - "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873", - "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b", - "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6", - "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb", - "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160", - "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c", - "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079", - "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d", - "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6" - ], - "index": "pypi", - "version": "==5.5" - }, - "deprecated": { - "hashes": [ - "sha256:08452d69b6b5bc66e8330adde0a4f8642e969b9e1702904d137eeb29c8ffc771", - "sha256:6d2de2de7931a968874481ef30208fd4e08da39177d61d3d4ebdf4366e7dbca1" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.2.12" - }, - "docutils": { - "hashes": [ - "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125", - "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.17.1" - }, - "docxtpl": { - "hashes": [ - "sha256:60a8be7400fe9226fc52412cb7cd011064a40ac9984246f873dcf21f3c908377", - "sha256:ca247f3d97d9b908ecbb48fa99ec6d5670c96c3d6960432cd322d0791f808578" - ], - "index": "pypi", - "version": "==0.11.5" - }, - "et-xmlfile": { - "hashes": [ - "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c", - "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada" - ], - "markers": "python_version >= '3.6'", - "version": "==1.1.0" - }, - "flask": { - "hashes": [ - "sha256:1c4c257b1892aec1398784c63791cbaa43062f1f7aeb555c4da961b20ee68f55", - "sha256:a6209ca15eb63fc9385f38e452704113d679511d9574d09b2cf9183ae7d20dc9" - ], - "index": "pypi", - "version": "==2.0.1" - }, - "flask-admin": { - "hashes": [ - "sha256:eb06a1f31b98881dee53a55c64faebd1990d6aac38826364b280df0b2679ff74" - ], - "index": "pypi", - "version": "==1.5.8" - }, - "flask-bcrypt": { - "hashes": [ - "sha256:d71c8585b2ee1c62024392ebdbc447438564e2c8c02b4e57b56a4cafd8d13c5f" - ], - "index": "pypi", - "version": "==0.7.1" - }, - "flask-cors": { - "hashes": [ - "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438", - "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de" - ], - "index": "pypi", - "version": "==3.0.10" - }, - "flask-mail": { - "hashes": [ - "sha256:22e5eb9a940bf407bcf30410ecc3708f3c56cc44b29c34e1726fe85006935f41" - ], - "index": "pypi", - "version": "==0.9.1" - }, - "flask-marshmallow": { - "hashes": [ - "sha256:2adcd782b5a4a6c5ae3c96701f320d8ca6997995a52b2661093c56cc3ed24754", - "sha256:bd01a6372cbe50e36f205cfff0fc5dab0b7b662c4c8b2c4fc06a3151b2950950" - ], - "index": "pypi", - "version": "==0.14.0" - }, - "flask-migrate": { - "hashes": [ - "sha256:4d42e8f861d78cb6e9319afcba5bf76062e5efd7784184dd2a1cccd9de34a702", - "sha256:df9043d2050df3c0e0f6313f6b529b62c837b6033c20335e9d0b4acdf2c40e23" - ], - "index": "pypi", - "version": "==3.0.1" - }, - "flask-restful": { - "hashes": [ - "sha256:4970c49b6488e46c520b325f54833374dc2b98e211f1b272bd4b0c516232afe2", - "sha256:ccec650b835d48192138c85329ae03735e6ced58e9b2d9c2146d6c84c06fa53e" - ], - "index": "pypi", - "version": "==0.3.9" - }, - "flask-sqlalchemy": { - "hashes": [ - "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912", - "sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.5.1" - }, - "future": { - "hashes": [ - "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.2" - }, - "greenlet": { - "hashes": [ - "sha256:03f28a5ea20201e70ab70518d151116ce939b412961c33827519ce620957d44c", - "sha256:06d7ac89e6094a0a8f8dc46aa61898e9e1aec79b0f8b47b2400dd51a44dbc832", - "sha256:06ecb43b04480e6bafc45cb1b4b67c785e183ce12c079473359e04a709333b08", - "sha256:096cb0217d1505826ba3d723e8981096f2622cde1eb91af9ed89a17c10aa1f3e", - "sha256:0c557c809eeee215b87e8a7cbfb2d783fb5598a78342c29ade561440abae7d22", - "sha256:0de64d419b1cb1bfd4ea544bedea4b535ef3ae1e150b0f2609da14bbf48a4a5f", - "sha256:14927b15c953f8f2d2a8dffa224aa78d7759ef95284d4c39e1745cf36e8cdd2c", - "sha256:16183fa53bc1a037c38d75fdc59d6208181fa28024a12a7f64bb0884434c91ea", - "sha256:206295d270f702bc27dbdbd7651e8ebe42d319139e0d90217b2074309a200da8", - "sha256:22002259e5b7828b05600a762579fa2f8b33373ad95a0ee57b4d6109d0e589ad", - "sha256:2325123ff3a8ecc10ca76f062445efef13b6cf5a23389e2df3c02a4a527b89bc", - "sha256:258f9612aba0d06785143ee1cbf2d7361801c95489c0bd10c69d163ec5254a16", - "sha256:3096286a6072553b5dbd5efbefc22297e9d06a05ac14ba017233fedaed7584a8", - "sha256:3d13da093d44dee7535b91049e44dd2b5540c2a0e15df168404d3dd2626e0ec5", - "sha256:408071b64e52192869129a205e5b463abda36eff0cebb19d6e63369440e4dc99", - "sha256:598bcfd841e0b1d88e32e6a5ea48348a2c726461b05ff057c1b8692be9443c6e", - "sha256:5d928e2e3c3906e0a29b43dc26d9b3d6e36921eee276786c4e7ad9ff5665c78a", - "sha256:5f75e7f237428755d00e7460239a2482fa7e3970db56c8935bd60da3f0733e56", - "sha256:60848099b76467ef09b62b0f4512e7e6f0a2c977357a036de602b653667f5f4c", - "sha256:6b1d08f2e7f2048d77343279c4d4faa7aef168b3e36039cba1917fffb781a8ed", - "sha256:70bd1bb271e9429e2793902dfd194b653221904a07cbf207c3139e2672d17959", - "sha256:76ed710b4e953fc31c663b079d317c18f40235ba2e3d55f70ff80794f7b57922", - "sha256:7920e3eccd26b7f4c661b746002f5ec5f0928076bd738d38d894bb359ce51927", - "sha256:7db68f15486d412b8e2cfcd584bf3b3a000911d25779d081cbbae76d71bd1a7e", - "sha256:8833e27949ea32d27f7e96930fa29404dd4f2feb13cce483daf52e8842ec246a", - "sha256:944fbdd540712d5377a8795c840a97ff71e7f3221d3fddc98769a15a87b36131", - "sha256:9a6b035aa2c5fcf3dbbf0e3a8a5bc75286fc2d4e6f9cfa738788b433ec894919", - "sha256:9bdcff4b9051fb1aa4bba4fceff6a5f770c6be436408efd99b76fc827f2a9319", - "sha256:a9017ff5fc2522e45562882ff481128631bf35da444775bc2776ac5c61d8bcae", - "sha256:aa4230234d02e6f32f189fd40b59d5a968fe77e80f59c9c933384fe8ba535535", - "sha256:ad80bb338cf9f8129c049837a42a43451fc7c8b57ad56f8e6d32e7697b115505", - "sha256:adb94a28225005890d4cf73648b5131e885c7b4b17bc762779f061844aabcc11", - "sha256:b3090631fecdf7e983d183d0fad7ea72cfb12fa9212461a9b708ff7907ffff47", - "sha256:b33b51ab057f8a20b497ffafdb1e79256db0c03ef4f5e3d52e7497200e11f821", - "sha256:b97c9a144bbeec7039cca44df117efcbeed7209543f5695201cacf05ba3b5857", - "sha256:be13a18cec649ebaab835dff269e914679ef329204704869f2f167b2c163a9da", - "sha256:be9768e56f92d1d7cd94185bab5856f3c5589a50d221c166cc2ad5eb134bd1dc", - "sha256:c1580087ab493c6b43e66f2bdd165d9e3c1e86ef83f6c2c44a29f2869d2c5bd5", - "sha256:c35872b2916ab5a240d52a94314c963476c989814ba9b519bc842e5b61b464bb", - "sha256:c70c7dd733a4c56838d1f1781e769081a25fade879510c5b5f0df76956abfa05", - "sha256:c767458511a59f6f597bfb0032a1c82a52c29ae228c2c0a6865cfeaeaac4c5f5", - "sha256:c87df8ae3f01ffb4483c796fe1b15232ce2b219f0b18126948616224d3f658ee", - "sha256:ca1c4a569232c063615f9e70ff9a1e2fee8c66a6fb5caf0f5e8b21a396deec3e", - "sha256:cc407b68e0a874e7ece60f6639df46309376882152345508be94da608cc0b831", - "sha256:da862b8f7de577bc421323714f63276acb2f759ab8c5e33335509f0b89e06b8f", - "sha256:dfe7eac0d253915116ed0cd160a15a88981a1d194c1ef151e862a5c7d2f853d3", - "sha256:ed1377feed808c9c1139bdb6a61bcbf030c236dd288d6fca71ac26906ab03ba6", - "sha256:f42ad188466d946f1b3afc0a9e1a266ac8926461ee0786c06baac6bd71f8a6f3", - "sha256:f92731609d6625e1cc26ff5757db4d32b6b810d2a3363b0ff94ff573e5901f6f" - ], - "markers": "python_version >= '3'", - "version": "==1.1.0" - }, - "gunicorn": { - "hashes": [ - "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e", - "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8" - ], - "index": "pypi", - "version": "==20.1.0" - }, - "httpretty": { - "hashes": [ - "sha256:229ade39175ea4324e767f29dc24e5f846fbc72bf80e1a919b2547a6574ff601" - ], - "index": "pypi", - "version": "==1.1.3" - }, - "idna": { - "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.10" - }, - "imagesize": { - "hashes": [ - "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1", - "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.2.0" - }, - "inflection": { - "hashes": [ - "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417", - "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2" - ], - "markers": "python_version >= '3.5'", - "version": "==0.5.1" - }, - "isodate": { - "hashes": [ - "sha256:2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", - "sha256:aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81" - ], - "version": "==0.6.0" - }, - "itsdangerous": { - "hashes": [ - "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c", - "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" - }, - "jinja2": { - "hashes": [ - "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4", - "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4" - ], - "markers": "python_version >= '3.6'", - "version": "==3.0.1" - }, - "jsonschema": { - "hashes": [ - "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", - "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a" - ], - "version": "==3.2.0" - }, - "kombu": { - "hashes": [ - "sha256:01481d99f4606f6939cdc9b637264ed353ee9e3e4f62cfb582324142c41a572d", - "sha256:e2dedd8a86c9077c350555153825a31e456a0dc20c15d5751f00137ec9c75f0a" - ], - "markers": "python_version >= '3.6'", - "version": "==5.1.0" - }, - "ldap3": { - "hashes": [ - "sha256:18c3ee656a6775b9b0d60f7c6c5b094d878d1d90fc03d56731039f0a4b546a91", - "sha256:4139c91f0eef9782df7b77c8cbc6243086affcb6a8a249b768a9658438e5da59", - "sha256:8c949edbad2be8a03e719ba48bd6779f327ec156929562814b3e84ab56889c8c", - "sha256:afc6fc0d01f02af82cd7bfabd3bbfd5dc96a6ae91e97db0a2dab8a0f1b436056", - "sha256:c1df41d89459be6f304e0ceec4b00fdea533dbbcd83c802b1272dcdb94620b57" - ], - "index": "pypi", - "version": "==2.9" - }, - "lxml": { - "hashes": [ - "sha256:079f3ae844f38982d156efce585bc540c16a926d4436712cf4baee0cce487a3d", - "sha256:0fbcf5565ac01dff87cbfc0ff323515c823081c5777a9fc7703ff58388c258c3", - "sha256:122fba10466c7bd4178b07dba427aa516286b846b2cbd6f6169141917283aae2", - "sha256:1b38116b6e628118dea5b2186ee6820ab138dbb1e24a13e478490c7db2f326ae", - "sha256:1b7584d421d254ab86d4f0b13ec662a9014397678a7c4265a02a6d7c2b18a75f", - "sha256:26e761ab5b07adf5f555ee82fb4bfc35bf93750499c6c7614bd64d12aaa67927", - "sha256:289e9ca1a9287f08daaf796d96e06cb2bc2958891d7911ac7cae1c5f9e1e0ee3", - "sha256:2a9d50e69aac3ebee695424f7dbd7b8c6d6eb7de2a2eb6b0f6c7db6aa41e02b7", - "sha256:3082c518be8e97324390614dacd041bb1358c882d77108ca1957ba47738d9d59", - "sha256:33bb934a044cf32157c12bfcfbb6649807da20aa92c062ef51903415c704704f", - "sha256:3439c71103ef0e904ea0a1901611863e51f50b5cd5e8654a151740fde5e1cade", - "sha256:36108c73739985979bf302006527cf8a20515ce444ba916281d1c43938b8bb96", - "sha256:39b78571b3b30645ac77b95f7c69d1bffc4cf8c3b157c435a34da72e78c82468", - "sha256:4289728b5e2000a4ad4ab8da6e1db2e093c63c08bdc0414799ee776a3f78da4b", - "sha256:4bff24dfeea62f2e56f5bab929b4428ae6caba2d1eea0c2d6eb618e30a71e6d4", - "sha256:4c61b3a0db43a1607d6264166b230438f85bfed02e8cff20c22e564d0faff354", - "sha256:542d454665a3e277f76954418124d67516c5f88e51a900365ed54a9806122b83", - "sha256:5a0a14e264069c03e46f926be0d8919f4105c1623d620e7ec0e612a2e9bf1c04", - "sha256:5c8c163396cc0df3fd151b927e74f6e4acd67160d6c33304e805b84293351d16", - "sha256:66e575c62792c3f9ca47cb8b6fab9e35bab91360c783d1606f758761810c9791", - "sha256:6f12e1427285008fd32a6025e38e977d44d6382cf28e7201ed10d6c1698d2a9a", - "sha256:74f7d8d439b18fa4c385f3f5dfd11144bb87c1da034a466c5b5577d23a1d9b51", - "sha256:7610b8c31688f0b1be0ef882889817939490a36d0ee880ea562a4e1399c447a1", - "sha256:76fa7b1362d19f8fbd3e75fe2fb7c79359b0af8747e6f7141c338f0bee2f871a", - "sha256:7728e05c35412ba36d3e9795ae8995e3c86958179c9770e65558ec3fdfd3724f", - "sha256:8157dadbb09a34a6bd95a50690595e1fa0af1a99445e2744110e3dca7831c4ee", - "sha256:820628b7b3135403540202e60551e741f9b6d3304371712521be939470b454ec", - "sha256:884ab9b29feaca361f7f88d811b1eea9bfca36cf3da27768d28ad45c3ee6f969", - "sha256:89b8b22a5ff72d89d48d0e62abb14340d9e99fd637d046c27b8b257a01ffbe28", - "sha256:92e821e43ad382332eade6812e298dc9701c75fe289f2a2d39c7960b43d1e92a", - "sha256:b007cbb845b28db4fb8b6a5cdcbf65bacb16a8bd328b53cbc0698688a68e1caa", - "sha256:bc4313cbeb0e7a416a488d72f9680fffffc645f8a838bd2193809881c67dd106", - "sha256:bccbfc27563652de7dc9bdc595cb25e90b59c5f8e23e806ed0fd623755b6565d", - "sha256:c47ff7e0a36d4efac9fd692cfa33fbd0636674c102e9e8d9b26e1b93a94e7617", - "sha256:c4f05c5a7c49d2fb70223d0d5bcfbe474cf928310ac9fa6a7c6dddc831d0b1d4", - "sha256:cdaf11d2bd275bf391b5308f86731e5194a21af45fbaaaf1d9e8147b9160ea92", - "sha256:ce256aaa50f6cc9a649c51be3cd4ff142d67295bfc4f490c9134d0f9f6d58ef0", - "sha256:d2e35d7bf1c1ac8c538f88d26b396e73dd81440d59c1ef8522e1ea77b345ede4", - "sha256:d916d31fd85b2f78c76400d625076d9124de3e4bda8b016d25a050cc7d603f24", - "sha256:df7c53783a46febb0e70f6b05df2ba104610f2fb0d27023409734a3ecbb78fb2", - "sha256:e1cbd3f19a61e27e011e02f9600837b921ac661f0c40560eefb366e4e4fb275e", - "sha256:efac139c3f0bf4f0939f9375af4b02c5ad83a622de52d6dfa8e438e8e01d0eb0", - "sha256:efd7a09678fd8b53117f6bae4fa3825e0a22b03ef0a932e070c0bdbb3a35e654", - "sha256:f2380a6376dfa090227b663f9678150ef27543483055cc327555fb592c5967e2", - "sha256:f8380c03e45cf09f8557bdaa41e1fa7c81f3ae22828e1db470ab2a6c96d8bc23", - "sha256:f90ba11136bfdd25cae3951af8da2e95121c9b9b93727b1b896e3fa105b2f586" - ], - "index": "pypi", - "version": "==4.6.3" - }, - "mako": { - "hashes": [ - "sha256:17831f0b7087c313c0ffae2bcbbd3c1d5ba9eeac9c38f2eb7b50e8c99fe9d5ab", - "sha256:aea166356da44b9b830c8023cd9b557fa856bd8b4035d6de771ca027dfc5cc6e" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.1.4" - }, - "markdown": { - "hashes": [ - "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49", - "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c" - ], - "index": "pypi", - "version": "==3.3.4" - }, - "markupsafe": { - "hashes": [ - "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", - "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", - "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", - "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", - "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", - "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", - "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", - "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", - "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", - "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", - "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", - "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", - "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", - "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", - "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", - "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", - "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", - "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", - "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", - "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", - "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", - "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", - "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", - "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", - "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", - "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", - "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", - "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", - "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", - "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", - "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", - "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", - "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", - "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" - }, - "marshmallow": { - "hashes": [ - "sha256:8050475b70470cc58f4441ee92375db611792ba39ca1ad41d39cad193ea9e040", - "sha256:b45cde981d1835145257b4a3c5cb7b80786dcf5f50dd2990749a50c16cb48e01" - ], - "index": "pypi", - "version": "==3.12.1" - }, - "marshmallow-enum": { - "hashes": [ - "sha256:38e697e11f45a8e64b4a1e664000897c659b60aa57bfa18d44e226a9920b6e58", - "sha256:57161ab3dbfde4f57adeb12090f39592e992b9c86d206d02f6bd03ebec60f072" - ], - "index": "pypi", - "version": "==1.5.1" - }, - "marshmallow-sqlalchemy": { - "hashes": [ - "sha256:ba7493eeb8669a3bf00d8f906b657feaa87a740ae9e4ecf829cfd6ddf763d276", - "sha256:d8525f74de51554b5c8491effe036f60629a426229befa33ff614c8569a16a73" - ], - "index": "pypi", - "version": "==0.26.1" - }, - "numpy": { - "hashes": [ - "sha256:1a784e8ff7ea2a32e393cc53eb0003eca1597c7ca628227e34ce34eb11645a0e", - "sha256:2ba579dde0563f47021dcd652253103d6fd66165b18011dce1a0609215b2791e", - "sha256:3537b967b350ad17633b35c2f4b1a1bbd258c018910b518c30b48c8e41272717", - "sha256:3c40e6b860220ed862e8097b8f81c9af6d7405b723f4a7af24a267b46f90e461", - "sha256:598fe100b2948465cf3ed64b1a326424b5e4be2670552066e17dfaa67246011d", - "sha256:620732f42259eb2c4642761bd324462a01cdd13dd111740ce3d344992dd8492f", - "sha256:709884863def34d72b183d074d8ba5cfe042bc3ff8898f1ffad0209161caaa99", - "sha256:75579acbadbf74e3afd1153da6177f846212ea2a0cc77de53523ae02c9256513", - "sha256:7c55407f739f0bfcec67d0df49103f9333edc870061358ac8a8c9e37ea02fcd2", - "sha256:a1f2fb2da242568af0271455b89aee0f71e4e032086ee2b4c5098945d0e11cf6", - "sha256:a290989cd671cd0605e9c91a70e6df660f73ae87484218e8285c6522d29f6e38", - "sha256:ac4fd578322842dbda8d968e3962e9f22e862b6ec6e3378e7415625915e2da4d", - "sha256:ad09f55cc95ed8d80d8ab2052f78cc21cb231764de73e229140d81ff49d8145e", - "sha256:b9205711e5440954f861ceeea8f1b415d7dd15214add2e878b4d1cf2bcb1a914", - "sha256:bba474a87496d96e61461f7306fba2ebba127bed7836212c360f144d1e72ac54", - "sha256:bebab3eaf0641bba26039fb0b2c5bf9b99407924b53b1ea86e03c32c64ef5aef", - "sha256:cc367c86eb87e5b7c9592935620f22d13b090c609f1b27e49600cd033b529f54", - "sha256:ccc6c650f8700ce1e3a77668bb7c43e45c20ac06ae00d22bdf6760b38958c883", - "sha256:cf680682ad0a3bef56dae200dbcbac2d57294a73e5b0f9864955e7dd7c2c2491", - "sha256:d2910d0a075caed95de1a605df00ee03b599de5419d0b95d55342e9a33ad1fb3", - "sha256:d5caa946a9f55511e76446e170bdad1d12d6b54e17a2afe7b189112ed4412bb8", - "sha256:d89b0dc7f005090e32bb4f9bf796e1dcca6b52243caf1803fdd2b748d8561f63", - "sha256:d95d16204cd51ff1a1c8d5f9958ce90ae190be81d348b514f9be39f878b8044a", - "sha256:e4d5a86a5257843a18fb1220c5f1c199532bc5d24e849ed4b0289fb59fbd4d8f", - "sha256:e58ddb53a7b4959932f5582ac455ff90dcb05fac3f8dcc8079498d43afbbde6c", - "sha256:e80fe25cba41c124d04c662f33f6364909b985f2eb5998aaa5ae4b9587242cce", - "sha256:eda2829af498946c59d8585a9fd74da3f810866e05f8df03a86f70079c7531dd", - "sha256:fd0a359c1c17f00cb37de2969984a74320970e0ceef4808c32e00773b06649d9" - ], - "version": "==1.21.0" - }, - "openapi-schema-validator": { - "hashes": [ - "sha256:215b516d0942f4e8e2446cf3f7d4ff2ed71d102ebddcc30526d8a3f706ab1df6", - "sha256:a4b2712020284cee880b4c55faa513fbc2f8f07f365deda6098f8ab943c9f0df", - "sha256:b65d6c2242620bfe76d4c749b61cd9657e4528895a8f4fb6f916085b508ebd24" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.1.5" - }, - "openapi-spec-validator": { - "hashes": [ - "sha256:0a7da925bad4576f4518f77302c0b1990adb2fbcbe7d63fb4ed0de894cad8bdd", - "sha256:3d70e6592754799f7e77a45b98c6a91706bdd309a425169d17d8e92173e198a2", - "sha256:ba28b06e63274f2bc6de995a07fb572c657e534425b5baf68d9f7911efe6929f" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.3.1" - }, - "openpyxl": { - "hashes": [ - "sha256:46af4eaf201a89b610fcca177eed957635f88770a5462fb6aae4a2a52b0ff516", - "sha256:6456a3b472e1ef0facb1129f3c6ef00713cebf62e736cd7a75bcc3247432f251" - ], - "index": "pypi", - "version": "==3.0.7" - }, - "packaging": { - "hashes": [ - "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", - "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.9" - }, - "pandas": { - "hashes": [ - "sha256:0c34b89215f984a9e4956446e0a29330d720085efa08ea72022387ee37d8b373", - "sha256:0dbd125b0e44e5068163cbc9080a00db1756a5e36309329ae14fd259747f2300", - "sha256:1102d719038e134e648e7920672188a00375f3908f0383fd3b202fbb9d2c3a95", - "sha256:14abb8ea73fce8aebbb1fb44bec809163f1c55241bcc1db91c2c780e97265033", - "sha256:25fc8ef6c6beb51c9224284a1ad89dfb591832f23ceff78845f182de35c52356", - "sha256:38e7486410de23069392bdf1dc7297ae75d2d67531750753f3149c871cd1c6e3", - "sha256:4bfbf62b00460f78a8bc4407112965c5ab44324f34551e8e1f4cac271a07706c", - "sha256:78de96c1174bcfdbe8dece9c38c2d7994e407fd8bb62146bb46c61294bcc06ef", - "sha256:7b09293c7119ab22ab3f7f086f813ac2acbfa3bcaaaeb650f4cddfb5b9fa9be4", - "sha256:821d92466fcd2826656374a9b6fe4f2ec2ba5e370cce71d5a990577929d948df", - "sha256:9244fb0904512b074d8c6362fb13aac1da6c4db94372760ddb2565c620240264", - "sha256:94ca6ea3f46f44a979a38a4d5a70a88cee734f7248d7aeeed202e6b3ba485af1", - "sha256:a67227e17236442c6bc31c02cb713b5277b26eee204eac14b5aecba52492e3a3", - "sha256:c862cd72353921c102166784fc4db749f1c3b691dd017fc36d9df2c67a9afe4e", - "sha256:d9e6edddeac9a8e473391d2d2067bb3c9dc7ad79fd137af26a39ee425c2b4c78", - "sha256:e36515163829e0e95a6af10820f178dd8768102482c01872bff8ae592e508e58", - "sha256:f20e4b8a7909f5a0c0a9e745091e3ea18b45af9f73496a4d498688badbdac7ea", - "sha256:fc9215dd1dd836ff26b896654e66b2dfcf4bbb18aa4c1089a79bab527b665a90" - ], - "index": "pypi", - "version": "==1.2.5" - }, - "psycopg2-binary": { - "hashes": [ - "sha256:0b7dae87f0b729922e06f85f667de7bf16455d411971b2043bbd9577af9d1975", - "sha256:0f2e04bd2a2ab54fa44ee67fe2d002bb90cee1c0f1cc0ebc3148af7b02034cbd", - "sha256:123c3fb684e9abfc47218d3784c7b4c47c8587951ea4dd5bc38b6636ac57f616", - "sha256:1473c0215b0613dd938db54a653f68251a45a78b05f6fc21af4326f40e8360a2", - "sha256:14db1752acdd2187d99cb2ca0a1a6dfe57fc65c3281e0f20e597aac8d2a5bd90", - "sha256:1e3a362790edc0a365385b1ac4cc0acc429a0c0d662d829a50b6ce743ae61b5a", - "sha256:1e85b74cbbb3056e3656f1cc4781294df03383127a8114cbc6531e8b8367bf1e", - "sha256:20f1ab44d8c352074e2d7ca67dc00843067788791be373e67a0911998787ce7d", - "sha256:2f62c207d1740b0bde5c4e949f857b044818f734a3d57f1d0d0edc65050532ed", - "sha256:3242b9619de955ab44581a03a64bdd7d5e470cc4183e8fcadd85ab9d3756ce7a", - "sha256:35c4310f8febe41f442d3c65066ca93cccefd75013df3d8c736c5b93ec288140", - "sha256:4235f9d5ddcab0b8dbd723dca56ea2922b485ea00e1dafacf33b0c7e840b3d32", - "sha256:5ced67f1e34e1a450cdb48eb53ca73b60aa0af21c46b9b35ac3e581cf9f00e31", - "sha256:7360647ea04db2e7dff1648d1da825c8cf68dc5fbd80b8fb5b3ee9f068dcd21a", - "sha256:8c13d72ed6af7fd2c8acbd95661cf9477f94e381fce0792c04981a8283b52917", - "sha256:988b47ac70d204aed01589ed342303da7c4d84b56c2f4c4b8b00deda123372bf", - "sha256:995fc41ebda5a7a663a254a1dcac52638c3e847f48307b5416ee373da15075d7", - "sha256:a36c7eb6152ba5467fb264d73844877be8b0847874d4822b7cf2d3c0cb8cdcb0", - "sha256:aed4a9a7e3221b3e252c39d0bf794c438dc5453bc2963e8befe9d4cd324dff72", - "sha256:aef9aee84ec78af51107181d02fe8773b100b01c5dfde351184ad9223eab3698", - "sha256:b0221ca5a9837e040ebf61f48899926b5783668b7807419e4adae8175a31f773", - "sha256:b4d7679a08fea64573c969f6994a2631908bb2c0e69a7235648642f3d2e39a68", - "sha256:c250a7ec489b652c892e4f0a5d122cc14c3780f9f643e1a326754aedf82d9a76", - "sha256:ca86db5b561b894f9e5f115d6a159fff2a2570a652e07889d8a383b5fae66eb4", - "sha256:cfc523edecddaef56f6740d7de1ce24a2fdf94fd5e704091856a201872e37f9f", - "sha256:da113b70f6ec40e7d81b43d1b139b9db6a05727ab8be1ee559f3a69854a69d34", - "sha256:f6fac64a38f6768e7bc7b035b9e10d8a538a9fadce06b983fb3e6fa55ac5f5ce", - "sha256:f8559617b1fcf59a9aedba2c9838b5b6aa211ffedecabca412b92a1ff75aac1a", - "sha256:fbb42a541b1093385a2d8c7eec94d26d30437d0e77c1d25dae1dcc46741a385e" - ], - "index": "pypi", - "version": "==2.9.1" - }, - "pyasn1": { - "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" - ], - "version": "==0.4.8" - }, - "pycparser": { - "hashes": [ - "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", - "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.20" - }, - "pygithub": { - "hashes": [ - "sha256:1bbfff9372047ff3f21d5cd8e07720f3dbfdaf6462fcaed9d815f528f1ba7283", - "sha256:2caf0054ea079b71e539741ae56c5a95e073b81fa472ce222e81667381b9601b" - ], - "index": "pypi", - "version": "==1.55" - }, - "pygments": { - "hashes": [ - "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f", - "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e" - ], - "markers": "python_version >= '3.5'", - "version": "==2.9.0" - }, - "pyjwt": { - "hashes": [ - "sha256:934d73fbba91b0483d3857d1aff50e96b2a892384ee2c17417ed3203f173fca1", - "sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130" - ], - "index": "pypi", - "version": "==2.1.0" - }, - "pynacl": { - "hashes": [ - "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4", - "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4", - "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574", - "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d", - "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634", - "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25", - "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f", - "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505", - "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122", - "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7", - "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420", - "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f", - "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96", - "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6", - "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6", - "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514", - "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff", - "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.4.0" - }, - "pyparsing": { - "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.4.7" - }, - "pyrsistent": { - "hashes": [ - "sha256:097b96f129dd36a8c9e33594e7ebb151b1515eb52cceb08474c10a5479e799f2", - "sha256:2aaf19dc8ce517a8653746d98e962ef480ff34b6bc563fc067be6401ffb457c7", - "sha256:404e1f1d254d314d55adb8d87f4f465c8693d6f902f67eb6ef5b4526dc58e6ea", - "sha256:48578680353f41dca1ca3dc48629fb77dfc745128b56fc01096b2530c13fd426", - "sha256:4916c10896721e472ee12c95cdc2891ce5890898d2f9907b1b4ae0f53588b710", - "sha256:527be2bfa8dc80f6f8ddd65242ba476a6c4fb4e3aedbf281dfbac1b1ed4165b1", - "sha256:58a70d93fb79dc585b21f9d72487b929a6fe58da0754fa4cb9f279bb92369396", - "sha256:5e4395bbf841693eaebaa5bb5c8f5cdbb1d139e07c975c682ec4e4f8126e03d2", - "sha256:6b5eed00e597b5b5773b4ca30bd48a5774ef1e96f2a45d105db5b4ebb4bca680", - "sha256:73ff61b1411e3fb0ba144b8f08d6749749775fe89688093e1efef9839d2dcc35", - "sha256:772e94c2c6864f2cd2ffbe58bb3bdefbe2a32afa0acb1a77e472aac831f83427", - "sha256:773c781216f8c2900b42a7b638d5b517bb134ae1acbebe4d1e8f1f41ea60eb4b", - "sha256:a0c772d791c38bbc77be659af29bb14c38ced151433592e326361610250c605b", - "sha256:b29b869cf58412ca5738d23691e96d8aff535e17390128a1a52717c9a109da4f", - "sha256:c1a9ff320fa699337e05edcaae79ef8c2880b52720bc031b219e5b5008ebbdef", - "sha256:cd3caef37a415fd0dae6148a1b6957a8c5f275a62cca02e18474608cb263640c", - "sha256:d5ec194c9c573aafaceebf05fc400656722793dac57f254cd4741f3c27ae57b4", - "sha256:da6e5e818d18459fa46fac0a4a4e543507fe1110e808101277c5a2b5bab0cd2d", - "sha256:e79d94ca58fcafef6395f6352383fa1a76922268fa02caa2272fff501c2fdc78", - "sha256:f3ef98d7b76da5eb19c37fda834d50262ff9167c65658d1d8f974d2e4d90676b", - "sha256:f4c8cabb46ff8e5d61f56a037974228e978f26bfefce4f61a4b1ac0ba7a2ab72" - ], - "version": "==0.18.0" - }, - "python-dateutil": { - "hashes": [ - "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", - "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" - ], - "index": "pypi", - "version": "==2.8.1" - }, - "python-docx": { - "hashes": [ - "sha256:1105d233a0956dd8dd1e710d20b159e2d72ac3c301041b95f4d4ceb3e0ebebc4" - ], - "version": "==0.8.11" - }, - "python-editor": { - "hashes": [ - "sha256:1bf6e860a8ad52a14c3ee1252d5dc25b2030618ed80c022598f00176adc8367d", - "sha256:51fda6bcc5ddbbb7063b2af7509e43bd84bfc32a4ff71349ec7847713882327b", - "sha256:5f98b069316ea1c2ed3f67e7f5df6c0d8f10b689964a4a811ff64f0106819ec8", - "sha256:c3da2053dbab6b29c94e43c486ff67206eafbe7eb52dbec7390b5e2fb05aac77", - "sha256:ea87e17f6ec459e780e4221f295411462e0d0810858e055fc514684350a2f522" - ], - "version": "==1.0.4" - }, - "python-levenshtein": { - "hashes": [ - "sha256:dc2395fbd148a1ab31090dd113c366695934b9e85fe5a4b2a032745efd0346f6" - ], - "index": "pypi", - "version": "==0.12.2" - }, - "pytz": { - "hashes": [ - "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", - "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798" - ], - "version": "==2021.1" - }, - "pyyaml": { - "hashes": [ - "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", - "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", - "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", - "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", - "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", - "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", - "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", - "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", - "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", - "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", - "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", - "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", - "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", - "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", - "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", - "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", - "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", - "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", - "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", - "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", - "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", - "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", - "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", - "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", - "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", - "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", - "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", - "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==5.4.1" - }, - "recommonmark": { - "hashes": [ - "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f", - "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67" - ], - "index": "pypi", - "version": "==0.7.1" - }, - "requests": { - "hashes": [ - "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", - "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" - ], - "index": "pypi", - "version": "==2.25.1" - }, - "sentry-sdk": { - "extras": [ - "flask" - ], - "hashes": [ - "sha256:0e5e947d0f7a969314aa23669a94a9712be5a688ff069ff7b9fc36c66adc160c", - "sha256:799a8bf76b012e3030a881be00e97bc0b922ce35dde699c6537122b751d80e2c" - ], - "index": "pypi", - "version": "==0.14.4" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "snowballstemmer": { - "hashes": [ - "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2", - "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914" - ], - "version": "==2.1.0" - }, - "soupsieve": { - "hashes": [ - "sha256:052774848f448cf19c7e959adf5566904d525f33a3f8b6ba6f6f8f26ec7de0cc", - "sha256:c2c1c2d44f158cdbddab7824a9af8c4f83c76b1e23e049479aa432feb6c4c23b" - ], - "markers": "python_version >= '3'", - "version": "==2.2.1" - }, - "sphinx": { - "hashes": [ - "sha256:b5c2ae4120bf00c799ba9b3699bc895816d272d120080fbc967292f29b52b48c", - "sha256:d1cb10bee9c4231f1700ec2e24a91be3f3a3aba066ea4ca9f3bbe47e59d5a1d4" - ], - "index": "pypi", - "version": "==4.0.2" - }, - "sphinxcontrib-applehelp": { - "hashes": [ - "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a", - "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.2" - }, - "sphinxcontrib-devhelp": { - "hashes": [ - "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e", - "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.2" - }, - "sphinxcontrib-htmlhelp": { - "hashes": [ - "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07", - "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.0" - }, - "sphinxcontrib-jsmath": { - "hashes": [ - "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", - "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.1" - }, - "sphinxcontrib-qthelp": { - "hashes": [ - "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72", - "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.3" - }, - "sphinxcontrib-serializinghtml": { - "hashes": [ - "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd", - "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952" - ], - "markers": "python_version >= '3.5'", - "version": "==1.1.5" - }, - "spiffworkflow": { - "git": "https://github.com/sartography/SpiffWorkflow.git", - "ref": "109c237423e4e2645b4605b1166075546f22d272" - }, - "sqlalchemy": { - "hashes": [ - "sha256:0f6d467b67a7e5048f1408e8ea60d6caa70be5b386d0eebbf1185ab49cb8c7e4", - "sha256:238d78b3110b7f7cffdb70bf9cda686e0d876a849bc78ba4d471aa7b1461f306", - "sha256:25c0e0f3a7e8c19350086b3c0fe93c4def045cec053d749ef15da710c4d54c81", - "sha256:2f60a2e599cf5cf5e5327ce60f2918b897e42ad9f405d10dd01e37869c0ce6fc", - "sha256:38ee3a266afef2978e82824650457f70c5d74ec0cadec1b10fe5ed6f038eb5d0", - "sha256:46361690f1e1c5385994a4caeb6e8126063ff593a5c635700bbc1245de793c1e", - "sha256:46b99eab618cdc1c871ea707b7c52edc23cfea6c750740cd242ba62b5c84de7f", - "sha256:4a67371752fd86d1d03a3b82d4e75404608f6f4d579b9676124079a22a40c79f", - "sha256:525dd3c2205b11a2bc6d770bf1ec63bde0253fd754b4c19c399d27ddc9dad0d3", - "sha256:6c8406c3d8c1c7d15da454de15d77f7bb48d14ede5db994f74226c348cf1050e", - "sha256:6da83225a23eaf7b3f48f3d5f53c91b2cf00fbfa48b24a7a758160112dd3e123", - "sha256:7150e5b543b466f45f668b352f7abda27998cc8035f051d1b7e9524ca9eb2f5f", - "sha256:76fbc24311a3d039d6cd147d396719f606d96d1413f3816c028a48e29367f646", - "sha256:854a7b15750e617e16f8d65dbc004f065a7963544b253b923f16109557648777", - "sha256:86c079732328f1add097b0b8079cd532b5d28e207fac93e9d6ea5f487506deef", - "sha256:8d860c62e3f51623ccd528d8fac44580501df557d4b467cc5581587fcf057719", - "sha256:9675d5bc7e4f96a7bb2b54d14e9b269a5fb6e5d36ecc7d01f0f65bb9af3185f9", - "sha256:9841762d114018c49483c089fa2d47f7e612e57666323f615913d7d7f46e9606", - "sha256:9eb25bcf9161e2fcbe9eebe8e829719b2334e849183f0e496bf4b83722bcccfa", - "sha256:aad3234a41340e9cf6184e621694e2a7233ba3f8aef9b1e6de8cba431b45ebd2", - "sha256:b502b5e2f08500cc4b8d29bfc4f51d805adcbc00f8d149e98fda8aae85ddb644", - "sha256:b86d83fefc8a8c394f3490c37e1953bc16c311a3d1d1cf91518793bfb9847fb4", - "sha256:c0eb2cd3ad4967fcbdd9e066e8cd91fe2c23c671dbae9952f0b4d3d42832cc5f", - "sha256:e0d48456e1aa4f0537f9c9af7be71e1f0659ff68bc1cd538ebc785f6b007bd0d", - "sha256:eaee5dd378f6f0d7c3ec49aeeb26564d55ac0ad73b9b4688bf29e66deabddf73", - "sha256:f14acb0fd16d404fda9370f93aace682f284340c89c3442ac747c5466ac7e2b5", - "sha256:f6fc526bd70898489d02bf52c8f0632ab377592ae954d0c0a5bb38d618dddaa9", - "sha256:fcd84e4d46a86291495d131a7824ba38d2e8278bda9425c50661a04633174319", - "sha256:ff38ecf89c69a531a7326c2dae71982edfe2f805f3c016cdc5bfd1a04ebf80cb", - "sha256:ff8bebc7a9d297dff2003460e01db2c20c63818b45fb19170f388b1a72fe5a14" - ], - "version": "==1.4.20" - }, - "swagger-ui-bundle": { - "hashes": [ - "sha256:f5255f786cde67a2638111f4a7d04355836743198a83c4ecbe815d9fc384b0c8", - "sha256:f5691167f2e9f73ecbe8229a89454ae5ea958f90bb0d4583ed7adaae598c4122" - ], - "index": "pypi", - "version": "==0.0.8" - }, - "tzlocal": { - "hashes": [ - "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44", - "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4" - ], - "version": "==2.1" - }, - "urllib3": { - "hashes": [ - "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4", - "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f" - ], - "version": "==1.26.6" - }, - "waitress": { - "hashes": [ - "sha256:29af5a53e9fb4e158f525367678b50053808ca6c21ba585754c77d790008c746", - "sha256:69e1f242c7f80273490d3403c3976f3ac3b26e289856936d1f620ed48f321897" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.0" - }, - "wcwidth": { - "hashes": [ - "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", - "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" - ], - "version": "==0.2.5" - }, - "webob": { - "hashes": [ - "sha256:73aae30359291c14fa3b956f8b5ca31960e420c28c1bec002547fb04928cf89b", - "sha256:b64ef5141be559cfade448f044fa45c2260351edcb6a8ef6b7e00c7dcef0c323" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.8.7" - }, - "webtest": { - "hashes": [ - "sha256:44ddfe99b5eca4cf07675e7222c81dd624d22f9a26035d2b93dc8862dc1153c6", - "sha256:aac168b5b2b4f200af4e35867cf316712210e3d5db81c1cbdff38722647bb087" - ], - "index": "pypi", - "version": "==2.0.35" - }, - "werkzeug": { - "hashes": [ - "sha256:1de1db30d010ff1af14a009224ec49ab2329ad2cde454c8a708130642d579c42", - "sha256:6c1ec500dcdba0baa27600f6a22f6333d8b662d22027ff9f6202e3367413caa8" - ], - "index": "pypi", - "version": "==2.0.1" - }, - "wrapt": { - "hashes": [ - "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" - ], - "version": "==1.12.1" - }, - "wtforms": { - "hashes": [ - "sha256:7b504fc724d0d1d4d5d5c114e778ec88c37ea53144683e084215eed5155ada4c", - "sha256:81195de0ac94fbc8368abbaf9197b88c4f3ffd6c2719b5bf5fc9da744f3d829c" - ], - "version": "==2.3.3" - }, - "xlrd": { - "hashes": [ - "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd", - "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88" - ], - "index": "pypi", - "version": "==2.0.1" - }, - "xlsxwriter": { - "hashes": [ - "sha256:1a7fac99687020e76aa7dd0d7de4b9b576547ed748e5cd91a99d52a6df54ca16", - "sha256:641db6e7b4f4982fd407a3f372f45b878766098250d26963e95e50121168cbe2" - ], - "index": "pypi", - "version": "==1.4.3" - } - }, - "develop": { - "attrs": { - "hashes": [ - "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", - "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.2.0" - }, - "coverage": { - "hashes": [ - "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c", - "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6", - "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45", - "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a", - "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03", - "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529", - "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a", - "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a", - "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2", - "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6", - "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759", - "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53", - "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a", - "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4", - "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff", - "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502", - "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793", - "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb", - "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905", - "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821", - "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b", - "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81", - "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0", - "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b", - "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3", - "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184", - "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701", - "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a", - "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82", - "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638", - "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5", - "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083", - "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6", - "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90", - "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465", - "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a", - "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3", - "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e", - "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066", - "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf", - "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b", - "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae", - "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669", - "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873", - "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b", - "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6", - "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb", - "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160", - "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c", - "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079", - "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d", - "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6" - ], - "index": "pypi", - "version": "==5.5" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "packaging": { - "hashes": [ - "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", - "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.9" - }, - "pbr": { - "hashes": [ - "sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd", - "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4" - ], - "index": "pypi", - "version": "==5.6.0" - }, - "pluggy": { - "hashes": [ - "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", - "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.13.1" - }, - "py": { - "hashes": [ - "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3", - "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.10.0" - }, - "pyparsing": { - "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.4.7" - }, - "pytest": { - "hashes": [ - "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b", - "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890" - ], - "index": "pypi", - "version": "==6.2.4" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - } - } -} diff --git a/crc/api.yml b/crc/api.yml index 21d5074c..ca9bd51e 100644 --- a/crc/api.yml +++ b/crc/api.yml @@ -426,6 +426,70 @@ paths: application/json: schema: $ref: "#/components/schemas/WorkflowSpec" + + /workflow-specification/{spec_id}/libraries: + parameters: + - name: spec_id + in: path + required: true + description: The unique id of an existing workflow specification. + schema: + type: string + get: + operationId: crc.api.workflow.get_workflow_specification_libraries + summary: Returns all libraries that are enabled for a workflow spec + tags: + - Workflow Specifications + responses: + '200': + description: Workflow specification. + content: + application/json: + schema: + $ref: "#/components/schemas/WorkflowSpec" + + /workflow-specification/{spec_id}/library/{library_id}: + parameters: + - name: spec_id + in: path + required: true + description: The unique id of an existing workflow specification. + schema: + type: string + - name: library_id + in: path + required: true + description: The unique id of an existing library specification. + schema: + type: string + + + post: + operationId: crc.api.workflow.add_workflow_spec_library + summary: Adds a library to a workflow spec + tags: + - Workflow Specifications + responses: + '200': + description: Workflow specification. + content: + application/json: + schema: + $ref: "#/components/schemas/WorkflowSpec" + delete: + operationId: crc.api.workflow.drop_workflow_spec_library + summary: Delete a library from a workflow + tags: + - Workflow Specifications + responses: + '200': + description: Workflow specification. + content: + application/json: + schema: + $ref: "#/components/schemas/WorkflowSpec" + + /workflow-specification/{spec_id}: parameters: - name: spec_id @@ -502,6 +566,21 @@ paths: type: array items: $ref: "#/components/schemas/WorkflowSpec" + /workflow-specification/libraries: + get: + operationId: crc.api.workflow.library_workflow_specs + summary: Provides a list of workflow specifications that are considered libraries. + tags: + - Workflow Specifications + responses: + '200': + description: A list of workflow specifications + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/WorkflowSpec" /workflow-specification/{spec_id}/validate: parameters: - name: spec_id diff --git a/crc/api/workflow.py b/crc/api/workflow.py index 3ad94044..dc5e18cb 100644 --- a/crc/api/workflow.py +++ b/crc/api/workflow.py @@ -10,7 +10,7 @@ from crc.models.study import StudyModel, WorkflowMetadata, StudyStatus from crc.models.task_event import TaskEventModel, TaskEvent, TaskEventSchema from crc.models.user import UserModelSchema from crc.models.workflow import WorkflowModel, WorkflowSpecModelSchema, WorkflowSpecModel, WorkflowSpecCategoryModel, \ - WorkflowSpecCategoryModelSchema + WorkflowSpecCategoryModelSchema, WorkflowLibraryModel, WorkflowLibraryModelSchema from crc.services.error_service import ValidationErrorService from crc.services.file_service import FileService from crc.services.lookup_service import LookupService @@ -22,7 +22,8 @@ from crc.services.workflow_service import WorkflowService def all_specifications(): schema = WorkflowSpecModelSchema(many=True) - return schema.dump(session.query(WorkflowSpecModel).all()) + return schema.dump(session.query(WorkflowSpecModel).filter((WorkflowSpecModel.library==False)|( + WorkflowSpecModel.library==None)).all()) def add_workflow_specification(body): @@ -45,6 +46,50 @@ def get_workflow_specification(spec_id): return WorkflowSpecModelSchema().dump(spec) +def get_workflow_specification_libraries(spec_id): + if spec_id is None: + raise ApiError('unknown_spec', 'Please provide a valid Workflow Specification ID.') + spec: WorkflowSpecModel = session.query(WorkflowSpecModel).filter_by(id=spec_id).first() + libraries: WorkflowLibraryModel = session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id).all() + if spec is None: + raise ApiError('unknown_spec', 'The Workflow Specification "' + spec_id + '" is not recognized.') + return WorkflowLibraryModelSchema(many=True).dump(libraries) + +def validate_spec_and_library(spec_id,library_id): + if spec_id is None: + raise ApiError('unknown_spec', 'Please provide a valid Workflow Specification ID.') + if library_id is None: + raise ApiError('unknown_spec', 'Please provide a valid Library Specification ID.') + spec: WorkflowSpecModel = session.query(WorkflowSpecModel).filter_by(id=spec_id).first() + library: WorkflowSpecModel = session.query(WorkflowSpecModel).filter_by(id=library_id).first() + if spec is None: + raise ApiError('unknown_spec', 'The Workflow Specification "' + spec_id + '" is not recognized.') + if library is None: + raise ApiError('unknown_spec', 'The Library Specification "' + library_id + '" is not recognized.') + if not library.library: + raise ApiError('unknown_spec', 'Linked workflow spec is not a library.') + + +def add_workflow_spec_library(spec_id,library_id): + validate_spec_and_library(spec_id, library_id) + libraries: WorkflowLibraryModel = session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id).all() + libraryids = [x.library_spec_id for x in libraries] + if library_id in libraryids: + raise ApiError('unknown_spec', 'The Library Specification "' + spec_id + '" is already attached.') + newlib = WorkflowLibraryModel() + newlib.workflow_spec_id = spec_id + newlib.library_spec_id = library_id + session.add(newlib) + session.commit() + libraries: WorkflowLibraryModel = session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id).all() + return WorkflowLibraryModelSchema(many=True).dump(libraries) + +def drop_workflow_spec_library(spec_id,library_id): + validate_spec_and_library(spec_id, library_id) + session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id,library_spec_id=library_id).delete() + session.commit() + libraries: WorkflowLibraryModel = session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id).all() + return WorkflowLibraryModelSchema(many=True).dump(libraries) def validate_workflow_specification(spec_id, validate_study_id=None, test_until=None): errors = {} @@ -118,6 +163,10 @@ def standalone_workflow_specs(): specs = WorkflowService.get_standalone_workflow_specs() return schema.dump(specs) +def library_workflow_specs(): + schema = WorkflowSpecModelSchema(many=True) + specs = WorkflowService.get_library_workflow_specs() + return schema.dump(specs) def get_workflow(workflow_id, do_engine_steps=True): """Retrieve workflow based on workflow_id, and return it in the last saved State. diff --git a/crc/api/workflow_sync.py b/crc/api/workflow_sync.py index 8ab6e703..e094fff9 100644 --- a/crc/api/workflow_sync.py +++ b/crc/api/workflow_sync.py @@ -159,7 +159,6 @@ def create_or_update_local_spec(remote,workflow_spec_id): localcategory.name = specdict['category']['name'] localcategory.display_name = specdict['category']['display_name'] localcategory.display_order = specdict['category']['display_order'] - localcategory.library = False session.add(localcategory) localspec.category = localcategory diff --git a/crc/models/workflow.py b/crc/models/workflow.py index f6604ce6..f9e9fd0f 100644 --- a/crc/models/workflow.py +++ b/crc/models/workflow.py @@ -1,7 +1,7 @@ import enum import marshmallow -from marshmallow import EXCLUDE +from marshmallow import EXCLUDE,fields from marshmallow_sqlalchemy import SQLAlchemyAutoSchema from sqlalchemy import func @@ -15,7 +15,6 @@ class WorkflowSpecCategoryModel(db.Model): name = db.Column(db.String) display_name = db.Column(db.String) display_order = db.Column(db.Integer) - library = db.Column(db.Boolean) class WorkflowSpecCategoryModelSchema(SQLAlchemyAutoSchema): @@ -25,6 +24,7 @@ class WorkflowSpecCategoryModelSchema(SQLAlchemyAutoSchema): include_relationships = True + class WorkflowSpecModel(db.Model): __tablename__ = 'workflow_spec' id = db.Column(db.String, primary_key=True) @@ -36,6 +36,19 @@ class WorkflowSpecModel(db.Model): category = db.relationship("WorkflowSpecCategoryModel") is_master_spec = db.Column(db.Boolean, default=False) standalone = db.Column(db.Boolean, default=False) + library = db.Column(db.Boolean, default=False) + + +class WorkflowLibraryModel(db.Model): + __tablename__ = 'workflow_library' + id = db.Column(db.Integer, primary_key=True) + workflow_spec_id = db.Column(db.String, db.ForeignKey('workflow_spec.id'), nullable=True) + library_spec_id = db.Column(db.String, db.ForeignKey('workflow_spec.id'), nullable=True) + workflow_side = db.relationship(WorkflowSpecModel, + primaryjoin=workflow_spec_id==WorkflowSpecModel.id, + backref='libraries') + library = db.relationship(WorkflowSpecModel,primaryjoin=library_spec_id==WorkflowSpecModel.id, + backref='referred_by') class WorkflowSpecModelSchema(SQLAlchemyAutoSchema): @@ -47,7 +60,10 @@ class WorkflowSpecModelSchema(SQLAlchemyAutoSchema): unknown = EXCLUDE category = marshmallow.fields.Nested(WorkflowSpecCategoryModelSchema, dump_only=True) - + libraries = marshmallow.fields.Function(lambda obj: [{'id':x.library.id, + 'name':x.library.name, + 'display_name':x.library.display_name} for x in + obj.libraries] ) class WorkflowState(enum.Enum): hidden = "hidden" @@ -79,6 +95,15 @@ class WorkflowSpecDependencyFile(db.Model): file_data = db.relationship(FileDataModel) + +class WorkflowLibraryModelSchema(SQLAlchemyAutoSchema): + class Meta: + model = WorkflowLibraryModel + load_instance = True + include_relationships = True + + library = marshmallow.fields.Nested('WorkflowSpecModelSchema') + class WorkflowModel(db.Model): __tablename__ = 'workflow' id = db.Column(db.Integer, primary_key=True) diff --git a/crc/services/study_service.py b/crc/services/study_service.py index 922daa64..3aa12fed 100644 --- a/crc/services/study_service.py +++ b/crc/services/study_service.py @@ -242,8 +242,7 @@ class StudyService(object): def get_categories(): """Returns a list of category objects, in the correct order.""" cat_models = db.session.query(WorkflowSpecCategoryModel) \ - .order_by(WorkflowSpecCategoryModel.display_order) \ - .filter((WorkflowSpecCategoryModel.library == None)|(WorkflowSpecCategoryModel.library ==False)).all() + .order_by(WorkflowSpecCategoryModel.display_order).all() categories = [] for cat_model in cat_models: categories.append(Category(cat_model)) diff --git a/crc/services/workflow_service.py b/crc/services/workflow_service.py index 5694eaa0..2f6afdb7 100644 --- a/crc/services/workflow_service.py +++ b/crc/services/workflow_service.py @@ -886,6 +886,11 @@ class WorkflowService(object): specs = db.session.query(WorkflowSpecModel).filter_by(standalone=True).all() return specs + @staticmethod + def get_library_workflow_specs(): + specs = db.session.query(WorkflowSpecModel).filter_by(library=True).all() + return specs + @staticmethod def get_primary_workflow(workflow_spec_id): # Returns the FileModel of the primary workflow for a workflow_spec diff --git a/migrations/versions/a931e2b7b070_.py b/migrations/versions/a931e2b7b070_.py new file mode 100644 index 00000000..466ceec7 --- /dev/null +++ b/migrations/versions/a931e2b7b070_.py @@ -0,0 +1,35 @@ +"""empty message + +Revision ID: a931e2b7b070 +Revises: 47b10b171d7c +Create Date: 2021-07-12 08:46:08.814577 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'a931e2b7b070' +down_revision = 'bbf064082623' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('workflow_library', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('workflow_spec_id', sa.String(), nullable=True), + sa.Column('library_spec_id', sa.String(), nullable=True), + sa.ForeignKeyConstraint(['library_spec_id'], ['workflow_spec.id'], ), + sa.ForeignKeyConstraint(['workflow_spec_id'], ['workflow_spec.id'], ), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('workflow_library') + # ### end Alembic commands ### diff --git a/migrations/versions/b0f38c78db40_.py b/migrations/versions/b0f38c78db40_.py new file mode 100644 index 00000000..355d08d3 --- /dev/null +++ b/migrations/versions/b0f38c78db40_.py @@ -0,0 +1,28 @@ +"""empty message + +Revision ID: b0f38c78db40 +Revises: a931e2b7b070 +Create Date: 2021-07-14 09:30:42.562825 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'b0f38c78db40' +down_revision = 'a931e2b7b070' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('workflow_spec', sa.Column('library', sa.Boolean(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('workflow_spec', 'library') + # ### end Alembic commands ### From 48516e4009300a99eb4b804bb0441623f47c5fb5 Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Thu, 22 Jul 2021 10:23:05 -0400 Subject: [PATCH 04/11] Parent side working --- crc/models/workflow.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crc/models/workflow.py b/crc/models/workflow.py index f9e9fd0f..5b7f910b 100644 --- a/crc/models/workflow.py +++ b/crc/models/workflow.py @@ -44,11 +44,11 @@ class WorkflowLibraryModel(db.Model): id = db.Column(db.Integer, primary_key=True) workflow_spec_id = db.Column(db.String, db.ForeignKey('workflow_spec.id'), nullable=True) library_spec_id = db.Column(db.String, db.ForeignKey('workflow_spec.id'), nullable=True) - workflow_side = db.relationship(WorkflowSpecModel, + parent = db.relationship(WorkflowSpecModel, primaryjoin=workflow_spec_id==WorkflowSpecModel.id, backref='libraries') library = db.relationship(WorkflowSpecModel,primaryjoin=library_spec_id==WorkflowSpecModel.id, - backref='referred_by') + backref='parents') class WorkflowSpecModelSchema(SQLAlchemyAutoSchema): @@ -64,6 +64,10 @@ class WorkflowSpecModelSchema(SQLAlchemyAutoSchema): 'name':x.library.name, 'display_name':x.library.display_name} for x in obj.libraries] ) + parents = marshmallow.fields.Function(lambda obj: [{'id':x.parent.id, + 'name':x.parent.name, + 'display_name':x.parent.display_name} for x in + obj.parents] ) class WorkflowState(enum.Enum): hidden = "hidden" From b857fddbadc185a33c14d362d7fd73af0125df6b Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Mon, 26 Jul 2021 13:00:11 -0400 Subject: [PATCH 05/11] commit in intermediate changes to work on a bug --- crc/api.yml | 73 +++++++++++++++++++++++++----------------- crc/api/workflow.py | 34 +++++++++++++------- crc/models/workflow.py | 4 +-- 3 files changed, 68 insertions(+), 43 deletions(-) diff --git a/crc/api.yml b/crc/api.yml index ca9bd51e..b64c2278 100644 --- a/crc/api.yml +++ b/crc/api.yml @@ -400,6 +400,19 @@ paths: summary: Provides a list of workflows specifications that can be added to a study manually. Please note that Protocol Builder will handle this most of the time. tags: - Workflow Specifications + parameters : + - name : libraries + in : query + required : false + description : True if we should return just library schemas + schema : + type : boolean + - name : standalone + in : query + required : false + description : True if we should return just standalone schemas + schema : + type : boolean responses: '200': description: An array of workflow specifications @@ -551,36 +564,36 @@ paths: responses: '204': description: The workflow specification has been removed. - /workflow-specification/standalone: - get: - operationId: crc.api.workflow.standalone_workflow_specs - summary: Provides a list of workflow specifications that can be run outside a study. - tags: - - Workflow Specifications - responses: - '200': - description: A list of workflow specifications - content: - application/json: - schema: - type: array - items: - $ref: "#/components/schemas/WorkflowSpec" - /workflow-specification/libraries: - get: - operationId: crc.api.workflow.library_workflow_specs - summary: Provides a list of workflow specifications that are considered libraries. - tags: - - Workflow Specifications - responses: - '200': - description: A list of workflow specifications - content: - application/json: - schema: - type: array - items: - $ref: "#/components/schemas/WorkflowSpec" +# /workflow-specification/standalone: +# get: +# operationId: crc.api.workflow.standalone_workflow_specs +# summary: Provides a list of workflow specifications that can be run outside a study. +# tags: +# - Workflow Specifications +# responses: +# '200': +# description: A list of workflow specifications +# content: +# application/json: +# schema: +# type: array +# items: +# $ref: "#/components/schemas/WorkflowSpec" +# /workflow-specification/libraries: +# get: +# operationId: crc.api.workflow.library_workflow_specs +# summary: Provides a list of workflow specifications that are considered libraries. +# tags: +# - Workflow Specifications +# responses: +# '200': +# description: A list of workflow specifications +# content: +# application/json: +# schema: +# type: array +# items: +# $ref: "#/components/schemas/WorkflowSpec" /workflow-specification/{spec_id}/validate: parameters: - name: spec_id diff --git a/crc/api/workflow.py b/crc/api/workflow.py index dc5e18cb..2a01a34a 100644 --- a/crc/api/workflow.py +++ b/crc/api/workflow.py @@ -20,10 +20,22 @@ from crc.services.workflow_processor import WorkflowProcessor from crc.services.workflow_service import WorkflowService -def all_specifications(): +def all_specifications(libraries=False,standalone=False): + if libraries and standalone: + raise ApiError('inconceivable!', 'You should specify libraries or standalone, but not both') schema = WorkflowSpecModelSchema(many=True) - return schema.dump(session.query(WorkflowSpecModel).filter((WorkflowSpecModel.library==False)|( - WorkflowSpecModel.library==None)).all()) + if libraries: + return schema.dump(session.query(WorkflowSpecModel)\ + .filter(WorkflowSpecModel.library==True).all()) + + if standalone: + return schema.dump(session.query(WorkflowSpecModel)\ + .filter(WorkflowSpecModel.standalone==True).all()) + # this still returns standalone workflow specs as well, but by default + # we do not return specs marked as library + return schema.dump(session.query(WorkflowSpecModel)\ + .filter((WorkflowSpecModel.library==False)|( + WorkflowSpecModel.library==None)).all()) def add_workflow_specification(body): @@ -158,15 +170,15 @@ def get_workflow_from_spec(spec_id): return WorkflowApiSchema().dump(workflow_api_model) -def standalone_workflow_specs(): - schema = WorkflowSpecModelSchema(many=True) - specs = WorkflowService.get_standalone_workflow_specs() - return schema.dump(specs) +# def standalone_workflow_specs(): +# schema = WorkflowSpecModelSchema(many=True) +# specs = WorkflowService.get_standalone_workflow_specs() +# return schema.dump(specs) -def library_workflow_specs(): - schema = WorkflowSpecModelSchema(many=True) - specs = WorkflowService.get_library_workflow_specs() - return schema.dump(specs) +# def library_workflow_specs(): +# schema = WorkflowSpecModelSchema(many=True) +# specs = WorkflowService.get_library_workflow_specs() +# return schema.dump(specs) def get_workflow(workflow_id, do_engine_steps=True): """Retrieve workflow based on workflow_id, and return it in the last saved State. diff --git a/crc/models/workflow.py b/crc/models/workflow.py index 5b7f910b..8230069b 100644 --- a/crc/models/workflow.py +++ b/crc/models/workflow.py @@ -63,11 +63,11 @@ class WorkflowSpecModelSchema(SQLAlchemyAutoSchema): libraries = marshmallow.fields.Function(lambda obj: [{'id':x.library.id, 'name':x.library.name, 'display_name':x.library.display_name} for x in - obj.libraries] ) + obj.libraries] ) parents = marshmallow.fields.Function(lambda obj: [{'id':x.parent.id, 'name':x.parent.name, 'display_name':x.parent.display_name} for x in - obj.parents] ) + obj.parents] ) class WorkflowState(enum.Enum): hidden = "hidden" From d7c66fb055c7f9449e34570780c6f3ebe9c654c9 Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Thu, 29 Jul 2021 09:41:39 -0400 Subject: [PATCH 06/11] fix revisions --- migrations/versions/a931e2b7b070_.py | 2 +- migrations/versions/c16d3047abbe_.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/versions/a931e2b7b070_.py b/migrations/versions/a931e2b7b070_.py index 466ceec7..0de57fd0 100644 --- a/migrations/versions/a931e2b7b070_.py +++ b/migrations/versions/a931e2b7b070_.py @@ -11,7 +11,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. revision = 'a931e2b7b070' -down_revision = 'bbf064082623' +down_revision = 'c16d3047abbe' branch_labels = None depends_on = None diff --git a/migrations/versions/c16d3047abbe_.py b/migrations/versions/c16d3047abbe_.py index 4deb56b3..c7f37c79 100644 --- a/migrations/versions/c16d3047abbe_.py +++ b/migrations/versions/c16d3047abbe_.py @@ -11,7 +11,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. revision = 'c16d3047abbe' -down_revision = 'bbf064082623' +down_revision = '30e017a03948' branch_labels = None depends_on = None From 25319a0e6a31c565180995861cb29640b3495ed0 Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Mon, 2 Aug 2021 08:59:24 -0400 Subject: [PATCH 07/11] Make changes to alembic process - fix test for new API --- .../{a931e2b7b070_.py => 2a6f7ea00e5f_.py} | 12 ++++---- migrations/versions/b0f38c78db40_.py | 28 ------------------- tests/workflow/test_workflow_spec_api.py | 4 +-- 3 files changed, 9 insertions(+), 35 deletions(-) rename migrations/versions/{a931e2b7b070_.py => 2a6f7ea00e5f_.py} (74%) delete mode 100644 migrations/versions/b0f38c78db40_.py diff --git a/migrations/versions/a931e2b7b070_.py b/migrations/versions/2a6f7ea00e5f_.py similarity index 74% rename from migrations/versions/a931e2b7b070_.py rename to migrations/versions/2a6f7ea00e5f_.py index 0de57fd0..9c1e5174 100644 --- a/migrations/versions/a931e2b7b070_.py +++ b/migrations/versions/2a6f7ea00e5f_.py @@ -1,8 +1,8 @@ """empty message -Revision ID: a931e2b7b070 -Revises: 47b10b171d7c -Create Date: 2021-07-12 08:46:08.814577 +Revision ID: 2a6f7ea00e5f +Revises: dc30b8f6571c +Create Date: 2021-07-29 10:51:56.857341 """ from alembic import op @@ -10,8 +10,8 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = 'a931e2b7b070' -down_revision = 'c16d3047abbe' +revision = '2a6f7ea00e5f' +down_revision = 'dc30b8f6571c' branch_labels = None depends_on = None @@ -26,10 +26,12 @@ def upgrade(): sa.ForeignKeyConstraint(['workflow_spec_id'], ['workflow_spec.id'], ), sa.PrimaryKeyConstraint('id') ) + op.add_column('workflow_spec', sa.Column('library', sa.Boolean(), nullable=True)) # ### end Alembic commands ### def downgrade(): # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('workflow_spec', 'library') op.drop_table('workflow_library') # ### end Alembic commands ### diff --git a/migrations/versions/b0f38c78db40_.py b/migrations/versions/b0f38c78db40_.py deleted file mode 100644 index 355d08d3..00000000 --- a/migrations/versions/b0f38c78db40_.py +++ /dev/null @@ -1,28 +0,0 @@ -"""empty message - -Revision ID: b0f38c78db40 -Revises: a931e2b7b070 -Create Date: 2021-07-14 09:30:42.562825 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = 'b0f38c78db40' -down_revision = 'a931e2b7b070' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('workflow_spec', sa.Column('library', sa.Boolean(), nullable=True)) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_column('workflow_spec', 'library') - # ### end Alembic commands ### diff --git a/tests/workflow/test_workflow_spec_api.py b/tests/workflow/test_workflow_spec_api.py index 498ea37c..d867ed88 100644 --- a/tests/workflow/test_workflow_spec_api.py +++ b/tests/workflow/test_workflow_spec_api.py @@ -109,13 +109,13 @@ class TestWorkflowSpec(BaseTest): category = session.query(WorkflowSpecCategoryModel).first() ExampleDataLoader().create_spec('hello_world', 'Hello World', category_id=category.id, standalone=True, from_tests=True) - rv = self.app.get('/v1.0/workflow-specification/standalone', headers=self.logged_in_headers()) + rv = self.app.get('/v1.0/workflow-specification?standalone=true', headers=self.logged_in_headers()) self.assertEqual(1, len(rv.json)) ExampleDataLoader().create_spec('email_script', 'Email Script', category_id=category.id, standalone=True, from_tests=True) - rv = self.app.get('/v1.0/workflow-specification/standalone', headers=self.logged_in_headers()) + rv = self.app.get('/v1.0/workflow-specification?standalone=true', headers=self.logged_in_headers()) self.assertEqual(2, len(rv.json)) def test_get_workflow_from_workflow_spec(self): From 8566fff69079d72707cef9b42702d845d3d3a739 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Mon, 2 Aug 2021 10:35:28 -0400 Subject: [PATCH 08/11] See if this is why Travis fails --- Pipfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index 99124e4e..a4ce6c24 100644 --- a/Pipfile +++ b/Pipfile @@ -45,7 +45,7 @@ pygithub = "*" apscheduler = "*" [requires] -python_version = "3.9" +python_version = "3.8" [packages.connexion] extras = [ "swagger-ui",] From 6e1fedb704b4c4b30f1f84af18b0862e9153e2ee Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Tue, 3 Aug 2021 10:02:22 -0400 Subject: [PATCH 09/11] Add tests for libraries, remove an API endpoint that didn't make sense after recent changes and remove some commented out sections that were not needed after some decisions about the api endpoints were made --- crc/api.yml | 50 -------------------------------------- crc/api/workflow.py | 19 --------------- example_data.py | 5 ++-- tests/test_workflow_api.py | 38 +++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 71 deletions(-) diff --git a/crc/api.yml b/crc/api.yml index 0099a6f4..bea7f284 100644 --- a/crc/api.yml +++ b/crc/api.yml @@ -440,26 +440,6 @@ paths: schema: $ref: "#/components/schemas/WorkflowSpec" - /workflow-specification/{spec_id}/libraries: - parameters: - - name: spec_id - in: path - required: true - description: The unique id of an existing workflow specification. - schema: - type: string - get: - operationId: crc.api.workflow.get_workflow_specification_libraries - summary: Returns all libraries that are enabled for a workflow spec - tags: - - Workflow Specifications - responses: - '200': - description: Workflow specification. - content: - application/json: - schema: - $ref: "#/components/schemas/WorkflowSpec" /workflow-specification/{spec_id}/library/{library_id}: parameters: @@ -564,36 +544,6 @@ paths: responses: '204': description: The workflow specification has been removed. -# /workflow-specification/standalone: -# get: -# operationId: crc.api.workflow.standalone_workflow_specs -# summary: Provides a list of workflow specifications that can be run outside a study. -# tags: -# - Workflow Specifications -# responses: -# '200': -# description: A list of workflow specifications -# content: -# application/json: -# schema: -# type: array -# items: -# $ref: "#/components/schemas/WorkflowSpec" -# /workflow-specification/libraries: -# get: -# operationId: crc.api.workflow.library_workflow_specs -# summary: Provides a list of workflow specifications that are considered libraries. -# tags: -# - Workflow Specifications -# responses: -# '200': -# description: A list of workflow specifications -# content: -# application/json: -# schema: -# type: array -# items: -# $ref: "#/components/schemas/WorkflowSpec" /workflow-specification/{spec_id}/validate: parameters: - name: spec_id diff --git a/crc/api/workflow.py b/crc/api/workflow.py index 44305e4c..82c83e23 100644 --- a/crc/api/workflow.py +++ b/crc/api/workflow.py @@ -58,15 +58,6 @@ def get_workflow_specification(spec_id): return WorkflowSpecModelSchema().dump(spec) -def get_workflow_specification_libraries(spec_id): - if spec_id is None: - raise ApiError('unknown_spec', 'Please provide a valid Workflow Specification ID.') - spec: WorkflowSpecModel = session.query(WorkflowSpecModel).filter_by(id=spec_id).first() - libraries: WorkflowLibraryModel = session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id).all() - if spec is None: - raise ApiError('unknown_spec', 'The Workflow Specification "' + spec_id + '" is not recognized.') - return WorkflowLibraryModelSchema(many=True).dump(libraries) - def validate_spec_and_library(spec_id,library_id): if spec_id is None: raise ApiError('unknown_spec', 'Please provide a valid Workflow Specification ID.') @@ -163,16 +154,6 @@ def get_workflow_from_spec(spec_id): return WorkflowApiSchema().dump(workflow_api_model) -# def standalone_workflow_specs(): -# schema = WorkflowSpecModelSchema(many=True) -# specs = WorkflowService.get_standalone_workflow_specs() -# return schema.dump(specs) - -# def library_workflow_specs(): -# schema = WorkflowSpecModelSchema(many=True) -# specs = WorkflowService.get_library_workflow_specs() -# return schema.dump(specs) - def get_workflow(workflow_id, do_engine_steps=True): """Retrieve workflow based on workflow_id, and return it in the last saved State. If do_engine_steps is False, return the workflow without running any engine tasks or logging any events. """ diff --git a/example_data.py b/example_data.py index 21b4dd12..11751798 100644 --- a/example_data.py +++ b/example_data.py @@ -268,7 +268,7 @@ class ExampleDataLoader: from_tests=True) def create_spec(self, id, name, display_name="", description="", filepath=None, master_spec=False, - category_id=None, display_order=None, from_tests=False, standalone=False): + category_id=None, display_order=None, from_tests=False, standalone=False, library=False): """Assumes that a directory exists in static/bpmn with the same name as the given id. further assumes that the [id].bpmn is the primary file for the workflow. returns an array of data models to be added to the database.""" @@ -281,7 +281,8 @@ class ExampleDataLoader: is_master_spec=master_spec, category_id=category_id, display_order=display_order, - standalone=standalone) + standalone=standalone, + library=library) db.session.add(spec) db.session.commit() if not filepath and not from_tests: diff --git a/tests/test_workflow_api.py b/tests/test_workflow_api.py index 02b5b348..07a5b214 100644 --- a/tests/test_workflow_api.py +++ b/tests/test_workflow_api.py @@ -25,3 +25,41 @@ class TestWorkflowApi(BaseTest): content_type="application/json", headers=self.logged_in_headers()) self.assert_success(rv) + + + def test_library_code(self): + self.load_example_data() + spec1 = ExampleDataLoader().create_spec('hello_world', 'Hello World', category_id=0, library=False, + from_tests=True) + + spec2 = ExampleDataLoader().create_spec('hello_world_lib', 'Hello World Library', category_id=0, library=True, + from_tests=True) + user = session.query(UserModel).first() + self.assertIsNotNone(user) + #WorkflowService.get_workflow_from_spec(spec.id, user) + + rv = self.app.post(f'/v1.0/workflow-specification/%s/library/%s'%(spec1.id,spec2.id), + follow_redirects=True, + content_type="application/json", + headers=self.logged_in_headers()) + self.assert_success(rv) + + rv = self.app.get(f'/v1.0/workflow-specification/%s'%spec1.id,follow_redirects=True, + content_type="application/json", + headers=self.logged_in_headers()) + returned=rv.json + self.assertIsNotNone(returned.get('libraries')) + self.assertEqual(len(returned['libraries']),1) + self.assertEqual(returned['libraries'][0].get('id'),'hello_world_lib') + rv = self.app.delete(f'/v1.0/workflow-specification/%s/library/%s'%(spec1.id,spec2.id),follow_redirects=True, + content_type="application/json", + headers=self.logged_in_headers()) + rv = self.app.get(f'/v1.0/workflow-specification/%s'%spec1.id,follow_redirects=True, + content_type="application/json", + headers=self.logged_in_headers()) + returned=rv.json + self.assertIsNotNone(returned.get('libraries')) + self.assertEqual(len(returned['libraries']),0) + + + From 70f391d6129f0c7bda89897bf47f866de641b420 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 6 Aug 2021 09:50:57 -0400 Subject: [PATCH 10/11] Make sure tables exist before we try to delete them --- example_data.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/example_data.py b/example_data.py index 11751798..99b7cd54 100644 --- a/example_data.py +++ b/example_data.py @@ -16,8 +16,11 @@ class ExampleDataLoader: @staticmethod def clean_db(): session.flush() # Clear out any transactions before deleting it all to avoid spurious errors. + engine = session.bind.engine + connection = engine.connect() for table in reversed(db.metadata.sorted_tables): - session.execute(table.delete()) + if engine.dialect.has_table(connection, table): + session.execute(table.delete()) session.commit() session.flush() From 069f1d12b7de951e1959989200b915549e187757 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 6 Aug 2021 15:41:23 -0400 Subject: [PATCH 11/11] re-enable the reset_db --- docker_run.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docker_run.sh b/docker_run.sh index e0788f80..ec80bb99 100755 --- a/docker_run.sh +++ b/docker_run.sh @@ -13,14 +13,10 @@ if [ "$UPGRADE_DB" = "true" ]; then pipenv run flask db upgrade fi -# This is commented to keep humans from clearing the db accidentally. -# If you need to reset the db, you can uncomment, -# then set RESET_DB to true in config, push code, and pray - -#if [ "$RESET_DB" = "true" ]; then -# echo 'Resetting database and seeding it with example CR Connect data...' -# pipenv run flask load-example-data -#fi +if [ "$RESET_DB" = "true" ]; then + echo 'Resetting database and seeding it with example CR Connect data...' + pipenv run flask load-example-data +fi if [ "$RESET_DB_RRT" = "true" ]; then echo 'Resetting database and seeding it with example RRT data...'