अजगर के अनुरोधों के लिए टाइमआउट। पूरी प्रतिक्रिया दें


169

मैं वेबसाइटों की एक सूची पर आंकड़े इकट्ठा कर रहा हूं और मैं इसके लिए अनुरोध कर रहा हूं। यहाँ मेरा कोड है:

data=[]
websites=['http://google.com', 'http://bbc.co.uk']
for w in websites:
    r= requests.get(w, verify=False)
    data.append( (r.url, len(r.content), r.elapsed.total_seconds(), str([(l.status_code, l.url) for l in r.history]), str(r.headers.items()), str(r.cookies.items())) )

अब, मैं requests.get10 सेकंड के बाद टाइमआउट करना चाहता हूं ताकि लूप अटक न जाए।

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

मैंने सुना है कि शायद अनुरोधों का उपयोग नहीं करना एक अच्छा विचार है लेकिन फिर मुझे अच्छी चीजें कैसे मिलनी चाहिए। (टपल में लोग)


1
आप किस तरह के उत्तर की तलाश कर रहे हैं? (या, दूसरे शब्दों में, वर्तमान उत्तर आपके लिए पर्याप्त क्यों नहीं हैं?)
यूवी

हम इनाम के ग्रेस पीरियड में हैं। उत्तर चुनने का समय?
टोटकाका

मैं अभी भी ईवेंटलेट समाधान और संकेतों के बीच निर्णय ले रहा हूं। मैं आज रात तक इस सवाल का जवाब दूंगा।
कीराश


जवाबों:


137

क्या ईवेंट का उपयोग करने के बारे में? यदि आप 10 सेकंड के बाद अनुरोध को टाइमआउट करना चाहते हैं, भले ही डेटा प्राप्त हो रहा हो, तो यह स्निपेट आपके लिए काम करेगा:

import requests
import eventlet
eventlet.monkey_patch()

with eventlet.Timeout(10):
    requests.get("http://ipv4.download.thinkbroadband.com/1GB.zip", verify=False)

114
निश्चित रूप से यह अनावश्यक रूप से जटिल है।
होल्डनवेब

7
धन्यवाद। अब मैं आपके समाधान की तकनीकी श्रेष्ठता (जो आपने अपने उत्तर की शुरुआत में स्पष्ट रूप से बताई थी) को समझा और उसे उकेरा। तीसरे पक्ष के मॉड्यूल के साथ समस्या उन्हें आयात नहीं कर रही है, लेकिन यह सुनिश्चित करना है कि वे आयात किए जाने वाले हैं, इसलिए मानक पुस्तकालय का उपयोग करने के लिए मेरी अपनी पसंद जहां संभव हो।
होल्डनवेब

9
की eventlet.monkey_patch()आवश्यकता है?
उपयोगकर्ता

3
हां, socketमॉड्यूल को बंदर से पैच करने की आवश्यकता है, इसलिए कम से कम आपको eventlet.monkey_patch(socket=True)
अल्वारो

52
के रूप में 2018 इस उत्तर पुरानी है। उपयोगrequests.get('https://github.com', timeout=5)
CONvid19

313

टाइमआउट पैरामीटर सेट करें :

r = requests.get(w, verify=False, timeout=10) # 10 seconds

जब तक आप stream=Trueउस अनुरोध पर सेट नहीं करते हैं, requests.get()यदि कनेक्शन दस सेकंड से अधिक समय लेता है, या यदि सर्वर दस सेकंड से अधिक के लिए डेटा नहीं भेजता है , तो यह कॉल टाइमआउट करने का कारण होगा ।


31
यह पूरी प्रतिक्रिया के लिए नहीं है। requests.readthedocs.org/en/latest/user/quickstart/#timeouts
kiarash

1
हाँ, यह कुछ परिस्थितियों में है। उन परिस्थितियों में से एक आपका होना होता है। =) यदि आप आश्वस्त नहीं हैं तो मैं आपको कोड देखने के लिए आमंत्रित करता हूं।
लुकासा

