When I do this:
url = 'http://www.example.com'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }
data = urllib.parse.urlencode(values)
data = data.encode('utf-8') # data should be bytes
req = urllib.request.Request(url, data)
print(req)
Using Python, I get this:
< urllib.request.Request object at 0x0000000002E8FF60 >
What does it mean?
What happened to my req variable?
Could someone explain this to me?
What you are seeing is an object of type Request A request object is an abstraction of a URL request.
To view the elements, you can do req.__dict__
Also, dir(req) would give you the available keys in the request object.
Here is the documentation of the Request class
The reason you are seeing <urllib.request.Request object at 0x0000000002E8FF60> is, by default it provides the object in the following format:
(Normally, you would override this by specifying __unicode__, which would refer to some property within the class object)
Related
I need add friend on faceit by api. There my code
facapi = 'Bearer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
targetid = '54372d6d-134f-4a0d-90c1-babccfaf9e08'
headers = {"Authorization":facapi,"users":[targetid]}
payload={"users":targetid,"conversionPoint":"profile"}
url = f'https://api.faceit.com/friend-requests/v1/users/{myfaceitid}/requests'
print(requests.post(url, headers=headers ).text)
When i send post request i get that
requests.exceptions.InvalidHeader: Header part ([targetid]) from {'users': [targetid]} must be of type str or bytes, not <class 'list'>
Im changed [targetid] to targetid and got another error
{"errors":[{"code":"err_br0","message":"'users' field must contain user ids"}]}
The joke is that the first request contains a list of user ids and the request requires a string type or byte, and the second request already contains just a string with userid and the error requires this uid
Also tried to add payload, but in that case i got another error
{"errors":[{"code":"err_br0","message":"invalid character 'u' looking for beginning of value"}]}
<bound method Response.json of <Response [400]>>
My payload is silimar to faceit payload
payload={"users":'7efe7dc4-23cc-43c0-b0ac-25fe3385ef71',"conversionPoint":"matchroom"}
idk how to fix that. It feels broken
I am trying to add a feature to the Dataset via Mapbox API using Python. I'm following this instruction https://docs.mapbox.com/api/maps/#update-a-dataset but keep getting this error:
{'message': 'Provide a single Feature to insert'}
The code looks like this:
rs = []
dictionary = {
"id":1,
"type":"Feature",
"properties":{},
"geometry":{"coordinates":[-83.750246, 42.269375],"type":"Point"}}
url = "https://api.mapbox.com/datasets/v1/voratima/"+dataset+"/features/1?access_token="+access_token
rs.append(grequests.put(url, data=dictionary, hooks = {'response' : do_something}))
grequests.map(rs, exception_handler=exception_handler)
I've tried the following but none of them work:
using requests instead of grequests
wrapping the dictionary with json.dumps()
changing the put parameter from data=dictionary to json=dictionary
Making sure the id for both data and URL are set to 1.
Postman of the exact same request does not have the error. What am I missing?
Given a dataset with dataset ID dataset exists, your request body looks ok.
Please add the header
headers = {'Content-type': 'application/json'}
Also can you check if you meet these specs:
This should be one individual GeoJSON feature, not a GeoJSON
FeatureCollection. If the GeoJSON feature has a top-level id property,
it must match the feature_id you use in the URL endpoint.
It turns out I forgot the header. Thanks to Mortiz for pointing that out. After the update I got
<Response [400]> {'message': 'Unexpected token i'}
That's because I need to wrap the dictionary inside json.dumps(). Then the error became
<Response [422]> {'message': 'Request URI does not match feature id'}
That's because the id in the dictionary has to be a string i.e. "id":"1" not "id":1. Here's the code that works:
rs = []
dictionary = {
"id":"1",
"type":"Feature",
"properties":{},
"geometry":{"coordinates":[-83.750246, 42.269375],"type":"Point"}}
headers = {'Content-type': 'application/json'}
url = "https://api.mapbox.com/datasets/v1/voratima/"+dataset+"/features/1?access_token="+access_token
rs.append(grequests.put(url, data=json.dumps(dictionary), headers=headers, hooks = {'response' : do_something}))
grequests.map(rs, exception_handler=exception_handler)
I received the error: AttributeError: 'set' object has no attribute 'items' while trying to get info via twitch API.
import requests
ENDPOINT = 'https://api.twitch.tv/kraken/clips/top?channel=Twitch&period=month&trending=true&limit=1'
HEAD = {
'Accept: application/vnd.twitchtv.v5+json',
'Client-ID: HIDDEN',
}
response = requests.get(url=ENDPOINT, headers=HEAD)
print (response.text)
The problem is the way you have defined your header in HEAD, you have actually created a set, not a dictionary. Revise your HEAD as follows:
HEAD = {
'Accept': 'application/vnd.twitchtv.v5+json',
'Client-ID': 'HIDDEN',
}
Not that the key and value are wrapped inside a quotation.
Dictionary:
{'key', 'value'}
What you had done was to create a Set:
{'key value'}
I need to add some extra key, value to response in requests lib of python3 without changing response structure (because the response will be sent into another service for the process). for example, I received this response:
>>import requests
>>r = requests.post(url=input_kong_address, data=data)
>>print(r.json())
{
"foo":"bar",
"key1":"val1"
}
I need to add "extra_key":"extra_value" to response:
{
"foo":"bar",
"key1":"val1",
"extra_key":"extra_value"
}
and now I want to add some extra key to response and sent it to the next service without changing in structure (class, type and etc):
>>import requests
>>import json
>>r = requests.post(url=input_kong_address, data=data)
>>response_data = r.json()
>>response_data['extra_key']='extra_value' # trying to add extra key and value to response
>>r.json = json.loads(json.dumps(response_data)) # trying to attach new dict to response
>>r.json() # check is worked?
{TypeError}'dict' object is not callable
thank you.
response.json() is a method, so rebinding it to a dict can only lead to this behaviour indeed. Now if you read the source of the response class, you'll find out that this method actually operates on the ._content attribute (accessed via either the .content and/or .text properties). IOW, you just have to assign your serialized json string to response._content:
>>> import requests
>>> import json
>>> r = requests.get("https://www.google.com")
>>> r._content = json.dumps({"foo": "bar"})
>>> r.json()
{u'foo': u'bar'}
>>>
This being said:
the response will be sent into another service for the process
you may want to think twice about your design then. It's of course impossible to tell without knowing much more about your concrete use case, but ask yourself whether this "other service" really needs the whole response object.
I am working a project, where in I am suppose to get some user input through web application, and send that data to cloudant DB. I am using python for the use case. Below is the sample code:
import requests
import json
dict_key ={}
key = frozenset(dict_key.items())
doc={
{
"_ID":"1",
"COORD1":"1,1",
"COORD2":"1,2",
"COORD3":"2,1",
"COORD4":"2,2",
"AREA":"1",
"ONAME":"abc",
"STYPE":"black",
"CROPNAME":"paddy",
"CROPPHASE":"initial",
"CROPSTARTDATE":"01-01-2017",
"CROPTYPE":"temp",
"CROPTITLE":"rice",
"HREADYDATE":"06-03-2017",
"CROPPRICE":"1000",
"WATERRQ":"1000",
"WATERSRC":"borewell"
}
}
auth = ('uid', 'pwd')
headers = {'Content-type': 'application/json'}
post_url = "server_IP".format(auth[0])
req = requests.put(post_url, auth=auth,headers=headers, data=json.dumps(doc))
#req = requests.get(post_url, auth=auth)
print json.dumps(req.json(), indent=1)
When I am running the code, I am getting the below error:
"WATERSRC":"borewell"
TypeError: unhashable type: 'dict'
I searched a bit, and found below stackflow link as a prospective resolution
TypeError: unhashable type: 'dict'
It says that "To use a dict as a key you need to turn it into something that may be hashed first. If the dict you wish to use as key consists of only immutable values, you can create a hashable representation of it like this:
key = frozenset(dict_key.items())"
I have below queries:
1) I have tried using it in my code above,but I am not sure if I have used it correctly.
2) To put the data in the cloudant DB, I am using Python module "requests". In the code, I am using the below line to put the data in the DB:
req = requests.put(post_url, auth=auth,headers=headers, data=json.dumps(doc))
But I am getting below error:
"reason": "Only GET,HEAD,POST allowed"
I searched on that as well, and I found IBM BLuemix document about it as follows
https://console.ng.bluemix.net/docs/services/Cloudant/basics/index.html#cloudant-basics
As I referred the document, I can say that I am using the right option. But may be I am wrong.
If you are adding a document to the database and you know the the _id, then you need to do an HTTP POST. Here's some slightly modified code:
import requests
import json
doc={
"_id":"2",
"COORD1":"1,1",
"COORD2":"1,2",
"COORD3":"2,1",
"COORD4":"2,2",
"AREA":"1",
"ONAME":"abc",
"STYPE":"black",
"CROPNAME":"paddy",
"CROPPHASE":"initial",
"CROPSTARTDATE":"01-01-2017",
"CROPTYPE":"temp",
"CROPTITLE":"rice",
"HREADYDATE":"06-03-2017",
"CROPPRICE":"1000",
"WATERRQ":"1000",
"WATERSRC":"borewell"
}
auth = ('admin', 'admin')
headers = {'Content-type': 'application/json'}
post_url = 'http://localhost:5984/mydb'
req = requests.post(post_url, auth=auth,headers=headers, data=json.dumps(doc))
print json.dumps(req.json(), indent=1)
Notice that
the _id field is supplied in the doc and is lower case
the request call is a POST not a PUT
the post_url contains the name of the database being written to - in this case mydb
N.B in the above example I am writing to local CouchDB, but replacing the URL with your Cloudant URL and adding correct credentials should get this working for you.