अजगर अनुरोध फ़ाइल अपलोड


123

मैं पायथन अनुरोध लाइब्रेरी का उपयोग करके फ़ाइल अपलोड करने का एक सरल कार्य कर रहा हूं। मैंने स्टैक ओवरफ्लो की खोज की और किसी को भी यही समस्या नहीं हुई, अर्थात्, फ़ाइल सर्वर द्वारा प्राप्त नहीं हुई है:

import requests
url='http://nesssi.cacr.caltech.edu/cgi-bin/getmulticonedb_release2.cgi/post'
files={'files': open('file.txt','rb')}
values={'upload_file' : 'file.txt' , 'DB':'photcat' , 'OUT':'csv' , 'SHORT':'short'}
r=requests.post(url,files=files,data=values)

मैं अपने फ़ाइल नाम के साथ 'upload_file' कीवर्ड का मान भर रहा हूं, क्योंकि अगर मैं इसे खाली छोड़ता हूं, तो यह कहता है

Error - You must select a file to upload!

और अब मुझे मिलता है

File  file.txt  of size    bytes is  uploaded successfully!
Query service results:  There were 0 lines.

जो फाइल खाली होने पर ही आता है। इसलिए मैं अपनी फ़ाइल को सफलतापूर्वक भेजने के तरीके के रूप में फंस गया हूं। मुझे पता है कि फ़ाइल काम करती है क्योंकि अगर मैं इस वेबसाइट पर जाता हूं और मैन्युअल रूप से भरता हूं तो यह मिलान की गई वस्तुओं की एक अच्छी सूची देता है, जो कि मैं बाद में हूं। मैं वास्तव में सभी संकेत की सराहना करता हूं।

संबंधित कुछ अन्य सूत्र (लेकिन मेरी समस्या का जवाब नहीं):

जवाबों:


210

यदि upload_fileफ़ाइल होना चाहिए, तो उपयोग करें:

files = {'upload_file': open('file.txt','rb')}
values = {'DB': 'photcat', 'OUT': 'csv', 'SHORT': 'short'}

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

और फाइल के कंटेंट के लिए फील्ड सेट के requestsसाथ एक मल्टी-पार्ट फॉर्म POST बॉडी को भेजेगा ।upload_filefile.txt

फ़ाइल नाम को विशिष्ट फ़ील्ड के लिए माइम हेडर में शामिल किया जाएगा:

>>> import requests
>>> open('file.txt', 'wb')  # create an empty demo file
<_io.BufferedWriter name='file.txt'>
>>> files = {'upload_file': open('file.txt', 'rb')}
>>> print(requests.Request('POST', 'http://example.com', files=files).prepare().body.decode('ascii'))
--c226ce13d09842658ffbd31e0563c6bd
Content-Disposition: form-data; name="upload_file"; filename="file.txt"


--c226ce13d09842658ffbd31e0563c6bd--

filename="file.txt"पैरामीटर नोट करें ।

filesयदि आपको अधिक नियंत्रण की आवश्यकता है, तो आप 2 और 4 तत्वों के बीच, मैपिंग मान के लिए टपल का उपयोग कर सकते हैं । पहला तत्व फ़ाइल नाम है, उसके बाद सामग्री, और एक वैकल्पिक सामग्री-प्रकार हेडर मूल्य और अतिरिक्त हेडर का एक वैकल्पिक मानचित्रण:

files = {'upload_file': ('foobar.txt', open('file.txt','rb'), 'text/x-spam')}

यह वैकल्पिक फ़ाइल नाम और सामग्री प्रकार सेट करता है, जिससे वैकल्पिक हेडर निकल जाते हैं।

यदि आप अर्थ हैं संपूर्ण POST निकाय को किसी फ़ाइल (निर्दिष्ट अन्य क्षेत्रों के साथ) से लिया जाना है, तो filesपैरामीटर का उपयोग न करें , बस फ़ाइल को सीधे पोस्ट करें data। आप तब Content-Typeहेडर भी सेट करना चाह सकते हैं , क्योंकि कोई भी अन्यथा सेट नहीं किया जाएगा। पायथन अनुरोध देखें - एक फ़ाइल से POST डेटा


नमस्ते, मैं एक ही नाम साझा करने वाली कई फाइलें कैसे भेजूं? उदाहरण के लिए 'लगाव'।
विलियम विनो

4
@William: आप 2-वैल्यू टुपल्स के अनुक्रम का भी उपयोग कर सकते हैं, जो आपको फ़ील्ड नामों का फिर से उपयोग करने देता है files = [('attachment', open('attachment1.txt', 'rb')), ('attachment', open('attachment2.txt', 'rb'))]:। प्रत्येक टपल कुंजी और मूल्य की एक जोड़ी है।
Martijn Pieters

2
इसके अलावा, आप भी उपयोग कर सकते हैं, files={'file':('nameoffile',open('namoffile','rb'),'Content-Type':'text/html','other header'),'file2':('nameoffile2',open('nameoffile2','rb'),'Content-Type':'application/xml','other header')}लेकिन अगर फ़ाइलें = {} का उपयोग किया जाता है, तो हेडर = {'सामग्री-प्रकार': 'blah blah'} का उपयोग नहीं किया जाना चाहिए! -> @ मार्टिज़न-पीटर्स: मल्टीपार्ट / फॉर्म-डेटा कंटेंट-टाइप को रोकें, पोस्ट बॉडी में भागों को सीमांकित करने के लिए उपयोग की जाने वाली सीमा मूल्य शामिल होना चाहिए। कंटेंट-टाइप हेडर को सेट न करना यह सुनिश्चित करता है कि अनुरोध इसे सही मान पर सेट करें।
जकी