क्या हालात हैं?
किराष

1
मैंने अभी इसकी जाँच की और यह कभी नहीं रुका: r = request.get (' ipv4.download.thinkbroadband.com/1GB.zip ', टाइमआउट = 20)
Kiash

5
आह, क्षमा करें, मुझे गलत लगा कि जब आपने 'संपूर्ण प्रतिक्रिया' कहा था तो आपका क्या मतलब था। हां, आप सही हैं: प्रतीक्षा करने की कुल राशि पर यह ऊपरी सीमा नहीं है।
लुकासा

85

अद्यतन: https://requests.readthedocs.io/en/master/user/advanced/#timeouts

के नए संस्करण में requests:

यदि आप टाइमआउट के लिए एक एकल मान निर्दिष्ट करते हैं, जैसे:

r = requests.get('https://github.com', timeout=5)

टाइमआउट मान को connectऔर readटाइमआउट दोनों पर लागू किया जाएगा । यदि आप मानों को अलग से सेट करना चाहते हैं तो एक टपल निर्दिष्ट करें:

r = requests.get('https://github.com', timeout=(3.05, 27))

यदि रिमोट सर्वर बहुत धीमा है, तो आप किसी प्रतिक्रिया को हमेशा के लिए प्रतीक्षा करने के लिए कह सकते हैं, टाइमआउट मान के रूप में और फिर एक कप कॉफी प्राप्त करके।

r = requests.get('https://github.com', timeout=None)

मेरा पुराना (शायद पुराना) उत्तर (जो बहुत समय पहले पोस्ट किया गया था):

इस समस्या को दूर करने के अन्य तरीके हैं:

1. TimeoutSauceआंतरिक वर्ग का उपयोग करें

प्रेषक: https://github.com/kennethreitz/requests/issues/1928#issuecomment-35-3511116

import requests from requests.adapters import TimeoutSauce

class MyTimeout(TimeoutSauce):
    def __init__(self, *args, **kwargs):
        connect = kwargs.get('connect', 5)
        read = kwargs.get('read', connect)
        super(MyTimeout, self).__init__(connect=connect, read=read)

requests.adapters.TimeoutSauce = MyTimeout

यह कोड हमें रीड टाइमआउट को कनेक्ट टाइमआउट के बराबर सेट करने के लिए प्रेरित करता है, जो कि आपके Session.get () कॉल पर आपके द्वारा पास किए गए टाइमआउट मूल्य है। (ध्यान दें कि मैंने वास्तव में इस कोड का परीक्षण नहीं किया है, इसलिए इसे कुछ त्वरित डिबगिंग की आवश्यकता हो सकती है, मैंने इसे सीधे GHHHH विंडो में लिखा था।)

2. केविनबर्क से अनुरोधों के एक कांटे का उपयोग करें: https://github.com/kevinburke/requests/tree/connect-time

इसके प्रलेखन से: https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst

यदि आप टाइमआउट के लिए एक एकल मान निर्दिष्ट करते हैं, जैसे:

r = requests.get('https://github.com', timeout=5)

टाइमआउट मान कनेक्ट और रीड टाइमआउट दोनों पर लागू होगा। यदि आप मानों को अलग से सेट करना चाहते हैं तो एक टपल निर्दिष्ट करें:

r = requests.get('https://github.com', timeout=(3.05, 27))

kevinburke ने इसे मुख्य अनुरोध परियोजना में विलय करने का अनुरोध किया है, लेकिन इसे अभी तक स्वीकार नहीं किया गया है।


विकल्प 1 काम नहीं करता है। यदि आप उस थ्रेड को पढ़ना जारी रखते हैं, तो अन्य लोगों ने कहा है "यह आपके उपयोग-मामले के लिए काम नहीं करेगा, मुझे डर है। रीड टाइमआउट फ़ंक्शन एक व्यक्तिगत सॉकेट recv () कॉल के दायरे में है, ताकि यदि सर्वर हम पढ़े गए समय से अधिक के लिए डेटा भेजना बंद कर देंगे। "
कियारश

