2012-09-25 17 views
5

मैं सोच रहा था कि आप पाइथन अनुरोधों का उपयोग करके ऐसा कुछ कैसे अनुवाद करते हैं? Urllib2 में, आप एपीआई सेवा में तार पर भेजे जा रहे डेटा को मैन्युअल रूप से कुशलतापूर्वक उपयोग कर सकते हैं, लेकिन अनुरोधों का दावा है कि फ़ाइल अपलोड मल्टीपार्ट आसान है। हालांकि, अनुरोध लाइब्रेरी का उपयोग करके एक ही अनुरोध को भेजने का प्रयास करते समय, मुझे विश्वास है कि यह दो भागों में से प्रत्येक के लिए सामग्री-प्रकार में कुछ महत्वपूर्ण पैरामीटर निर्दिष्ट नहीं कर रहा है। क्या कोई इस मामले पर कुछ प्रकाश डाल सकता है। आपका अग्रिम में ही बहुत धन्यवाद!पायथन अनुरोध मल्टीपार्ट HTTP पोस्ट

def upload_creative(self, account_id, file_path): 
    """""" 
    boundary = '-----------------------------' + str(int(random.random()*1e10)) 
    parts = [] 

    # Set account ID part. 
    parts.append('--' + boundary) 
    parts.append('Content-Disposition: form-data; name="account_id"') 
    parts.append('') 
    parts.append(str(account_id)) 

    # Set creative contents part. 
    parts.append('--' + boundary) 
    parts.append('Content-Disposition: form-data; name="userfile"; filename="%s"' % file_path) 
    parts.append('Content-Type: %s' % mimetypes.guess_type(file_path)[0] or 'application/octet-stream') 
    parts.append('') 
    # TODO: catch errors with opening file. 
    parts.append(open(file_path, 'r').read()) 

    parts.append('--' + boundary + '--') 
    parts.append('') 

    body = '\r\n'.join(parts) 

    headers = {'content-type': 'multipart/form-data; boundary=' + boundary} 
    url = self._resolve_url('/a/creative/uploadcreative') 
    req = urllib2.Request(url, headers=headers, data=body) 
    res = urllib2.urlopen(req) 

    return json.loads(res.read()) 

जब मैं यूआई से फायरबग की जांच करता हूं, तो मुझे POST स्रोत में निम्न मिलता है।

-----------------------------662549079759661058833120391 
Content-Disposition: form-data; name="userfile"; filename="IMG_1377.jpg" Content-Type: image/jpeg 

