331 votes

Comment envoyer un "multipart/form-data" avec des requêtes en python ?

Comment envoyer un multipart/form-data con requests en python ? Comment envoyer un fichier, je comprends, mais comment envoyer les données du formulaire par cette méthode ne peut pas comprendre.

0 votes

Votre question n'est pas vraiment claire. Que voulez-vous obtenir ? Souhaitez-vous envoyer des données "multipart/form-data" sans téléchargement de fichier dans le formulaire ?

4 votes

Le fait que files est utilisé pour faire les deux est une très mauvaise API. J'ai soulevé un problème intitulé Envoi de données multipart - nous avons besoin d'une meilleure API pour régler ce problème. Si vous êtes d'accord pour dire que l'utilisation files Le paramètre permettant d'envoyer des données en plusieurs parties est, au mieux, trompeur. Veuillez demander la modification de l'API dans la question ci-dessus.

0 votes

@PiotrDobrogost ce problème est clos. N'encouragez pas les gens à commenter les questions fermées, qu'elles soient pertinentes ou non.

5voto

Mohamed MosȜd Points 80
import requests
# assume sending two files
url = "put ur url here"
f1 = open("file 1 path", 'rb')
f2 = open("file 2 path", 'rb')
response = requests.post(url,files={"file1 name": f1, "file2 name":f2})
print(response)

5voto

Chris Points 402

En spécifiant un files dans les POST demande, le Content-Type de la demande est automatiquement réglé sur multipart/form-data (suivi par le boundary utilisée pour séparer chaque partie du corps dans les données utiles multipart), si vous envoyez seulement files ou form données et files en même temps (ainsi, un ne devrait pas tenter de définir le Content-Type manuellement dans ce cas). Alors que, si seulement form ont été envoyées, le Content-Type sera automatiquement réglé sur application/x-www-form-urlencoded .

Vous pouvez imprimer le Content-Type de la requête afin de vérifier ce qui précède à l'aide de l'exemple ci-dessous, qui montre comment télécharger plusieurs fichiers (ou un seul) avec (éventuellement) le même key (c'est-à-dire, 'files' dans le cas ci-dessous), ainsi qu'avec les options form données (c'est-à-dire, data=form_data ). La documentation sur la manière de POST unique et multiple files peuvent être trouvés aquí y aquí respectivement. Si vous avez besoin de télécharger des fichiers volumineux sans les lire en mémoire, jetez un coup d'oeil à Téléchargements en streaming . Pour le côté serveur - au cas où vous en auriez besoin - veuillez jeter un coup d'oeil à cette réponse d'où est extrait le code ci-dessous, et qui utilise la fonction FastAPI cadre web.

import requests

url = 'http://127.0.0.1:8000/submit'
files = [('files', open('test_files/a.txt', 'rb')), ('files', open('test_files/b.txt', 'rb'))]
#file = {'file': open('test_files/a.txt','rb')} # for sending a single file
form_data ={"name": "foo", "point": 0.13, "is_accepted": False}
resp = requests.post(url=url, data=form_data, files=files) 
print(resp.json())
print(resp.request.headers['content-type'])

4voto

RCross Points 630

Pour clarifier les exemples donnés ci-dessus,

"Vous devez utiliser le paramètre files pour envoyer une requête POST de formulaire multipart, même si vous n'avez pas besoin de télécharger de fichiers."

files={}

ne fonctionnera pas, malheureusement.

Vous aurez besoin de mettre quelques valeurs fictives, par ex.

files={"foo": "bar"}

J'ai rencontré ce problème en essayant de télécharger des fichiers vers l'API REST de Bitbucket et j'ai dû écrire cette abomination pour éviter l'erreur redoutée "Unsupported Media Type" :

url = "https://my-bitbucket.com/rest/api/latest/projects/FOO/repos/bar/browse/foobar.txt"
payload = {'branch': 'master', 
           'content': 'text that will appear in my file',
           'message': 'uploading directly from python'}
files = {"foo": "bar"}
response = requests.put(url, data=payload, files=files)

:O=

0 votes

Vous ne pourriez pas faire requests.put(url, files=payload)

3voto

crifan Points 1242

Envoyer une clé et une valeur multipart/form-data

commande curl :

curl -X PUT http://127.0.0.1:8080/api/xxx ...
-H 'content-type: multipart/form-data; boundary=----xxx' \
-F taskStatus=1

python requests - Demandes POST plus compliquées :

    updateTaskUrl = "http://127.0.0.1:8080/api/xxx"
    updateInfoDict = {
        "taskStatus": 1,
    }
    resp = requests.put(updateTaskUrl, data=updateInfoDict)

Envoyer un fichier multipart/form-data

commande curl :

curl -X POST http://127.0.0.1:8080/api/xxx ...
-H 'content-type: multipart/form-data; boundary=----xxx' \
-F file=@/Users/xxx.txt

python requests - POST d'un fichier codé en Multipart-Encoding :

    filePath = "/Users/xxx.txt"
    fileFp = open(filePath, 'rb')
    fileInfoDict = {
        "file": fileFp,
    }
    resp = requests.post(uploadResultUrl, files=fileInfoDict)

c'est tout.

0voto

vinaymk Points 56

Voici le snippet python dont vous avez besoin pour télécharger un grand fichier unique en tant que données de formulaire à plusieurs parties. Avec le middleware Multer de NodeJs fonctionnant du côté du serveur.

import requests
latest_file = 'path/to/file'
url = "http://httpbin.org/apiToUpload"
files = {'fieldName': open(latest_file, 'rb')}
r = requests.put(url, files=files)

Pour le côté serveur, veuillez consulter la documentation de Multer à l'adresse suivante : https://github.com/expressjs/multer ici le champ single('fieldName') est utilisé pour accepter un seul fichier, comme dans :

var upload = multer().single('fieldName');

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X