सिग्नल का उपयोग करते हुए उस धागे में एक और अच्छा समाधान है, जो मेरे लिए भी काम नहीं करेगा, क्योंकि मैं विंडोज और सिग्नल का उपयोग करता हूं। अलार्म केवल लिनक्स है।
कियारश

@ करिश मैंने अभी तक इसका परीक्षण नहीं किया है। हालांकि, जैसा कि मैं समझता हूं कि जब लुकासा ने कहा था this won't work for you use-case। उनका मतलब था कि यह एमपी 3 स्ट्रीम के साथ काम नहीं करता है जो दूसरे आदमी द्वारा चाहता है।
हियु

1
@ हियु - यह एक और पुल अनुरोध में विलय कर दिया गया था - github.com/kennethreitz/requests/pull/…
yprez

मध्यांतर = कोई भी कॉल ब्लॉक नहीं कर रहा है।
crazydan

49

timeout = int(seconds)

चूंकि requests >= 2.4.0, आप timeoutतर्क का उपयोग कर सकते हैं , अर्थात:

requests.get('https://duckduckgo.com/', timeout=10)

ध्यान दें:

timeoutसंपूर्ण प्रतिक्रिया डाउनलोड पर कोई समय सीमा नहीं है; इसके बजाय, exceptionयदि सर्वर ने टाइमआउट सेकंड के लिए कोई प्रतिक्रिया जारी नहीं की है , तो इसे उठाया जाता है (अधिक सटीक रूप से, यदि टाइमआउट सेकंड के लिए अंतर्निहित सॉकेट पर कोई बाइट्स प्राप्त नहीं हुआ है)। यदि कोई टाइमआउट स्पष्ट रूप से निर्दिष्ट नहीं किया गया है, तो अनुरोधों का समय समाप्त नहीं होता है।


नए टाइमआउट पैरामीटर के अनुरोधों के किस संस्करण में है?
रस्टी

1
संस्करण 2.4.0 के बाद से होना लगता है: कनेक्ट टाइमआउट के लिए समर्थन! टाइमआउट अब एक ट्यूपल (कनेक्ट, रीड) को स्वीकार करता है जिसका उपयोग व्यक्तिगत कनेक्ट और टाइमआउट को सेट करने के लिए किया जाता हैpypi.org/project/requests/2.4.0
CONvid19

23

टाइमआउट बनाने के लिए आप संकेतों का उपयोग कर सकते हैं ।

इस मामले को हल करने का सबसे अच्छा तरीका शायद है

  1. अलार्म सिग्नल के लिए हैंडलर के रूप में एक अपवाद सेट करें
  2. दस सेकंड की देरी के साथ अलार्म सिग्नल को कॉल करें
  3. किसी try-except-finallyब्लॉक के अंदर फ़ंक्शन को कॉल करें ।
  4. यदि कार्य समय से समाप्त हो जाता है, तो अपवाद ब्लॉक तक पहुंच जाता है।
  5. अंत में आप अलार्म को रोकते हैं, इसलिए यह बाद में सिंगल नहीं होता है।

यहाँ कुछ उदाहरण कोड है:

import signal
from time import sleep

class TimeoutException(Exception):
    """ Simple Exception to be called on timeouts. """
    pass

def _timeout(signum, frame):
    """ Raise an TimeoutException.

    This is intended for use as a signal handler.
    The signum and frame arguments passed to this are ignored.

    """
    # Raise TimeoutException with system default timeout message
    raise TimeoutException()

# Set the handler for the SIGALRM signal:
signal.signal(signal.SIGALRM, _timeout)
# Send the SIGALRM signal in 10 seconds:
signal.alarm(10)

try:    
    # Do our code:
    print('This will take 11 seconds...')
    sleep(11)
    print('done!')
except TimeoutException:
    print('It timed out!')
finally:
    # Abort the sending of the SIGALRM signal:
    signal.alarm(0)

