Subtracting of a python request - python

I am using python to send a request to an API in order to pull sensor data.
The first request that I am sending is to gauge the current time of the sensor.
The second request is to gauge the amount of time, since the sensor identified motion.
I am looking to subtract the first request, by the second.
Below is the method of pulling the data I am using, which works fine. I just cant figure out why it doesn't work when I try and subtract them.
Any help would be much appreciated.
url = "IPADDRESS"
payload={}
headers = {
"Authorization":"Password"
}
response1 = requests.request("GET", url, headers=headers, data=payload, verify=False)
print('Current Time: ', response1.text)
url = "IPAddress"
payload={}
headers = {
"Authorization": "Password"
}
response = requests.request("GET", url, headers=headers, data=payload, verify=False) #HTTP request
print('Time since last motion: ', response.text)
updatedtime = response1.text
occupancelevel = response.text
result = updatedtime - occupancelevel
print(result)

Subtraction only works with some datatypes. (Specifically, only objects which have a .__sub__ method can be subtracted.)
I'm not sure what .data is, as per the docs it doesn't exist, but if it does it clearly isn't something subtractable.
If you are getting a simple number back from your endpoint, you can cast it first:
response = float(response1.data) - float(response2.data)
Otherwise you are going to have to dig into what the response type is, and work accordingly. (Hint: if you don't know, it's probably json.)
Incidentally if, as I think, there is no undeclared .data, you want .text or .json() to get at the response.
References
https://docs.python-requests.org/en/latest/api/#requests.Response

Related

Get Google Calendar events by given date using Python

