python telegram bot issue: accessing json data - python

im building a script in python for a chat group. i am trying to add a / command for the user to get info from a json output. i can have them see the full json output like
def eosvol(bot, update):
"""Send a message when the command /vol is issued."""
volCallJson = requests.get("https://min-api.cryptocompare.com/data/generateAvg?fsym=EOS&tsym=USD&e=Kraken").json()
vol_name = (volCallJson)
volOut = volCallJson
update.message.reply_text(volOut)
and this is what sends it to user
dp.add_handler(CommandHandler("eosvol", eosvol))
i would like to select parts of the json data but i get errors like
vol_name = volCallJson()
TypeError: 'dict' object is not callable
or
line 341, in loads
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict
i understand im not accessing the json correctly. im just not sure how to do so.

Related

Unbale to send a .yml file from spring boot service to fastApi python service

I am trying to send a .yml file from my spring boot service to my python FastApi service. but I keep getting following error.
org.springframework.web.client.HttpClientErrorException$UnprocessableEntity: 422 : [{"detail":[{"loc":["body","files",0],"msg":"Expected UploadFile, received: <class 'str'>","type":"value_error"}]}]
here is the spring boot code that i am using to send the file to python service.
File file2 = new File(("./src/main/resources/testcases/"+filename+".yml"));
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("files",file1);
body.add("files",file2);
body.add("message", message);
HttpHeaders bbheaders = new HttpHeaders();
bbheaders.set("x-api-key", x-api-key);
bbheaders.set(StringUtils.HEADER_AUTHORIZATION, request.getHeader(StringUtils.HEADER_AUTHORIZATION));
HttpEntity<MultiValueMap<String, Object>> bbhttpEntity = new HttpEntity<>(body, bbheaders);
restTemplate.postForEntity( url, bbhttpEntity, String.class);
and here is the python code that is receiving the request:
async def upload_file(request:Request,files:List[UploadFile]= File(...),message:str=Body(...),Authorize: AuthJWT = Depends()):
Actually, this is not the right way to send HttpEntity including .yaml file body.
Firstly you have to convert yaml files to json and then send json as the body of your request.
To convert that you can use:
String convertYamlToJson(String yaml) {
ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory());
Object obj = yamlReader.readValue(yaml, Object.class);
ObjectMapper jsonWriter = new ObjectMapper();
return jsonWriter.writeValueAsString(obj);
}
Then put the String in the body.

Flask unable to send image back in json response

Attempting to send an image to the client browser - the following code works perfectly - please assume that I am receiving the correct base64.b64encoded byte stream:
def get_user_image(usr_rec):
with open("config.json",) as config:
data = json.load(config)
avatar = data["PATHS"]["AVATAR"]
file_ext = os.path.splitext(usrdata["avatar"])[1] if usrdata["avatar"] else ".png"
file_fmt = ".jpeg" if file_ext.upper()==".JPG" else file_ext
path = "{}/{}{}".format(avatar,usr_rec["recordid"],file_ext)
img = Image.open(path,mode="r")
barr = io.BytesIO()
img.save(barr,format="{}".format(file_fmt[1:].upper()))
return b64encode(barr.getvalue())
def format_record (usr_rec):
avatar = get_user_image(usr_rec["recordid"])
return jsonify({"avatar": str(avatar)})
On my development box. Move it to a flask production running under gunicorn and I get JSON serialization errors: TypeError: Object of type bytes is not JSON serializable I am also getting this error for Decimal types as well.
How can I get around this issue?
This is because your get_user_image function returns a stream of bytes and not a string, so you have to cast the bytes read into a string: get_user_image(usr_rec["recordid"]).decode("utf-8"). The same happens for the object of type Decimal.
The jsonify function only serializes objects of type string, as you can also see here and here

How do I serialize this JSON response from API in Python?

