import requests def inventory_request(url, attributes): """ Thin wrapper for PSI Inventory system (I4). This wrapper does nothing more than sanitises output (decompresses dict) and takes care of dict to json conversion for attributes and json to dict conversion for response. Use: https://inventory.psi.ch/#action=Introspection for details Example usage: Query: query = {"query": [ {"Field": "Holy List Name", "Operator": "Is", "Value": holy_name}, {"Field": 'Type', "Operator": "Is", "Value": type} ], "columns": ["Label"]} attr = {"search": query} r = inventory_request('https://inventory.psi.ch/DataAccess.asmx/FindObjects', attr) Fetch atributes for part: attributes = inventory_request('https://inventory.psi.ch/DataAccess.asmx/GetPartAttributes', {'psiLabel': part_id}) :param url: Inventory URL endpoint :param attributes: Python dict of attributes :return: """ r = requests.post(url, json=attributes) if not r.ok: raise ConnectionError("Inventory returned error: ", r.json()) return r.json()['d'] def find_partid_by_holy(holy_name, type="DSCR"): """ :param holy_name: :param type: :return: Returns first partId that matches holy_name and type """ query = {"query": [ {"Field": "Holy List Name", "Operator": "Is", "Value": holy_name}, {"Field": 'Type', "Operator": "Is", "Value": type} ], "columns": ["Label"]} attr = {"search": query} r = inventory_request('https://inventory.psi.ch/DataAccess.asmx/FindObjects', attr) try: id = r['Rows'][0][0] except: return None return id def find_all_by_type(type="DSCR", column = "Holy List Name"): """ :param type: Type to match :param column: Label, Holy List Name, ... :return: List """ query = {"query": [ {"Field": 'Type', "Operator": "Is", "Value": type} ], "columns": [column]} attr = {"search": query} r = inventory_request('https://inventory.psi.ch/DataAccess.asmx/FindObjects', attr) rows = [] for i in r['Rows']: rows.append(i[0]) return rows def get_part_attributes_from_inventory(part_label = None, holy_name = None): if holy_name: part_label = find_partid_by_holy(holy_name, "DSCR") if not part_label: raise RuntimeError("Could not find inventory part for >>{}<<".format(holy_name)) return inventory_request('https://inventory.psi.ch/DataAccess.asmx/GetPartAttributes', {'psiLabel': part_label}) def get_logbook_from_inventory(part_label = None, holy_name = None): import re attributes = get_part_attributes_from_inventory(part_label, holy_name) elog_link = None for a in attributes: if a['Name'] == 'Elog': try: elog_link = a['Value'] elog_link = re.findall('http(?:s|)://[^\s]*') if elog_link: elog_link = elog_link[0] else: elog_link = None except TypeError: elog_link = None return elog_link def get_calib_from_invetory(part_label = None, holy_name = None): horizontal_dist = 0.0 vertical_dist = 0.0 horizontal_tilt = 0.0 vertical_tilt = 0.0 attributes = get_part_attributes_from_inventory(part_label, holy_name) for a in attributes: if a['Name'] == 'Crystal angle in x (e-beam system) [deg]': try: horizontal_tilt = float(a['Value']) except TypeError: pass if a['Name'] == 'Crystal angle in y (e-beam system) [deg]': try: vertical_tilt = float(a['Value']) except TypeError: pass if a['Name'] == 'Mark distance in x (e-beam system) [mm]': try: horizontal_dist = float(a['Value']) * 1e3 except TypeError: pass if a['Name'] == 'Mark distance in y (e-beam system) [mm]': try: vertical_dist = float(a['Value']) * 1e3 except TypeError: pass return horizontal_dist, vertical_dist, horizontal_tilt, vertical_tilt print get_calib_from_invetory(None, "SINEG01-DSCR190")