Python3 json with japanese characters - python-3.x

I am using aws lambda to return a simple json with some Japanese characters.
I can't seem to get the characters to display correctly.
Here's what my code looks like:
def lambda_handler(event, context):
minutes = datetime.datetime.now().minute
status = ""
if minutes < 10:
status = u"良好"
else:
status = u"不良"
response = {}
response['ID'] = 1
response['Status'] = status
data = json.dumps(response, indent=2, ensure_ascii=False)
data = json.loads(data)
return data
The above code returns:
{"ID": 1, "Status": "\u4e0d\u826f"}
I have also tried this:
data = json.dumps(response, indent=2, ensure_ascii=False).encode('utf-8)
But to no avail.
How can I get the response to return japanese characters?
Edit:
One more thing I noticed. In the browser I get the above json output, however when running a test in AWS console I get the characters displayed properly. What does this mean?

Isn't it your terminal's problem?
I got Japanese characters displayed correctly on my Mac terminal.
import json
minutes = 9
status = ""
if minutes < 10:
status = u"良好"
else:
status = u"不良"
response = {}
response['ID'] = 1
response['Status'] = status
data = json.dumps(response, indent=2, ensure_ascii=False)
data = json.loads(data)
print(data)
{'ID': 1, 'Status': '良好'}
https://ideone.com/XZeVkS

In case you are running flask using the ensure_ascii did not fix the problem, you have to change disable it on the app level this way:
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

Related

Python: Is there a way to use a set amount of inputs?

I have this simple python webhook sender for Discord with 3 inputs for the URLs.
I want to figure out how to make on option to use 1, 2 or all 3 of the inputs. Is that possible?
I'm not the most experienced person so please answer in some detail.
from discord_webhook import DiscordWebhook
print('paste webhook 1')
url1 = input()
print('paste webhook 2')
url2 = input()
print('paste webhook 3')
url3 = input()
print('what do you want them to say?')
content = input()
print('sending...')
while True:
webhook_urls = [url1, url2, url3]
webhook = DiscordWebhook(url=webhook_urls, content=content)
response = webhook.execute()
I'm assuming you would initially ask them how many webhooks they want to input
from discord_webhook import DiscordWebhook
def ask_for_count():
webhooks_num = input('How many webhooks would you like to use? (1, 2 or 3) \n')
# Firstly, you don't need a seperate print statement to ask for input
# it can be in the input function and if you need the answer in a new line,
# use the escape character /n which creates a new line after execution.
return webhooks_num
def get_webhooks():
if count == '1':
url1 = input('paste webhook 1 \n')
webhook_urls.append(url1)
return # The return ends function as soon as the urls are added to the list.
elif count == '2':
url1 = input('paste webhook 1 \n')
url2 = input('paste webhook 2 \n')
webhook_urls.append(url1)
webhook_urls.append(url2)
return
elif count == '3':
url1 = input('paste webhook 1 \n')
url2 = input('paste webhook 2 \n')
url3 = input('paste webhook 3 \n')
webhook_urls.append(url1)
webhook_urls.append(url2)
webhook_urls.append(url3)
return
else:
print('Please enter a valid choice.')
def get_content():
answer = input('what do you want them to say? \n')
print('sending...')
return answer
webhook_urls = []
# List is intentionally outside of the function,
# so that you don't create an empty list everytime the function is called.
# Now you call the functions defined above to execute in order.
count = ask_for_count()
get_webhooks()
content = get_content()
while True:
webhook = DiscordWebhook(url=webhook_urls, content=content)
response = webhook.execute()
So, basically, as soon as the program runs, the user is asked for the number of webhooks needed and then based on the input (out of 3), they get asked for the webhooks which are then added to the webhook_urls list initiated earlier.
After that, the user is asked for the content and the while loop initiates, executing the code normally, using the function outputs and the list initiated earlier; webhook_urls.
Hope I helped.

Python sockets error TypeError: a bytes-like object is required, not 'int'

I am trying to create a server that will recieve messages from the client and answer them properly.
When i ask for a random number(RAND) i get this error "a bytes-like object is required, not 'int'",
how can i fix it?
and another question, i tried to change the bytes in 'recv' function, and didn't succeed. Can somebody help me out ):?
import socket
import time
import random
server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 8820))
server_socket.listen(1)
(client_socket, client_address) = server_socket.accept()
localtime = time.asctime( time.localtime(time.time()) )
ran = random.randint(0,10)
RUN = True
recieve = 1024
while RUN:
client_input = (client_socket.recv(recieve)).decode('utf8')
print(client_input)
if client_input == 'TIME':
client_socket.send(localtime.encode())
elif client_input == 'RECV':
recieve = client_socket.send(input("the current recieve amount is " + int(recieve) + ". Enter the recieve amount: "))
elif client_input == 'NAME':
client_socket.send(str("my name is SERVER").encode())
elif client_input == 'RAND':
client_socket.send(ran.encode())
elif client_input == 'EXIT':
RUN = False
else:
client_socket.send(str("I can only get 'TIME', 'NAME', 'RAND', 'EXIT'").encode())
client_socket.close()
server_socket.close()
the client code is:
import socket
my_socket = socket.socket()
my_socket.connect(('127.0.0.1', 8820))
while True:
user_input = input("Naor: ")
my_socket.send(user_input.encode())
data = my_socket.recv(1024)
print("Server: " + data.decode('utf8'))
my_socket.close()
The reason for this error is that in Python 3, strings are Unicode, but when transmitting on the network, the data needs to be bytes instead. So... a couple of suggestions:
Suggest using client_socket.sendall() instead of client_socket.send() to prevent possible issues where you may not have sent the entire msg with one call (see docs).
For literals, add a 'b' for bytes string: client_socket.sendallsend(str("I can only get 'TIME', 'NAME', 'RAND', 'EXIT'").encode())
For variables, you need to encode Unicode strings to byte strings (see below)
output = 'connection has been processed'
client_socket.sendall(output.encode('utf-8'))

