Python HTTP Requests - python

The following figure shows the TMDb endpoint documentation by which a client can request a movie or TV show be added to a user's watchlist, where the user has previously established a session_id.
Based on the developer documentation, and using the (fictional) values of the various pieces that need to be part of the request and that are presented in the following table:
Question !!
Can you please provide the HTTP for this request? You can present the request in a line-oriented fashion, and without needing to note linefeeds or carriage returns.

If you are asking about writing code, the following lines could be useful for you:
import requests
account_id = 12345
url = 'https://YOUR_URL.com/accout/' + account_id + '/watchlist'
payload = {'media_type': 'movie', 'media_id': 777, 'watchlist': 'true'}
x = requests.post(url, data = payload)
print(x.text)
Where is:
requests.post(url, data={key: value}, json={key: value} -> string, args)

Related

How to send POST request with each payload on its own line using Python requests

I have to send a POST request to the /batch endpoint of : 'https://www.google-analytics.com'.
As mentioned in the Documentation I have to send the request to /batch endpoint and specify each payload on its own line.
I was able to achieve this using POSTMAN as follows:
My query is to make a POST request using Python's requests library
I tried something like this :
import requests
text = '''v=1&cid=43223523&tid=UA-XXXXXX-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=bookmarks&ev=13
v=1&cid=43223523&tid=UA-XXXXXX-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=upvotes&ev=65
v=1&cid=43223523&tid=UA-XXXXXX-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=questions&ev=15
v=1&cid=43223523&tid=UA-XXXXXX-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=postviews&ev=95'''
response = requests.post('https://www.google-analytics.com/batch', data=text)
but it doesn't works.
UPDATE
I Tried this and it works !
import http.client
conn = http.client.HTTPSConnection("www.google-analytics.com")
payload = "v=1&cid=43223523&tid=UA-200248207-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=bookmarks&ev=13\r\nv=1&cid=43223523&tid=UA-200248207-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=upvotes&ev=63\r\nv=1&cid=43223523&tid=UA-200248207-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=questions&ev=11\r\nv=1&cid=43223523&tid=UA-200248207-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=postviews&ev=23"
headers = {
'Content-Type': 'text/plain'
}
conn.request("POST", "/batch", payload, headers)
res = conn.getresponse()
But the question remains open, what's the issue with requests here.
You don't need to double-escape the newline symbol.
Moreover, you don't need the newline symbol at all for the multi-line string.
And also the indentations you put in your multi-line string are counted:
test = '''abc
def
ghi'''
print(test)
Here's an SO answer that explains this with some additional ways to make long stings: https://stackoverflow.com/a/10660443/4570170
Now the request body.
The documentation says
payload_data – The BODY of the post request. The body must include exactly 1 URI encoded payload and must be no longer than 8192 bytes.
So try uri-encoding your payload:
text = '''v=1&cid=43223523&tid=UA-XXXXXX-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=bookmarks&ev=13
v=1&cid=43223523&tid=UA-XXXXXX-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=upvotes&ev=65
v=1&cid=43223523&tid=UA-XXXXXX-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=questions&ev=15
v=1&cid=43223523&tid=UA-XXXXXX-1&t=event&ec=aggregated_stats&ea=daily_kpi&el=postviews&ev=95'''
text_final = requests.utils.quote(text)
response = requests.post('https://www.google-analytics.com/batch', data=text_final)
Finally , I figured out the solution myself.
Updating for others help.
The problem was I was working on AWS Cloud9 and as mentioned in the documentation
Some environments are not able to send hits to Google Analytics directly. Examples of this are older mobile phones that can't run JavaScript or corporate intranets behind a firewall.
So we just need to include the User Agent parameter
ua=Opera/9.80
in each of our payloads
It works !

Python POST request does not take form data with no files

