Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def autofill(ctx, steps, metadata, fixed, study, environment, subject):
"""Request enterable data for a subject, generate data values and post back to Rave.
Requires 'rwscmd_getdata' configurable dataset to be installed on the Rave URL."""
if metadata is not None: # Read metadata from file, if supplied
odm_metadata = metadata.read()
meta_v = etree.fromstring(odm_metadata).find('.//' + E_ODM.METADATA_VERSION.value).get(A_ODM.OID.value)
else:
odm_metadata = None
meta_v = None
fixed_values = {}
if fixed is not None: # Read fixed values from file, if supplied
for f in fixed:
oid, value = f.decode().split(',')
fixed_values[oid] = value
if ctx.obj['VERBOSE']:
click.echo('Fixing {} to value: {}'.format(oid, value))
try:
for n in range(0, steps):
if ctx.obj['VERBOSE']:
click.echo('Step {}'.format(str(n + 1)))
def scramble_codelist(self, codelist):
"""Return random element from code list"""
# TODO: External code lists
path = ".//{0}[@{1}='{2}']".format(E_ODM.CODELIST.value, A_ODM.OID.value, codelist)
elem = self.metadata.find(path)
codes = []
for c in elem.iter(E_ODM.CODELIST_ITEM.value):
codes.append(c.get(A_ODM.CODED_VALUE.value))
for c in elem.iter(E_ODM.ENUMERATED_ITEM.value):
codes.append(c.get(A_ODM.CODED_VALUE.value))
return fake.random_element(codes)
def scramble_itemdata(self, oid, value):
"""If metadata provided, use it to scramble the value based on data type"""
if self.metadata is not None:
path = ".//{0}[@{1}='{2}']".format(E_ODM.ITEM_DEF.value, A_ODM.OID.value, oid)
elem = self.metadata.find(path)
# for elem in self.metadata.iter(E_ODM.ITEM_DEF.value):
datatype = elem.get(A_ODM.DATATYPE.value)
codelist = None
for el in elem.iter(E_ODM.CODELIST_REF.value):
codelist = el.get(A_ODM.CODELIST_OID.value)
length = 1 if not A_ODM.LENGTH in elem else int(elem.get(A_ODM.LENGTH.value))
if A_ODM.SIGNIFICANT_DIGITS.value in elem.keys():
sd = elem.get(A_ODM.SIGNIFICANT_DIGITS.value)
else:
sd = 0
if A_ODM.DATETIME_FORMAT.value in elem.keys():
def scramble_itemdata(self, oid, value):
"""If metadata provided, use it to scramble the value based on data type"""
if self.metadata is not None:
path = ".//{0}[@{1}='{2}']".format(E_ODM.ITEM_DEF.value, A_ODM.OID.value, oid)
elem = self.metadata.find(path)
# for elem in self.metadata.iter(E_ODM.ITEM_DEF.value):
datatype = elem.get(A_ODM.DATATYPE.value)
codelist = None
for el in elem.iter(E_ODM.CODELIST_REF.value):
codelist = el.get(A_ODM.CODELIST_OID.value)
length = 1 if not A_ODM.LENGTH in elem else int(elem.get(A_ODM.LENGTH.value))
if A_ODM.SIGNIFICANT_DIGITS.value in elem.keys():
sd = elem.get(A_ODM.SIGNIFICANT_DIGITS.value)
else:
sd = 0
if A_ODM.DATETIME_FORMAT.value in elem.keys():
dt_format = elem.get(A_ODM.DATETIME_FORMAT.value)
for fmt in [('yyyy', '%Y'), ('MMM', '%b'), ('dd', '%d'), ('HH', '%H'), ('nn', '%M'), ('ss', '%S'),
('-', '')]:
dt_format = dt_format.replace(fmt[0], fmt[1])
if codelist is not None:
def fill_empty(self, fixed_values, input):
"""Fill in random values for all empty-valued ItemData elements in an ODM document"""
odm_elements = etree.fromstring(input)
for v in odm_elements.iter(E_ODM.ITEM_DATA.value):
if v.get(A_ODM.VALUE.value) == "":
oid = v.get(A_ODM.ITEM_OID.value)
if fixed_values is not None and oid in fixed_values:
d = fixed_values[oid]
else:
d = self.scramble_itemdata(v.get(A_ODM.ITEM_OID.value), v.get(A_ODM.VALUE.value))
v.set(A_ODM.VALUE.value, d)
else:
# Remove ItemData if it already has a value
v.getparent().remove(v)
# Remove empty ItemGroupData elements
for v in odm_elements.iter(E_ODM.ITEM_GROUP_DATA.value):
if len(v) == 0:
if meta_v != subject_meta_v:
if ctx.obj['VERBOSE']:
click.echo('Getting metadata version {}'.format(subject_meta_v))
ctx.obj['RWS'].send_request(StudyVersionRequest(study, subject_meta_v))
odm_metadata = ctx.obj['RWS'].last_result.text
meta_v = subject_meta_v
# Generate data values to fill in empty fields
if ctx.obj['VERBOSE']:
click.echo('Generating data')
scr = Scramble(odm_metadata)
odm = scr.fill_empty(fixed_values, subject_data)
# If new data values, post to RWS
if etree.fromstring(odm).find('.//' + E_ODM.ITEM_DATA.value) is None:
if ctx.obj['VERBOSE']:
click.echo('No data to send')
break
ctx.obj['RWS'].send_request(PostDataRequest(odm))
if ctx.obj['RAW']:
click.echo(ctx.obj['RWS'].last_result.text)
except RWSException as e:
click.echo(e.rws_error)
except requests.exceptions.HTTPError as e:
click.echo(e.strerror)