Let JSON object accept bytes or let urlopen output strings
HTTP sends bytes. If the resource in question is text, the character encoding is normally specified, either by the Content-Type HTTP header or by another mechanism (an RFC, HTML meta http-equiv
,...).
urllib
should know how to encode the bytes to a string, but it's too naïve—it's a horribly underpowered and un-Pythonic library.
Dive Into Python 3 provides an overview about the situation.
Your "work-around" is fine—although it feels wrong, it's the correct way to do it.
Python3 strange error with json.loads
The data returned by request
library is a binary string while json.loads
accepts str
ings so you need to convert the data (decode
) to a string using the encoding that your request returns (which is usually ok to assume that it is UTF-8
).
You should be able to just change your code to this:
return json.loads(data.decode("utf-8"))
PS: Storing the variable right before returning it is redundant so I simplified things
HTTPResponse object -- JSON object must be str, not 'bytes'
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']
Related Topics
How to Get an Event Callback When a Tkinter Entry Widget Is Modified
How to Move a Tick Label in Matplotlib
Does Python Have a Bitfield Type
First Non-Null Value Per Row from a List of Pandas Columns
Beginner Python: Reading and Writing to the Same File
Repeating Each Element of a Numpy Array 5 Times
Matching Nested Structures with Regular Expressions in Python
Transpose Nested List in Python
Python's Insert Returning None
Find Column Name in Pandas That Matches an Array
Collision Between Masks in Pygame
Pygame.Error: Video System Not Initialized