The response from the API is:
{"states":[{"state_id":1,"state_name":"Andaman and Nicobar Islands"},{"state_id":2,"state_name":"Andhra Pradesh"},{"state_id":3,"state_name":"Arunachal Pradesh"},{"state_id":4,"state_name":"Assam"},{"state_id":5,"state_name":"Bihar"},{"state_id":6,"state_name":"Chandigarh"},{"state_id":7,"state_name":"Chhattisgarh"},{"state_id":8,"state_name":"Dadra and Nagar Haveli"},{"state_id":37,"state_name":"Daman and Diu"},{"state_id":9,"state_name":"Delhi"},{"state_id":10,"state_name":"Goa"},{"state_id":11,"state_name":"Gujarat"},{"state_id":12,"state_name":"Haryana"},{"state_id":13,"state_name":"Himachal Pradesh"},{"state_id":14,"state_name":"Jammu and Kashmir"},{"state_id":15,"state_name":"Jharkhand"},{"state_id":16,"state_name":"Karnataka"},{"state_id":17,"state_name":"Kerala"},{"state_id":18,"state_name":"Ladakh"},{"state_id":19,"state_name":"Lakshadweep"},{"state_id":20,"state_name":"Madhya Pradesh"},{"state_id":21,"state_name":"Maharashtra"},{"state_id":22,"state_name":"Manipur"},{"state_id":23,"state_name":"Meghalaya"},{"state_id":24,"state_name":"Mizoram"},{"state_id":25,"state_name":"Nagaland"},{"state_id":26,"state_name":"Odisha"},{"state_id":27,"state_name":"Puducherry"},{"state_id":28,"state_name":"Punjab"},{"state_id":29,"state_name":"Rajasthan"},{"state_id":30,"state_name":"Sikkim"},{"state_id":31,"state_name":"Tamil Nadu"},{"state_id":32,"state_name":"Telangana"},{"state_id":33,"state_name":"Tripura"},{"state_id":34,"state_name":"Uttar Pradesh"},{"state_id":35,"state_name":"Uttarakhand"},{"state_id":36,"state_name":"West Bengal"}],"ttl":24}
I am trying to send this data to my Telegram bot.
states_url = "https://cdn-api.co-vin.in/api/v2/admin/location/states"
res = requests.get(states_url,headers={'User-Agent':my_headers})
bot.send_message(chat_id = chat_id, text=response)
I am getting this error:
TypeError: Object of type Response is not JSON serializable
You're trying to send the Response object, while you want either the Python object from the response, in which case you can use res.json(), or you want the raw text of the response, in which case you can use res.text.

Python urllib.request.urlopen: AttributeError: 'bytes' object has no attribute 'data'

I am using Python 3 and trying to connect to dstk. I am getting an error with urllib package.
I researched a lot on SO and could not find anything similar to this problem.
api_url = self.api_base+'/street2coordinates'
api_body = json.dumps(addresses)
#api_url=api_url.encode("utf-8")
#api_body=api_body.encode("utf-8")
print(type(api_url))
response_string = six.moves.urllib.request.urlopen(api_url, api_body).read()
response = json.loads(response_string)
If I do not encode the api_url and api_body I get the below:
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 1247, in do_request_
raise TypeError(msg)
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
However if I try and encode them to utf-8 (uncommenting the lines) then I get the below error:
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 514, in open
req.data = data
AttributeError: 'bytes' object has no attribute 'data'
This seems like a circular error for me and I am not able to resolve it. I did try make to solutions from SO regards to change it to json.load etc but nothing seems to work.
You are encoding both the url and the request body, but only the body should be encoded.
This ought to work:
api_url = self.api_base+'/street2coordinates'
api_body = json.dumps(addresses)
api_body=api_body.encode("utf-8")
response_string = six.moves.urllib.request.urlopen(api_url, api_body).read()
response = json.loads(response_string)
urlopen's arguments are passed to another class to create an opener, and this class does not know whether it has been passed a url or a Request instance. So it checks whether the "url" is a string - if the "url" is a string, it creates a Request, if not it assumes that "url" is a Request instance and tries to set its data attribute, causing the exception that you are seeing.
The code in question is here.

Getting error '_io.BufferedReader' object has no attribute 'startswith' while uploading local image on a webhook's avatar

I I'm trying to use a local image as a webhook's avatar as a webhook, webhooks don't allow image links as an avatar but using a local image gives me error: '_io.BufferedReader' object has no attribute 'startswith', here below is my scrip
As using a link as an avatar isn't allowed (I think this because when i use an image link i get error: TypeError: startswith first arg must be str or a tuple of str, not bytes) I tried to use a local file using with open but I'm just getting more errors!
#bot.command()
async def whook(ctx):
with open("image.png", 'rb') as pfp:
await ctx.channel.create_webhook(name="Mr.W.hook",avatar=pfp)
await ctx.send("Done")
You need to pass in the data of the avatar image, as a bytes object, not the file object that contains the data. The exception is thrown because the create_webhook() code tries to use the bytes.startswith() method on the pfp object you passed in, and file objects don't have that method.
Instead of pfp itself, pass in the result of pfp.read(). This returns the image data as a bytes value:
with open("image.png", 'rb') as pfp:
await ctx.channel.create_webhook(name="Mr.W.hook", avatar=pfp.read())
await ctx.send("Done")
From the discord.TextChannel.create_webhook() documentation:
avatar (Optional[bytes]) – A bytes-like object representing the webhook’s default avatar.

Categories

Resources