इसके लिए कुछ संकेत हैं:

  1. यह थ्रेडसेफ़ नहीं है, संकेतों को हमेशा मुख्य धागे तक पहुंचाया जाता है, इसलिए आप इसे किसी अन्य धागे में नहीं डाल सकते।
  2. सिग्नल के शेड्यूलिंग और वास्तविक कोड के निष्पादन के बाद थोड़ी देरी हुई है। इसका मतलब यह है कि उदाहरण समय के बाहर होगा भले ही यह केवल दस सेकंड के लिए सोया हो।

लेकिन, यह सब मानक अजगर पुस्तकालय में है! नींद समारोह के आयात को छोड़कर यह केवल एक आयात है। यदि आप कई स्थानों पर टाइमआउट का उपयोग करने जा रहे हैं, तो आप आसानी से टाइमआउट एक्सेप्शन, _ टाइमआउट और सिंगलिंग को एक फंक्शन में डाल सकते हैं और बस कॉल कर सकते हैं। या आप एक डेकोरेटर बना सकते हैं और इसे कार्यों पर रख सकते हैं, नीचे दिए गए उत्तर को देखें।

आप इसे "संदर्भ प्रबंधक" के रूप में भी सेट कर सकते हैं ताकि आप इसे withकथन के साथ उपयोग कर सकें :

import signal
class Timeout():
    """ Timeout for use with the `with` statement. """

    class TimeoutException(Exception):
        """ Simple Exception to be called on timeouts. """
        pass

    def _timeout(signum, frame):
        """ Raise an TimeoutException.

        This is intended for use as a signal handler.
        The signum and frame arguments passed to this are ignored.

        """
        raise Timeout.TimeoutException()

    def __init__(self, timeout=10):
        self.timeout = timeout
        signal.signal(signal.SIGALRM, Timeout._timeout)

    def __enter__(self):
        signal.alarm(self.timeout)

    def __exit__(self, exc_type, exc_value, traceback):
        signal.alarm(0)
        return exc_type is Timeout.TimeoutException

# Demonstration:
from time import sleep

print('This is going to take maximum 10 seconds...')
with Timeout(10):
    sleep(15)
    print('No timeout?')
print('Done')

इस संदर्भ प्रबंधक दृष्टिकोण के साथ एक संभावित डाउन साइड यह है कि आप यह नहीं जान सकते कि कोड वास्तव में समय से बाहर है या नहीं।

स्रोत और अनुशंसित पढ़ने:


3
सिग्नल केवल मुख्य थ्रेड में दिया जाता है, इस प्रकार यह defnitely अन्य धागे में काम नहीं करेगा, नहीं शायद
दिमा तिस्नेक

1
टाइमआउट-डेकोरेटर पैकेज एक टाइमआउट डेकोरेटर संकेतों (या वैकल्पिक रूप से बहु) का उपयोग करता है प्रदान करता है।
क्रिश्चियन लांग

13

इस अनुरोध को टाइमआउट और त्रुटि से निपटने की कोशिश करें:

import requests
try: 
    url = "http://google.com"
    r = requests.get(url, timeout=10)
except requests.exceptions.Timeout as e: 
    print e

5

सेट करें stream=Trueऔर उपयोग करें r.iter_content(1024)। हां, eventlet.Timeoutबस किसी तरह मेरे लिए काम नहीं करता है।

try:
    start = time()
    timeout = 5
    with get(config['source']['online'], stream=True, timeout=timeout) as r:
        r.raise_for_status()
        content = bytes()
        content_gen = r.iter_content(1024)
        while True:
            if time()-start > timeout:
                raise TimeoutError('Time out! ({} seconds)'.format(timeout))
            try:
                content += next(content_gen)
            except StopIteration:
                break
        data = content.decode().split('\n')
        if len(data) in [0, 1]:
            raise ValueError('Bad requests data')
except (exceptions.RequestException, ValueError, IndexError, KeyboardInterrupt,
        TimeoutError) as e:
    print(e)
    with open(config['source']['local']) as f:
        data = [line.strip() for line in f.readlines()]

चर्चा यहाँ https://redd.it/80kp1h है


