A helper for using the python API

LabKey Support Forum
A helper for using the python API Brian Connolly (Proteinms.net)  2018-09-20 16:10
Status: Closed
 

One of the big annoyances when using it the LabKey python api is that I need to define the URL for the LabKey server as a bunch of different variables. This makes it hard to write scripts/tools for non programmers to use.

This problem has gotten so annoying lately that I wrote a little function to help me The function simply takes a LabKey URL and breaks it into it's component parts. It has been so useful I figured I would share it.

The function which will take a URL and

  1. Check if it for a LabKey Server
  2. Rip the URL apart and find the hostname, port, protocol, context path and container path.
def read_url(url):
    """
    Break apart URL provided into protocol, hostname and context path
    :param url: LabKey Server url
    """
    url_config = {}

    # Parse the url
    o = urlparse(url)

    # Verify URL is a URL
    if not o.scheme:
        raise ExitCommandWithMessage("URL specified is not valid. Please enter valid URL")
    if not o.netloc:
        raise ExitCommandWithMessage("URL specified is not valid. Please enter valid URL")

    # Check if URL includes a context path
    test_url = o.scheme + '://' + o.netloc + '/project-getContainers.view'
    response = requests.get(test_url)
    if response.status_code == 200:
        context_path = None
    else:
        context_path = o.path.split('/')[1]
        test_url = o.scheme + '://' + o.netloc + '/' + context_path + '/project-getContainers.view'
        response = requests.get(test_url)
        if response.status_code != 200:
            raise ExitCommandWithMessage("URL specified is not running a LabKey Server. Please enter valid URL")

    # Determine if URL includes a container path
    # This assumes using new style LabKey URLs
    if context_path is None:
        if len(o.path.split('/')) < 3:
            # The url does not contain a container path
            url_config['container_path'] = None
        else:
            url_config['container_path'] = o.path.rsplit('/', 1)[0]
    else:
        urlpath = o.path.split('/', maxsplit=2)
        if len(urlpath) < 4:
            # The url does not contain a container path
            url_config['container_path'] = None
        else:
            url_config['container_path'] = urlpath[2].rsplit('/', 1).join('/')

    # Create output for function
    url_config['labkey_server'] = o.netloc
    url_config['context_path'] = context_path
    if o.scheme == 'http':
        url_config['use_ssl'] = False
        url_config['verify_ssl'] = False
        url_config['url'] = "http://" + o.netloc
    elif o.scheme == 'https':
        url_config['use_ssl'] = True
        url_config['verify_ssl'] = True
        url_config['url'] = "https://" + o.netloc
    else:
        raise ExitCommandWithMessage("URL specified is not valid. Please enter valid URL")

    return url_config

To use this function, all you need to do is

from labkey.utils import create_server_context
import urlparse

labkey_url = "https://www.labkey.org/home/Developer/issues/project-begin.view?"
# Validate LabKey Server URL break into component parts
url_config = read_url(labkey_url)
server_context = create_server_context(url_config['labkey_server'],
                                       url_config['container_path'],
                                       url_config['context_path'],
                                       use_ssl=url_config['use_ssl'],
                                       verify_ssl=url_config['verify_ssl']
                                       )
....

I hope this helps.

Brian

PS: I also have some code that can be used to access the server using username/password (via basic auth) instead of relying on a netrc file. I would be happy to share if anyone is interested.