Python Requests - Sending POST form data multi-part - python-2.7

I've looked through the posts here, and I haven't found a solution yet.
I'm trying to send a POST request to send a file to a server.
Part of the form data accepts the binary file, and there are other mandatory fields to add to the form.
The last solution I've tried was this:
my_data = {
"repo_upload_file": ("filename.pdf", open("filename.pdf", rb), "application/pdf"),
"sesskey": (None, sess_key),
"repo_id": (None, repo_id),
"author": (None, author),
"savepath": (None, save_path),
"title": (None, title),
"itemid": (None, itemid),
"ctx_id": (None, ctx_id)
}
response = session.post("http://mywebsite/repo.php?action=upload", files=my_data)
print response.content # expecting a json object that stores the url to the uploaded file
When I try via my browser (this server has a ui), it works fine. Using fiddler, I've seen that the fields get sent as WebForms :
However, when using my code, it appears on fiddler that somehow the server doesn't recognize them as WebForms, even though it appears that the request was sent correctly
This is how the server expects them, but for some reason this doesn't seem to be working
When I got it working fine from the browser, this was the request form datas:

If you desire to post other data which is not file, you should follow one of those
my_data = {
"repo_upload_file": ("filename.pdf", open("filename.pdf", "rb"), "application/pdf")
}
data = {
"sesskey": sess_key,
"repo_id": repo_id,
"author": author,
"savepath": save_path,
"title": title,
"itemid": itemid,
"ctx_id": ctx_id
}
Type 1, post data normally
response = session.post(url, data = data , files=my_data)
Type 2, post as json
response = session.post(url, json = data , files=my_data)

Related

copyleaks sent pdfReport to endpoint as binary on request.body, not as file

I have django view that gets request and I try to send pdf result of copyleak scan.
I get file as request.body and request.FILES is empty.
I have checked copyleaks docs to see if I could pass extra argument as we should pass
enctype="multipart/form-data" in django form to get files in request.FILES, but I did not see anything related.
I can read request body and write it to file, no problem here, but would be great if I directly get pdf file in request FILES.
myobj = json.dumps(
{
"pdfReport": {
"verb": "POST",
"endpoint": "https://aa67-212-47-137-71.in.ngrok.io/en/tool/copyleaks/download/",
},
"completionWebhook": "https://aa67-212-47-137-71.in.ngrok.io/en/tool/copyleaks/complete/",
"maxRetries": 3,
}
)
response = requests.post(
"https://api.copyleaks.com/v3/downloads/file4/export/export16",
headers=headers,
data=myobj,
)
I tried to change Content-Type manually and got error
django.http.multipartparser.MultiPartParserError: Invalid boundary in multipart: None
Bad request (Unable to parse request body): /en/tool/copyleaks/download/

Uploading a file in a form group in angular and send it to Django API

I have a form in the front-end having multiple entries, i.e name, email, phone and also a file field entry. A Form group is used to group all these elements in the same form in Angular. There is also a corresponding model in Django, (Using Django Rest Framework).
I could not manage to have the file sent to the API, even if the rest of the data is sent correctly and saved on the back-end.
First, I am able to upload the file successfully to Front-end, below I log in the console:
Second, the object I send is something like this:
{"name":"name", "age":49, "email":"email#field.com", "file":File}
The File in the JSON is the same file object displayed in the console above.
I tested my backend with Postman, I was able to succesfully have the file as well as the other data saved. (I believe the problem to be more on the Front-end side ).
Solutions I found for uploading file in Angular used form data (i.e here), these solutions were not convenient as the form consists only of a file, however in my case I have file as well as other data (Form Group).
Another thing I tried that did not work was the following: putting a form Data object with the file in the "file" key of the JSON to be sent. Still, this it did not work.
Also, this is how I upload the file in angular:
public file: File | null = null;
public form: FormGroup;
formData = new FormData();
ngOnInit(){
this.form = this.fb.group({
name: [], [Validators.required]],
age: [],
email: [], [Validators.required]],
file: []});
fileUploadedHandler(file) {
this.file = file;
this.formData.append("file",file, file.name);
this.form.patchValue({file:file}); //this.formData});
this.createDocumentForm.updateValueAndValidity();
console.log(file);}
}
Any propositions to solve this ?
Managed to solve the problem. First I had to use formData instead of formGroup, It was also possible to have multiple fields in formData using append method :
this.formData.append("file",file, file.name);
this.formData.append("name",name);
this.formData.append("age",age);
I had also to revisit the HTTP headers used to submit the form to the API, this was the blocking part.
In my case I had to Remove the 'Content-Type': 'application/json' from the headers. The new working one was:
working_headers = new HttpHeaders({
"Accept": "*/*",
"Authorization": 'Token laksjd8654a6s56a498as5d4a6s8d7a6s5d4a',
});

spotify api "player/currently-playing" enpoint is not return currently playing song data