यह शर्म की बात है कि अधिकतम समय का समर्थन नहीं करता है, यह समाधान केवल asyncio के साथ काम किया है
wukong

4

यह ओवरकिल हो सकता है, लेकिन अजवाइन वितरित कार्य कतार में टाइमआउट के लिए अच्छा समर्थन है।

विशेष रूप से, आप एक नरम समय सीमा को परिभाषित कर सकते हैं जो आपकी प्रक्रिया में केवल एक अपवाद को बढ़ाता है (इसलिए आप साफ कर सकते हैं) और / या एक कठिन समय सीमा जो कार्य को समाप्त कर देती है जब समय सीमा पार हो गई है।

कवर के तहत, यह आपके "पहले" पोस्ट में संदर्भित समान सिग्नल दृष्टिकोण का उपयोग करता है, लेकिन अधिक उपयोगी और प्रबंधनीय तरीके से। और यदि आप जिन वेब साइटों की सूची देख रहे हैं, वे लंबी हैं, तो आप इसकी प्राथमिक विशेषता से लाभान्वित हो सकते हैं - बड़ी संख्या में कार्यों के निष्पादन के प्रबंधन के सभी प्रकार।


यह एक अच्छा समाधान हो सकता है। कुल टाइमआउट की समस्या सीधे संबंधित नहीं है, python-requestsलेकिन httplib(पायथन 2.7 के लिए अनुरोध द्वारा उपयोग किया जाता है)। पैकेज timeoutसीधे कैनप्लिब से संबंधित सब कुछ गुजरता है । मुझे लगता है कि अनुरोध में कुछ भी तय नहीं किया जा सकता है क्योंकि प्रक्रिया लंबे समय तक कैंपलिब में रह सकती है।
18

@hynekcer, मुझे लगता है कि आप सही हैं। यही कारण है कि समय-समय पर आउट-ऑफ-प्रोसेस का पता लगाना और सफाई से हत्या प्रक्रियाओं को लागू करना, जैसा कि सेलेरी करता है, एक अच्छा दृष्टिकोण हो सकता है।
क्रिस जॉनसन

3

मेरा मानना ​​है कि आप multiprocessingतृतीय पक्ष पैकेज पर उपयोग कर सकते हैं और निर्भर नहीं कर सकते हैं :

import multiprocessing
import requests

def call_with_timeout(func, args, kwargs, timeout):
    manager = multiprocessing.Manager()
    return_dict = manager.dict()

    # define a wrapper of `return_dict` to store the result.
    def function(return_dict):
        return_dict['value'] = func(*args, **kwargs)

    p = multiprocessing.Process(target=function, args=(return_dict,))
    p.start()

    # Force a max. `timeout` or wait for the process to finish
    p.join(timeout)

    # If thread is still active, it didn't finish: raise TimeoutError
    if p.is_alive():
        p.terminate()
        p.join()
        raise TimeoutError
    else:
        return return_dict['value']

call_with_timeout(requests.get, args=(url,), kwargs={'timeout': 10}, timeout=60)

समय समाप्ति के लिए पारित kwargsटाइमआउट प्राप्त करने के लिए है किसी भी सर्वर से प्रतिक्रिया, तर्क timeoutटाइमआउट प्राप्त करने के लिए है पूरा प्रतिक्रिया।


