2013-10-18 21 views
19

Dosya hakkında ayrıntılı bilgi içeren bir JSON dizesiyle birlikte dosya yüklemek için bir API çağrısı yapmalıyım.Python İstekleri: JSON ve dosyaya özel istek gönder

Bunu yapmak piton istekleri lib kullanın çalışıyorum:

import requests 

info = { 
    'var1' : 'this', 
    'var2' : 'that', 
} 

data = json.dumps({ 
    'token' : auth_token, 
    'info' : info, 
}) 

headers = {'Content-type': 'multipart/form-data'} 

files = {'document': open('file_name.pdf', 'rb')} 

r = requests.post(url, files=files, data=data, headers=headers) 

Bu, aşağıdaki hata atıyor: Ben istekten 'dosyalarını' kaldırırsanız

raise ValueError("Data must not be a string.") 
ValueError: Data must not be a string 

, çalışıyor .
'Verileri' istekten kaldırırsam çalışır.
Verileri JSON olarak kodlamıyorsam, çalışır.

Bu nedenle, hata aynı istekte JSON veri ve dosyaları göndermekle ilgili olduğunu düşünüyorum.

Bu çalışma hakkında nasıl bir fikir var?

+0

bir yazım hatası olduğu görülmektedir kodunuzda: 'var2' bir' '' ile takip edilmeli, değil mi? –

+0

evet, örneğimi düzeltdim, teşekkürler! – oznu

cevap

13

. Başka bir form-data bölümü olacağından

import requests 

info = { 
    'var1' : 'this', 
    'var2' : 'that', 
} 

data = { 
    'token' : auth_token, 
    'info' : info, 
} 

headers = {'Content-type': 'multipart/form-data'} 

files = {'document': open('file_name.pdf', 'rb')} 

r = requests.post(url, files=files, data=data, headers=headers) 

Not bu mutlaka, ne istediğinizi olmayabilir.

+0

Önerirseniz, başka bir istisna daha alırım: "paketlemek için 1'den fazla değere ihtiyacım var" ve bununla ne yapacağını merak ediyorum :-( – Arkady

1

Sana çok parçalı kodlanmış dosyada hem verileri ve dosyaları gönderebilir sanmıyorum değilim, böylece veri de bir "dosya" yapmak gerekir: json kullanarak kodlamak etmeyin

files = { 
    'data' : data, 
    'document': open('file_name.pdf', 'rb') 
} 

r = requests.post(url, files=files, headers=headers) 
+0

Bunu nasıl çözersiniz? Müşteri bir python dict değil JSON haklı olsun? bu bir soru! – ivansabik

+0

@sabik: istek, sözlüğü form verileri olarak kodlar. – RemcoGerlich

5

Konuyu How to send JSON as part of multipart POST-request

Bkz

kendinize pyrequests bırakıyorum içerik türü belirtilir nedir

def send_request(): 
payload = {"param_1": "value_1", "param_2": "value_2"} 
files = { 
    'json': (None, json.dumps(payload), 'application/json'), 
    'file': (os.path.basename(file), open(file, 'rb'), 'application/octet-stream') 
} 

r = requests.post(url, files=files) 
print(r.content) 
+0

Wow .. "Hiçbiri" beni kurtardı !!! – EvgenyKolyakov

+0

Flask diyelim alıcı, bunun için flask kodunun ne olacağını? – MouIdri

+0

@Mouldri try 'response.data' –

0

üretmek için belirlemeyin daha:

files = { 
    'document': open('file_name.pdf', 'rb') 
} 

Bu, yalnızca dosyanız, dosyanızın bulunduğu dizinde bulunuyorsa çalışır t öyle.

yapmanız gereken farklı dizinden dosya eklemek isterseniz: dir_path sizin 'file_name.pdf' dosya ile bir dizindir

files = { 
    'document': open(os.path.join(dir_path, 'file_name.pdf'), 'rb') 
} 

.

Ancak, birden fazla PDF göndermek istiyor musunuz?

İhtiyacınız olan dosyaların listesini döndürmek için özel bir işlev oluşturabilirsiniz (durumda, yalnızca .pdf uzantısına sahip olanlar olabilir).Bu da (yinelemeli dosyaları aramak) alt dizinlerinde dosyalar içerir:

my_data = prepare_pdfs() 

Ve basit döngü ile:

def prepare_pdfs(): 
    return sorted([os.path.join(root, filename) for root, dirnames, filenames in os.walk(dir_path) for filename in filenames if filename.endswith('.pdf')]) 

O zaman arayabilirsin

for file in my_data: 

    pdf = open(file, 'rb') 

    files = { 
     'document': pdf 
    } 

    r = requests.post(url, files=files, ...)