pythonpython-2.7authenticationsocratasoda

Socrata Metadata API Authorization Issue


I am attempting to update my entire metadata asset inventory via python using the Socrata Metadata API. Using the python code example from the Metadata Api Docs, I was able to read the metadata, but I am unable to update it due to Error 403 even with proper Authentication. I have administrator access, access to the secret token, and app token. I have attempted to use both OAuth2 and Basic Authentication to no avail. Here is a quick code sample:

from urllib2 import Request, urlopen

values = """
  {
    "name": "Business Entities in Colorado_TEST",
  }
"""

headers = {
  'X-Socrata-Host': 'data.colorado.gov',
  'Content-Type': 'application/json',
  'Authorization': 'OAuth {REDACTED}'
}
request = Request('https://data.colorado.gov/api/views/metadata/v1/4eit-nuxn', data=values, headers=headers)
request.get_method = lambda: 'PATCH'

response_body = urlopen(request).read()
print response_body

Where {REDACTED} is equal to App Token less curly braces. In lieu of 'Authorization' I have also tried 'X-App-Token' to no avail. I feel like this is a pretty basic fix, but I'm definitely missing something.

I also attempted to enter a base64 string using:

username = '{REDACTED}'
password = '{REDACTED}'
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')

Added the variable base64string to my headers and ran into the same issue. Based on: Update a Socrata dataset using app token and private in HTTP basic

Here's my Traceback if it's of any help:

Traceback (most recent call last):
  File "test.py", line 19, in <module>
    response_body = urlopen(request).read()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
    return opener.open(url, data, timeout)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 437, in open
    response = meth(req, response)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 550, in http_response
    'http', request, response, code, msg, hdrs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 475, in error
    return self._call_chain(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 558, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
>urllib2.HTTPError: HTTP Error 403: Forbidden

Thank you!


Solution

  • I have fixed the authentication error and have done so by using requests on Python 3 instead of using urllib2. Here is my updated code

    #!/usr/bin/python
    #coding: utf-8
    import base64
    import json
    import requests
    
    username = '{REDACTED}'
    password = '{REDACTED}'
    string = '%s:%s' % (username, password)
    base64string = base64.b64encode(string.encode())
    app_token = '{REDACTED}'
    
    values = """
    {
      "metadata" : {
        "id" : "TEST",
        "name" : "Business Entities_TEST"
      }
    }
    """
    
    headers = {
      'Accept': '*/*',  
      'X-Socrata-Host': 'data.colorado.gov',
      'Content-Type': 'application/json',
      'Authorization': 'Basic {REDACTED}',
      'X-App-Token': app_token
    }
    
    request = requests.get('https://data.colorado.gov/api/views/metadata/v1/4ykn-tg5h', data=values, headers=headers)
    request.get_method = lambda: 'PATCH'
    
    response_body = request.json()
    print(response_body)