I am trying to get data about a song playing on one of my devices from the spotify API. I have created a view that fetches data from the API and part of it looks like this:
class Song(viewsets.ModelViewSets):
....
room_code = request.data['room_code']
room = Room.objects.filter(code=room_code)[0]
host = room.host
endpoint = 'player/currently-playing'
response = execute_spotify_api_request(host, endpoint)
item = response.get('item')
duration = item.get('duration_ms')
progress = response.get('progress_ms')
album_cover = item.get('album').get('images')[0].get('url')
return Response(response, status=status.HTTP_200_OK)
The execute_spotify_api_request(host, endpoint) is a utility function and it looks like this:
def execute_spotify_api_request(session_id, endpoint, post_=False, put_=False):
tokens = get_user_tokens(session_id)
headers = {'Content-Type': 'application/json',
'Authorization': "Bearer " + tokens.access_token}
if post_:
post(BASE_URL + endpoint, headers=headers)
if put_:
post(BASE_URL + endpoint, headers=headers)
response = get(BASE_URL, {}, headers=headers)
try:
return response.json()
except:
return {'error': 'Could not retrieve a response'}
The full url from which im fetching is ""https://api.spotify.com/v1/me/player/currently-playing"
The problem is with the response that im getting from the API, the response is not an error but data that im not expecting to get. Im getting a response that looks like this:
response = {
"display_name": "Tanatswamanyakara",
"external_urls": {
"spotify": "https://open.spotify.com/user/dlnsysel6bndktbvduz6cl79w"
},
"followers": {
"href": null,
"total": 0
},
"href": "https://api.spotify.com/v1/users/dlnsysel6bndktbvduz6cl79w",
"id": "dlnsysel6bndktbvduz6cl79w",
"images": [],
"type": "user",
"uri": "spotify:user:dlnsysel6bndktbvduz6cl79w"
}
I was hoping to get data (the progress, title, duration, album, artist etc) about the song I am playing on my spotify account but instead I get that response, how do I fix that?
N.B
My access tokens and refresh tokens are working as they should. (so I think)
If the data is not what you are expecting then there's going to be something wrong with your API endpoint. You can use the Spotify developer console to generate the endpoint link, it would be worth debugging your execute_spotify_api_request code and the url it generates against the value in the console.
Having just re-read your code half way through answering, I've noticed that you aren't appending your endpoint variable to your GET url:
response = get(BASE_URL, {}, headers=headers)
This means that the get doesn't have 'player/currently-playing' and just returns the base URL which is probably 'https://api.spotify.com/v1/me/' - hence the response you receive is just your profile data.

Telegram bot sendMediaGroup() in Postman - JSON-serialized array?

I'm using Postman app to interact with a Telegram bot api. I've sent photos using the sendPhoto() method, like this:
https://api.telegram.org/botToken/sendPhoto?chat_id=00000000&photo=AgAC***rgehrehrhrn
But I don't understand the sendMediaGroup() method. Can someone post an example how to compose the https string to send two photos?
Thanks
You need to send a POST request at the url https://api.telegram.org/botToken/sendPhoto with a JSON body. You are using the url to specify all the parameters of the request but urls are only 2000 characters long. The body of a POST request, instead, has no limits in terms of size. The JSON body should look something like this:
{
"chat_id": 777000,
"media": [
{
"type": "photo",
"media": "https://example.com/first_photo_url.png",
"caption": "an optional description of the first photo",
"parse_mode": "optional (you can delete this parameter) the parse mode of the caption"
},
{
"type": "photo",
"media": "https://example.com/fsecond_photo_url.png",
"caption": "an optional description of the second photo",
"parse_mode": "optional (you can delete this parameter) the parse mode of the caption"
}
],
}
For more info see:
how to send JSON (raw) data with Postman
and
sendMediaGroup Telegram API's method.
You must send JSON as a string, or serialized JSON, to Telegram API. The format is as same as #GioIacca9's answer.
Note: only the caption in the first image will be showen.
Have a try this Python code.
def send_photos(api_key, chat_id, photo_paths):
params = {
'chat_id': chat_id,
'media': [],
}
for path in photo_paths:
params['media'].append({'type': 'photo', 'media': path})
params['media'] = json.dumps(params['media'])
url = f'https://api.telegram.org/bot{api_key}/sendMediaGroup'
return requests.post(url, data=params)
if __name__ == '__main__':
send_photos('your_key', '#yourchannel', ['http://your.image.one', 'http://your.image.two'])

How to get data of particular sender and receiver in chatbox?

I want to get all messages history of particular sender and receiver. i am using fronEnd angular5 and Backend Django..
my db sample table :
{
"id": 288,
"name": "Faric",
"receiver": "drit",
"text": "hiee",
"myDate": "2018-07-26T04:38:05.505000Z"
}
chatService:
url : string = 'http://127.0.0.1:8000/msg/';
messages: Subject<ChatMessage>;
getMessage(): Promise<chatMessage[]>{
return this.http.get(this.url).map(res => res.json()).topromise(); #url of messages API
}
chatcomponent:
this.chat.getMessage()
.then(msg=> this.messages = msg); # messges = []
using this service and component i get all mssages.. jst i want to get perticular sender and receiver's data. how to do this?
You can use ES6's find function to fetch data for a particular sender / receiver,
Let's say if you want to get the data based on the ID field (in your json), you can try something like,
this.messageForAnUser = this.messages.find(message=> message.id === THE_SENDER_OR_RECEIVER_ID_YOU_WANT_TO_SEARCH)
Hope this helps!