Before downvoting/marking as duplicate, please note:
I have already tried out this, this, this, this,this, this - basically almost all the methods I could find pointed out by the Requests documentation but do not seem to find any solution.
Problem:
I want to make a POST request with a set of headers and form data.
There are no files to be uploaded. As per the request body in Postman, we set the parameters by selecting 'form-data' under the 'Body' section for the request.
Here is the code I have:
headers = {'authorization': token_string,
'content-type':'multipart/form-data; boundary=----WebKitFormBoundaryxxxxxXXXXX12345'} # I get 'unsupported application/x-www-form-url-encoded' error if I remove this line
body = {
'foo1':'bar1',
'foo2':'bar2',
#... and other form data, NO FILE UPLOADED
}
#I have also tried the below approach
payload = dict()
payload['foo1']='bar1'
payload['foo2']='bar2'
page = ''
page = requests.post(url, proxies=proxies, headers=headers,
json=body, files=json.dump(body)) # also tried data=body,data=payload,files={} when giving data values
Error
{"errorCode":404,"message":"Required String parameter 'foo1' is not
present"}
EDIT:
Adding a trace of the network console. I am defining it in the same way in the payload as mentioned on the request payload.
There isn't any gui at all? You could get the network data from chrome, although:
Try this:
headers = {'authorization': token_string}
Probably there is more authorization? Or smthng else?
You shouldn't add Content-Type as requests will handle it for you.
Important, you could see the content type as WebKitFormBoundary, so for the payload you must take, the data from the "name" variable.
Example:
(I know you won't upload any file, it just an example) -
So in this case, for my payload would look like this: payload = {'photo':'myphoto'} (yea there would be an open file etc etc, but I try to keep it simple)
So your payload would be this-> (So always use name from the WebKit)
payload = {'foo1':'foo1data',
'foo2':'foo2data'}
session.post(url,data = payload, proxies etc...)
Important! As I can see you use the method from requests library. Firstly you always should create a session like this
session = requests.session() -> it will handle cookies, headers, etc, and won't open a new session, or plain requests with every requests.get/post.

Unable to see Measurement protocol hit in GA reports (using Python Request library)

Trying to send pageview hit using Measurement Protocol to Google Analytics, Universal property (using Python's Requests library to make HTTP request)
import requests
endpoint = 'https://www.google-analytics.com/collect'
payload = {'v':'1'
,'tid':'UA-XXXXXX-Y'
,'t':'pageview'
,'dl': 'http%3A%2F%2Fvibhorj.com%2Ftest1%2Fpath2'
,'cid':'928534239.3492469166'
}
r = requests.post(url = endpoint, data = payload)
r.status_code is returned as 200 (OK), but still can't see the hit in Real Time reports or in standard report
also tried GET request:
requests.post(url = endpoint, params = payload)
(same result: status_code returned in 200 OK but still no data in GA reports)
any help, pointers will be highly appreciated
[SOLVED!]:
Apparently I notice User-Agent is mandatory to set. Following code worked for me
r = requests.post(url = endpoint, data = dic2
, headers={'User-Agent': 'My User Agent 1.0'})
To enable to see the Python hits on the tool you have yo uncheck the option of "Exclude all hits from known bots and spiders". Also check the filter if you are not excluding this data in others ways.
Also, it's highly recommended to add the parameter title ("&dt"), this parameter is used on the Report "User Explorer" or in other "reports of behavior section" is not mandatory but you can expect undesired issues with the tool.
Greetings

How to post to hipchat from python

I have some python tools that I would like to have send updates to a hipchat room. I do this elsewhere with shell scripts, so I know it works in our environment, but I can't seem to get the token pushed to the hipchat API. Gotta be something simple.
First, this authenticates properly and delivers a message:
curl -d "room_id=xxx&from=DummyFrom&message=ThisIsATest&color=green" https://api.hipchat.com/v1/rooms/message?auth_token=yyy
But when I try to use the python "requests" module, I am getting stuck.
import requests
room_id_real="xxx"
auth_token_real="yyy"
payload={"room_id":room_id_real,"from":"DummyFrom","message":"ThisIsATest","color":"green"}
headerdata={"auth_token":auth_token_real,"format":"json"}
r=requests.post("https://api.hipchat.com/v1/rooms/message", params=payload, headers=headerdata)
print r.ok, r.status_code, r.text
Here is my error information:
False 401 {"error":{"code":401,"type":"Unauthorized","message":"Auth token not found. Please see: https:\/\/www.hipchat.com\/docs\/api\/auth"}}
Basically I don't seem to be passing the authentication token in properly. How can I get this working?
In case it helps, here's a working V2 API example. I did find the V2 API to be a bit more sensitive about getting the form of the request exactly right. But, it might be more forward-looking to conform to the V2 API (though the original question seemed to pertain to V1).
#!/usr/bin/env python
import json
from urllib2 import Request, urlopen
V2TOKEN = '--V2 API token goes here--'
ROOMID = --room-id-nr-goes-here--
# API V2, send message to room:
url = 'https://api.hipchat.com/v2/room/%d/notification' % ROOMID
message = "It's a<br><em>trap!</em>"
headers = {
"content-type": "application/json",
"authorization": "Bearer %s" % V2TOKEN}
datastr = json.dumps({
'message': message,
'color': 'yellow',
'message_format': 'html',
'notify': False})
request = Request(url, headers=headers, data=datastr)
uo = urlopen(request)
rawresponse = ''.join(uo)
uo.close()
assert uo.code == 204
Another basic example using requests:
import requests, json
amessage = 'Hello World!'
room = 'https://api.hipchat.com/v2/room/18REPLACE35/notification'
headers = {'Authorization':'Bearer UGetYourOwnAuthKey', 'Content-type':'application/json'}
requests.post(url = room, data = json.dumps({'message':amessage}), headers = headers)
As Ianzz said, try including it in the URL query string. Although clunky (you probably want to hash it!), it definitely works.
The other strange quirk is the tokens that you get through Hipchat; I had no end of problems earlier this evening using my own personal token; it seemed to correspond to v2 beta of the API. If you go in through Group Admin and get a token from there, it may help.
Old question is old.
Here's an official list of libs which use the HipChat API v2 interface
https://www.hipchat.com/docs/apiv2/libraries

Infoblox WAPI: how to search for an IP

Our network team uses InfoBlox to store information about IP ranges (Location, Country, etc.)
There is an API available but Infoblox's documentation and examples are not very practical.
I would like to search via the API for details about an IP. To start with - I would be happy to get anything back from the server. I modified the only example I found
import requests
import json
url = "https://10.6.75.98/wapi/v1.0/"
object_type = "network"
search_string = {'network':'10.233.84.0/22'}
response = requests.get(url + object_type, verify=False,
data=json.dumps(search_string), auth=('adminname', 'adminpass'))
print "status code: ", response.status_code
print response.text
which returns an error 400
status code: 400
{ "Error": "AdmConProtoError: Invalid input: '{\"network\": \"10.233.84.0/22\"}'",
"code": "Client.Ibap.Proto",
"text": "Invalid input: '{\"network\": \"10.233.84.0/22\"}'"
}
I would appreciate any pointers from someone who managed to get this API to work with Python.
UPDATE: Following up on the solution, below is a piece of code (it works but it is not nice, streamlined, does not perfectly checks for errors, etc.) if someone one day would have a need to do the same as I did.
def ip2site(myip): # argument is an IP we want to know the localization of (in extensible_attributes)
baseurl = "https://the_infoblox_address/wapi/v1.0/"
# first we get the network this IP is in
r = requests.get(baseurl+"ipv4address?ip_address="+myip, auth=('youruser', 'yourpassword'), verify=False)
j = simplejson.loads(r.content)
# if the IP is not in any network an error message is dumped, including among others a key 'code'
if 'code' not in j:
mynetwork = j[0]['network']
# now we get the extended atributes for that network
r = requests.get(baseurl+"network?network="+mynetwork+"&_return_fields=extensible_attributes", auth=('youruser', 'youpassword'), verify=False)
j = simplejson.loads(r.content)
location = j[0]['extensible_attributes']['Location']
ipdict[myip] = location
return location
else:
return "ERROR_IP_NOT_MAPPED_TO_SITE"
By using requests.get and json.dumps, aren't you sending a GET request while adding JSON to the query string? Essentially, doing a
GET https://10.6.75.98/wapi/v1.0/network?{\"network\": \"10.233.84.0/22\"}
I've been using the WebAPI with Perl, not Python, but if that is the way your code is trying to do things, it will probably not work very well. To send JSON to the server, do a POST and add a '_method' argument with 'GET' as the value:
POST https://10.6.75.98/wapi/v1.0/network
Content: {
"_method": "GET",
"network": "10.233.84.0/22"
}
Content-Type: application/json
Or, don't send JSON to the server and send
GET https://10.6.75.98/wapi/v1.0/network?network=10.233.84.0/22
which I am guessing you will achieve by dropping the json.dumps from your code and handing search_string to requests.get directly.

Categories