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.
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
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.
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.
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.