def process_GET(self, request): # parse input arguments args = {} args['sid'] = request.args0.get('station_id', '') args['end'] = request.args0.get('datetime', 'NOW()') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT document_id, end_datetime FROM "gis_gps-data" WHERE station_id = :sid AND end_datetime <= :end ORDER BY end_datetime DESC LIMIT 1; """) try: result = self.env.db.query(query, **args).fetchone() if not result: return toString(xml) except: return toString(xml) s = Sub(xml, "resource", document_id=str(result.document_id)) Sub(s, 'station_id').text = args['sid'] Sub(s, 'last_datetime').text = (result.end_datetime).isoformat() return toString(xml)
def process_GET(self, request): # parse input arguments args = {} args['pid'] = request.args0.get('project_id', '') args['start'] = request.args0.get('start_datetime', '') args['end'] = request.args0.get('end_datetime', '') args['event'] = request.args0.get('event', '') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT DISTINCT document_id, event_type FROM "/seismology/event" WHERE event_type = :event AND datetime > :start AND datetime < :end """) #XXX project_id is missing in seismic events!!! # AND project_id = :pid try: result = self.env.db.query(query, **args) except: return toString(xml) for i in result: s = Sub(xml, "resource", document_id=str(i.document_id)) Sub(s, 'event_type').text = str(i.event_type) return toString(xml)
def process_GET(self, request): # parse input arguments args = {} args['pid'] = request.args0.get('project_id', '') args['vid'] = request.args0.get('volcano_id', '') args['start'] = request.args0.get('start_datetime', 'NOW()') args['end'] = request.args0.get('end_datetime', 'NOW()') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT event_type, count(event_type) AS event_count FROM "/seismology/event" WHERE datetime >= :start AND datetime <= :end GROUP BY event_type; """) try: result = self.env.db.query(query, **args) except: return toString(xml) for res in result: if not res.event_type: continue s = Sub(xml, "eventcount", type=res.event_type) s.text = str(res.event_count) return toString(xml)
def process_GET(self, request): # parse input arguments pid = request.args0.get('project_id', '') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT DISTINCT document_id, volcano_id, datetime, level, comment FROM "/exupery/alert-level" WHERE project_id = :pid """) try: result = self.env.db.query(query, pid=pid) except: return toString(xml) for i in result: s = Sub(xml, "resource", document_id=str(i.document_id)) Sub(s, 'volcano_id').text = i.volcano_id Sub(s, 'datetime').text = (i.datetime).isoformat() Sub(s, 'level').text = str(i.level) Sub(s, 'comment').text = i.comment return toString(xml)
def process_GET(self, request): # parse input arguments args = {} args['pid'] = request.args0.get('project_id', '') args['start'] = request.args0.get('start_datetime', '') args['end'] = request.args0.get('end_datetime', '') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT DISTINCT document_id, SO2_range3 FROM "/exupery/so2-gome2" WHERE project_id = :pid AND start_datetime > :start AND end_datetime < :end """) try: result = self.env.db.query(query, **args) except: return toString(xml) for i in result: s = Sub(xml, "resource", document_id=str(i.document_id)) Sub(s, 'SO2_range3').text = str(i.SO2_range3) return toString(xml)
def process_GET(self, request): # parse input arguments args = {} args['sid'] = request.args0.get('station_id', '') args['start'] = request.args0.get('start_datetime', 'NOW()') args['end'] = request.args0.get('end_datetime', 'NOW()') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT * FROM "/exupery/gps-data" WHERE station_id = :sid AND start_datetime >= :start AND end_datetime <= :end; """) try: result = self.env.db.query(query, **args) except: return toString(xml) for res in result: s = Sub(xml, "resource", document_id=str(res.document_id)) for id, value in res.items(): if id in ['start_datetime', 'end_datetime']: Sub(s, id).text = (value).isoformat() else: Sub(s, id).text = str(value) return toString(xml)
def process_GET(self, request): # parse input arguments pid = request.args0.get('project_id', '') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT document_id, start_datetime, end_datetime, local_path_image FROM "/exupery/so2-traj-disp" WHERE local_path_image IS NOT NULL AND project_id = :pid """) try: result = self.env.db.query(query, pid=pid) except: return toString(xml) for i in result: s = Sub(xml, "resource", document_id=str(i.document_id)) Sub(s, 'start_datetime').text = (i.start_datetime).isoformat() Sub(s, 'end_datetime').text = (i.end_datetime).isoformat() Sub(s, 'url').text = 'local://' + i.local_path_image return toString(xml)
def process_GET(self, request): tab = Table('/exupery/insar', request.env.db.metadata, autoload=True) # fetch arguments try: limit = int(request.args0.get('limit')) offset = int(request.args0.get('offset', 0)) except: limit = None offset = 0 oncl = sql.and_(1 == 1) # build up query columns = [tab.c['document_id'], tab.c['project_id'], tab.c['start_datetime'], tab.c['end_datetime'], tab.c['satellite'], tab.c[self.type_id]] query = sql.select(columns, oncl, limit=limit, distinct=True, offset=offset, order_by=tab.c['start_datetime']) # process arguments try: temp = request.args0.get('project_id') if temp: query = query.where(tab.c['project_id'] == temp) except: pass try: temp = request.args0.get('start_datetime') if temp: temp = UTCDateTime(temp) query = query.where(tab.c['start_datetime'] >= temp.datetime) except: pass try: temp = request.args0.get('end_datetime') if temp: temp = UTCDateTime(temp) query = query.where(tab.c['end_datetime'] < temp.datetime) except: pass # generate XML result xml = Element("query") # execute query try: results = request.env.db.query(query) except: return toString(xml) for i in results: s = Sub(xml, "resource", document_id=str(i.document_id)) try: temp = i.start_datetime.isoformat() except: temp = '' Sub(s, 'start_datetime').text = temp try: temp = i.end_datetime.isoformat() except: temp = '' Sub(s, 'end_datetime').text = temp Sub(s, 'satellite').text = i['satellite'] Sub(s, 'url').text = 'local://' + i[self.type_id] return toString(xml)
def process_GET(self, request): tab = Table('/exupery/infrared', request.env.db.metadata, autoload=True) # fetch arguments try: limit = int(request.args0.get('limit')) offset = int(request.args0.get('offset', 0)) except: limit = None offset = 0 oncl = sql.and_(1 == 1) # build up query columns = [tab.c['document_id'], tab.c['project_id'], tab.c['start_datetime'], tab.c['end_datetime'], tab.c['local_path_image'], tab.c['local_path_image_16bit']] query = sql.select(columns, oncl, limit=limit, distinct=True, offset=offset, order_by=tab.c['start_datetime']) query = query.where(tab.c['local_path_image'] != None) # process arguments try: temp = request.args0.get('project_id', '') query = query.where(tab.c['project_id'] == temp) except: pass # generate XML result xml = Element("query") # execute query try: results = request.env.db.query(query) except: return toString(xml) for i in results: s = Sub(xml, "resource", document_id=str(i.document_id)) try: temp = i.start_datetime.isoformat() except: temp = '' Sub(s, 'start_datetime').text = temp try: temp = i.end_datetime.isoformat() except: temp = '' Sub(s, 'end_datetime').text = temp Sub(s, 'url').text = 'local://' + i.local_path_image if i.local_path_image_16bit: path = 'local://' + i.local_path_image_16bit else: path = '' Sub(s, 'url16').text = path return toString(xml)
def process_GET(self, request): tab = Table('/exupery/psi', request.env.db.metadata, autoload=True) # fetch arguments try: limit = int(request.args0.get('limit')) offset = int(request.args0.get('offset', 0)) except: limit = None offset = 0 oncl = sql.and_(1 == 1) # build up query columns = [tab.c['document_id'], tab.c['project_id'], tab.c['volcano_id'], tab.c['start_datetime'], tab.c['end_datetime'], tab.c['local_path_kml']] query = sql.select(columns, oncl, limit=limit, distinct=True, offset=offset, order_by=tab.c['start_datetime']) # only with non empty local_path_kml query = query.where(tab.c['local_path_kml'] != None) # process arguments try: temp = request.args0.get('project_id') if temp: query = query.where(tab.c['project_id'] == temp) except: pass # generate XML result xml = Element("query") # execute query try: results = request.env.db.query(query) except: return toString(xml) for i in results: s = Sub(xml, "resource", document_id=str(i.document_id)) try: start = i.start_datetime.isoformat() except: start = '' try: end = i.end_datetime.isoformat() except: end = '' Sub(s, 'project_id').text = i['project_id'] Sub(s, 'volcano_id').text = i['volcano_id'] Sub(s, 'start_datetime').text = start Sub(s, 'end_datetime').text = end Sub(s, 'url').text = 'local://' + i.local_path_kml return toString(xml)
def process_GET(self, request): tab = Table('gis_gps-absdata', request.env.db.metadata, autoload=True) # fetch arguments try: limit = int(request.args0.get('limit')) offset = int(request.args0.get('offset', 0)) except: limit = None offset = 0 oncl = sql.and_(1 == 1) # build up query query = sql.select([tab], oncl, limit=limit, distinct=True, offset=offset, order_by=tab.c['start_datetime']) # process arguments try: temp = request.args0.get('station_id', '') query = query.where(tab.c['station_id'] == temp) except: pass try: temp = UTCDateTime(request.args0.get('start_datetime')) except: temp = UTCDateTime() query = query.where(tab.c['start_datetime'] >= temp.datetime) try: temp = UTCDateTime(request.args0.get('end_datetime')) except: temp = UTCDateTime() query = query.where(tab.c['end_datetime'] <= temp.datetime) # generate XML result xml = Element("query") # execute query try: results = request.env.db.query(query) except: return toString(xml) for res in results: s = Sub(xml, "resource", document_id=str(res.document_id)) for id, value in res.items(): if id in ['start_datetime', 'end_datetime']: Sub(s, id).text = (value).isoformat() else: Sub(s, id).text = str(value) return toString(xml)
def process_GET(self, request): # build up query session = self.env.db.session() query = session.query(WaveformPath.path, WaveformFile.file, WaveformChannel.network, WaveformChannel.station, WaveformChannel.location, WaveformChannel.channel) query = query.filter(WaveformPath.id == WaveformFile.path_id) query = query.filter(WaveformFile.id == WaveformChannel.file_id) # process arguments for key in ['network_id', 'station_id', 'location_id', 'channel_id']: text = request.args0.get(key, None) if text == None: continue col = getattr(WaveformChannel, key[:-3]) if text == "": query = query.filter(col == None) elif '*' in text or '?' in text: text = text.replace('?', '_') text = text.replace('*', '%') query = query.filter(col.like(text)) else: query = query.filter(col == text) # start and end time try: start = request.args0.get('start_datetime') start = UTCDateTime(start) except: start = UTCDateTime() - 60 * 20 finally: query = query.filter(WaveformChannel.endtime > start.datetime) try: end = request.args0.get('end_datetime') end = UTCDateTime(end) except: # 10 minutes end = UTCDateTime() finally: query = query.filter(WaveformChannel.starttime < end.datetime) # execute query file_dict = {} for result in query: fname = result[0] + os.sep + result[1] key = '%s.%s.%s.%s' % (result[2], result[3], result[4], result[5]) file_dict.setdefault(key, []).append(fname) # return as xml resource xml = Element("query") for _i in file_dict.keys(): s = Sub(xml, "channel", id=_i) for _j in file_dict[_i]: t = Sub(s, "file") t.text = _j session.close() return toString(xml)
def process_GET(self, request): # parse input arguments pid = request.args0.get('project_id', '') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT document_id, datetime, local_path_image_pressure, local_path_image_s1, local_path_image_s2, local_path_image_s3 FROM "/exupery/mogi" WHERE project_id = :pid """) try: result = self.env.db.query(query, pid=pid) except: return toString(xml) image_types = { 'pressure': 'local_path_image_pressure', 'sigma1': 'local_path_image_s1', 'sigma2': 'local_path_image_s2', 'sigma3': 'local_path_image_s3', } for i in result: for type, image_id in image_types.iteritems(): s = Sub(xml, "resource", document_id=str(i.document_id)) Sub(s, 'type').text = type Sub(s, 'datetime').text = (i.datetime).isoformat() Sub(s, 'url').text = 'local://' + i[image_id] return toString(xml)
def formatORMResults(request, query, build_url=False): """ """ base_url = request.env.getRestUrl() # create stats stats = {} stats['totalResultsAvailable'] = query.count() # limits or offset try: limit = int(request.args0.get('limit')) query = query.limit(limit) except: pass offset = int(request.args0.get('offset', 0)) query = query.offset(offset) stats['firstResultPosition'] = offset stats['totalResultsReturned'] = query.count() # get format formats = request.args.get('format', []) or request.args.get('output', []) if 'json' in formats: # build up JSON string data = stats data['Result'] = [] for result in query: temp = {} for key in result.keys(): value = getattr(result, key, '') temp[key] = str(value) data['Result'].append(temp) # add attributes to root node for key, value in stats.iteritems(): if not isinstance(value, list): data[key] = str(value) else: data[key] = value # generate correct header request.setHeader('content-type', 'application/json; charset=UTF-8') # create output return json.dumps({'ResultSet': data}, cls=CustomJSONEncoder, indent=4) elif 'xhtml' in formats: # build up a XHTML table html = Element("html") body = SubElement(html, "body") table = SubElement(body, "table", border="1") sub = SubElement(table, "tr") for key in query._entities: SubElement(sub, "th").text = str(key._label_name) # build URL if build_url: SubElement(sub, "th").text = "URL" for result in query: sub = SubElement(table, "tr") for key in result.keys(): value = getattr(result, key, '') if value == None: value = '' SubElement(sub, "td").text = str(value) # build URL if not build_url: continue url = '/'.join([base_url, 'xml', result['package_id'], result['resourcetype_id'], result['resource_name']]) td = SubElement(sub, 'td') SubElement(td, 'a', href=url).text = url # generate correct header request.setHeader('content-type', 'text/html; charset=UTF-8') return tostring(html, method='html', encoding='utf-8') else: # build up XML document xml = Element("ResultSet") for result in query: sub = SubElement(xml, "Item") for key in result.keys(): value = getattr(result, key, '') SubElement(sub, key).text = str(value) # build URL if not build_url: continue SubElement(sub, 'url').text = '/'.join([base_url, 'xml', result['package_id'], result['resourcetype_id'], result['resource_name']]) # add attributes to root node for key, value in stats.iteritems(): xml.set(key, str(value)) return toString(xml)
def formatResults(request, results, count=None, limit=None, offset=0, build_url=False): """ Fetches results from database and creates either a XML resource or a JSON document. It also takes care of limit and offset requests. """ base_url = request.env.getRestUrl() # create stats stats = {} stats['firstResultPosition'] = offset # get format formats = request.args.get('format', []) or request.args.get('output', []) if 'json' in formats: # build up JSON string data = stats data['Result'] = [dict(r) for r in results] data['totalResultsReturned'] = limit or len(data['Result']) data['totalResultsAvailable'] = count or len(data['Result']) # generate correct header request.setHeader('content-type', 'application/json; charset=UTF-8') # create output return json.dumps({'ResultSet': data}, cls=CustomJSONEncoder, indent=4) elif 'xhtml' in formats: # build up a XHTML table html = Element("html") body = SubElement(html, "body") table = SubElement(body, "table", border="1") sub = SubElement(table, "tr") for key in results.keys(): SubElement(sub, "th").text = str(key) # build URL if build_url: SubElement(sub, "th").text = "URL" for result in results: sub = SubElement(table, "tr") for value in result: if value == None: value = '' SubElement(sub, "td").text = str(value) # build URL if not build_url: continue url = '/'.join([base_url, 'xml', result['package_id'], result['resourcetype_id'], result['resource_name']]) td = SubElement(sub, 'td') SubElement(td, 'a', href=url).text = url # generate correct header request.setHeader('content-type', 'text/html; charset=UTF-8') return tostring(html, method='html', encoding='utf-8') else: # build up XML document xml = Element("ResultSet") i = 0 for result in results: i = i + 1 sub = SubElement(xml, "Item") for (key, value) in dict(result).iteritems(): if value == None: value = '' SubElement(sub, key).text = str(value) # build URL if not build_url: continue SubElement(sub, 'url').text = '/'.join([base_url, 'xml', result['package_id'], result['resourcetype_id'], result['resource_name']]) # add attributes to root node stats['totalResultsReturned'] = limit or i stats['totalResultsAvailable'] = count or i for key, value in stats.iteritems(): xml.set(key, str(value)) return toString(xml)
def process_GET(self, request): # parse input arguments args = {} args['pid'] = request.args0.get('project_id', '') args['start'] = request.args0.get('start_datetime', '') args['end'] = request.args0.get('end_datetime', '') # generate XML result xml = Element("query") # build up and execute query query = sql.text(""" SELECT DISTINCT document_id, station_id FROM "/exupery/gps-station" WHERE project_id = :pid AND start_datetime < :start AND end_datetime > :end """) try: available_stations = self.env.db.query(query, **args) except: return toString(xml) # extracts the absolute height and height confidence for each station for s in available_stations: # MONITOR sid = s.station_id query = sql.text(""" SELECT DISTINCT document_id, abs_height, abs_height_conf, start_datetime FROM "/exupery/gps-data" WHERE project_id = :pid AND station_id = :sid ORDER BY start_datetime ASC LIMIT 1 """) try: monitor = self.env.db.query(query, sid=sid, **args) except: print "Exception Monitor" continue #BASELINE query = sql.text(""" SELECT DISTINCT document_id, abs_height, abs_height_conf, start_datetime FROM "/exupery/gps-data" WHERE project_id = :pid AND station_id = :sid ORDER BY start_datetime DESC LIMIT 1 """) try: baseline = self.env.db.query(query, sid=sid, **args) except: print "Exception BASELINE" continue # We only get this far if we have a valid baseline and monitor s = Sub(xml, "station", id=str(sid), document_id=str(s.document_id)) for j in monitor: t = Sub(s, "monitor", document_id=str(j.document_id)) Sub(t, 'start_datetime').text = (j.start_datetime).isoformat() Sub(t, 'abs_height').text = str(j.abs_height) Sub(t, 'abs_height_conf').text = str(j.abs_height_conf) for k in baseline: u = Sub(s, "baseline", document_id=str(k.document_id)) Sub(u, 'start_datetime').text = (k.start_datetime).isoformat() Sub(u, 'abs_height').text = str(k.abs_height) Sub(u, 'abs_height_conf').text = str(k.abs_height_conf) return toString(xml)
def formatResults(request, results, count=None, limit=None, offset=0, build_url=False): """ Takes a list of (potentially nested) dictionaries and produces output in XML, JSON or XHTML. The limit and offset kwargs have to be provided by the user. Also sets the correct HTML headers. """ base_url = request.env.getRestUrl() # create stats stats = {} stats['firstResultPosition'] = offset # get format formats = request.args.get('format', []) or request.args.get('output', []) if 'json' in formats: # build up JSON string data = stats data['Result'] = [dict(r) for r in results] data['totalResultsReturned'] = len(data['Result']) data['totalResultsAvailable'] = count or len(data['Result']) # generate correct header request.setHeader('content-type', 'application/json; charset=UTF-8') # create output return json.dumps({'ResultSet': data}, cls=CustomJSONEncoder, indent=4) elif 'xhtml' in formats: # build up a XHTML table html = Element("html") body = SubElement(html, "body") table = SubElement(body, "table", border="1") sub = SubElement(table, "tr") # In xhtml the order of keys matters as we want to build a table. # If the result object is a sqlalchemy.engine.base.ResultProxy object, # use the key order stored there, otherwise just sort the keys # alphabetically. if hasattr(results, "keys"): keys = [str(_i) for _i in results.keys()] else: keys = sorted([str(_i) for _i in results[0].keys()]) for key in keys: SubElement(sub, "th").text = key # build URL if build_url: SubElement(sub, "th").text = "URL" for result in results: sub = SubElement(table, "tr") for key in keys: try: value = result[key] except: value = "" if value is None: value = "" SubElement(sub, "td").text = str(value) # build URL if not build_url: continue url = '/'.join([base_url, 'xml', result['package_id'], result['resourcetype_id'], result['resource_name']]) td = SubElement(sub, 'td') SubElement(td, 'a', href=url).text = url # generate correct header request.setHeader('content-type', 'text/html; charset=UTF-8') return tostring(html, method='html', encoding='utf-8', pretty_print=True) else: def toXML(root, item): """ Recursively translate a dict of dicts/lists to a SubElement structure. Can deal with nested dicts and lists of dictionaries, e.g. item = {"root": {"item1": "a", "list_of_a": [{"a": "2"}, {"a": "3"}]}} would results in <root> <item1>a</item1> <list_of_a> <a>2</a> <a>3</a> </list_of_a> </root> """ try: item = dict(item) except: pass if isinstance(item, dict): for (key, value) in item.iteritems(): new_root = SubElement(root, key) toXML(new_root, value) elif hasattr(item, "__iter__"): for sub_item in item: toXML(root, sub_item) else: if item is None: item = "" elif item is True: item = "true" elif item is False: item = "false" root.text = str(item) # build up XML document xml = Element("ResultSet") i = 0 for result in results: i += 1 sub = SubElement(xml, "Item") toXML(sub, result) # build URL if not build_url: continue SubElement(sub, 'url').text = '/'.join([base_url, 'xml', result['package_id'], result['resourcetype_id'], result['resource_name']]) # add attributes to root node stats['totalResultsReturned'] = i stats['totalResultsAvailable'] = count or i for key, value in stats.iteritems(): xml.set(key, str(value)) request.setHeader('content-type', 'text/xml; charset=UTF-8') return toString(xml)
def formatResults(request, results, count=None, limit=None, offset=0, build_url=False): """ Takes a list of (potentially nested) dictionaries and produces output in XML, JSON or XHTML. The limit and offset kwargs have to be provided by the user. Also sets the correct HTML headers. """ base_url = request.env.getRestUrl() # create stats stats = {} stats['firstResultPosition'] = offset # get format formats = request.args.get('format', []) or request.args.get('output', []) if 'json' in formats: # build up JSON string data = stats data['Result'] = [dict(r) for r in results] data['totalResultsReturned'] = len(data['Result']) data['totalResultsAvailable'] = count or len(data['Result']) # generate correct header request.setHeader('content-type', 'application/json; charset=UTF-8') # create output return json.dumps({'ResultSet': data}, cls=CustomJSONEncoder, indent=4) elif 'xhtml' in formats: # build up a XHTML table html = Element("html") body = SubElement(html, "body") table = SubElement(body, "table", border="1") sub = SubElement(table, "tr") # In xhtml the order of keys matters as we want to build a table. # If the result object is a sqlalchemy.engine.base.ResultProxy object, # use the key order stored there, otherwise just sort the keys # alphabetically. if hasattr(results, "keys"): keys = [str(_i) for _i in results.keys()] else: keys = sorted([str(_i) for _i in results[0].keys()]) for key in keys: SubElement(sub, "th").text = key # build URL if build_url: SubElement(sub, "th").text = "URL" for result in results: sub = SubElement(table, "tr") for key in keys: try: value = result[key] except: value = "" if value is None: value = "" SubElement(sub, "td").text = str(value) # build URL if not build_url: continue url = '/'.join([base_url, 'xml', result['package_id'], result['resourcetype_id'], result['resource_name']]) td = SubElement(sub, 'td') SubElement(td, 'a', href=url).text = url # generate correct header request.setHeader('content-type', 'text/html; charset=UTF-8') return tostring(html, method='html', encoding='utf-8', pretty_print=True) else: def toXML(root, item): """ Recursively translate a dict of dicts/lists to a SubElement structure. Can deal with nested dicts and lists of dictionaries, e.g. item = {"root": {"item1": "a", "list_of_a": [{"a": "2"}, {"a": "3"}]}} would results in <root> <item1>a</item1> <list_of_a> <a>2</a> <a>3</a> </list_of_a> </root> """ try: item = dict(item) except: pass if isinstance(item, dict): for (key, value) in item.iteritems(): new_root = SubElement(root, key) toXML(new_root, value) elif hasattr(item, "__iter__"): for sub_item in item: toXML(root, sub_item) else: root.text = str(item) # build up XML document xml = Element("ResultSet") i = 0 for result in results: i += 1 sub = SubElement(xml, "Item") toXML(sub, result) # build URL if not build_url: continue SubElement(sub, 'url').text = '/'.join([base_url, 'xml', result['package_id'], result['resourcetype_id'], result['resource_name']]) # add attributes to root node stats['totalResultsReturned'] = i stats['totalResultsAvailable'] = count or i for key, value in stats.iteritems(): xml.set(key, str(value)) request.setHeader('content-type', 'text/xml; charset=UTF-8') return toString(xml)