RequestAuthorizationError: '401: Authorization Failed'

LabKey Support Forum (Inactive)
RequestAuthorizationError: '401: Authorization Failed' jpseabrook  2017-06-12 08:50
Status: Closed
 
Hi,

I'm trying to make use of the python api but I'm having some troubles. My server is on a local network but has a public domain and SSL cert attached. I'm using get_user_by_email() to test the connection and the script is throwing a 'RequestAuthorizationError: '401: Authorization Failed'. I've setup a user labkey on the server to run Labkey Server via tomcat8 with startup.sh/shutdown.sh. The 'Runtime Information' lists the 'User Home Dir' and 'Working Dir' as '/home/labkey'. Any help would be greatly appreciated.

******
/home/labkey/.netrc (chmod 400)
******
machine [PUBLIC DOMAIN ADDRESS]
login [LOGIN EMAIL ADDRESS]
password [PASSWORD]

******
script running in a jupyter notebook
******
from labkey.utils import create_server_context
from labkey.query import select_rows
from labkey.security import create_user, get_user_by_email

labkey_server = '[PUBLIC DOMAIN ADDRESS WITH PORT]'
project_name = 'test' # Project folder name
contextPath = 'labkey'
schema = 'core'
table = 'Users'

server_context = create_server_context(labkey_server, project_name, contextPath, use_ssl=True)
print("Created a server context")

print(get_user_by_email(server_context, '[LOGIN EMAIL ADDRESS]'))

******
exact error output
******
Created a server context
---------------------------------------------------------------------------
RequestAuthorizationError Traceback (most recent call last)
<ipython-input-25-9bfd09f77045> in <module>()
     12 print("Created a server context")
     13
---> 14 print(get_user_by_email(server_context, '[LOGIN EMAIL ADDRESS]'))

/opt/miniconda3/lib/python3.6/site-packages/labkey/security.py in get_user_by_email(server_context, email)
    130 url = server_context.build_url(user_controller, 'getUsers.api')
    131 payload = dict(includeDeactivatedAccounts=True)
--> 132 result = server_context.make_request(url, payload)
    133
    134 if result is None or result['users'] is None:

/opt/miniconda3/lib/python3.6/site-packages/labkey/utils.py in make_request(self, url, payload, headers, timeout, method)
    149 else:
    150 raw_response = self._session.post(url, data=payload, headers=headers, timeout=timeout)
--> 151 return handle_response(raw_response)
    152 except SSLError as e:
    153 raise ServerContextError(e)

/opt/miniconda3/lib/python3.6/site-packages/labkey/utils.py in handle_response(response)
     73
     74 elif sc == 401:
---> 75 raise RequestAuthorizationError(response)
     76 elif sc == 404:
     77 try:

RequestAuthorizationError: '401: Authorization Failed'
 
 
Jon (LabKey DevOps) responded:  2017-06-12 13:32
Hello,

Does the user in question have the ability to view the core.Users table from the UI?

I ran a similar query and had no issues doing this against labkey.org's own servers:
==============================
import labkey
from labkey.utils import create_server_context
from labkey.query import select_rows

labkey_server = 'www.labkey.org'
project_name = 'home'
schema = 'core'
table = 'Users'

server_context = create_server_context(labkey_server, project_name, use_ssl=True)

result = select_rows(server_context, schema, table)
if result is not None:
    print(result['rows'][0])
    print("select_rows: Number of rows returned: " + str(result['rowCount']))
else:
    print('select_rows: Failed to load results from ' + schema + '.' + table)
==============================

I did notice you didn't have the "import labkey" option at the top of your python code. Did you make sure to include that too before the:

from labkey.utils import create_server_context
from labkey.query import select_rows
from labkey.security import create_user, get_user_by_email

So it would look like:

import labkey
from labkey.utils import create_server_context
from labkey.query import select_rows
from labkey.security import create_user, get_user_by_email

Regards,

Jon
 
jpseabrook responded:  2017-06-12 14:36
Hi. Thanks for replying. I do have the import statement, an error in copy pasting. The user is the administrator, and only user. I noticed in your snippet you didn't include 'context_path' is that unnecessary?
 
Jon (LabKey DevOps) responded:  2017-06-12 21:36
Hello,

The context_path is only used if you are actually using it.

For example, I would use it if my URL that I was hitting was https://www.labkey.org/labkey.

But since I'm not using a context path, my site operates as https://www.labkey.org instead.