यह एक सामान्य कोशिश के साथ सुधारा जा सकता है / निजी फ़ंक्शन को छोड़कर जो सभी त्रुटियों को पकड़ता है और उन्हें रिटर्न_डिक्ट ['त्रुटि] में डाल देता है। फिर, लौटने से पहले, जाँच करें कि क्या 'त्रुटि' return_dict में है और फिर इसे बढ़ाएं। इससे टेस्ट करना भी आसान हो जाता है।
डायल करें

2

टाइमआउट = (कनेक्शन टाइमआउट, डेटा टाइमआउट पढ़ें) या एक भी तर्क दें (टाइमआउट = १)

import requests

try:
    req = requests.request('GET', 'https://www.google.com',timeout=(1,1))
    print(req)
except requests.ReadTimeout:
    print("READ TIME OUT")

1

यह कोड सॉकेट के लिए काम कर रहा है 11004 और 10060 ......

# -*- encoding:UTF-8 -*-
__author__ = 'ACE'
import requests
from PyQt4.QtCore import *
from PyQt4.QtGui import *


class TimeOutModel(QThread):
    Existed = pyqtSignal(bool)
    TimeOut = pyqtSignal()

    def __init__(self, fun, timeout=500, parent=None):
        """
        @param fun: function or lambda
        @param timeout: ms
        """
        super(TimeOutModel, self).__init__(parent)
        self.fun = fun

        self.timeer = QTimer(self)
        self.timeer.setInterval(timeout)
        self.timeer.timeout.connect(self.time_timeout)
        self.Existed.connect(self.timeer.stop)
        self.timeer.start()

        self.setTerminationEnabled(True)

    def time_timeout(self):
        self.timeer.stop()
        self.TimeOut.emit()
        self.quit()
        self.terminate()

    def run(self):
        self.fun()


bb = lambda: requests.get("http://ipv4.download.thinkbroadband.com/1GB.zip")

a = QApplication([])

z = TimeOutModel(bb, 500)
print 'timeout'

a.exec_()

रचनात्मकता के लिए उत्थान
जेस्मिथ

1

अनुरोधों के बारे में प्रश्न होने के बावजूद, मुझे pycurl CURLOPT_TIMEOUT के साथ ऐसा करना बहुत आसान लगता है या CURLOPT_TIMEOUT_MS के ।

कोई थ्रेडिंग या सिग्नलिंग की आवश्यकता नहीं है:

import pycurl
import StringIO

url = 'http://www.example.com/example.zip'
timeout_ms = 1000
raw = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(pycurl.TIMEOUT_MS, timeout_ms)  # total timeout in milliseconds
c.setopt(pycurl.WRITEFUNCTION, raw.write)
c.setopt(pycurl.NOSIGNAL, 1)
c.setopt(pycurl.URL, url)
c.setopt(pycurl.HTTPGET, 1)
try:
    c.perform()
except pycurl.error:
    traceback.print_exc() # error generated on timeout
    pass # or just pass if you don't want to print the error

1

यदि आप विकल्प का उपयोग कर रहे stream=Trueहैं तो आप ऐसा कर सकते हैं:

r = requests.get(
    'http://url_to_large_file',
    timeout=1,  # relevant only for underlying socket
    stream=True)

with open('/tmp/out_file.txt'), 'wb') as f:
    start_time = time.time()
    for chunk in r.iter_content(chunk_size=1024):
        if chunk:  # filter out keep-alive new chunks
            f.write(chunk)
        if time.time() - start_time > 8:
            raise Exception('Request took longer than 8s')

समाधान के लिए सिग्नल या मल्टीप्रोसेसिंग की आवश्यकता नहीं है।


1

