mdsol / rwslib

Provide a (programmer) friendly client library to Rave Web Services (RWS).
MIT License
31 stars 13 forks source link

How to retrieve definition of form field variable format rules? #119

Closed vagarwal77 closed 3 years ago

vagarwal77 commented 3 years ago

Hello,

I need some help to understand format rules and how to get them via rwslib? Heigh field (M_VSSTAT_HEIGHT) has a format of "$10". Where and how i can get these rules via rwelib so, we can have client side validations also?

We have seen different formats like $10, $10.4, 6, 3 etc etc image

isparks commented 3 years ago

You can download the CDISC ODM format of a study via the MetadataVersions endpoint. This includes the data format for forms. You need to parse the ODM XML format yourself but it's not rocket surgery.

See: https://rwslib.readthedocs.io/en/latest/working_architect.html#studyversionrequest-projectname-oid

Note that as the docs say, there isn't a way to get an ODM document representing a Draft only a Version. The difference for those that don't know and may be listening in, is that a Version is a Draft that has been "published".

glow-mdsol commented 3 years ago

You can compose the original Rave data formats from the metadata in the ODM; the mdsol:VariableOIDon the odm:ItemDef can be used to identify the variable and then by looking at odm:DataType, odm:Length and odm:SignificantDigits attributes you should be able to reconstitute the Rave Variable format. Similarly for the odm:CodeListRef and odm:MeasurementUnitRef for the Data Dictionaries and Unit Dictionaries, respectively.

glow-mdsol commented 3 years ago

Something like the following should work....

def extract_variable(idef, ns):
    """
    Extract a Variable from an ItemDef
    :param Element idef: ItemDef instance
    :param dict ns: namespace
    :rtype OE
    """
    variable = dict(OID=idef.get(mdsol("VariableOID")), DataType=idef.get("DataType"))
    if idef.get("Length") is not None:
        variable["Length"] = int(idef.get("Length"))
    if idef.find("./odm:CodeListRef", namespaces=ns) is not None:
        cl = idef.find("./odm:CodeListRef", namespaces=ns)
        variable["DataDictionary"] = cl.get("CodeListOID")
    if idef.get(mdsol("CodingDictionary")) is not None:
        variable["CodingDictionary"] = idef.get(mdsol("CodingDictionary"))
    measurement_units = extract_measurement_unit_refs(idef, ns)
    if measurement_units:
        for item in measurement_units:
            if not item.Fixed:
                # only add the UnitDictionary (only at the Variable level for the UnitDictionary)
                variable["UnitDictionary"] = item.UnitDictionary
    if idef.get("DataType") == "text":
        variable["DataFormat"] = f"${idef.get('Length')}"
    elif idef.get("DataType") in ("integer",):
        variable["DataFormat"] = idef.get("Length")
    elif idef.get("DataType") in ("float",):
        variable["DataFormat"] = f"{idef.get('Length')}.{idef.get('SignificantDigits')}"
    elif idef.get("DataType") in ("date", "time", "datetime"):
        variable["DataFormat"] = idef.get(mdsol("DateTimeFormat"))
    return OE("Variable", variable)

Closing this...