Just merging stuff real quick.

This commit is contained in:
Dan Funk 2020-03-18 17:03:36 -04:00
parent 02be8ede75
commit 83d859fd3a
9 changed files with 320 additions and 105 deletions

View File

@ -34,6 +34,7 @@ psycopg2-binary = "*"
docxtpl = "*"
flask-sso = "*"
python-dateutil = "*"
pandas = "*"
[requires]
python_version = "3.7"

234
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "60e48d05048f627878a5c81377318bc2ff2a94b2574441c166fda3a523c789df"
"sha256": "0e22a6c7b84b96d9d8677790cc90cc7f0a894f5742d7ecbcbd0fdcbe59587eda"
},
"pipfile-spec": 6,
"requires": {
@ -25,10 +25,10 @@
},
"alembic": {
"hashes": [
"sha256:2df2519a5b002f881517693b95626905a39c5faf4b5a1f94de4f1441095d1d26"
"sha256:791a5686953c4b366d3228c5377196db2f534475bb38d26f70eb69668efd9028"
],
"index": "pypi",
"version": "==1.4.0"
"version": "==1.4.1"
},
"amqp": {
"hashes": [
@ -104,10 +104,10 @@
},
"celery": {
"hashes": [
"sha256:7c544f37a84a5eadc44cab1aa8c9580dff94636bb81978cdf9bf8012d9ea7d8f",
"sha256:d3363bb5df72d74420986a435449f3c3979285941dff57d5d97ecba352a0e3e2"
"sha256:108a0bf9018a871620936c33a3ee9f6336a89f8ef0a0f567a9001f4aa361415f",
"sha256:5b4b37e276033fe47575107a2775469f0b721646a08c96ec2c61531e4fe45f2a"
],
"version": "==4.4.0"
"version": "==4.4.2"
},
"certifi": {
"hashes": [
@ -158,10 +158,10 @@
},
"click": {
"hashes": [
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
"sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc",
"sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a"
],
"version": "==7.0"
"version": "==7.1.1"
},
"clickclick": {
"hashes": [
@ -197,40 +197,40 @@
},
"coverage": {
"hashes": [
"sha256:15cf13a6896048d6d947bf7d222f36e4809ab926894beb748fc9caa14605d9c3",
"sha256:1daa3eceed220f9fdb80d5ff950dd95112cd27f70d004c7918ca6dfc6c47054c",
"sha256:1e44a022500d944d42f94df76727ba3fc0a5c0b672c358b61067abb88caee7a0",
"sha256:25dbf1110d70bab68a74b4b9d74f30e99b177cde3388e07cc7272f2168bd1477",
"sha256:3230d1003eec018ad4a472d254991e34241e0bbd513e97a29727c7c2f637bd2a",
"sha256:3dbb72eaeea5763676a1a1efd9b427a048c97c39ed92e13336e726117d0b72bf",
"sha256:5012d3b8d5a500834783689a5d2292fe06ec75dc86ee1ccdad04b6f5bf231691",
"sha256:51bc7710b13a2ae0c726f69756cf7ffd4362f4ac36546e243136187cfcc8aa73",
"sha256:527b4f316e6bf7755082a783726da20671a0cc388b786a64417780b90565b987",
"sha256:722e4557c8039aad9592c6a4213db75da08c2cd9945320220634f637251c3894",
"sha256:76e2057e8ffba5472fd28a3a010431fd9e928885ff480cb278877c6e9943cc2e",
"sha256:77afca04240c40450c331fa796b3eab6f1e15c5ecf8bf2b8bee9706cd5452fef",
"sha256:7afad9835e7a651d3551eab18cbc0fdb888f0a6136169fbef0662d9cdc9987cf",
"sha256:9bea19ac2f08672636350f203db89382121c9c2ade85d945953ef3c8cf9d2a68",
"sha256:a8b8ac7876bc3598e43e2603f772d2353d9931709345ad6c1149009fd1bc81b8",
"sha256:b0840b45187699affd4c6588286d429cd79a99d509fe3de0f209594669bb0954",
"sha256:b26aaf69713e5674efbde4d728fb7124e429c9466aeaf5f4a7e9e699b12c9fe2",
"sha256:b63dd43f455ba878e5e9f80ba4f748c0a2156dde6e0e6e690310e24d6e8caf40",
"sha256:be18f4ae5a9e46edae3f329de2191747966a34a3d93046dbdf897319923923bc",
"sha256:c312e57847db2526bc92b9bfa78266bfbaabac3fdcd751df4d062cd4c23e46dc",
"sha256:c60097190fe9dc2b329a0eb03393e2e0829156a589bd732e70794c0dd804258e",
"sha256:c62a2143e1313944bf4a5ab34fd3b4be15367a02e9478b0ce800cb510e3bbb9d",
"sha256:cc1109f54a14d940b8512ee9f1c3975c181bbb200306c6d8b87d93376538782f",
"sha256:cd60f507c125ac0ad83f05803063bed27e50fa903b9c2cfee3f8a6867ca600fc",
"sha256:d513cc3db248e566e07a0da99c230aca3556d9b09ed02f420664e2da97eac301",
"sha256:d649dc0bcace6fcdb446ae02b98798a856593b19b637c1b9af8edadf2b150bea",
"sha256:d7008a6796095a79544f4da1ee49418901961c97ca9e9d44904205ff7d6aa8cb",
"sha256:da93027835164b8223e8e5af2cf902a4c80ed93cb0909417234f4a9df3bcd9af",
"sha256:e69215621707119c6baf99bda014a45b999d37602cb7043d943c76a59b05bf52",
"sha256:ea9525e0fef2de9208250d6c5aeeee0138921057cd67fcef90fbed49c4d62d37",
"sha256:fca1669d464f0c9831fd10be2eef6b86f5ebd76c724d1e0706ebdff86bb4adf0"
"sha256:03f630aba2b9b0d69871c2e8d23a69b7fe94a1e2f5f10df5049c0df99db639a0",
"sha256:046a1a742e66d065d16fb564a26c2a15867f17695e7f3d358d7b1ad8a61bca30",
"sha256:0a907199566269e1cfa304325cc3b45c72ae341fbb3253ddde19fa820ded7a8b",
"sha256:165a48268bfb5a77e2d9dbb80de7ea917332a79c7adb747bd005b3a07ff8caf0",
"sha256:1b60a95fc995649464e0cd48cecc8288bac5f4198f21d04b8229dc4097d76823",
"sha256:1f66cf263ec77af5b8fe14ef14c5e46e2eb4a795ac495ad7c03adc72ae43fafe",
"sha256:2e08c32cbede4a29e2a701822291ae2bc9b5220a971bba9d1e7615312efd3037",
"sha256:3844c3dab800ca8536f75ae89f3cf566848a3eb2af4d9f7b1103b4f4f7a5dad6",
"sha256:408ce64078398b2ee2ec08199ea3fcf382828d2f8a19c5a5ba2946fe5ddc6c31",
"sha256:443be7602c790960b9514567917af538cac7807a7c0c0727c4d2bbd4014920fd",
"sha256:4482f69e0701139d0f2c44f3c395d1d1d37abd81bfafbf9b6efbe2542679d892",
"sha256:4a8a259bf990044351baf69d3b23e575699dd60b18460c71e81dc565f5819ac1",
"sha256:513e6526e0082c59a984448f4104c9bf346c2da9961779ede1fc458e8e8a1f78",
"sha256:5f587dfd83cb669933186661a351ad6fc7166273bc3e3a1531ec5c783d997aac",
"sha256:62061e87071497951155cbccee487980524d7abea647a1b2a6eb6b9647df9006",
"sha256:641e329e7f2c01531c45c687efcec8aeca2a78a4ff26d49184dce3d53fc35014",
"sha256:65a7e00c00472cd0f59ae09d2fb8a8aaae7f4a0cf54b2b74f3138d9f9ceb9cb2",
"sha256:6ad6ca45e9e92c05295f638e78cd42bfaaf8ee07878c9ed73e93190b26c125f7",
"sha256:73aa6e86034dad9f00f4bbf5a666a889d17d79db73bc5af04abd6c20a014d9c8",
"sha256:7c9762f80a25d8d0e4ab3cb1af5d9dffbddb3ee5d21c43e3474c84bf5ff941f7",
"sha256:85596aa5d9aac1bf39fe39d9fa1051b0f00823982a1de5766e35d495b4a36ca9",
"sha256:86a0ea78fd851b313b2e712266f663e13b6bc78c2fb260b079e8b67d970474b1",
"sha256:8a620767b8209f3446197c0e29ba895d75a1e272a36af0786ec70fe7834e4307",
"sha256:922fb9ef2c67c3ab20e22948dcfd783397e4c043a5c5fa5ff5e9df5529074b0a",
"sha256:9fad78c13e71546a76c2f8789623eec8e499f8d2d799f4b4547162ce0a4df435",
"sha256:a37c6233b28e5bc340054cf6170e7090a4e85069513320275a4dc929144dccf0",
"sha256:c3fc325ce4cbf902d05a80daa47b645d07e796a80682c1c5800d6ac5045193e5",
"sha256:cda33311cb9fb9323958a69499a667bd728a39a7aa4718d7622597a44c4f1441",
"sha256:db1d4e38c9b15be1521722e946ee24f6db95b189d1447fa9ff18dd16ba89f732",
"sha256:eda55e6e9ea258f5e4add23bcf33dc53b2c319e70806e180aecbff8d90ea24de",
"sha256:f372cdbb240e09ee855735b9d85e7f50730dcfb6296b74b95a3e5dea0615c4c1"
],
"index": "pypi",
"version": "==5.0.3"
"version": "==5.0.4"
},
"docutils": {
"hashes": [
@ -294,11 +294,11 @@
},
"flask-migrate": {
"hashes": [
"sha256:6fb038be63d4c60727d5dfa5f581a6189af5b4e2925bc378697b4f0a40cfb4e1",
"sha256:a96ff1875a49a40bd3e8ac04fce73fdb0870b9211e6168608cbafa4eb839d502"
"sha256:4dc4a5cce8cbbb06b8dc963fd86cf8136bd7d875aabe2d840302ea739b243732",
"sha256:a69d508c2e09d289f6e55a417b3b8c7bfe70e640f53d2d9deb0d056a384f37ee"
],
"index": "pypi",
"version": "==2.5.2"
"version": "==2.5.3"
},
"flask-restful": {
"hashes": [
@ -393,10 +393,10 @@
},
"kombu": {
"hashes": [
"sha256:2a9e7adff14d046c9996752b2c48b6d9185d0b992106d5160e1a179907a5d4ac",
"sha256:67b32ccb6fea030f8799f8fd50dd08e03a4b99464ebc4952d71d8747b1a52ad1"
"sha256:2d1cda774126a044d91a7ff5fa6d09edf99f46924ab332a810760fe6740e9b76",
"sha256:598e7e749d6ab54f646b74b2d2df67755dee13894f73ab02a2a9feb8870c7cb2"
],
"version": "==4.6.7"
"version": "==4.6.8"
},
"lxml": {
"hashes": [
@ -432,9 +432,10 @@
},
"mako": {
"hashes": [
"sha256:2984a6733e1d472796ceef37ad48c26f4a984bb18119bb2dbc37a44d8f6e75a4"
"sha256:3139c5d64aa5d175dbafb95027057128b5fbd05a40c53999f3905ceb53366d9d",
"sha256:8e8b53c71c7e59f3de716b6832c4e401d903af574f6962edbbbf6ecc2a5fe6c9"
],
"version": "==1.1.1"
"version": "==1.1.2"
},
"markupsafe": {
"hashes": [
@ -476,11 +477,11 @@
},
"marshmallow": {
"hashes": [
"sha256:3a94945a7461f2ab4df9576e51c97d66bee2c86155d3d3933fab752b31effab8",
"sha256:4b95c7735f93eb781dfdc4dded028108998cad759dda8dd9d4b5b4ac574cbf13"
"sha256:90854221bbb1498d003a0c3cc9d8390259137551917961c8b5258c64026b2f85",
"sha256:ac2e13b30165501b7d41fc0371b8df35944f5849769d136f20e2c5f6cdc6e665"
],
"index": "pypi",
"version": "==3.5.0"
"version": "==3.5.1"
},
"marshmallow-enum": {
"hashes": [
@ -492,11 +493,37 @@
},
"marshmallow-sqlalchemy": {
"hashes": [
"sha256:a370e247216e1a005277d92079d2f0d8d5b0a70fba68ee645730f6a1200991d1",
"sha256:f3155e87717e3a52def3a177b4022fd0500e71f626cbb0672adcb95588a99aa3"
"sha256:9301c6fd197bd97337820ea1417aa1233d0ee3e22748ebd5821799bc841a57e8",
"sha256:dde9e20bcb710e9e59f765a38e3d6d17f1b2d6b4320cbdc2cea0f6b57f70d08c"
],
"index": "pypi",
"version": "==0.22.2"
"version": "==0.22.3"
},
"numpy": {
"hashes": [
"sha256:1598a6de323508cfeed6b7cd6c4efb43324f4692e20d1f76e1feec7f59013448",
"sha256:1b0ece94018ae21163d1f651b527156e1f03943b986188dd81bc7e066eae9d1c",
"sha256:2e40be731ad618cb4974d5ba60d373cdf4f1b8dcbf1dcf4d9dff5e212baf69c5",
"sha256:4ba59db1fcc27ea31368af524dcf874d9277f21fd2e1f7f1e2e0c75ee61419ed",
"sha256:59ca9c6592da581a03d42cc4e270732552243dc45e87248aa8d636d53812f6a5",
"sha256:5e0feb76849ca3e83dd396254e47c7dba65b3fa9ed3df67c2556293ae3e16de3",
"sha256:6d205249a0293e62bbb3898c4c2e1ff8a22f98375a34775a259a0523111a8f6c",
"sha256:6fcc5a3990e269f86d388f165a089259893851437b904f422d301cdce4ff25c8",
"sha256:82847f2765835c8e5308f136bc34018d09b49037ec23ecc42b246424c767056b",
"sha256:87902e5c03355335fc5992a74ba0247a70d937f326d852fc613b7f53516c0963",
"sha256:9ab21d1cb156a620d3999dd92f7d1c86824c622873841d6b080ca5495fa10fef",
"sha256:a1baa1dc8ecd88fb2d2a651671a84b9938461e8a8eed13e2f0a812a94084d1fa",
"sha256:a244f7af80dacf21054386539699ce29bcc64796ed9850c99a34b41305630286",
"sha256:a35af656a7ba1d3decdd4fae5322b87277de8ac98b7d9da657d9e212ece76a61",
"sha256:b1fe1a6f3a6f355f6c29789b5927f8bd4f134a4bd9a781099a7c4f66af8850f5",
"sha256:b5ad0adb51b2dee7d0ee75a69e9871e2ddfb061c73ea8bc439376298141f77f5",
"sha256:ba3c7a2814ec8a176bb71f91478293d633c08582119e713a0c5351c0f77698da",
"sha256:cd77d58fb2acf57c1d1ee2835567cd70e6f1835e32090538f17f8a3a99e5e34b",
"sha256:cdb3a70285e8220875e4d2bc394e49b4988bdb1298ffa4e0bd81b2f613be397c",
"sha256:deb529c40c3f1e38d53d5ae6cd077c21f1d49e13afc7936f7f868455e16b64a0",
"sha256:e7894793e6e8540dbeac77c87b489e331947813511108ae097f1715c018b8f3d"
],
"version": "==1.18.2"
},
"openapi-spec-validator": {
"hashes": [
@ -515,10 +542,32 @@
},
"packaging": {
"hashes": [
"sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73",
"sha256:e665345f9eef0c621aa0bf2f8d78cf6d21904eef16a93f020240b704a57f1334"
"sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3",
"sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"
],
"version": "==20.1"
"version": "==20.3"
},
"pandas": {
"hashes": [
"sha256:07c1b58936b80eafdfe694ce964ac21567b80a48d972879a359b3ebb2ea76835",
"sha256:0ebe327fb088df4d06145227a4aa0998e4f80a9e6aed4b61c1f303bdfdf7c722",
"sha256:11c7cb654cd3a0e9c54d81761b5920cdc86b373510d829461d8f2ed6d5905266",
"sha256:12f492dd840e9db1688126216706aa2d1fcd3f4df68a195f9479272d50054645",
"sha256:167a1315367cea6ec6a5e11e791d9604f8e03f95b57ad227409de35cf850c9c5",
"sha256:1a7c56f1df8d5ad8571fa251b864231f26b47b59cbe41aa5c0983d17dbb7a8e4",
"sha256:1fa4bae1a6784aa550a1c9e168422798104a85bf9c77a1063ea77ee6f8452e3a",
"sha256:32f42e322fb903d0e189a4c10b75ba70d90958cc4f66a1781ed027f1a1d14586",
"sha256:387dc7b3c0424327fe3218f81e05fc27832772a5dffbed385013161be58df90b",
"sha256:6597df07ea361231e60c00692d8a8099b519ed741c04e65821e632bc9ccb924c",
"sha256:743bba36e99d4440403beb45a6f4f3a667c090c00394c176092b0b910666189b",
"sha256:858a0d890d957ae62338624e4aeaf1de436dba2c2c0772570a686eaca8b4fc85",
"sha256:863c3e4b7ae550749a0bb77fa22e601a36df9d2905afef34a6965bed092ba9e5",
"sha256:a210c91a02ec5ff05617a298ad6f137b9f6f5771bf31f2d6b6367d7f71486639",
"sha256:ca84a44cf727f211752e91eab2d1c6c1ab0f0540d5636a8382a3af428542826e",
"sha256:d234bcf669e8b4d6cbcd99e3ce7a8918414520aeb113e2a81aeb02d0a533d7f7"
],
"index": "pypi",
"version": "==1.0.3"
},
"psycopg2-binary": {
"hashes": [
@ -560,16 +609,17 @@
},
"pycparser": {
"hashes": [
"sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"
"sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0",
"sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"
],
"version": "==2.19"
"version": "==2.20"
},
"pygments": {
"hashes": [
"sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b",
"sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe"
"sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44",
"sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"
],
"version": "==2.5.2"
"version": "==2.6.1"
},
"pyjwt": {
"hashes": [
@ -676,25 +726,25 @@
},
"sphinx": {
"hashes": [
"sha256:776ff8333181138fae52df65be733127539623bb46cc692e7fa0fcfc80d7aa88",
"sha256:ca762da97c3b5107cbf0ab9e11d3ec7ab8d3c31377266fd613b962ed971df709"
"sha256:b4c750d546ab6d7e05bdff6ac24db8ae3e8b8253a3569b754e445110a0a12b66",
"sha256:fc312670b56cb54920d6cc2ced455a22a547910de10b3142276495ced49231cb"
],
"index": "pypi",
"version": "==2.4.3"
"version": "==2.4.4"
},
"sphinxcontrib-applehelp": {
"hashes": [
"sha256:edaa0ab2b2bc74403149cb0209d6775c96de797dfd5b5e2a71981309efab3897",
"sha256:fb8dee85af95e5c30c91f10e7eb3c8967308518e0f7488a2828ef7bc191d0d5d"
"sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a",
"sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"
],
"version": "==1.0.1"
"version": "==1.0.2"
},
"sphinxcontrib-devhelp": {
"hashes": [
"sha256:6c64b077937330a9128a4da74586e8c2130262f014689b4b89e2d08ee7294a34",
"sha256:9512ecb00a2b0821a146736b39f7aeb90759834b07e81e8cc23a9c70bacb9981"
"sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e",
"sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"
],
"version": "==1.0.1"
"version": "==1.0.2"
},
"sphinxcontrib-htmlhelp": {
"hashes": [
@ -712,17 +762,17 @@
},
"sphinxcontrib-qthelp": {
"hashes": [
"sha256:513049b93031beb1f57d4daea74068a4feb77aa5630f856fcff2e50de14e9a20",
"sha256:79465ce11ae5694ff165becda529a600c754f4bc459778778c7017374d4d406f"
"sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72",
"sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"
],
"version": "==1.0.2"
"version": "==1.0.3"
},
"sphinxcontrib-serializinghtml": {
"hashes": [
"sha256:c0efb33f8052c04fd7a26c0a07f1678e8512e0faec19f4aa8f2473a8b81d5227",
"sha256:db6615af393650bf1151a6cd39120c29abaf93cc60db8c48eb2dddbfdc3a9768"
"sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc",
"sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"
],
"version": "==1.1.3"
"version": "==1.1.4"
},
"spiffworkflow": {
"editable": true,
@ -731,9 +781,9 @@
},
"sqlalchemy": {
"hashes": [
"sha256:64a7b71846db6423807e96820993fa12a03b89127d278290ca25c0b11ed7b4fb"
"sha256:c4cca4aed606297afbe90d4306b49ad3a4cd36feb3f87e4bfd655c57fd9ef445"
],
"version": "==1.3.13"
"version": "==1.3.15"
},
"swagger-ui-bundle": {
"hashes": [
@ -797,10 +847,10 @@
},
"zipp": {
"hashes": [
"sha256:12248a63bbdf7548f89cb4c7cda4681e537031eda29c02ea29674bc6854460c2",
"sha256:7c0f8e91abc0dc07a5068f315c52cb30c66bfbc581e5b50704c8a2f6ebae794a"
"sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
"sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
],
"version": "==3.0.0"
"version": "==3.1.0"
}
},
"develop": {
@ -828,10 +878,10 @@
},
"packaging": {
"hashes": [
"sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73",
"sha256:e665345f9eef0c621aa0bf2f8d78cf6d21904eef16a93f020240b704a57f1334"
"sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3",
"sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"
],
"version": "==20.1"
"version": "==20.3"
},
"pluggy": {
"hashes": [
@ -856,11 +906,11 @@
},
"pytest": {
"hashes": [
"sha256:0d5fe9189a148acc3c3eb2ac8e1ac0742cb7618c084f3d228baaec0c254b318d",
"sha256:ff615c761e25eb25df19edddc0b970302d2a9091fbce0e7213298d85fb61fef6"
"sha256:0e5b30f5cb04e887b91b1ee519fa3d89049595f428c1db76e73bd7f17b09b172",
"sha256:84dde37075b8805f3d1f392cc47e38a0e59518fb46a431cfdaf7cf1ce805f970"
],
"index": "pypi",
"version": "==5.3.5"
"version": "==5.4.1"
},
"six": {
"hashes": [
@ -878,10 +928,10 @@
},
"zipp": {
"hashes": [
"sha256:12248a63bbdf7548f89cb4c7cda4681e537031eda29c02ea29674bc6854460c2",
"sha256:7c0f8e91abc0dc07a5068f315c52cb30c66bfbc581e5b50704c8a2f6ebae794a"
"sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
"sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
],
"version": "==3.0.0"
"version": "==3.1.0"
}
}
}

View File

@ -0,0 +1,17 @@
from marshmallow_sqlalchemy import ModelSchema
from crc import db
class IRBDocumentModel(db.Model):
"""Provides a lookup table for information about how to submit IRB documents,
which are named according to category levels. These may be linked
to a ProtocolBuilder required document, which is the irb_required_doc_id """
__tablename__ = 'irb_document'
id = db.Column(db.Integer, primary_key=True)
irb_required_doc_id = db.Column(db.Integer)
category1 = db.Column(db.String)
category2 = db.Column(db.String)
category3 = db.Column(db.String)
who_uploads = db.Column(db.String)

View File

@ -18,6 +18,13 @@ class Script:
"This is an internal error. The script you are trying to execute " +
"does not properly implement the do_task function.")
def validate(self):
"""Override this method to perform an early check that the script has access to
everything it needs to properly process requests.
Should return an array of ScriptValidationErrors.
"""
return []
@staticmethod
def get_all_subclasses():
return Script._get_all_subclasses(Script)
@ -38,4 +45,15 @@ class Script:
all_subclasses.append(subclass)
all_subclasses.extend(Script._get_all_subclasses(subclass))
return all_subclasses
return all_subclasses
class ScriptValidationError:
def __init__(self, code, message):
self.code = code
self.message = message
@classmethod
def from_api_error(cls, api_error: ApiError):
return cls(api_error.code, api_error.message)

View File

@ -1,7 +1,10 @@
from crc import session
from pandas import ExcelFile
from crc import session, ma
from crc.api.common import ApiError
from crc.models.study import StudyModel, StudyModelSchema
from crc.scripts.script import Script
from crc.scripts.script import Script, ScriptValidationError
from crc.services.file_service import FileService
from crc.services.protocol_builder import ProtocolBuilderService
@ -9,6 +12,7 @@ class StudyInfo(Script):
"""Just your basic class that can pull in data from a few api endpoints and do a basic task."""
pb = ProtocolBuilderService()
type_options = ['info', 'investigators', 'required_docs', 'details']
IRB_PRO_CATEGORIES_FILE = "irb_pro_categories.xls"
def get_description(self):
return """StudyInfo [TYPE], where TYPE is one of 'info', 'investigators','required_docs', or 'details'
@ -37,22 +41,60 @@ class StudyInfo(Script):
if cmd == 'investigators':
study_info["investigators"] = self.pb.get_investigators(study_id)
if cmd == 'required_docs':
study_info["required_docs"] = self.pb.get_required_docs(study_id)
study_info["required_docs"] = self.get_required_docs(study_id)
if cmd == 'details':
study_info["details"] = self.pb.get_study_details(study_id)
task.data["study"] = study_info
def get_required_docs(self, study_id):
required_docs = self.pb.get_required_docs(study_id)
"""Takes data from the protocol builder, and merges it with data from the IRB Pro Categories spreadsheet to return
pertinant details about the required documents."""
pb_docs = self.pb.get_required_docs(study_id)
data_frame = self.get_file_reference_dictionary()
required_docs = []
for doc in pb_docs:
required_docs.append(RequiredDocument.form_pb_and_spread_sheet(doc, data_frame))
return required_docs
def get_file_reference_dictionary(self):
"""Loads up the xsl file that contains the IRB Pro Categories and converts it to a Panda's data frame for processing."""
data_model = FileService.get_reference_file_data(StudyInfo.IRB_PRO_CATEGORIES_FILE)
xls = ExcelFile(data_model.data)
df = xls.parse(xls.sheet_names[0])
return df
# Verifies that information is available for this script task to function
# correctly. Returns a list of validation errors.
@staticmethod
def validate():
errors = []
try:
FileService.get_reference_file_data(StudyInfo.IRB_PRO_CATEGORIES_FILE)
except ApiError as ae:
errors.append(ScriptValidationError.from_api_error(ae))
return errors
class RequiredDocument(object):
def __init__(self, pb_id, pb_name, category1, category2, category3, who_uploads, required, total_uploaded):
self.protocol_builder_id = pb_id
self.protocol_builder_name = pb_name
self.category1 = category1
self.category2 = category2
self.category3 = category3
self.who_uploads = who_uploads
self.required = required
self.total_uploaded = total_uploaded
@classmethod
def form_pb_and_spread_sheet(cls, pb_data, sheet_data):
"""Generates a Required Document record from protobol builder record and a Panda's data sheet"""
return cls(pb_id=pb_data['AUXDOCID'],
pb_name=pb_data['AUXDOC'],
category1="")
class RequiredDocumentSchema(ma.Schema):
class Meta:
model = RequiredDocument
fields = ["pb_id", "pb_name", "category1", "category2", "category3",
"who_uploads", "required", "total_uploaded"]

View File

@ -145,3 +145,4 @@ class FileService(object):
if not file_model:
raise ApiError("file_not_found", "There is no reference file with the name '%s'" % file_name)
return FileService.get_file_data(file_model.id, file_model)

View File

@ -0,0 +1,24 @@
"""merge D and F
Revision ID: 2b787cc265d8
Revises: 65f3fce6031a, 0c8a2f8db28c
Create Date: 2020-03-18 16:02:50.126232
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '2b787cc265d8'
down_revision = ('65f3fce6031a', '0c8a2f8db28c')
branch_labels = None
depends_on = None
def upgrade():
pass
def downgrade():
pass

View File

@ -27,6 +27,7 @@
</bpmn:extensionElements>
<bpmn:incoming>SequenceFlow_00p5po6</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_17ggqu2</bpmn:outgoing>
<bpmn:multiInstanceLoopCharacteristics />
</bpmn:userTask>
<bpmn:textAnnotation id="TextAnnotation_1haj11l">
<bpmn:text>We have a test that replaces tow_forms with this file, which adds a new step to the process.  A breaking change.</bpmn:text>

View File

@ -0,0 +1,61 @@
import os
from unittest.mock import patch
from crc import app
from crc.models.file import CONTENT_TYPES
from crc.scripts.study_info import StudyInfo
from crc.services.file_service import FileService
from crc.services.protocol_builder import ProtocolBuilderService
from tests.base_test import BaseTest
class TestStudyInfoService(BaseTest):
test_uid = "dhf8r"
test_study_id = 1
"""
1. get a list of only the required documents for the study.
2. For this study, is this document required accroding to the protocol builder?
3. For ALL uploaded documents, what the total number of files that were uploaded? per instance of this document naming
convention that we are implementing for the IRB.
"""
def test_get_required_docs(self):
"""The Study info service should re-structure required docs to provide
a flatted view of just the documents that are required.
"""
def create_reference_document(self):
file_path = os.path.join(app.root_path, '..', 'tests', 'data', 'reference', 'irb_documents.xlsx')
file = open(file_path, "rb")
FileService.add_reference_file(StudyInfo.IRB_PRO_CATEGORIES_FILE,
binary_data=file.read(),
content_type=CONTENT_TYPES['xls'])
def test_validate_returns_error_if_reference_files_do_not_exist(self):
errors = StudyInfo.validate()
FileService.
self.assertTrue(len(errors) > 0)
self.assertEquals("file_not_found", errors[0].code)
def test_no_validation_error_when_correct_file_exists(self):
self.create_reference_document()
errors = StudyInfo.validate()
self.assertTrue(len(errors) == 0)
def test_load_lookup_data(self):
self.create_reference_document()
dict = StudyInfo().get_file_reference_dictionary()
self.assertIsNotNone(dict)
@patch('crc.services.protocol_builder.requests.get')
def test_get_required_docs(self, mock_get):
mock_get.return_value.ok = True
mock_get.return_value.text = self.protocol_builder_response('required_docs.json')
self.create_reference_document()
studyInfo = StudyInfo()
required_docs = studyInfo.get_required_docs(12)
self.assertIsNotNone(required_docs)
self.assertTrue(len(required_docs) == 5)
self.assertEquals(6, required_docs[0].protocol_builder_id)