When I try to send image from flutter to flask, flask shows error 400.
I have no idea where is an error in my flutter code. Flutter function gets file(image in my case) as Uint8List. Then, I cast it as List, and trying to send with multipart.
Here is the code from flask and flutter.
Flask:
#auth.post('update/avatar')
#jwt_required()
def update_avatar():
current_user = get_jwt_identity()
save_folder = 'images/users/'
file = request.files.get('file', None)
file.filename = str(current_user) +".jpeg"
filename = secure_filename(file.filename)
file.save(os.path.join(save_folder, filename))
Flutter:
Future<String> uploadAvatar(Uint8List file, int userId) async {
var url = ApiConstants.baseUrlAuth + ApiConstants.updateAvatar + userId.toString();
String? access = await storage.storage.read(key: 'access');
if(access == null){
return '';
}
http.MultipartRequest request = http.MultipartRequest('POST', Uri.parse(url));
List<int> _selectedFile = file;
request.headers.addAll({'Authorization': access, "Content-type": "multipart/form-data"});
request.files.add(http.MultipartFile.fromBytes('file', _selectedFile, contentType: MediaType('file', 'jpeg'),));
http.StreamedResponse response = await request.send();
final responseStr = await response.stream.bytesToString();
Map data = json.decode(responseStr);
if (response.statusCode == 401 && data.containsKey("msg") && data['msg'] == "Token has expired!"){
String res = auths.refreshToken() as String;
if(res == "success"){
res = uploadImagePost(file, userId) as String;
}
return res;
} else if(response.statusCode == 201){
return data['photo_url'];
}
return '';
}
}
According to http Error 400 (Bad Request) the error is because request was somehow corrupted on the way.
check this Mozilla docs for more information about the main error.
Related
If I go into my firebase console and setup a campaign my end devices receive the notification just fine, but for messages to specific devices using the device's registration token, sent from django/python, I get no notification on my mobile devices.
Not sure if this matters but my app is still in development, it is not in production, so if this matters please let me know.
My frontend is flutter, here is the flutter code I am using to get the registration token and send it to the backend:
Future<StreamedResponse> AddProductPut(context, pk, name, quantity, cost, selling, XFile? chosenImage) async {
String id_token = await FirebaseAuth.instance.currentUser!.getIdToken();
late String? fcm_token;
await FirebaseMessaging.instance.getToken().then((token) async {
fcm_token = token!;
}).catchError((e) {
print(e);
});
print(fcm_token);
var url = backend + "/pm/createproduct/" + pk.toString() + "/";
var request = http.MultipartRequest('PUT', Uri.parse(url));
print("FCM TOKEN");
print(fcm_token);
request.headers["Authorization"] = "Token " + id_token;
request.fields["name"] = name;
request.fields["quantity"] = quantity.toString();
request.fields["cost_price"] = cost.toString();
request.fields["selling_price"] = selling.toString();
request.fields["barcode"] = "11111";
request.fields["token"] = fcm_token!;
request.files.add(
await http.MultipartFile.fromPath(
'image',
chosenImage!.path
)
);
return await request.send();
}
Here is the python code in my django serializer to send the notification message:
registration_token = self.context['request'].data["token"],
print(registration_token[0])
print(type(registration_token[0]))
# See documentation on defining a message payload.
message = Message(
notification=Notification(
title='New Product Added',
body='A new product called ' + validated_data['name'] + ' has been added to your account.',
),
token=registration_token[0]
)
# Send a message to the device corresponding to the provided
# registration token.
response = send(message)
print(response)
I am not getting any errors in my django/python console when sending this message, and response prints something like this:
projects/<project name>/messages/16641.......0329
My registration token is something like this:
cmLYCAbL0EsJrxppKzXvhF:APA..............qdt5ySYLbkQC_bpqwL6RdCwSzK_tX8iclp-e0QZB................lgw9g2eFNzfXpn2C4U................UnMphyWa6L9d-wUg
Not sure what the problem is, but I am receiving FCM messages on Apple and Android now...
registration_token = subuser.fcm
print(registration_token)
message = Message(
notification=Notification('Added As A Sub-User', f'A user with the phone {instance.userprofile.phone} has added you to their account as a sub user.'),
token=registration_token
)
and my flutter code that updates the database with the user's fcm registration token...
FirebaseMessaging.instance.getToken().then((token) async {
print(token);
String id_token = await FirebaseAuth.instance.currentUser!.getIdToken();
String uid = await FirebaseAuth.instance.currentUser!.uid;
final result = await http.put(
Uri.parse(backend + "/pm/setfcm/" + uid + "/"),
headers: {
"Content-Type": "application/json",
"Authorization": "Token " + id_token
},
body: jsonEncode({
"fcm": token,
})
);
}).catchError((e) {
print(e);
});
FirebaseMessaging.instance.onTokenRefresh.listen((newToken) async {
print(newToken);
String id_token = await FirebaseAuth.instance.currentUser!.getIdToken();
String uid = await FirebaseAuth.instance.currentUser!.uid;
final result = await http.put(
Uri.parse(backend + "/pm/setfcm/" + uid + "/"),
headers: {
"Content-Type": "application/json",
"Authorization": "Token " + id_token
},
body: jsonEncode({
"fcm": newToken,
})
);
});
response = send(message)
print(response)
This is my Kotlin code
imageButton.setOnClickListener {
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
startActivityForResult(gallery, pickImage)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == pickImage) {
imageUri = data?.data
imageView.setImageURI(imageUri)
//get email from preferences
val prefs = getSharedPreferences("db", Context.MODE_PRIVATE)
val email = prefs.getString("email", "")
val client = AsyncHttpClient(true, 80, 443)
val data = JSONObject()
data.put("files", imageUri.toString())
data.put("email", email.toString())
val condata = StringEntity(data.toString())
//post it to api
client.post(this, "https://jereson.pythonanywhere.com/editdp",
condata, "multipart/form-data; boundary=eBayClAsSiFiEdSpOsTiMaGe",
object: JsonHttpResponseHandler() {
override fun onSuccess(
statusCode: Int,
headers: Array<out Header>?,
response: JSONObject?
) {
Toast.makeText(applicationContext, "image updated successfully", Toast.LENGTH_LONG).show()
}
override fun onFailure(
statusCode: Int,
headers: Array<out Header>?,
responseString: String?,
throwable: Throwable?
) {
Toast.makeText(applicationContext, "Something went wrong "+statusCode, Toast.LENGTH_LONG).show()
}
})//ends the client.post
}//ends resultcode if
This is my python code
#app.route('/editdp', methods = ['POST', 'GET'])
def editdp():
connection = pymysql.connect(host ='jereson.mysql.pythonanywhere-services.com', user
='jereson', password ='jemuki.compassword#4321', database ='jereson$jemuki_com254_254')
cursor = connection.cursor()
from flask import request
json = request.json
email = json['email']
files = json['files']
files = request.files.getlist('files')
#print(files)
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
cursor.execute('UPDATE signup SET dp=%s WHERE email=%s ',[filename, email])
connection.commit()
print(file)
cursor.close()
response = jsonify({"message":"updated successfully"})
return response
When i post an image the code Toasts image updated successfully but whenever i check mysql the filename is not uploaded and also in the folder the image is not uploaded.The email from preferences is just to enable me update the image to the correct rowAny help would be highly appreciated.
I want to grab all chats of my Pinterest account
I have a Proto Service:
syntax = "proto3";
service Pinterest{
rpc GetConversations (request_chat_info) returns (chat_response);
}
message request_chat_info{
string conversation_id = 1;
string csrftoken = 2;
string _b = 3;
string _pinterest_sess = 4;
}
message chat_response{
string type = 1;
string id = 2;
string text = 3;
}
message chat_response_array{
repeated chat_response messages = 1;
}
and this is my Pinterest Servicer:
# GRPC Service
class PinterestService(pb2_grpc.PinterestServicer):
def GetConversations(self, request, context):
conversation_id = request.conversation_id
csrftoken = request.csrftoken
_b = request._b
_pinterest_sess = request._pinterest_sess
chats = _exec(
get_chat,
{"conversation_id": conversation_id, "csrftoken": csrftoken, "_b": _b, "_pinterest_sess": _pinterest_sess}
)
return pb2.chat_response_array(messages=chats)
and main Program is something like this:
# ENDPOINTS
CHAT_API = "https://www.pinterest.com/resource/ConversationMessagesResource/get/"
# Execute Fucntion
def _exec(func, params):
return func(**params)
# Make Requests here
def _get(url:str, cookies:Dict = None, headers:Dict = None) -> requests.Response:
response = requests.request("GET", url=url, cookies=cookies, headers=headers)
response.raise_for_status()
return response
# Chat Parser Function
def _chat_parser(chat_dict: Dict) -> Dict:
return {
"type": chat_dict.get("type", ""),
"id": chat_dict.get("id", ""),
"text": chat_dict.get("text", ""),
}
# Function to handle GRPC
def get_chat(conversation_id:str, csrftoken:str, _b:str, _pinterest_sess:str) -> Dict:
options = {"page_size":25,"conversation_id":conversation_id,"no_fetch_context_on_resource":False}
_cookies = {"csrftoken":csrftoken, "_b":_b, "_pinterest_sess":_pinterest_sess}
query = {"data": json.dumps({"options":options})}
encoded_query = urlencode(query).replace("+", "%20")
url = "{}?{}".format(CHAT_API, encoded_query)
msg_counter = 0
while True:
try:
return _chat_parser(_get(url, _cookies).json()["resource_response"]["data"][msg_counter])
except IndexError:
break
finally:
msg_counter += 1
I need to get all CHAT and I Don't know how to do that!
The Response JSON in Pinterest is exactly Like this:
["resource_response"]["data"][0]
["resource_response"]["data"][1]
["resource_response"]["data"][2]
["resource_response"]["data"][...]
Based on Messages Count the last number change from 0 to any number
I don't know how to handle that!
does the fault in my proto or what?
should I use stream in proto, if yes, bidirectional stream or for Client, Server...
Thank you for Helping me.
I found the answer
it must be server stream and use for loop and yield
I am working with the django framework. I'm trying to send a post request with token using the requests package but it doesn't work. the status code of the request is 200.Here is my code:
def modifier_periode_push(request):
url = "ip_addr/openapi/device"
option1,option2,option3 = "040A0001","041E0001","043C0001"
headers = {
"Accept-Encoding":"gzip","Content-Length":"286","Content-Type":"application/json","Token":"xxxxxxxxx",
"User-Agent":"python-requests/2.26.0"
}
if request.is_ajax() and request.method == "POST":
if request.POST["periode"] == "10":
payload = convertir_en_hexa(option1)
elif request.POST["periode"] == "30":
payload = convertir_en_hexa(option2)
else:
payload = convertir_en_hexa(option3)
data = {
"devEUI":request.POST["devEUI"],
"confirmed":False,
"fPort":int(request.POST["fPort"]),
"data":payload
}
try:
**req = requests.post(url, headers=headers, data=data)**
print(req.status_code)# returns 200
except:
print("Erreur")
return HttpResponse("ok")
else:
return HttpResponse("Requete non authorisée")
I have got this message {'code': 1003, 'msg': 'No Token, Please log in again'}
I want to know why it does not work and how to debug.
I've build a small flask application with a file input form, and now I want that file to be sent to an API.
#app.route('/test', methods=['POST', 'GET'])
def test():
if request.method == 'POST':
file = request.files['file']
file.save(secure_filename(file.filename))
My Layout for the post part:
data = {
"local": file,
"name": file.filename
}
rp = requests.post(f'https://www.meistertask.com/api/tasks/{task_id}/attachments', data, headers={'Authorization': f'Bearer {access_token}'})
print(rp.status_code)
print(rp.content)
No matter how I try to post that file to the API, I always get this response:
{
"errors": [
{
"message": "Parameter local should be of type ActionDispatch::Http::UploadedFile!",
"status": 400
}
]
}
I really don't know how to post a file of that type from my uploaded file in flask.
I'd really appreciate any help! Thank you very much in advance.
file is not a real file, but a filestorage from the werkzeug package.
https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.FileStorage
The API documentation of meistertask is not clear to me, especially I cannot see what local should be. A path? A stream? Bytes?
I got it working with python urlib... maybe this helps you
f = open(fname,'rb')
content = f.read()
f.close()
url = 'https://www.meistertask.com/api/tasks/%s/attachments' % (task_id)
request = urllib.request.Request("%s" %(url))
boundary = "5645645645654"
request.add_header("User-Agent", "python-test")
request.add_header("Accept", "*/*")
request.add_header("Accept-Encoding", "gzip, deflate")
request.add_header("Content-Type","multipart/form-data; boundary=%s" % boundary)
request.add_header("Connection", "keep-alive")
request.add_header("Expect", "100-continue")
request.add_header("Authorization", "Bearer 11111111111111111111")
body = bytes("--%s\r\n" % boundary,'utf-8')
body += bytes('Content-Disposition: form-data; name="name"\r\n\r\n','utf-8')
body += bytes('%s\r\n' % fname,'utf-8')
body += bytes("--%s\r\n" % boundary,'utf-8')
body += bytes('Content-Disposition: file; name="local"; filename="%s"\r\n' % fname,'utf-8')
body += bytes('Content-Type: text/plain\r\n\r\n','utf-8')
body += content
body += bytes('\r\n','utf-8')
body += bytes("\r\n--%s--\r\n" % boundary,'utf-8')
request.data = body
#print(body)
f = urllib.request.urlopen(request)
response = f.read() #bytes