Search code examples
pythonhttprequestpython-3.4intercom

Python Requests Works in Console, but not In App


I built a Python Script which is meant to upload data to an application called Intercom, using the python requests library. The idea is to insert a brand new field into the custom attributes with data we would need to key off for our auto-messaging.

The script is very long, but the method that is breaking is below:

def post_user(self, input_user, session=None):
    """
    :param user: a JSON object with all the user pieces needed to be posted to the endpoint
    :param session: a Requests session to be used. If None we'll create one
    """
    if not session:
        session = self.create_requests_session()
    else:
        session = session

    # JSON encode the user
    payload = json.dumps(input_user, sort_keys=True, indent=2, separators=(',', ': '))

    print(payload)  # DEBUG CODE

    # Post the data to endpoint
    response = session.post(self.endpoint, data=payload)

    # This will raise a status code on a bad status code
    response.raise_for_status()

Below is also the method for create_requests_session():

def create_requests_session(self):
    """
    Start a requests session. Set Auth & Headers so we don't have to send it with each request
    :return: A new requests.Session object with auth & header values prepopulated.
    """

    session = requests.Session()
    session.auth = (self.app_id, self.api_key)
    session.headers = {'Content-Type': 'application/json', 'accept': 'application/json'}

    return session

When I run the entire script and step through the first input_user it comes in as a dict, looking like. (Note: The data is anonymized, but the structure remains the exact same):

 {'user_id': '123456', 
  'email': '[email protected]', 
  'custom_attributes': {
      'test_cell' : 'Variation'}
 }

However, after delivering the user to json.dumps(user) and then sending it through a POST request, I got back a 404 error.

Here's the weird part. I sent this exact same user with the exact same JSON, except I created all of the parts using the Python Console (note, some lines are hidden to maintain user data anonymity):

In[82]: sesh = requests.session()
In[86]: header
Out[86]: {'Content-Type': 'application/json', 'accept': 'application/json'}
In[87]: sesh.headers = header
In[89]: payload = json.dumps(update_user)
In[91]: response = sesh.post(endpoint, data=payload)
In[92]: response
Out[92]: <Response [200]>

At this point, I'm completely lost. I've attempted to set up a proxy to try and compare the requests byte by byte, but haven't had much luck with that. Any help or insight is greatly appreciated.


Solution

  • Have you ensured that your authentication is valid?

    session.auth = (self.app_id, self.api_key)

    In particular, the app_id should be set to the one corresponding to the API Key (so the test app's app_id if you're using a test app).

    If Intercom receives an app id it does not recognise it (currently) returns a 404, which is what you're seeing. This should be fixed now to return a 401.