1
@MartijnPieters क्या यह जोखिम फ़ाइल को लीक करने का नहीं है? requestsइसे बंद करता है?
मैट मेस्मिथ

4
@MattMessersmith: नहीं, यह बंद नहीं है। यदि आप फ़ाइल को बंद करना चाहते हैं, तो मैपिंग में उपयोग with open(...) as fobj:और उपयोग करें । fobjfiles
मार्टिज़न पीटर

35

(2018) नए अजगर अनुरोध पुस्तकालय ने इस प्रक्रिया को सरल बना दिया है, हम सिग्नल के लिए 'फाइल' चर का उपयोग कर सकते हैं कि हम एक मल्टीपार्ट-एन्कोडेड फ़ाइल अपलोड करना चाहते हैं

url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}

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

3
क्या अनुरोध लाइब्रेरी स्वचालित रूप से फ़ाइल बंद कर देती है?
डेमेट्रीस

1
नमस्ते, जब से मैंने इस पुस्तकालय का उपयोग किया है, कुछ समय हो गया है। अच्छा प्रश्न। क्या आप मुझे और दूसरों को lsof लिखकर दे सकते हैं | grep "फ़ाइल नाम" और हमारे साथ अपने परिणाम साझा करें? धन्यवाद :)
laycat

1
के उपयोग के साथ lsof, ऐसा लगता है कि फ़ाइल खुली रहती है, या कम से कम, इस तरह से मैं निम्नलिखित परिणामों की व्याख्या करता हूं। इससे पहले, रन के बारे openमें lsofतालिका में कोई रिकॉर्ड नहीं है filename। फिर openनिष्पादित होने के बाद , कई रिकॉर्ड readएक्सेस के साथ दिखाई देते हैं। requests.postअभिलेखों को निष्पादित करने के बाद , रिकॉर्ड अभी भी इंगित कर रहे हैं कि फ़ाइल बंद नहीं हुई थी।
डेमेट्रीस

23

क्लाइंट अपलोड

यदि आप पायथन requestsलाइब्रेरी के साथ एक भी फाइल अपलोड करना चाहते हैं , तो अनुरोध अपलोडिंग का समर्थन करता है , जो आपको मेमोरी में पढ़े बिना बड़ी फाइल या स्ट्रीम भेजने की अनुमति देता है ।

with open('massive-body', 'rb') as f:
    requests.post('http://some.url/streamed', data=f)

सर्वर साइड

फिर फ़ाइल को उस server.pyतरफ स्टोर करें जैसे कि मेमोरी में लोड किए बिना स्ट्रीम को फाइल में सेव करें। निम्नलिखित फ्लास्क फ़ाइल अपलोड का उपयोग करने के साथ एक उदाहरण है ।

@app.route("/upload", methods=['POST'])
def upload_file():
    from werkzeug.datastructures import FileStorage
    FileStorage(request.stream).save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
    return 'OK', 200

या बड़ी फ़ाइलों को अपलोड करने पर अक्षमता से स्मृति का उपयोग करने से बचने के लिए " डेटा मेमोरी खाने के लिए बड़ी फ़ाइल अपलोड " के मुद्दे के लिए एक निश्चित रूप में उल्लिखित फॉर्म डेटा पार्सिंग का उपयोग करें (~ 22 सेकंड में जीबीबी फ़ाइल ~ 60 सेकंड में। मेमोरी का उपयोग निरंतर है। 13 मि.बी.)।

@app.route("/upload", methods=['POST'])
def upload_file():
    def custom_stream_factory(total_content_length, filename, content_type, content_length=None):
        import tempfile
        tmpfile = tempfile.NamedTemporaryFile('wb+', prefix='flaskapp', suffix='.nc')
        app.logger.info("start receiving file ... filename => " + str(tmpfile.name))
        return tmpfile

    import werkzeug, flask
    stream, form, files = werkzeug.formparser.parse_form_data(flask.request.environ, stream_factory=custom_stream_factory)
    for fil in files.values():
        app.logger.info(" ".join(["saved form name", fil.name, "submitted as", fil.filename, "to temporary file", fil.stream.name]))
        # Do whatever with stored file at `fil.stream.name`
    return 'OK', 200

0

उबंटू में आप इस तरह से आवेदन कर सकते हैं,

कुछ स्थान (अस्थायी) पर फ़ाइल को बचाने के लिए और फिर इसे खोलें और एपीआई को भेजें

      path = default_storage.save('static/tmp/' + f1.name, ContentFile(f1.read()))
      path12 = os.path.join(os.getcwd(), "static/tmp/" + f1.name)
      data={} #can be anything u want to pass along with File
      file1 = open(path12, 'rb')
      header = {"Content-Disposition": "attachment; filename=" + f1.name, "Authorization": "JWT " + token}
       res= requests.post(url,data,header)

dataचर का मूल्य क्या है ?
am.rez

यह उपयोगकर्ता के नाम की तरह कुछ भी हो सकता है, मैंने अभी दिखाया है कि REST एपिस को फाइलें कैसे अपलोड करें
हर्षित त्रिवेदी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.