#! /usr/bin/env python3.
# create ig definition file with all value sets in the /resources directory
import json, os, sys, logging, re
from lxml import etree
#logging.disable(logging.CRITICAL)
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s')
logging.info('Start of program')
logging.info('The logging module is working.')
# create the ig.json file template as dictoinary
'''
ig_template = open(dir +'ig-template.json') #ig-template lack spreadsheet and valueset information
igjson = ig_template.read() # convert to strings
igpy =json.loads(igjson) # convert to py dict format
'''
logging.info('create the ig.json file template as dictionary')
# globals
dir='/Users/ehaas/Documents/FHIR/DAF-Research/'
# the ig.json file template as dict
igpy = {"paths":{"temp":"temp","specification":"http://build.fhir.org","qa":"qa","txCache":"txCache","output":"output","pages":"pages","resources":["resources","examples"]},"extraTemplates":["mappings"],"defaults":{"StructureDefinition":{"template-base":"sd.html","template-defns":"sd-definitions.html","template-mappings":"sd-mappings.html"},"CapabilityStatement":{"template-base":"capst.html"},"CodeSystem":{"template-base":"codesys.html"},"ConceptMap":{"template-base":"cm.html"},"Any":{"template-format":"format.html","template-base":"base.html"},"ValueSet":{"template-base":"vs.html"}},"source":"ig.xml","canonicalBase":"http://hl7.org/fhir/us/daf-research","tool":"jekyll","sct-edition":"http://snomed.info/sct/731000124108","dependencyList":[{"name":"uscore","location":"http://build.fhir.org/ig/Healthedata1/US-Core","source":"resources"}],"spreadsheets":[],"resources":{},"fixed-business-version" : "1.0.0"}
# the ig.xml file template as stringgit pu
igxml =''''''
# extension in spreadsheet - these need to be manually listed here needs to be named same as SD files ( eg: daf-[id])
extensions = ['daf-data-model', 'daf-query-format']
# operation in spreadsheet - these need to be manually listed here
operations = []
# search in spreadsheet - these need to be manually listed here
searches = []
#if valueset in spreadsheet is a codesystem - these need to be manually listed here
codesystems = []
#if valueset in spreadsheet is not a codesystem - these need to be manually listed
valuesets = []
# ====================== this is all the same for all IGs ===================
# Function definitions here
def update_sd(i,type):
namespaces = {'o': 'urn:schemas-microsoft-com:office:office',
'x': 'urn:schemas-microsoft-com:office:excel',
'ss': 'urn:schemas-microsoft-com:office:spreadsheet', }
igpy['spreadsheets'].append(i)
logging.info('adding ' + i + ' to spreadsheets array')
sd_file = open(dir + 'resources/' + i) # for each spreadsheet in /resources open value and read SD id and create and append dict struct to definiions file
sdxml = etree.parse(sd_file) # lxml module to parse excel xml
sdid = sdxml.xpath('/ss:Workbook/ss:Worksheet[2]/ss:Table/ss:Row[11]/ss:Cell[2]/ss:Data',
namespaces=namespaces) # use xpath to get the id from the spreadsheet and lower case
update_igjson(type, sdid[0].text.lower()) # add base to definitions file
update_igjson(type, sdid[0].text.lower(), 'defns') # add base to definitions file
return
def update_igxml(type, purpose, id):
ev = 'false'
if purpose == "example":
ev = 'true'
vsxml = '' # concat id into appropriate string
global igxml
igxml = igxml.replace('name value="base"/>',
'name value="base"/>' + vsxml) # add valueset base def to ig resource
logging.info('adding ' + type + vsxml + ' to resources in ig.xml')
return
def update_igjson(type, id, template = 'base', filename = "blah"): # add base to ig.json - can extend for other templates if needed with extra 'template' param
if template == 'base':
igpy['resources'][type + '/' + id] = {
template : type + '-' + id + '.html'} # concat id into appropriate strings and add valuset base def to resources in def file
logging.info('adding ' + type + ' ' + id + ' base to resources ig.json')
if template == 'source':
igpy['resources'][type + '/' + id][template] = filename # concat filename + xml into appropriate strings and add source in def file
logging.info('adding ' + id + ' source filename to resources ig.json')
if template == 'defns':
igpy['resources'][type + '/' + id][template] = type + '-' + id + '-definitions.html' # concat id into appropriate strings and add sd defitions to in def file
logging.info('adding ' + type + ' ' + id + ' definitions to resources ig.json')
return
def update_def(filename, type, purpose):
vsid_re = re.compile(r'') # regex for finding the index in vs
vs_file = open(
dir + 'resources/' + filename) # can use a package like untangle or Xmltodict but I'm gonna regex it for now"
vsxml = vs_file.read() # convert to string
vsmo = vsid_re.search(vsxml) # get match object which contains id
vsid = vsmo.group(1) # get id as string
update_igjson(type, vsid) # add base to definitions file
update_igjson(type, vsid, 'source', filename) # add source filename to definitions file
if type == 'StructureDefinition':
update_igjson(type, vsid, 'defns') # add base to definitions file
update_igxml(type, purpose, vsid)
return
def update_example(type, id, filename):
update_igxml(type, 'example', id) # add example to ig.xml file
update_igjson(type, id ) # add example base to definitions file
update_igjson(type, id,'source', filename) # add source filename to definitions file
igpy['defaults'][type] = {'template-base': 'ex.html'} # add example template for type
logging.info('adding example template to type ' +type + ' in ig.json')
return
def get_file(e):
ex_file = open(dir + 'examples/' + e) # for each example in /examples open
logging.info('load example xml file ' + dir + 'examples/' + e)
return ex_file
def main():
resources = os.listdir(dir + 'resources') # get all the files in the resource directory
for i in range(len(resources)): # run through all the files looking for spreadsheets and valuesets
if 'spreadsheet' in resources[i]: # for spreadsheets append to the igpy[spreadsheet] array.
update_sd(resources[i], 'StructureDefinition')
if 'valueset' in resources[
i]: # for each vs in /resources open valueset resources and read id and create and append dict struct to definiions file
update_def(resources[i], 'ValueSet', 'terminology')
if 'codesystem' in resources[
i]: # for each vs in /resources open valueset resources and read id and create and append dict struct to definiions file
update_def(resources[i], 'CodeSystem', 'terminology')
if 'conceptmap' in resources[
i]: # for each vs in /resources open valueset resources and read id and create and append dict struct to definiions file
update_def(resources[i], 'ConceptMap', 'terminology')
if 'capabilitystatement' in resources[
i]: # for each cs in /resources open, read id and create and append dict struct to definiions file
update_def(resources[i], 'CapabilityStatement', 'conformance')
if 'operationdefinition' in resources[
i]: # for each cs in /resources open, read id and create and append dict struct to definiions file
update_def(resources[i], 'OperationDefinition', 'conformance')
if 'structuredefinition' in resources[
i]: # for each cs in /resources open, read id and create and append dict struct to definiions file
update_def(resources[i], 'StructureDefinition', 'conformance')
if 'searchparameter' in resources[
i]: # for each cs in /resources open, read id and create and append dict struct to definiions file
update_def(resources[i], 'SearchParameter', 'conformance')
# add spreadsheet extensions
for extension in extensions:
update_igjson('StructureDefinition', extension, 'base')
update_igjson('StructureDefinition', extension, 'defns')
# add spreadsheet operations
for operation in operations:
update_igjson('OperationDefinition', operation, 'base')
# add spreadsheet search parameters
for search in searches:
update_igjson('SearchParameter', search, 'base')
# add spreadsheet code systems
for codesystem in codesystems:
update_igjson('CodeSystem', codesystem, 'base')
update_igjson('ValueSet', codesystem, 'base')
# add spreadsheet valuesets
for valueset in valuesets:
update_igjson('ValueSet', valueset, 'base')
examples = os.listdir(
dir + 'examples') # get all the examples in the examples directory assuming are in json or xml
for i in range(len(examples)): # run through all the examples and get id and resource type
if 'json' in examples[
i]: # for each cs in /resources open, read id and create and append dict struct to definiions file
exjson = json.load(get_file(examples[i]))
extype = exjson['resourceType']
ex_id = exjson['id']
update_example(extype, ex_id, examples[i])
if 'xml' in examples[
i]: # for each cs in /resources open, read id and create and append dict struct to definiions file
ex_xml = etree.parse(get_file(examples[i])) # lxml module to parse example xml
ex_id = ex_xml.xpath('//f:id/@value', namespaces={'f': 'http://hl7.org/fhir'}) # use xpath to get the id
extype = ex_xml.xpath('name(/*)') # use xpath to get the type '''
update_example(extype, ex_id[0], examples[i])
# write files
ig_file = open(dir + 'ig.json', 'w')
ig_file.write(json.dumps(igpy)) # convert dict to json and replace ig.json with this file
logging.info('ig.json now looks like : ' + json.dumps(igpy))
ig_file = open(dir + 'resources/ig.xml', 'w')
ig_file.write(igxml) # replace ig.xml with this file
logging.info('ig.xml now looks like : ' + igxml)
return
#main
if __name__ == '__main__':
main()
logging.info('End of program')