def load_batch(server_context, assay_id, batch_id): """ Loads a batch from the server. :param server_context: A LabKey server context. See utils.create_server_context. :param assay_id: The protocol id of the assay from which to load a batch. :param batch_id: :return: """ load_batch_url = build_url(server_context, 'assay', 'getAssayBatch.api') session = server_context['session'] loaded_batch = None payload = { 'assayId': assay_id, 'batchId': batch_id } headers = { 'Content-type': 'application/json', 'Accept': 'text/plain' } try: response = session.post(load_batch_url, data=json.dumps(payload, sort_keys=True), headers=headers) json_body = handle_response(response) if json_body is not None: loaded_batch = Batch.from_data(json_body['batch']) except SSLError as e: raise ServerContextError(e) return loaded_batch
def delete_rows(server_context, schema_name, query_name, rows, container_path=None, timeout=_default_timeout): """ Delete a set of rows from the schema.query :param server_context: A LabKey server context. See utils.create_server_context. :param schema_name: schema of table :param query_name: table name to delete from :param rows: Set of rows to delete :param container_path: labkey container path if not already set in context :param timeout: timeout of request in seconds (defaults to 30s) :return: """ url = build_url(server_context, 'query', 'deleteRows.api', container_path=container_path) payload = { 'schemaName': schema_name, 'queryName': query_name, 'rows': rows } # explicit json payload and headers required for form generation delete_rows_response = _make_request(server_context, url, json.dumps(payload, sort_keys=True), headers=_query_headers, timeout=timeout) return delete_rows_response
def load_batch(server_context, assay_id, batch_id): """ Loads a batch from the server. :param server_context: A LabKey server context. See utils.create_server_context. :param assay_id: The protocol id of the assay from which to load a batch. :param batch_id: :return: """ load_batch_url = build_url(server_context, 'assay', 'getAssayBatch.api') session = server_context['session'] loaded_batch = None payload = {'assayId': assay_id, 'batchId': batch_id} headers = {'Content-type': 'application/json', 'Accept': 'text/plain'} try: response = session.post(load_batch_url, data=json.dumps(payload, sort_keys=True), headers=headers) json_body = handle_response(response) if json_body is not None: loaded_batch = Batch.from_data(json_body['batch']) except SSLError as e: raise ServerContextError(e) return loaded_batch
def execute_sql(server_context, schema_name, sql, container_path=None, max_rows=None, sort=None, offset=None, container_filter=None, save_in_session=None, parameters=None, required_version=None, timeout=_default_timeout): """ Execute sql query against a LabKey server. :param server_context: A LabKey server context. See utils.create_server_context. :param schema_name: schema of table :param sql: String of labkey sql to execute :param container_path: labkey container path if not already set in context :param max_rows: max number of rows to return :param sort: comma separated list of column names to sort by :param offset: number of rows to offset results by :param container_filter: enumeration of the various container filters available. See: https://www.labkey.org/download/clientapi_docs/javascript-api/symbols/LABKEY.Query.html#.containerFilter :param save_in_session: save query result as a named view to the session :param parameters: parameter values to pass through to a parameterized query :param required_version: Api version of response :param timeout: timeout of request in seconds (defaults to 30s) :return: """ url = build_url(server_context, 'query', 'executeSql.api', container_path=container_path) payload = { 'schemaName': schema_name, 'sql': sql } if container_filter is not None: payload['containerFilter'] = container_filter if max_rows is not None: payload['maxRows'] = max_rows if offset is not None: payload['offset'] = offset if sort is not None: payload['query.sort'] = sort if save_in_session is not None: payload['saveInSession'] = save_in_session if parameters is not None: payload['query.parameters'] = parameters if required_version is not None: payload['apiVersion'] = required_version execute_sql_response = _make_request(server_context, url, payload, timeout=timeout) return execute_sql_response
def save_batches(server_context, assay_id, batches): """ Saves a modified batches. :param server_context: A LabKey server context. See utils.create_server_context. :param assay_id: The assay protocol id. :param batches: The Batch(es) to save. :return: """ save_batch_url = build_url(server_context, 'assay', 'saveAssayBatch.api') session = server_context['session'] json_batches = [] if batches is None: return None # Nothing to save for batch in batches: if isinstance(batch, Batch): json_batches.append(batch.to_json()) else: raise Exception('save_batch() "batches" expected to be a set Batch instances') payload = { 'assayId': assay_id, 'batches': json_batches } headers = { 'Content-type': 'application/json', 'Accept': 'text/plain' } try: # print(payload) response = session.post(save_batch_url, data=json.dumps(payload, sort_keys=True), headers=headers) json_body = handle_response(response) if json_body is not None: resp_batches = json_body['batches'] return [Batch.from_data(resp_batch) for resp_batch in resp_batches] except SSLError as e: raise ServerContextError(e) return None
def save_batches(server_context, assay_id, batches): """ Saves a modified batches. :param server_context: A LabKey server context. See utils.create_server_context. :param assay_id: The assay protocol id. :param batches: The Batch(es) to save. :return: """ save_batch_url = build_url(server_context, 'assay', 'saveAssayBatch.api') session = server_context['session'] json_batches = [] if batches is None: return None # Nothing to save for batch in batches: if isinstance(batch, Batch): json_batches.append(batch.to_json()) else: raise Exception( 'save_batch() "batches" expected to be a set Batch instances') payload = {'assayId': assay_id, 'batches': json_batches} headers = {'Content-type': 'application/json', 'Accept': 'text/plain'} try: # print(payload) response = session.post(save_batch_url, data=json.dumps(payload, sort_keys=True), headers=headers) json_body = handle_response(response) if json_body is not None: resp_batches = json_body['batches'] return [Batch.from_data(resp_batch) for resp_batch in resp_batches] except SSLError as e: raise ServerContextError(e) return None
def post_message(server_context, message_title, message_body, render_as, container_path=None): """ Post a message to a message board on a LabKey instance. :param server_context: A LabKey server context. See utils.create_server_context. :param message_title: The title of the message. :param message_body: The content of the message. :param render_as: The content of the message. :param container_path: Optional container path that can be used to override the server_context container path :return: Returns 1 if successful, 0 is post failed. """ # Build the URL for querying LabKey Server message_url = build_url(server_context, 'announcements', 'insert.api', container_path=container_path) message_data = { 'title': message_title, 'body': message_body, 'rendererType': render_as } session = server_context['session'] try: message_response = session.post(message_url, message_data) except SSLError as e: print("There was problem while attempting to submit the message to " + str(e.geturl()) + ". The HTTP response code was " + str(e.getcode())) print("The HTTP client error was: " + format(e)) return 0 return 1
def update_wiki(server_context, wiki_name, wiki_body, container_path=None): """ Used to update an existing wiki page :param server_context: A LabKey server context. See labkey.utils.create_server_context. :param wiki_name: The name of the wiki. :param wiki_body: The body of the wiki. :param container_path: Optional container path that can be used to override the server_context container path :return: returns a dictionary containing the response from the server. The 'success' key in the dictionary will be true when the wiki was successfully updated. It will be false in the case of a failure. In the case of a failure, the 'error' key contains the error message returned by the server. """ # Build the URL for reading the wiki page read_wiki_url = build_url(server_context, 'wiki', 'editWiki.api', container_path=container_path) payload = {'name': wiki_name} headers = {'Content-type': 'application/json'} session = server_context['session'] try: read_response = session.get(read_wiki_url, params=payload, headers=headers) except SSLError as e: print( "There was a problem while attempting to submit the read for the wiki page " + str(wiki_name) + " via the URL " + str(e.geturl()) + ". The HTTP response code was " + str(e.getcode())) print("The HTTP client error was: " + format(e)) return 1 # TODO: this is incorrect, should return 'success'/'error' properly like the docs say data = read_response.text # Search HTML response for required information on wiki. This is stored in the javascript # variable named # - _wikiProps: for 14.3 and earlier # - LABKEY._wiki.setProps for 15.1 and later data_list = data.split('\n') # If LabKey Server is v14.3 or earlier find line containing '_wikiProp' v = next((i for i in range(len(data_list)) if '_wikiProp' in data_list[i]), None) # If v = None, then server is running 15.1 or later and find the line # containing 'LABKEY._wiki.setProps' if v is None: v = next((i for i in range(len(data_list)) if 'LABKEY._wiki.setProps' in data_list[i]), None) # Verify that we found the variable in the HTML response. If not # do not proceed if v is None: print( "There was a problem while attempting to read the data for the wiki page '" + str(wiki_name) + "'.") print( "The script is unable to find the wiki properties in the HTML response" ) return 1 # TODO: this is incorrect, should return 'success'/'error' properly like the docs say wiki_vars = {} for j in range(100): # Read each line, until find a javascript closing bracket. if '};' in data_list[v + j + 1]: break if '});' in data_list[v + j + 1]: break wvar = data_list[v + j + 1].rstrip().lstrip().replace('\'', '').replace( ',', '') wiki_vars[wvar.split(':')[0]] = wvar.split(':')[1] # Build the URL for updating the wiki page update_wiki_url = build_url(server_context, 'wiki', 'saveWiki.api', container_path=container_path) headers = {'Content-type': 'application/json'} # Update wiki_vars to use the new wiki content. wiki_vars['name'] = wiki_name wiki_vars['body'] = wiki_body try: response = session.post(update_wiki_url, data=json.dumps(wiki_vars, sort_keys=True), headers=headers) data = handle_response(response) except SSLError as e: print( "There was a problem while attempting to submit the read for the wiki page '" + str(wiki_name) + "' via the URL " + str(e.geturl()) + ". The HTTP response code was " + str(e.getcode())) print("The HTTP client error was: " + format(e)) return 1 # TODO: this is incorrect, should return 'success'/'error' properly like the docs say return data
def select_rows(server_context, schema_name, query_name, view_name=None, filter_array=None, container_path=None, columns=None, max_rows=None, sort=None, offset=None, container_filter=None, parameters=None, show_rows=None, include_total_count=None, include_details_column=None, include_update_column=None, selection_key=None, required_version=None, timeout=_default_timeout ): """ Query data from a LabKey server :param server_context: A LabKey server context. See utils.create_server_context. :param schema_name: schema of table :param query_name: table name to select from :param view_name: pre-existing named view :param filter_array: set of filter objects to apply :param container_path: folder path if not already part of server_context :param columns: set of columns to retrieve :param max_rows: max number of rows to retrieve :param sort: comma separated list of column names to sort by, prefix a column with '-' to sort descending :param offset: number of rows to offset results by :param container_filter: enumeration of the various container filters available. See: https://www.labkey.org/download/clientapi_docs/javascript-api/symbols/LABKEY.Query.html#.containerFilter :param parameters: Set of parameters to pass along to a parameterized query :param show_rows: An enumeration of various paging styles :param include_total_count: Boolean value that indicates whether to include a total count value in response :param include_details_column: Boolean value that indicates whether to include a Details link column in results :param include_update_column: Boolean value that indicates whether to include an Update link column in results :param selection_key: :param required_version: decimal value that indicates the response version of the api :param timeout: Request timeout in seconds (defaults to 30s) :return: """ url = build_url(server_context, 'query', 'getQuery.api', container_path=container_path) payload = { 'schemaName': schema_name, 'query.queryName': query_name } if view_name is not None: payload['query.viewName'] = view_name if filter_array is not None: for query_filter in filter_array: prefix = query_filter.get_url_parameter_name() payload[prefix] = query_filter.get_url_parameter_value() if columns is not None: payload['query.columns'] = columns if max_rows is not None: payload['query.maxRows'] = max_rows if sort is not None: payload['query.sort'] = sort if offset is not None: payload['query.offset'] = offset if container_filter is not None: payload['containerFilter'] = container_filter if parameters is not None: payload['query.parameters'] = parameters if show_rows is not None: payload['query.showRows'] = show_rows if include_total_count is not None: payload['includeTotalCount'] = include_total_count if include_details_column is not None: payload['includeDetailsColumn'] = include_details_column if include_update_column is not None: payload['includeUpdateColumn'] = include_update_column if selection_key is not None: payload['query.selectionKey'] = selection_key if required_version is not None: payload['apiVersion'] = required_version select_rows_response = _make_request(server_context, url, payload, timeout=timeout) return select_rows_response
def select_rows(server_context, schema_name, query_name, view_name=None, filter_array=None, container_path=None, columns=None, max_rows=None, sort=None, offset=None, container_filter=None, parameters=None, show_rows=None, include_total_count=None, include_details_column=None, include_update_column=None, selection_key=None, required_version=None, timeout=_default_timeout): """ Query data from a LabKey server :param server_context: A LabKey server context. See utils.create_server_context. :param schema_name: schema of table :param query_name: table name to select from :param view_name: pre-existing named view :param filter_array: set of filter objects to apply :param container_path: folder path if not already part of server_context :param columns: set of columns to retrieve :param max_rows: max number of rows to retrieve :param sort: comma separated list of column names to sort by, prefix a column with '-' to sort descending :param offset: number of rows to offset results by :param container_filter: enumeration of the various container filters available. See: https://www.labkey.org/download/clientapi_docs/javascript-api/symbols/LABKEY.Query.html#.containerFilter :param parameters: Set of parameters to pass along to a parameterized query :param show_rows: An enumeration of various paging styles :param include_total_count: Boolean value that indicates whether to include a total count value in response :param include_details_column: Boolean value that indicates whether to include a Details link column in results :param include_update_column: Boolean value that indicates whether to include an Update link column in results :param selection_key: :param required_version: decimal value that indicates the response version of the api :param timeout: Request timeout in seconds (defaults to 30s) :return: """ url = build_url(server_context, 'query', 'getQuery.api', container_path=container_path) payload = {'schemaName': schema_name, 'query.queryName': query_name} if view_name is not None: payload['query.viewName'] = view_name if filter_array is not None: for query_filter in filter_array: prefix = query_filter.get_url_parameter_name() payload[prefix] = query_filter.get_url_parameter_value() if columns is not None: payload['query.columns'] = columns if max_rows is not None: payload['query.maxRows'] = max_rows if sort is not None: payload['query.sort'] = sort if offset is not None: payload['query.offset'] = offset if container_filter is not None: payload['containerFilter'] = container_filter if parameters is not None: for key, value in parameters.items(): payload['query.param.' + key] = value if show_rows is not None: payload['query.showRows'] = show_rows if include_total_count is not None: payload['includeTotalCount'] = include_total_count if include_details_column is not None: payload['includeDetailsColumn'] = include_details_column if include_update_column is not None: payload['includeUpdateColumn'] = include_update_column if selection_key is not None: payload['query.selectionKey'] = selection_key if required_version is not None: payload['apiVersion'] = required_version select_rows_response = _make_request(server_context, url, payload, timeout=timeout) return select_rows_response
def execute_sql(server_context, schema_name, sql, container_path=None, max_rows=None, sort=None, offset=None, container_filter=None, save_in_session=None, parameters=None, required_version=None, timeout=_default_timeout): """ Execute sql query against a LabKey server. :param server_context: A LabKey server context. See utils.create_server_context. :param schema_name: schema of table :param sql: String of labkey sql to execute :param container_path: labkey container path if not already set in context :param max_rows: max number of rows to return :param sort: comma separated list of column names to sort by :param offset: number of rows to offset results by :param container_filter: enumeration of the various container filters available. See: https://www.labkey.org/download/clientapi_docs/javascript-api/symbols/LABKEY.Query.html#.containerFilter :param save_in_session: save query result as a named view to the session :param parameters: parameter values to pass through to a parameterized query :param required_version: Api version of response :param timeout: timeout of request in seconds (defaults to 30s) :return: """ url = build_url(server_context, 'query', 'executeSql.api', container_path=container_path) payload = {'schemaName': schema_name, 'sql': sql} if container_filter is not None: payload['containerFilter'] = container_filter if max_rows is not None: payload['maxRows'] = max_rows if offset is not None: payload['offset'] = offset if sort is not None: payload['query.sort'] = sort if save_in_session is not None: payload['saveInSession'] = save_in_session if parameters is not None: for key, value in parameters.items(): payload['query.param.' + key] = value if required_version is not None: payload['apiVersion'] = required_version execute_sql_response = _make_request(server_context, url, payload, timeout=timeout) return execute_sql_response