ÿØÿáÃExif��MM�*���� �������ª���� ���°���������������������º�������Â(�������1�������Ê2�������Ú<�������î�������i�������þ%������p��Apple�iPhone 4���H������H�����QuickTime 7.7.1�2012:08:17 11:47:11�Mac OS X 10.7.4�������������� "�������'�����P�������0220������(������<������ �����P������X������� ����� �� ������`������h �����0100 ������� ������ ������¢�������¤��������¤��������¤��������¤ ����������������������2011:10:01 17:19:23�2011:10:01 17:19:23���4��Á��¹��¡���M���Ç»¸������N����������Ê�����W����������â�������ú�����M�����������������!�����S���d����������T�����ÿ���d���������������������Ú����%Á��r��������������t������|(�������������������7������������H������H�����ÿØÿà�JFIF��H�H��ÿþ�AppleMark ÿÛ�� % #!,!#'(***.1-)1%)*((((((((((((((((((((((((((((((((((((((((((((((((((((ÿÄ¢���������� ������� ���}�!1AQa"q2¡#B±ÁRÑð$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖ×ØÙÚáâãäåæçèéêñòóôõö÷øùú��w�!1AQaq"2B¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz¢£¤¥¦§¨©ª²³´µ¶·¸¹ð.¥ÛWíÇLòV³FcaoæÂÒ8§É¸(è3E¢"Ú×S^+yj�!òû0Oüµn- yè){[oÝ/¸?ÃÔMY¡ÃgÔò4êò4n͸í¶={ÔM¤¸m¯K&ñæ«,©ù»zTÝ=öØô×6¶Ö:MÑi�,Û$Oö[ª÷ª©ÆiîỤJAxj>ÞAõúu¥}lIf÷û^Â)#´y^)Ô"/·v>n~4ººµ­¬æ}FURì·Î 3¿Ãèh»ÐµÈÿ�·|Gu:ß²<ëlWäG·^+¡Ó¼gâ.-Þè|ϸ*ª® }é?Ú=(i:2½Ïg!ʵÑi¤¼eþ!÷³ÍC'æCqv®ÖÊÕiçCë·øsQy#K_B´þ0s'¦|¿Þ²lò¼?½ÿ�]rZ¶¨ø·6ñÆØ·mvV;þÿ�þ=ôª¿»r\zPñtHö÷>Ù¤R#+ Á òBôR;ú²¾)!àËn<.ÁÔlÏcRäÂ&§­eX´fTóLžQßt§Zµ{â t·pK]ÈL1²îýúEüxþ÷j\î×-jÏÂ>!û:^,E­,>^ýêßwû+Ópæ»?i÷û5kéá¹^ 6Ddq°öÁ¯Rù¨¦yãjòÿÙ 
-----------------------------662549079759661058833120391 
Content-Disposition: form-data; name="account_id" 

69574 
-----------------------------662549079759661058833120391-- 

फ़ायरबग में हेडर इस प्रकार हैं:

Request Headersview source 
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Encoding gzip, deflate 
Accept-Language en-us,en;q=0.5 
Cache-Control no-cache 
Connection keep-alive 
Content-Length 1713991 
Content-Type multipart/form-data; boundary=---------------------------662549079759661058833120391 
Cookie instance_defaults=%7C%20%7Cen_US; access_token=75c48e 
Host ui.host.com 
Pragma no-cache 
Referer http://ui.host.com/ 
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:14.0) Gecko/20100101 Firefox/14.0.1 

मुझे लगता है कि मेरे सवाल है वहाँ डेटा को समायोजित करने के लिए अनुरोध पुस्तकालय के माध्यम से किसी भी तरह से है ताकि:

Content-Disposition: form-data; name="userfile"; filename="IMG_1377.jpg" Content-Type: image/jpeg 

और

Content-Disposition: form-data; name="account_id" 

69574 

sta तम्बू दोनों मौजूद हैं। मुझे लगता है कि मैं की तरह है फ़ाइलों

files = {'file': open('image.jpg', 'rb'), 'account_id': 12345} 

का एक शब्दकोश हो सकता है लेकिन किसी भी तरह इन भागों में से प्रत्येक की सामग्री-विन्यास मेटाडाटा को संपादित अलग

+0

क्या आप 'requests' साथ प्रयास किया? –

+0

मैं multipart फ़ाइल अपलोड POST अनुरोध के प्रत्येक भाग के सामग्री-विस्थापन मेटाडेटा को संपादित करने का प्रयास कर रहा हूं। उदाहरण के लिए मेरे संपादन में, मुझे नाम = "userfile" होना चाहिए; फ़ाइल नाम = "IMG_1377.jpg" सामग्री-प्रकार: छवि/जेपीईजी छवि फ़ाइल है, और उसके बाद दूसरे भाग के लिए, मुझे सामग्री-विस्थापन: फॉर्म-डेटा; नाम = "खाता_आईडी" मुझे उम्मीद है कि इस सवाल पर कुछ स्पष्टता आती है। कृपया मुझे बताएं कि अगर ऐसा कुछ पाइथन-अनुरोध लाइब्रेरी के साथ संभव है। बहुत बहुत धन्यवाद – user1698138

उत्तर

8
requests साथ

, मुझे विश्वास है कि आप डॉन 'कुछ करने के लिए होता है टी, तो मैनुअल होना है बस:

import requests 

# ... 
url = self._resolve_url('/a/creative/uploadcreative') 
files = {'file': ('userfile', open(filepath, 'rb'))} 
data = {'account_id': account_id} 
headers = {'content-type': 'multipart/form-data'} 
res = requests.post(url, files=files, data=data, headers=headers) 
return res.json 