urllib error: Too many requests

The below python program asks the user for two reddit usernames and compares their score.
import json
from urllib import request
def obtainKarma(users_data):
users_info = []
for user_data in users_data:
data = json.load(user_data)
posts = data["data"]["children"]
num_posts = len(posts)
scores = []
comments = []
for post_id in range(num_posts):
score = posts[post_id]["data"]["score"]
comment = posts[post_id]["num_comments"]
scores.append(score)
comments.append(comment)
users_info.append((scores,comments))
user_id = 0
for user_info in users_info:
user_id+=1
print("User"+str(user_id))
for user_attr in user_info:
print(user_attr)
def getUserInfo():
count = 2
users_data = []
while count:
count = count + 1
username = input("Please enter username:\n")
url = "https://reddit.com/user/"+username+".json"
try:
user_data = request.urlopen(url)
except:
print("No such user.\nRetry Please.\n")
count = count + 1
raise
users_data.append(user_data)
obtainKarma(users_data)
if __name__ == '__main__':
getUserInfo()
However, when I run the program and enter a username, I get an error:
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 429: Too Many Requests
I tried looking for similar issues but none of them satisfied to solve this specific issue. Looking at the error, it would make sense to say that the URL includes an amount of data that exceeds a specific limit? But that still sounds absurd because it is not that much of a data.
Thanks.
The problem seems to be resolved when you supply a User-Agent with your request.
import json
from urllib import request
def obtainKarma(users_data):
users_info = []
for user_data in users_data:
data = json.loads(user_data) # I've changed 'json.load' to 'json.loads' because you want to parse a string, not a file
posts = data["data"]["children"]
num_posts = len(posts)
scores = []
comments = []
for post_id in range(num_posts):
score = posts[post_id]["data"]["score"]
comment = posts[post_id]["data"]["num_comments"] # I think you forgot '["data"]' here, so I added it
scores.append(score)
comments.append(comment)
users_info.append((scores,comments))
user_id = 0
for user_info in users_info:
user_id+=1
print("User"+str(user_id))
for user_attr in user_info:
print(user_attr)
def getUserInfo():
count = 2
users_data = []
while count:
count = count + 1
username = input("Please enter username:\n")
url = "https://reddit.com/user/"+username+".json"
user_data = None
try:
req = request.Request(url)
req.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)')
resp = request.urlopen(req)
user_data = resp.read().decode("utf-8")
except Exception as e:
print(e)
print("No such user.\nRetry Please.\n")
count = count + 1
raise # why raise? --> Program will end if user is not found
if user_data:
print(user_data)
users_data.append(user_data)
obtainKarma(users_data)
if __name__ == '__main__':
getUserInfo()
There were still other issues with your code:
You should not write json.load(user_data), because you are parsing a string. So I changed it to use json.loads(user_data).
The Python documentation for json.loads states:
Deserialize s (a str instance containing a JSON document) to a Python object using this conversion table.
And in the code comment = posts[post_id]["num_comments"], I think you forgot to index on 'data', so I changed it to comment = posts[post_id]["data"]["num_comments"]
And why are you raising the exception in the except-block? This will end the program, however it seems that you expect it not to, from looking at the following code:
print("No such user.\nRetry Please.\n")

