示例#1
0
    def test_encoder(self):
        # test date and datetime encoding
        payload = {
            'my_date': date(1985, 9, 11),
            'my_date_time': datetime(2018, 9, 18, 5, 25)
        }

        utils.json_dumps(payload)
示例#2
0
    def test_encoder_override(self):
        payload = {'testdate': datetime(2018, 9, 11, 6, 45)}

        try:
            # disable the "cls" override by passing None
            utils.json_dumps(payload, cls=None)
        except TypeError as e:
            if "is not JSON serializable" not in str(e):
                print("Did not see expected exception")
                raise e
示例#3
0
def load_batch(server_context, assay_id, batch_id):
    # type: (ServerContext, int, int) -> Union[Batch, None]
    """
    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 = server_context.build_url('assay', 'getAssayBatch.api')
    loaded_batch = None

    payload = {
        'assayId': assay_id,
        'batchId': batch_id
    }

    headers = {
        'Content-type': 'application/json',
        'Accept': 'text/plain'
    }

    json_body = server_context.make_request(load_batch_url, json_dumps(payload, sort_keys=True), headers=headers)
    if json_body is not None:
        loaded_batch = Batch.from_data(json_body['batch'])

    return loaded_batch
示例#4
0
def save(server_context, schema_name, query_name, domain, container_path=None):
    # type: (ServerContext, str, str, Domain, str) -> None
    """
    Saves the provided domain design
    :param server_context: A LabKey server context. See utils.create_server_context.
    :param schema_name: schema of domain
    :param query_name: query name of domain
    :param domain: Domain to save
    :param container_path: labkey container path if not already set in context
    :return:
    """
    url = server_context.build_url('property',
                                   'saveDomain.api',
                                   container_path=container_path)

    headers = {'Content-Type': 'application/json'}

    payload = {
        'domainDesign': domain.to_json(),
        'queryName': query_name,
        'schemaName': schema_name
    }

    return server_context.make_request(url,
                                       json_dumps(payload),
                                       headers=headers)
示例#5
0
def create(server_context, domain_definition, container_path=None):
    # type: (ServerContext, dict, str) -> Domain
    """
    Create a domain
    :param server_context: A LabKey server context. See utils.create_server_context.
    :param domain_definition: A domain definition.
    :param container_path: labkey container path if not already set in context
    :return: Domain
    """
    url = server_context.build_url('property',
                                   'createDomain.api',
                                   container_path=container_path)

    headers = {'Content-Type': 'application/json'}

    domain = None

    raw_domain = server_context.make_request(url,
                                             json_dumps(domain_definition),
                                             headers=headers)

    if raw_domain is not None:
        domain = Domain.from_data(raw_domain)

    return domain
示例#6
0
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 = server_context.build_url('query',
                                   'deleteRows.api',
                                   container_path=container_path)

    payload = {
        'schemaName': schema_name,
        'queryName': query_name,
        'rows': rows
    }

    return server_context.make_request(url,
                                       json_dumps(payload, sort_keys=True),
                                       headers=_query_headers,
                                       timeout=timeout)
def save_batches(server_context, assay_id, batches):
    # type: (ServerContext, int, List[Batch]) -> Union[List[Batch], None]
    """
    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 = server_context.build_url('assay', 'saveAssayBatch.api')
    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'}

    json_body = server_context.make_request(save_batch_url,
                                            json_dumps(payload,
                                                       sort_keys=True),
                                            headers=headers)
    if json_body is not None:
        resp_batches = json_body['batches']
        return [Batch.from_data(resp_batch) for resp_batch in resp_batches]

    return None
示例#8
0
    def make_request(
        self,
        url: str,
        payload: any = None,
        headers: dict = None,
        timeout: int = 300,
        method: str = "POST",
        non_json_response: bool = False,
        file_payload: any = None,
        json: dict = None,
    ) -> any:
        if self._api_key is not None:
            if self._session.headers.get(API_KEY_TOKEN) is not self._api_key:
                self._session.headers.update({API_KEY_TOKEN: self._api_key})

        if not self._disable_csrf and CSRF_TOKEN not in self._session.headers.keys():
            try:
                csrf_url = self.build_url("login", "whoami.api")
                response = handle_response(self._session.get(csrf_url))
                self._session.headers.update({CSRF_TOKEN: response["CSRF"]})
            except RequestException as e:
                self.handle_request_exception(e)

        try:
            if method == "GET":
                response = self._session.get(url, params=payload, headers=headers, timeout=timeout)
            else:
                if file_payload is not None:
                    response = self._session.post(
                        url,
                        data=payload,
                        files=file_payload,
                        headers=headers,
                        timeout=timeout,
                    )
                elif json is not None:
                    if headers is None:
                        headers = {}

                    headers_ = {**headers, "Content-Type": "application/json"}
                    # sort_keys is a hack to make unit tests work
                    data = json_dumps(json, sort_keys=True)
                    response = self._session.post(url, data=data, headers=headers_, timeout=timeout)
                else:
                    response = self._session.post(
                        url, data=payload, headers=headers, timeout=timeout
                    )
            return handle_response(response, non_json_response)
        except RequestException as e:
            self.handle_request_exception(e)
示例#9
0
def drop(server_context, schema_name, query_name, container_path=None):
    # type: (ServerContext, str, str, str) -> dict
    """
    Delete a domain
    :param server_context: A LabKey server context. See utils.create_server_context.
    :param schema_name: schema of table
    :param query_name: table name of domain to drop
    :param container_path: labkey container path if not already set in context
    :return:
    """
    url = server_context.build_url('property',
                                   'deleteDomain.api',
                                   container_path=container_path)

    headers = {'Content-Type': 'application/json'}

    payload = {'schemaName': schema_name, 'queryName': query_name}

    return server_context.make_request(url,
                                       json_dumps(payload),
                                       headers=headers)
示例#10
0
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 = server_context.build_url('wiki',
                                             'editWiki.api',
                                             container_path=container_path)
    payload = {'name': wiki_name}
    headers = {'Content-type': 'application/json'}

    try:
        read_response = server_context.make_request(read_wiki_url,
                                                    payload,
                                                    headers=headers,
                                                    method='GET',
                                                    non_json_response=True)
    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 = server_context.build_url('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:
        data = server_context.make_request(update_wiki_url,
                                           payload=json_dumps(wiki_vars,
                                                              sort_keys=True),
                                           headers=headers,
                                           non_json_response=True)
    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