मैं आपकी चिंता लगता है के साथ अपने निहित है:

parts.append('Content-Type: %s' % mimetypes.guess_type(file_path)[0] or 'application/octet-stream') 

मैंने इसे संदेह की छाया से परे खुद को साबित नहीं किया है। लेकिन, मुझे लगता है कि here अनुरोध करने के लिए बनाया गया है।

संपादित करें:

files = {'file': open('image.jpg', 'rb'), 'account_id': 12345} 

और फ़ाइल नाम नाम दे सकते हैं के रूप में आप चाहते हैं:

files = {'file': ('userfile', open('image.jpg', 'rb')), 'account_id': 12345} 

, क्या तुम करोगी लेकिन यह looks like आप फाइलों में सामान्य क्षेत्रों dict, जैसा कि आप का प्रस्ताव कर सकते हैं पर body.write(b'Content-Type: text/plain\r\n\r\n') प्राप्त करें जो शायद आप नहीं चाहते हैं और प्रत्येक फ़ील्ड के लिए सामग्री-विस्थापन को अनुकूलित करने का कोई तरीका नहीं है (अभी भी सुनिश्चित नहीं है कि आपको इसकी आवश्यकता क्यों है); फ़ाइल और फ़ील्ड दोनों के लिए आपको मिलेगा: Content-Disposition: form-data - जो आप दोनों के लिए दिखाते हैं।

मुझे यकीन नहीं है कि आप requests के साथ वही कर सकते हैं, शायद आपको एक सुविधा अनुरोध का प्रयास करना चाहिए।

+1

सटीक होने के लिए, कभी-कभी आपको कुछ प्रतिबंधों के कारण शीर्षलेख निर्दिष्ट करने की आवश्यकता होती है। अनुरोध 'urlib3' का उपयोग करता है, इसलिए यह बहुत अच्छा है। – CppLearner

+0

तो, क्या आप 'अनुरोध' के साथ फ़ाइल का सामग्री-प्रकार मैन्युअल रूप से निर्दिष्ट कर सकते हैं? ऐसा प्रतीत होता है कि यह प्रश्न के समान ही ह्युरिस्टिक का उपयोग करता है लेकिन फ़ाइल के सीटी को मैन्युअल रूप से निर्दिष्ट करने का तरीका प्रदान नहीं करता है। –

+0

मैं समझता हूं, हालांकि, मुझे नहीं लगता कि यह मेरे प्रश्न का उत्तर है। मैंने उम्मीद में अधिक स्पष्टीकरण के साथ अपना प्रश्न संपादित किया है कि किसी के पास वह जवाब होगा जिसका मैं खोज रहा हूं। आपको बहुत धन्यवाद – user1698138

-3

मुझे पता चला कि पाइथन-अनुरोध लाइब्रेरी (v.0.13.3) में, यदि आप अनुरोध में "फाइल" फ़ील्ड से पहले "डेटा" फ़ील्ड को शामिल करते हैं तो आपका डेटा मिटा दिया जाएगा।

उदाहरण के लिए

,

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

खाली फार्म डेटा निकलेगा। हालांकि, निम्नलिखित उनके जवाब

के लिए फार्म डेटा के रूप में डेटा शब्दकोश भेज देंगे

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

सभी को धन्यवाद

+0

नामित तर्कों का क्रम पायथन में कोई फर्क नहीं पड़ता - ये दो कॉल बिल्कुल वही हैं। व्यवहार जो आप देखते हैं वह है क्योंकि आप शायद 'डेटा' तर्क में विभिन्न प्रकार के मान भेजते हैं - देखें [यह] (http://stackoverflow.com/a/12385661/95735) उत्तर। –

0
import requests 

import urllib 

def upload_creative(self, account_id, file_path): 

    files = [('userfile', (file_path, open(file_path, 'rb'), "image/jpeg"))] 

    url = self._resolve_url('/a/creative/uploadcreative') 

    url = url + "?" + urlib.urlencode(account_id=account_id) 

    reuests.post(url, files=files)