Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how enable requests async mode?

for this code:

import sys

import gevent
from gevent import monkey

monkey.patch_all()

import requests
import urllib2

def worker(url, use_urllib2=False):
    if use_urllib2:
        content = urllib2.urlopen(url).read().lower()
    else:
        content = requests.get(url, prefetch=True).content.lower()
    title = content.split('<title>')[1].split('</title>')[0].strip()

urls = ['http://www.mail.ru']*5

def by_requests():
    jobs = [gevent.spawn(worker, url) for url in urls]
    gevent.joinall(jobs)

def by_urllib2():
    jobs = [gevent.spawn(worker, url, True) for url in urls]
    gevent.joinall(jobs)

if __name__=='__main__':
    from timeit import Timer
    t = Timer(stmt="by_requests()", setup="from __main__ import by_requests")  
    print 'by requests: %s seconds'%t.timeit(number=3)
    t = Timer(stmt="by_urllib2()", setup="from __main__ import by_urllib2")  
    print 'by urllib2: %s seconds'%t.timeit(number=3)
    sys.exit(0)

this result:

by requests: 18.3397213892 seconds
by urllib2: 2.48605842363 seconds

in sniffer it looks this:

description: first 5 requests are sended by requests library, next 5 requests are sended by urllib2 library. red - is time when work was freeze, dark - when data receiving... wtf?!

How it posible if socket library patched and libraries must work identically? How use requests without requests.async for asynchronious work?

like image 200
user12397901 Avatar asked Feb 29 '12 15:02

user12397901


People also ask

How do you send asynchronous request?

You can also send requests synchronously by calling WdfRequestSend, but you have to format the request first by following the rules that are described in Sending I/O Requests Asynchronously. Sending I/O requests to an I/O target synchronously is simpler to program than sending I/O requests asynchronously.

What is asynchronous request?

Asynchronous request — Where the client continues execution after initiating the request and processes the result whenever the AppServer makes it available.

Can I use requests with Asyncio?

Requests does not currently support asyncio and there are no plans to provide such support. It's likely that you could implement a custom "Transport Adapter" (as discussed here) that knows how to use asyncio .


4 Answers

Sorry Kenneth Reitz. His library is wonderful.

I am stupid. I need select monkey patch for httplib like this:

gevent.monkey.patch_all(httplib=True)

Because patch for httplib is disabled by default.

like image 121
user12397901 Avatar answered Oct 05 '22 10:10

user12397901


I ran your code on my machine (python 2.7.1, gevent 0.13.0, requests 0.10.6). It turned out that the time was always a good second or two faster when using the requests module . What versions are you using? An upgrade might simply solve the issue for you.

by requests: 3.7847161293 seconds
by urllib2: 4.92611193657 seconds

by requests: 2.90777993202 seconds
by urllib2: 7.99798607826 seconds
like image 20
Phani Avatar answered Oct 05 '22 08:10

Phani


Requests has gevent support integrated into the codebase:

http://docs.python-requests.org/en/latest/user/advanced/#asynchronous-requests

like image 43
Kenneth Reitz Avatar answered Oct 05 '22 08:10

Kenneth Reitz


From the requests doc Blocking Or Non-Blocking:

If you are concerned about the use of blocking IO, there are lots of projects out there that combine Requests with one of Python's asynchronicity frameworks. Two excellent examples are grequests and requests-futures.

like image 20
selfboot Avatar answered Oct 05 '22 08:10

selfboot