str(int(time.time())) gives error string indices must be integers in python 3

I am new to python i create one python pip package for my site API in this i need to pass the nonce. I write the code like below
payload = {}
headers = {}
if self.api_key is not None:
payload["api_key"] = self.api_key
if self.secret_key is not None:
payload["secret_key"] = self.secret_key
payload["request"] = method
payload["nonce"] = str(int(time.time()))
payload.update(kwargs)
headers["X-WCX-APIKEY"] = self.api_key
headers["X-WCX-PAYLOAD"] = base64.b64encode(json.dumps(payload).encode('utf-8'))
headers["X-WCX-SIGNATURE"] = 'SIGNATURE'
url = self.base_url.replace('API_CALL',method)
# update the parameters with the API key
session = requests.session()
response = session.post(url, data = payload, headers = headers)
when run this code i got this error "string indices must be integers"
How can i fix it please help anyone
Note i import the "time"

Python 3.4 : continue function after try and except

Question
I am currently pulling data from yahoo finance. When using try and except, the function stops after the error has been reached. How can I continue the function after the except statement to pull the remaining data for stocks in the index?
index = sp500
def yhooKeyStats():
try:
for eachStock in index:
isUrl = 'http://finance.yahoo.com/q/is?s='+eachStock+'+Income+Statement&annual'
bsUrl = 'http://finance.yahoo.com/q/bs?s='+eachStock+'+Balance+Sheet&annual'
cfUrl = 'http://finance.yahoo.com/q/cf?s='+eachStock+'+Cash+Flow&annual'
def bsYhooStats(url):
req = urllib.request.Request(url)
resp = urllib.request.urlopen(req)
respData = resp.read()
dRespData = respData.decode('utf-8')
gw = dRespData.split('Goodwill</td><td align="right">')[1].split(' &nbsp')[0]
if len(gw) < 14:
gw = gw
else:
gw = '-'
return gw
print(eachStock, bsYhooStats(bsUrl))
except IndexError:
pass
yhooKeyStats()
Output
MMM 7,050,000
ABT 10,067,000
ABBV 5,862,000
ACN 2,395,894
ACE -
ACT 24,521,500
ADT 3,738,000
AES 1,458,000
AET 10,613,200
AFL -
Just put the try/except inside the loop. One of several possibilities:
for eachStock in index:
...
try:
def bsYhooStats(url):
...
return gw if len(gw) < 14 else '-'
print(eachStock, bsYhooStats(bsUrl))
except IndexError:
pass

Resources