I have to pass an integer field in headers for a request but it is giving me an error:
requests.exceptions.InvalidHeader: Value for header {orgId: 721067787} must be of type str or bytes, not <class 'int'>
This is my code please help, regarding the exception:
authenticationHeaders = {'Authorization':tmpAuthToken,'orgId':organizationId}
response = requests.get("https://desk.zoho.com/api/v1/tickets",headers = authenticationHeaders)
return response.json()
You have to send a string value inside the dictionary.
This would work:
authenticationHeaders = {'Authorization':str(tmpAuthToken),'orgId':str(organizationId)}
response = requests.get("https://desk.zoho.com/api/v1/tickets",headers = authenticationHeaders)
return response.json()
Related
My question
I tried many times to get information from url, In the website information is written in json form. And I found that 1,2,3 is wrong form.
what does request.get return?? and i wonder why 1, 2 and 3 does not work.
And how can I turn json in to dictionary form( not like fourth case)? I want to know other ways too. different from
response = response.json()
My codes(1,2,3 Wrong and 4 is correct)
1.TypeError: the JSON object must be str, bytes or bytearray, not Response
response = requests.get(URL)
response = json.loads(response)
2.TypeError: the JSON object must be str, bytes or bytearray, not Response
response = requests.get(URL)
response = json.load(response)
3.AttributeError: 'Response' object has no attribute 'read'
response = requests.get(URL)
response = response.read()
correct one
response = requests.get(URL)
response = response.read()
what does request.get return?
According to the documentation, it returns a requests.Response object.
And how can I turn json in to dictionary form
What's wrong with response = response.json()?
Your attempts to use json.load() and json.loads() failed because you passed it a Response object, instead of a str, bytes or bytearray. Be sure to fully read the documentation.
response.text gives you a str of the response, which is what you are really after. response.read() raises an AttributeError because there is no read() method for requests.Response objects. Again, make sure you fully read the documentation.
This is what you want: json.loads(response.text).
Is JSON parsing possible into a type data or any other form where I can access each individual item within F# using built-in Microsoft provided library?
Following is an output generated by the following code.
"{"account_type":"type1","address":"US","preferred_languages":["en","ar","cn"],"displayName":"John","last_name":"Doe"}"
type Token = {access_token: string; refresh_token: string}
type Authentication =
new() = {}
static member token = null;
member this.RequestToken(credentials) =
let url = "example.com"
let request = WebRequest.Create(url) :?> HttpWebRequest
request.Method <- "POST"
request.ContentLength <- (int64)data.Length
use requestStream = request.GetRequestStream()
requestStream.Write(data, 0, (data.Length))
requestStream.Flush()
requestStream.Close()
let response = request.GetResponse() :?> HttpWebResponse
use reader = new StreamReader(response.GetResponseStream())
let output = reader.ReadToEnd()
reader.Close()
response.Close()
request.Abort()
Authentication.token = JsonConvert.DeserializeObject<Token>(output)
// the value or constructor "Token" is not defined
Preferably in a type, for instance
type Token = {access_token: string; refresh_token: string}
Edit
Attempting using JSON.net
You will need to use an external library of some kind. If you want to get the most out of F#, you can solve this very nicely using the F# Data JSON type provider.
The type provider can infer type of JSON data from a sample, so you could parse the above data by using your sample response to guide the inference and then use the inferred type to parse more data:
open FSharp.Data
// Define a type using a sample JSON
type Account = JsonProvider<"""
{ "account_type":"type1","address":"US",
"preferred_languages":["en","ar","cn"],
"displayName":"John","last_name":"Doe"}""">
// Now, parse actual data you loaded from somewhere
let parsed = Account.Parse(data)
// Access all the members using a member generated by the type provider.
parsed.AccountType
parsed.Address
parsed.PreferredLanguages |> Seq.length
I'm trying to parse JSON file with JsonSlurper.parseText but keep getting similar problems.
def jsonParse = null
def http = new HTTPBuilder(url)
http.auth.basic(username, password)
http.request(Method.GET) {
response.success = { resp, reader ->;
jsonParse = new JsonSlurper().parseText(reader)
}
}
Whenever I run my application the error message says
No signature of method: groovy.json.JsonSlurper.parseText() is applicable for argument types: (java.util.ArrayList)
I understand that JsonSlurper.parseText() is asking for a java.util.ArrayList type as an input. So I tried the following to figure out the type of the input using this code.
def jsonParse = null
def http = new HTTPBuilder(url)
http.auth.basic(username, password)
http.request(Method.GET) {
response.success = { resp, reader ->;
jsonParse = reader
}
}
render jsonParse.getClass()
This prints out the following:
class java.util.ArrayList
I don't understand why I'm getting this error when I am feeding the input with correct datatype.
Any suggestions?
According to the documentation, the HTTPBuilder could be parsing your JSON for you. If your JSON response has its root as a JSON array, then that explains the ArrayList object in your reader variable.
Regarding how this explains the exception being thrown. The reader parameter of the Closure is an ArrayList of parsed JSON, not a String of unparsed JSON. Thus, the code fails on new JsonSlurper().parseText(reader) because reader is not text and the JsonSlurper does not have a method defined for how to parse an ArrayList as JSON.
I have this code:
"response=3&responsetext=Duplicate transaction REFID:3154223053&authcode=&transactionid=&avsresponse=&cvvresponse=&orderid=&type=auth&response_code=300"
I tried converting it into json format using this code:
def converted = "{\"" + resp.data.toString()
.replaceAll('=','\":\"')
.replaceAll('&','\",\"') + "\"}"
it returns the valid json format though I want to get a specific value from that string I tried doing:
println converted.responsetext.toString()
it has an error saying
No such property: responsetext for class: java.lang.String
You can convert request parameters to Map and if required to json string as below:
String str = "response=3&responsetext=Duplicate transaction REFID:3154223053&authcode=&transactionid=&avsresponse=&cvvresponse=&orderid=&type=auth&response_code=300"
def map = str.tokenize(/&/).collectEntries {
def entity = it.tokenize(/=/)
[ entity[0], entity[1] ]
}
assert map.responsetext == "Duplicate transaction REFID:3154223053"
// Json
println new groovy.json.JsonBuilder( map ).toPrettyString()
If you want to go ahead from what you have right now instead, then below implementation should be sufficient:
def items = new groovy.json.JsonSlurper().parseText( converted )
assert items.responsetext == "Duplicate transaction REFID:3154223053"
I've been trying to update a small Python library called libpynexmo to work with Python 3.
I've been stuck on this function:
def send_request_json(self, request):
url = request
req = urllib.request.Request(url=url)
req.add_header('Accept', 'application/json')
try:
return json.load(urllib.request.urlopen(req))
except ValueError:
return False
When it gets to this, json responds with:
TypeError: the JSON object must be str, not 'bytes'
I read in a few places that for json.load you should pass objects (In this case an HTTPResponse object) with a .read() attached, but it doesn't work on HTTPResponse objects.
I'm at a loss as to where to go with this next, but being that my entire 1500 line script is freshly converted to Python 3, I don't feel like going back to 2.7.
Facing the same problem I solve it using decode()
...
rawreply = connection.getresponse().read()
reply = json.loads(rawreply.decode())
I recently wrote a small function to send Nexmo messages. Unless you need the full functionality of the libpynexmo code, this should do the job for you. And if you want to continue overhauling libpynexmo, just copy this code. The key is utf8 encoding.
If you want to send any other fields with your message, the full documentation for what you can include with a nexmo outbound message is here
Python 3.4 tested Nexmo outbound (JSON):
def nexmo_sendsms(api_key, api_secret, sender, receiver, body):
"""
Sends a message using Nexmo.
:param api_key: Nexmo provided api key
:param api_secret: Nexmo provided secrety key
:param sender: The number used to send the message
:param receiver: The number the message is addressed to
:param body: The message body
:return: Returns the msgid received back from Nexmo after message has been sent.
"""
msg = {
'api_key': api_key,
'api_secret': api_secret,
'from': sender,
'to': receiver,
'text': body
}
nexmo_url = 'https://rest.nexmo.com/sms/json'
data = urllib.parse.urlencode(msg)
binary_data = data.encode('utf8')
req = urllib.request.Request(nexmo_url, binary_data)
response = urllib.request.urlopen(req)
result = json.loads(response.readall().decode('utf-8'))
return result['messages'][0]['message-id']
I met the problem as well and now it pass
import json
import urllib.request as ur
import urllib.parse as par
html = ur.urlopen(url).read()
print(type(html))
data = json.loads(html.decode('utf-8'))
Since you are getting a HTTPResponse, you can use Tornado.escape and its json_decode() to convert the JSON string into a dictionary:
from tornado import escape
body = escape.json_decode(body)
From the manual:
tornado.escape.json_decode(value)
Returns Python objects for the given JSON string.