This would make my home project under https://www.labkey.org/home, rather than https://www.labkey.org/labkey/home.

I tried your actual code, but I'm running into an error that's unrelated to the problem you're seeing.

Can you try my code, tweak it out with your specific info along with the context path, and see if you get the same 401?

Regards,

Jon
 
jpseabrook responded:  2017-06-14 13:19
Here's your code tweaked with my specific info.

******
******
import labkey
from labkey.utils import create_server_context
from labkey.query import select_rows

labkey_server = 'seabrook.land:11211/'
project_name = 'home'
contextPath = 'labkey'
schema = 'core'
table = 'Users'

server_context = create_server_context(labkey_server, contextPath, project_name, use_ssl=True)

result = select_rows(server_context, schema, table)
if result is not None:
    print(result['rows'][0])
    print("select_rows: Number of rows returned: " + str(result['rowCount']))
else:
    print('select_rows: Failed to load results from ' + schema + '.' + table)

******
******

Here's the full error output

******
******
JSONDecodeError Traceback (most recent call last)
/opt/miniconda3/lib/python3.6/site-packages/labkey/utils.py in handle_response(response)
     77 try:
---> 78 response.json() # attempt to decode response
     79 raise QueryNotFoundError(response)

/opt/miniconda3/lib/python3.6/site-packages/requests/models.py in json(self, **kwargs)
    884 pass
--> 885 return complexjson.loads(self.text, **kwargs)
    886

/opt/miniconda3/lib/python3.6/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    353 parse_constant is None and object_pairs_hook is None and not kw):
--> 354 return _default_decoder.decode(s)
    355 if cls is None:

/opt/miniconda3/lib/python3.6/json/decoder.py in decode(self, s, _w)
    338 """
--> 339 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    340 end = _w(s, end).end()

/opt/miniconda3/lib/python3.6/json/decoder.py in raw_decode(self, s, idx)
    356 except StopIteration as err:
--> 357 raise JSONDecodeError("Expecting value", s, err.value) from None
    358 return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

ServerNotFoundError Traceback (most recent call last)
<ipython-input-12-4d1826f6747b> in <module>()
     11 server_context = create_server_context(labkey_server, contextPath, project_name, use_ssl=True)
     12
---> 13 result = select_rows(server_context, schema, table)
     14 if result is not None:
     15 print(result['rows'][0])

/opt/miniconda3/lib/python3.6/site-packages/labkey/query.py in select_rows(server_context, schema_name, query_name, view_name, filter_array, container_path, columns, max_rows, sort, offset, container_filter, parameters, show_rows, include_total_count, include_details_column, include_update_column, selection_key, required_version, timeout)
    263 payload['apiVersion'] = required_version
    264
--> 265 return server_context.make_request(url, payload, timeout=timeout)
    266
    267

/opt/miniconda3/lib/python3.6/site-packages/labkey/utils.py in make_request(self, url, payload, headers, timeout, method)
    137 try:
    138 csrf_url = self.build_url('login', 'whoami.api')
--> 139 response = handle_response(self._session.get(csrf_url))
    140 self._session.headers.update({
    141 CSRF_TOKEN: response['CSRF']

/opt/miniconda3/lib/python3.6/site-packages/labkey/utils.py in handle_response(response)
     80 except ValueError:
     81 # could not decode response
---> 82 raise ServerNotFoundError(response)
     83 else:
     84 raise RequestError(response)

ServerNotFoundError: '404: Server resource not found. Please verify context path and project path are valid'

******
******
 
Jon (LabKey DevOps) responded:  2017-06-14 22:36
Hello,

Is your actual LabKey URL setup as below?

https://seabrook.land:11211/labkey

If so, the line:

labkey_server = 'seabrook.land:11211/'

should really be:

labkey_server = 'seabrook.land:11211'

Another way to test this out is to rewrite your code like this:

===============

import labkey
from labkey.utils import create_server_context
from labkey.query import select_rows

schema = 'core'
table = 'Users'

server_context = create_server_context('seabrook.land:11211', 'labkey', 'home', use_ssl=True)

result = select_rows(server_context, schema, table)
if result is not None:
    print(result['rows'][0])
    print("select_rows: Number of rows returned: " + str(result['rowCount']))
else:
    print('select_rows: Failed to load results from ' + schema + '.' + table)

===============
Can you give this a try and see if you get the same result?

Regards,

Jon