瀏覽代碼

Adding mirrors of crf module (crude) for python-ish CRF management

Andrej 5 天之前
父節點
當前提交
f64144e304
共有 1 個文件被更改,包括 237 次插入0 次删除
  1. 237 0
      manageCRF.py

+ 237 - 0
manageCRF.py

@@ -0,0 +1,237 @@
+import labkeyInterface
+import labkeyInterface
+import labkeyDatabaseBrowser
+
+# interact with the database (connect, get handle, getRows, uploadRows)
+
+def connectDB(server):
+
+   net=labkeyInterface.labkeyInterface()
+   fconfig=os.path.join(os.path.expanduser('~'),'.labkey',f'{server}.json')
+   net.init(fconfig)
+   return net,labkeyDatabaseBrowser.labkeyDB(net)
+
+def getDB(pars):
+   try:
+      return pars['db']
+   except KeyError:
+      pass
+   pars['net'],pars['db']=connectDB(pars['server'])
+   return pars['db']
+
+def getRows(pars):
+   db=getDB(pars)
+   qFilter=pars.get('qFilter',[])
+   return db.selectRows(pars['project'],pars['schema'],
+      pars['query'],qFilter)['rows']
+
+def modifyRows(pars,mode,rows):
+   db=getDB(pars)
+   return db.modifyRows(mode,pars['project'],pars['schema'],pars['query'],rows)
+
+# helper function
+
+#very generic variable splitting routine
+def parseVariables(q):
+   if q==None:
+      return []
+   arr=q.split(';')
+   v=[x.split('=') for x in arr]
+   return [{'varName':x[0],'varValue':x[1]} for x in v]
+
+
+# get snapshot of the data layout
+
+#this should really look at FormStatus on layout and do the conversion
+def toStatus(x):
+   if x=='Submitted':
+      return 2
+   if x=='InProgress':
+      return 1
+   if x=='Approved':
+      return 5
+
+#get dataset names
+def getInputLists(pars):
+   try:
+      return pars['inputLists']
+   except KeyError:
+      pass
+   parServerLayout={'db':pars['db'],'project':'crfLayout/hypoAfrica'}
+   parInputLists={'schema':'lists','query':'inputLists'}
+   rows=getRows(parServerLayout|parInputLists)
+   pars['inputLists']={r['Key']:r['queryName'] for r in rows}
+   return pars['inputLists']
+
+
+#get datasets for form
+def getDatasets(pars,form):
+   try:
+      return pars['datasets'][form]
+   except KeyError:
+      pass
+   parServerLayout={'db':pars['db'],'project':'crfLayout/hypoAfrica'}
+# set datasets for forms
+   formFilter={'variable':'formName','value':f'{form}','oper':'eq'}
+   parFormSetup={'schema':'lists','query':'FormSetup'}
+   parFilter={'qFilter':[formFilter]}
+   rows=getRows(parServerLayout|parFormSetup|parFilter)
+#ignore show query since 15 has all set to NONE
+#keep variable definition
+   inputLists=getInputLists(pars)
+   datasets={r['Key']:r|{'query':inputLists[r['queryName']]} for r in rows}
+   try:
+      pars['datasets'][form]=datasets
+   except KeyError:
+      pars['datasets']={form:datasets}
+   return datasets
+    
+#manager CRF master entries (get, modify, upload)
+
+def getCrfEntry(pars,crf):
+   crfFilter={'variable':'entryId','value':crf,'oper':'eq'}
+   parFilter={'qFilter':[crfFilter]}
+   parCrf={'schema':'lists','query':'crfEntry'}
+   rows=getRows(pars|parCrf|parFilter)
+   if len(rows)!=1:
+      print('Fail crfEntry')
+      return None
+   return rows[0]
+
+def changeFormStatus(pars,crfEntry,targetStatus):
+   crfEntry['FormStatus']=toStatus(targetStatus)
+   updateCrfEntry(pars,crfEntry)
+ 
+def uploadCrfEntry(pars,crfEntry):
+   parCrf={'schema':'lists','query':'crfEntry'}
+   outcome=modifyRows(pars|parCrf,'update',[crfEntry])
+   try:
+      print(outcome['exception'])
+   except KeyError:
+      pass
+
+
+#manage DATA (set, verify, upload)   
+def setData(pars,crfEntry,schema):
+   datasets=getDatasets(pars,crfEntry['Form'])
+   for k in datasets:
+      d=datasets[k]
+      crf=crfEntry['entryId']
+#print('Setting [{}:{}/{}]'.format(schema,d['query'],d['variableDefinition']))
+      crfFilter={'variable':'crfRef','value':crf,'oper':'eq'}
+      qFilter=[crfFilter]
+      qvar=parseVariables(d['variableDefinition'])
+      qvarFilter=[{'variable':x['varName'],'value':x['varValue'],'oper':'eq'} for x in qvar]
+      qFilter.extend(qvarFilter)
+      parD={'schema':schema,'query':d['query'],'qFilter':qFilter}
+      rows=getRows(pars|parD)
+      try:
+         pars['data'][schema][k]=rows
+      except KeyError:
+         try:
+            pars['data'][schema]={k:rows}
+         except KeyError:
+            pars['data']={schema:{k:rows}}
+        
+def verifyData(pars,crfEntry,schema):
+   ok=True
+   datasets=getDatasets(pars,crfEntry['Form'])
+   for k in datasets:
+      d=datasets[k]
+      rows=pars['data'][schema][k]
+      testFailed={'lists':len(rows)!=1,'study':len(rows)>1}
+      if testFailed[schema]:
+         print('[{} {}/{}]: {}'.format(schema,d['query'],
+            d['variableDefinition'],len(rows)))
+         #at least one fail 
+         ok=False
+         continue
+   return ok
+
+       
+def uploadData(pars,crfEntry):
+   status=True
+   datasets=getDatasets(pars,crfEntry['Form'])
+   for k in datasets:
+      listRow=pars['data']['lists'][k][0]
+      studyRows=pars['data']['study'][k]
+      try:
+         outRow=studyRows[0]
+         outRow.update(listRow)
+         mode='update'
+      except IndexError:
+         outRow={x:listRow[x] for x in listRow}
+         mode='insert'
+         outRow['ParticipantId']=crfEntry['participantStudyId']
+         outRow['SequenceNum']=(int(crfEntry['entryId']) % 1000000000 )
+        
+        
+      d=datasets[k]
+      parD={'schema':'study','query':d['query']}
+      outcome=modifyRows(pars|parD,mode,[outRow])
+      try:
+         print(outcome['exception'])
+         status=False
+      except KeyError:
+         pass
+
+   return status
+
+## mimic CRF actions
+
+def onSubmitedToInProgress(pars,crf):
+   crfEntry=getCrfEntry(pars,crf)
+   statusIn=crfEntry['FormStatus']
+   if statusIn!=toStatus('Submitted'):
+      print(f'[{crf}]: Inappropriate status({statusIn})')
+      return
+   changeFormStatus(pars,crfEntry,'InProgress')
+
+def onApprovedToSubmited(pars,crf):
+   crfEntry=getCrfEntry(pars,crf)
+   statusIn=crfEntry['FormStatus']
+   if statusIn!=toStatus('Approved'):
+      print(f'[{crf}]: Inappropriate status({statusIn})')
+      return
+   changeFormStatus(pars,crfEntry,'Submitted')
+    
+def onSubmit(pars,crf):
+   crfEntry=getCrfEntry(pars,crf)
+   statusIn=crfEntry['FormStatus']
+   if statusIn!=toStatus('InProgress'):
+      print(f'[{crf}]: Inappropriate status({statusIn})')
+      return
+    
+   form=crfEntry['Form']
+   setData(pars,crfEntry,'lists')
+   status=verifyData(pars,crfEntry,'lists')
+   crf=crfEntry['entryId']
+   if not status:
+      print(f'[{crf}/{form}] verification failed')
+      return
+   changeFormStatus(pars,crfEntry,'Submitted')
+
+
+def onDatabaseUpload(pars,crf):
+   crfEntry=getCrfEntry(pars,crf)
+   statusIn=crfEntry['FormStatus']
+   if statusIn!=toStatus('Submitted'):
+      print(f'[{crf}]: Inappropriate status({statusIn})')
+      return
+    
+   form=crfEntry['Form']
+   setData(pars,crfEntry,'lists')
+   setData(pars,crfEntry,'study')
+   dataOK=verifyData(pars,crfEntry,'study')
+   if not dataOK:
+      print(f'[{crf}]: verification failed')
+      return
+   print(f'[{crf}]: verification OK')
+    
+   uploadOK=uploadData(pars,crfEntry)
+   if not uploadOK:
+      print(f'[{crf}]: upload failed')
+      return
+   print(f'[{crf}]: upload OK')
+   changeFormStatus(pars,crfEntry,'Approved')
+