I got the following code for fetching all events from a specific calendar.
This code works for me.
I would like to add a variable to get the events of today's date.
I'm using the GET HTTP Request: https://www.googleapis.com/calendar/v3/calendars/calendarId/events
from developers.google.com/calendar/api/v3/reference/events
My code:
import requests
url = "https://www.googleapis.com/calendar/v3/calendars/***calendarId***/events"
payload={}
headers = {
'Authorization': 'Bearer *************************************************'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
Building on the comment already posted, you can refer to Google's events list documentation. It explains that you can use the timeMin and timeMax parameters to specify a minimum and maximum date. Note that you have to enter the date in RFC3339 format or you will get an error. Here's an example based on your code:
import requests
url = "https://www.googleapis.com/calendar/v3/calendars/***calendarId***/events"
headers = {
'Authorization': 'Bearer *************************************************'
}
params= {
"timeMin":"2022-09-19T00:00:00-06:00",
"timeMax":"2022-09-19T23:59:59-06:00"
}
response = requests.request("GET", url, headers=headers, params=params)
print(response.text)
You don't need a payload for this method so I removed it from the sample. As explained in the documentation, the offset is mandatory so you have to keep that in mind. There are many ways to generate the datetime, but you can refer to this answer for some samples using the datetime module.

Django Rest Framework sending Request to External API - Expecting value: line 1 column 1 (char 0)

I'm working on an API for my application to send a POST request to an external API. So for example, if my app hits endpoint /myapp/api I want it to call out to an external API and grab some data. In this case, I need this to be a POST request because in order to get the data that I want, I need to pass in some values.
I have made this POST call directly to the external API via Postman successfully many times, and I'm now trying to reproduce that in my python code.
In my views.py, I have this:
class MyAPPViews(APIView):
def post(self,request):
crt = 'path/to/crtfile'
key = 'path/to/keyfile'
#here I tried to reproduce the headers from the postman call
#as best as I could just to be extra specific
headers = {
'Content-Type': 'application/json',
'Accept': '/*/',
'Accept-Encoding': 'gzip,deflate,br',
'Connection': 'keep-alive'
}
payload = {
"unitList": [
"CFQU319303"
]
}
res = requests.post('external/api/url', headers=headers, data=payload, cert=(crt,key))
print('this is the true http resonse: ',res.status_code)
data = res.json()
return Response({"status": "success", "data": data})
in my urls.py I have this
path('externalAPI',MyAPPViews.as_view()),
Now, when I try to go into postman and hit http://127.0.0.1:8000/myapp/externalAPI
I get a 500 status code returned and the JSONDecodeError of Expecting value: line 1 column 1 (char 0). I understand that this means that basically the json response was empty and there was nothing for it to parse.
Is there anything blatantly wrong with my views.py code?
EDIT Within the res = requests.post('external/api/url', headers=headers, data=payload, cert=(crt,key)), I had to change data=payload to data=json.dumps(payload). I'm assuming it didn't like the way I formatted my payload initially. After that, I also deleted everything but the Content-Type: application/json out my headers dictionary.
I'd say, it's just a wrong URL in your call of the external API, as you are using some path without a domain.
So instead of
res = requests.post('external/api/url', headers=headers, data=payload, cert=(crt,key))
it should be sth. like
res = requests.post('https://SOMEDOMAIN.ORG/external/api/url', headers=headers, data=payload, cert=(crt,key))
Within the res = requests.post('external/api/url', headers=headers, data=payload, cert=(crt,key)), I had to change data=payload to data=json.dumps(payload). I'm assuming it didn't like the way I formatted my payload initially. After that, I also deleted everything but the Content-Type: application/json out my headers dictionary.

requests.post returns isSuccess:false even though Postman returns true

I am trying to post some information into an API based on their recommended format. When I use Postman( tool to test APIs), I see that the response has the isSuccess flag set to true. However, when I write the same code in Python using the requests library, I get the isSuccess flag as false
As mentioned about, I verified the headers and the json data object, both are the same yet the results defer
import requests
data = {"AccountNumber":"100007777",
"ActivityID":"78",
"ActivityDT":"2019-08-07 12:00:00",
"ActivityValue":"1"
}
url = "http://<IP>/<API_PATH>"
headers = {
"X-Tenant":"Default",
"Content-Type":"application/json"
}
response = requests.post(url,data=data, headers = headers)
print(response.content)
This code should successfully post the data and I should get a isSuccess:true in my response variable.
Can anyone help me figure out what might be wrong?
Can you try to change;
response = requests.post(url,data=data, headers = headers)
to;
response = requests.post(url,json=data, headers = headers)
or;
response = requests.post(url,body=data, headers = headers)

How to call an API using Python Requests library

I can't figure out how to call this api correctly using python urllib or requests.
Let me give you the code I have now:
import requests
url = "http://api.cortical.io:80/rest/expressions/similar_terms?retina_name=en_associative&start_index=0&max_results=1&sparsity=1.0&get_fingerprint=false"
params = {"positions":[0,6,7,29]}
headers = { "api-key" : key,
"Content-Type" : "application/json"}
# Make a get request with the parameters.
response = requests.get(url, params=params, headers=headers)
# Print the content of the response
print(response.content)
I've even added in the rest of the parameters to the params variable:
url = 'http://api.cortical.io:80/rest/expressions/similar_terms?'
params = {
"retina_name":"en_associative",
"start_index":0,
"max_results":1,
"sparsity":1.0,
"get_fingerprint":False,
"positions":[0,6,7,29]}
I get this message back:
An internal server error has been logged # Sun Apr 01 00:03:02 UTC
2018
So I'm not sure what I'm doing wrong. You can test out their api here, but even with testing I can't figure it out. If I go out to http://api.cortical.io/, click on the Expression tab, click on the POST /expressions/similar_terms option then paste {"positions":[0,6,7,29]} in the body textbox and hit the button, it'll give you a valid response, so nothing is wrong with their API.
I don't know what I'm doing wrong. can you help me?
The problem is that you're mixing query string parameters and post data in your params dictionary.
Instead, you should use the params parameter for your query string data, and the json parameter (since the content type is json) for your post body data.
When using the json parameter, the Content-Type header is set to 'application/json' by default. Also, when the response is json you can use the .json() method to get a dictionary.
An example,
import requests
url = 'http://api.cortical.io:80/rest/expressions/similar_terms?'
params = {
"retina_name":"en_associative",
"start_index":0,
"max_results":1,
"sparsity":1.0,
"get_fingerprint":False
}
data = {"positions":[0,6,7,29]}
r = requests.post(url, params=params, json=data)
print(r.status_code)
print(r.json())
200
[{'term': 'headphones', 'df': 8.991197733061748e-05, 'score': 4.0, 'pos_types': ['NOUN'], 'fingerprint': {'positions': []}}]
So, I can't speak to why there's a server error in a third-party API, but I followed your suggestion to try using the API UI directly, and noticed you're using a totally different endpoint than the one you're trying to call in your code. In your code you GET from http://api.cortical.io:80/rest/expressions/similar_terms but in the UI you POST to http://api.cortical.io/rest/expressions/similar_terms/bulk. It's apples and oranges.
Calling the endpoint you mention in the UI call works for me, using the following variation on your code, which requires using requests.post, and as was also pointed out by t.m. adam, the json parameter for the payload, which also needs to be wrapped in a list:
import requests
url = "http://api.cortical.io/rest/expressions/similar_terms/bulk?retina_name=en_associative&start_index=0&max_results=1&sparsity=1.0&get_fingerprint=false"
params = [{"positions":[0,6,7,29]}]
headers = { "api-key" : key,
"Content-Type" : "application/json"}
# Make a get request with the parameters.
response = requests.post(url, json=params, headers=headers)
# Print the content of the response
print(response.content)
Gives:
b'[[{"term":"headphones","df":8.991197733061748E-5,"score":4.0,"pos_types":["NOUN"],"fingerprint":{"positions":[]}}]]'

Google returning 400 Parse Error

I've recently been getting a 400 bad request parse error when making a request to my timeline_url.
Im posting to this url timeline_url = 'https://www.googleapis.com/mirror/v1/timeline'
EDIT
Here is the code:
headers = {'Content-Type': 'application/json',
'Authorization' : 'Bearer %s' % access_token}
body = {"text" : "Waddup doe!"}
""" ***********THIS IS RETURNING ERROR 400 PARSE ERROR***********"""
send_request(timeline_url, headers, 'POST',body)
The send_request method is using requests
req = requests.post(url, data=body, headers=headers)
I'm just trying to insert plain text to my timeline.
body_bytes = sys.getsizeof(body)
headers['Content-Length'] = body_bytes
This is inserting an incorrect value into your request headers. sys.getsizeof describes how large the data structure is -- including pointers, counters, etc. It does NOT describe how many bytes the string representation takes on the HTTP stream.
Just delete these lines; requests will fill in Content-Length automatically.
You don't describe how you json-encode the payload. Perhaps you need to do this:
req = requests.post(url, data=json.dumps(body), headers=headers)
See: http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests

Categories

Resources