बस एक और एक ही समाधान (से समझ में आ गया http://docs.python-requests.org/en/master/user/advanced/#streaming-uploads )

अपलोड करने से पहले आप सामग्री का आकार जान सकते हैं:

TOO_LONG = 10*1024*1024  # 10 Mb
big_url = "http://ipv4.download.thinkbroadband.com/1GB.zip"
r = requests.get(big_url, stream=True)
print (r.headers['content-length'])
# 1073741824  

if int(r.headers['content-length']) < TOO_LONG:
    # upload content:
    content = r.content

लेकिन सावधान रहें, एक प्रेषक 'सामग्री-लंबाई' प्रतिक्रिया क्षेत्र में गलत मान सेट कर सकता है।


धन्यवाद। स्वच्छ और सरल उपाय। मेरे लिये कार्य करता है।
पेट्ज़्यूरिच

0

यदि यह उस पर आता है, तो एक वॉचडॉग थ्रेड बनाएं जो 10 सेकंड के बाद अनुरोधों की आंतरिक स्थिति को गड़बड़ कर देता है, जैसे:

  • अंतर्निहित सॉकेट बंद कर देता है, और आदर्श रूप से
  • यदि अनुरोध ऑपरेशन को पुनः प्रयास करता है तो एक अपवाद को ट्रिगर करता है

ध्यान दें कि सिस्टम पुस्तकालयों के आधार पर आप DNS रिज़ॉल्यूशन की समय सीमा निर्धारित करने में असमर्थ हो सकते हैं।


0

खैर, मैंने इस पृष्ठ पर कई समाधानों की कोशिश की और अभी भी अस्थिरता, यादृच्छिक हैंग, खराब कनेक्शन प्रदर्शन का सामना किया।

मैं अब कर्ल का उपयोग कर रहा हूं और मैं वास्तव में "अधिकतम समय" के बारे में खुश हूं और इस तरह के खराब कार्यान्वयन के साथ, वैश्विक प्रदर्शन के बारे में भी:

content=commands.getoutput('curl -m6 -Ss "http://mywebsite.xyz"')

यहाँ, मैंने 6 सेकंड का अधिकतम समय पैरामीटर परिभाषित किया है, जो कनेक्शन और स्थानांतरण समय दोनों को संलग्न करता है।

मुझे यकीन है कि कर्ल में एक अच्छा पायथन बंधन है, अगर आप पायथोनिक सिंटैक्स से चिपकना पसंद करते हैं :)


0

टाइमआउट-डेकोरेटर नामक एक पैकेज है जिसे आप किसी भी पायथन फ़ंक्शन को समय-समय पर उपयोग कर सकते हैं।

@timeout_decorator.timeout(5)
def mytest():
    print("Start")
    for i in range(1,10):
        time.sleep(1)
        print("{} seconds have passed".format(i))

यह उन संकेतों के दृष्टिकोण का उपयोग करता है जो यहां कुछ उत्तर सुझाते हैं। वैकल्पिक रूप से, आप इसे संकेतों के बजाय मल्टीप्रोसेसिंग का उपयोग करने के लिए कह सकते हैं (जैसे कि यदि आप बहु-थ्रेड वातावरण में हैं)।


0

मैं अनुरोधों का उपयोग कर रहा हूँ 2.2.1 और ईवेंटलेट मेरे लिए काम नहीं किया। इसके बजाय मैं जियोवेंट टाइमआउट का उपयोग करने में सक्षम था, क्योंकि जियोवेंट को मेरी सेवा में उपयोग किया जाता है।

import gevent
import gevent.monkey
gevent.monkey.patch_all(subprocess=True)
try:
    with gevent.Timeout(5):
        ret = requests.get(url)
        print ret.status_code, ret.content
except gevent.timeout.Timeout as e:
    print "timeout: {}".format(e.message)

कृपया ध्यान दें कि gevent.timeout.Timeout सामान्य अपवाद हैंडलिंग द्वारा पकड़ा नहीं गया है। इसलिए या तो स्पष्ट रूप gevent.timeout.Timeout से उपयोग किए जाने वाले एक अलग अपवाद में पकड़ या पास करें: with gevent.Timeout(5, requests.exceptions.Timeout):हालांकि इस अपवाद को उठाए जाने पर कोई संदेश पारित नहीं किया जाता है।


-1

मैं एक और अधिक प्रत्यक्ष समाधान के साथ आया जो कि वास्तव में बदसूरत है, लेकिन वास्तविक समस्या को ठीक करता है। यह इस तरह से एक सा हो जाता है:

resp = requests.get(some_url, stream=True)
resp.raw._fp.fp._sock.settimeout(read_timeout)
# This will load the entire response even though stream is set
content = resp.content

पूरा विवरण आप यहां पढ़ सकते हैं


3
1- क्योंकि आपtimeoutrequests.get() बिना बदसूरत वर्कअराउंड के पैरामीटर पारित कर सकते हैं 2- हालांकि दोनों विपरीत समयसीमा को सीमित नहीं करेंगेeventlet.Timeout(10)
jfs
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.