Repository files navigation

GitHub Workflow CI StatusPyPIPython Version from PEP 621 TOMLPyPI - Downloads

geventhttpclient

A high performance, concurrent HTTP client library for python using gevent.

gevent.httplib support for patching http.client was removed in gevent 1.0, geventhttpclient now provides that missing functionality.

geventhttpclient uses a fast http parser, written in C.

geventhttpclient has been specifically designed for high concurrency, streaming and support HTTP 1.1 persistent connections. More generally it is designed for efficiently pulling from REST APIs and streaming APIs like Twitter's.

Safe SSL support is provided by default. geventhttpclient depends on the certifi CA Bundle. This is the same CA Bundle which ships with the Requests codebase, and is derived from Mozilla Firefox's canonical set.

Since version 2.3, geventhttpclient features a largely requests compatible interface. It covers basic HTTP usage including cookie management, form data encoding or decoding of compressed data, but otherwise isn't as feature rich as the original requests. For simple use-cases, it can serve as a drop-in replacement.

importgeventhttpclientasrequestsrequests.get("https://github.com").textrequests.post("http://httpbingo.org/post", data="asdfasd").json()
fromgeventhttpclientimportSessions=Session()
s.get("http://httpbingo.org/headers").json()
s.get("https://github.com").content

This interface builds on top of the lower level HTTPClient.

fromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURLurl=URL("http://gevent.org/")
client=HTTPClient(url.host)
response=client.get(url.request_uri)
response.status_codebody=response.read()
client.close()

httplib compatibility and monkey patch

geventhttpclient.httplib module contains classes for drop in replacement of http.client connection and response objects. If you use http.client directly you can replace the httplib imports by geventhttpclient.httplib.

# from http.client import HTTPConnectionfromgeventhttpclient.httplibimportHTTPConnection

If you use httplib2, urllib or urllib2; you can patch httplib to use the wrappers from geventhttpclient. For httplib2, make sure you patch before you import or the super() calls will fail.

importgeventhttpclient.httplibgeventhttpclient.httplib.patch()
importhttplib2

High Concurrency

HTTPClient has a connection pool built in and is greenlet safe by design. You can use the same instance among several greenlets. It is the low level building block of this library.

importgevent.poolimportjsonfromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURL# go to http://developers.facebook.com/tools/explorer and copy the access tokenTOKEN="<MY_DEV_TOKEN>"url=URL("https://graph.facebook.com/me/friends", params={"access_token": TOKEN})
# setting the concurrency to 10 allow to create 10 connections and# reuse them.client=HTTPClient.from_url(url, concurrency=10)
response=client.get(url.request_uri)
assertresponse.status_code==200# response comply to the read protocol. It passes the stream to# the json parser as it's being read.data=json.load(response)["data"]
defprint_friend_username(client, friend_id):
friend_url=URL(f"/{friend_id}", params={"access_token": TOKEN})
# the greenlet will block until a connection is availableresponse=client.get(friend_url.request_uri)
assertresponse.status_code==200friend=json.load(response)
if"username"infriend:
print(f"{friend['username']}: {friend['name']}")
else:
print(f"{friend['name']} has no username.")
# allow to run 20 greenlet at a time, this is more than concurrency# of the http client but isn't a problem since the client has its own# connection pool.pool=gevent.pool.Pool(20)
foritemindata:
friend_id=item["id"]
pool.spawn(print_friend_username, client, friend_id)
pool.join()
client.close()

Streaming

geventhttpclient supports streaming. Response objects have a read(n) and readline() method that read the stream incrementally. See examples/twitter_streaming.py for pulling twitter stream API.

Here is an example on how to download a big file chunk by chunk to save memory:

fromgeventhttpclientimportHTTPClient, URLurl=URL("http://127.0.0.1:80/100.dat")
client=HTTPClient.from_url(url)
response=client.get(url.query_string)
assertresponse.status_code==200CHUNK_SIZE=1024*16# 16KBwithopen("/tmp/100.dat", "w") asf:
data=response.read(CHUNK_SIZE)
whiledata:
f.write(data)
data=response.read(CHUNK_SIZE)

Benchmarks

The benchmark runs 10000 GET requests against a local nginx server in the default configuration with a concurrency of 10. See benchmarks folder. The requests per second for a couple of popular clients is given in the table below. Please read benchmarks/README.md for more details. Also note, HTTPX is better be used with asyncio, not gevent.

HTTP ClientRPS
GeventHTTPClient7268.9
Httplib2 (patched)2323.9
Urllib32242.5
Requests1046.1
Httpx770.3

Linux(x86_64), Python 3.11.6 @ Intel i7-7560U

License

This package is distributed under the MIT license. Previous versions of geventhttpclient used http_parser.c, which in turn was based on http/ngx_http_parse.c from NGINX, copyright Igor Sysoev, Joyent, Inc., and other Node contributors. For more information, see http://github.com/joyent/http-parser

About

A high performance, concurrent http client library for python with gevent

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

GitHub Workflow CI StatusPyPIPython Version from PEP 621 TOMLPyPI - Downloads

geventhttpclient

A high performance, concurrent HTTP client library for python using gevent.

gevent.httplib support for patching http.client was removed in gevent 1.0, geventhttpclient now provides that missing functionality.

geventhttpclient uses a fast http parser, written in C.

geventhttpclient has been specifically designed for high concurrency, streaming and support HTTP 1.1 persistent connections. More generally it is designed for efficiently pulling from REST APIs and streaming APIs like Twitter's.

Safe SSL support is provided by default. geventhttpclient depends on the certifi CA Bundle. This is the same CA Bundle which ships with the Requests codebase, and is derived from Mozilla Firefox's canonical set.

Since version 2.3, geventhttpclient features a largely requests compatible interface. It covers basic HTTP usage including cookie management, form data encoding or decoding of compressed data, but otherwise isn't as feature rich as the original requests. For simple use-cases, it can serve as a drop-in replacement.

importgeventhttpclientasrequestsrequests.get("https://github.com").textrequests.post("http://httpbingo.org/post", data="asdfasd").json()
fromgeventhttpclientimportSessions=Session()
s.get("http://httpbingo.org/headers").json()
s.get("https://github.com").content

This interface builds on top of the lower level HTTPClient.

fromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURLurl=URL("http://gevent.org/")
client=HTTPClient(url.host)
response=client.get(url.request_uri)
response.status_codebody=response.read()
client.close()

httplib compatibility and monkey patch

geventhttpclient.httplib module contains classes for drop in replacement of http.client connection and response objects. If you use http.client directly you can replace the httplib imports by geventhttpclient.httplib.

# from http.client import HTTPConnectionfromgeventhttpclient.httplibimportHTTPConnection

If you use httplib2, urllib or urllib2; you can patch httplib to use the wrappers from geventhttpclient. For httplib2, make sure you patch before you import or the super() calls will fail.

importgeventhttpclient.httplibgeventhttpclient.httplib.patch()
importhttplib2

High Concurrency

HTTPClient has a connection pool built in and is greenlet safe by design. You can use the same instance among several greenlets. It is the low level building block of this library.

importgevent.poolimportjsonfromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURL# go to http://developers.facebook.com/tools/explorer and copy the access tokenTOKEN="<MY_DEV_TOKEN>"url=URL("https://graph.facebook.com/me/friends", params={"access_token": TOKEN})
# setting the concurrency to 10 allow to create 10 connections and# reuse them.client=HTTPClient.from_url(url, concurrency=10)
response=client.get(url.request_uri)
assertresponse.status_code==200# response comply to the read protocol. It passes the stream to# the json parser as it's being read.data=json.load(response)["data"]
defprint_friend_username(client, friend_id):
friend_url=URL(f"/{friend_id}", params={"access_token": TOKEN})
# the greenlet will block until a connection is availableresponse=client.get(friend_url.request_uri)
assertresponse.status_code==200friend=json.load(response)
if"username"infriend:
print(f"{friend['username']}: {friend['name']}")
else:
print(f"{friend['name']} has no username.")
# allow to run 20 greenlet at a time, this is more than concurrency# of the http client but isn't a problem since the client has its own# connection pool.pool=gevent.pool.Pool(20)
foritemindata:
friend_id=item["id"]
pool.spawn(print_friend_username, client, friend_id)
pool.join()
client.close()

Streaming

geventhttpclient supports streaming. Response objects have a read(n) and readline() method that read the stream incrementally. See examples/twitter_streaming.py for pulling twitter stream API.

Here is an example on how to download a big file chunk by chunk to save memory:

fromgeventhttpclientimportHTTPClient, URLurl=URL("http://127.0.0.1:80/100.dat")
client=HTTPClient.from_url(url)
response=client.get(url.query_string)
assertresponse.status_code==200CHUNK_SIZE=1024*16# 16KBwithopen("/tmp/100.dat", "w") asf:
data=response.read(CHUNK_SIZE)
whiledata:
f.write(data)
data=response.read(CHUNK_SIZE)

Benchmarks

The benchmark runs 10000 GET requests against a local nginx server in the default configuration with a concurrency of 10. See benchmarks folder. The requests per second for a couple of popular clients is given in the table below. Please read benchmarks/README.md for more details. Also note, HTTPX is better be used with asyncio, not gevent.

HTTP ClientRPS
GeventHTTPClient7268.9
Httplib2 (patched)2323.9
Urllib32242.5
Requests1046.1
Httpx770.3

Linux(x86_64), Python 3.11.6 @ Intel i7-7560U

License

This package is distributed under the MIT license. Previous versions of geventhttpclient used http_parser.c, which in turn was based on http/ngx_http_parse.c from NGINX, copyright Igor Sysoev, Joyent, Inc., and other Node contributors. For more information, see http://github.com/joyent/http-parser

About

A high performance, concurrent http client library for python with gevent

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

GitHub Workflow CI StatusPyPIPython Version from PEP 621 TOMLPyPI - Downloads

geventhttpclient

A high performance, concurrent HTTP client library for python using gevent.

gevent.httplib support for patching http.client was removed in gevent 1.0, geventhttpclient now provides that missing functionality.

geventhttpclient uses a fast http parser, written in C.

geventhttpclient has been specifically designed for high concurrency, streaming and support HTTP 1.1 persistent connections. More generally it is designed for efficiently pulling from REST APIs and streaming APIs like Twitter's.

Safe SSL support is provided by default. geventhttpclient depends on the certifi CA Bundle. This is the same CA Bundle which ships with the Requests codebase, and is derived from Mozilla Firefox's canonical set.

Since version 2.3, geventhttpclient features a largely requests compatible interface. It covers basic HTTP usage including cookie management, form data encoding or decoding of compressed data, but otherwise isn't as feature rich as the original requests. For simple use-cases, it can serve as a drop-in replacement.

importgeventhttpclientasrequestsrequests.get("https://github.com").textrequests.post("http://httpbingo.org/post", data="asdfasd").json()
fromgeventhttpclientimportSessions=Session()
s.get("http://httpbingo.org/headers").json()
s.get("https://github.com").content

This interface builds on top of the lower level HTTPClient.

fromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURLurl=URL("http://gevent.org/")
client=HTTPClient(url.host)
response=client.get(url.request_uri)
response.status_codebody=response.read()
client.close()

httplib compatibility and monkey patch

geventhttpclient.httplib module contains classes for drop in replacement of http.client connection and response objects. If you use http.client directly you can replace the httplib imports by geventhttpclient.httplib.

# from http.client import HTTPConnectionfromgeventhttpclient.httplibimportHTTPConnection

If you use httplib2, urllib or urllib2; you can patch httplib to use the wrappers from geventhttpclient. For httplib2, make sure you patch before you import or the super() calls will fail.

importgeventhttpclient.httplibgeventhttpclient.httplib.patch()
importhttplib2

High Concurrency

HTTPClient has a connection pool built in and is greenlet safe by design. You can use the same instance among several greenlets. It is the low level building block of this library.

importgevent.poolimportjsonfromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURL# go to http://developers.facebook.com/tools/explorer and copy the access tokenTOKEN="<MY_DEV_TOKEN>"url=URL("https://graph.facebook.com/me/friends", params={"access_token": TOKEN})
# setting the concurrency to 10 allow to create 10 connections and# reuse them.client=HTTPClient.from_url(url, concurrency=10)
response=client.get(url.request_uri)
assertresponse.status_code==200# response comply to the read protocol. It passes the stream to# the json parser as it's being read.data=json.load(response)["data"]
defprint_friend_username(client, friend_id):
friend_url=URL(f"/{friend_id}", params={"access_token": TOKEN})
# the greenlet will block until a connection is availableresponse=client.get(friend_url.request_uri)
assertresponse.status_code==200friend=json.load(response)
if"username"infriend:
print(f"{friend['username']}: {friend['name']}")
else:
print(f"{friend['name']} has no username.")
# allow to run 20 greenlet at a time, this is more than concurrency# of the http client but isn't a problem since the client has its own# connection pool.pool=gevent.pool.Pool(20)
foritemindata:
friend_id=item["id"]
pool.spawn(print_friend_username, client, friend_id)
pool.join()
client.close()

Streaming

geventhttpclient supports streaming. Response objects have a read(n) and readline() method that read the stream incrementally. See examples/twitter_streaming.py for pulling twitter stream API.

Here is an example on how to download a big file chunk by chunk to save memory:

fromgeventhttpclientimportHTTPClient, URLurl=URL("http://127.0.0.1:80/100.dat")
client=HTTPClient.from_url(url)
response=client.get(url.query_string)
assertresponse.status_code==200CHUNK_SIZE=1024*16# 16KBwithopen("/tmp/100.dat", "w") asf:
data=response.read(CHUNK_SIZE)
whiledata:
f.write(data)
data=response.read(CHUNK_SIZE)

Benchmarks

The benchmark runs 10000 GET requests against a local nginx server in the default configuration with a concurrency of 10. See benchmarks folder. The requests per second for a couple of popular clients is given in the table below. Please read benchmarks/README.md for more details. Also note, HTTPX is better be used with asyncio, not gevent.

HTTP ClientRPS
GeventHTTPClient7268.9
Httplib2 (patched)2323.9
Urllib32242.5
Requests1046.1
Httpx770.3

Linux(x86_64), Python 3.11.6 @ Intel i7-7560U

License

This package is distributed under the MIT license. Previous versions of geventhttpclient used http_parser.c, which in turn was based on http/ngx_http_parse.c from NGINX, copyright Igor Sysoev, Joyent, Inc., and other Node contributors. For more information, see http://github.com/joyent/http-parser

About

A high performance, concurrent http client library for python with gevent

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

GitHub Workflow CI StatusPyPIPython Version from PEP 621 TOMLPyPI - Downloads

geventhttpclient

A high performance, concurrent HTTP client library for python using gevent.

gevent.httplib support for patching http.client was removed in gevent 1.0, geventhttpclient now provides that missing functionality.

geventhttpclient uses a fast http parser, written in C.

geventhttpclient has been specifically designed for high concurrency, streaming and support HTTP 1.1 persistent connections. More generally it is designed for efficiently pulling from REST APIs and streaming APIs like Twitter's.

Safe SSL support is provided by default. geventhttpclient depends on the certifi CA Bundle. This is the same CA Bundle which ships with the Requests codebase, and is derived from Mozilla Firefox's canonical set.

Since version 2.3, geventhttpclient features a largely requests compatible interface. It covers basic HTTP usage including cookie management, form data encoding or decoding of compressed data, but otherwise isn't as feature rich as the original requests. For simple use-cases, it can serve as a drop-in replacement.

importgeventhttpclientasrequestsrequests.get("https://github.com").textrequests.post("http://httpbingo.org/post", data="asdfasd").json()
fromgeventhttpclientimportSessions=Session()
s.get("http://httpbingo.org/headers").json()
s.get("https://github.com").content

This interface builds on top of the lower level HTTPClient.

fromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURLurl=URL("http://gevent.org/")
client=HTTPClient(url.host)
response=client.get(url.request_uri)
response.status_codebody=response.read()
client.close()

httplib compatibility and monkey patch

geventhttpclient.httplib module contains classes for drop in replacement of http.client connection and response objects. If you use http.client directly you can replace the httplib imports by geventhttpclient.httplib.

# from http.client import HTTPConnectionfromgeventhttpclient.httplibimportHTTPConnection

If you use httplib2, urllib or urllib2; you can patch httplib to use the wrappers from geventhttpclient. For httplib2, make sure you patch before you import or the super() calls will fail.

importgeventhttpclient.httplibgeventhttpclient.httplib.patch()
importhttplib2

High Concurrency

HTTPClient has a connection pool built in and is greenlet safe by design. You can use the same instance among several greenlets. It is the low level building block of this library.

importgevent.poolimportjsonfromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURL# go to http://developers.facebook.com/tools/explorer and copy the access tokenTOKEN="<MY_DEV_TOKEN>"url=URL("https://graph.facebook.com/me/friends", params={"access_token": TOKEN})
# setting the concurrency to 10 allow to create 10 connections and# reuse them.client=HTTPClient.from_url(url, concurrency=10)
response=client.get(url.request_uri)
assertresponse.status_code==200# response comply to the read protocol. It passes the stream to# the json parser as it's being read.data=json.load(response)["data"]
defprint_friend_username(client, friend_id):
friend_url=URL(f"/{friend_id}", params={"access_token": TOKEN})
# the greenlet will block until a connection is availableresponse=client.get(friend_url.request_uri)
assertresponse.status_code==200friend=json.load(response)
if"username"infriend:
print(f"{friend['username']}: {friend['name']}")
else:
print(f"{friend['name']} has no username.")
# allow to run 20 greenlet at a time, this is more than concurrency# of the http client but isn't a problem since the client has its own# connection pool.pool=gevent.pool.Pool(20)
foritemindata:
friend_id=item["id"]
pool.spawn(print_friend_username, client, friend_id)
pool.join()
client.close()

Streaming

geventhttpclient supports streaming. Response objects have a read(n) and readline() method that read the stream incrementally. See examples/twitter_streaming.py for pulling twitter stream API.

Here is an example on how to download a big file chunk by chunk to save memory:

fromgeventhttpclientimportHTTPClient, URLurl=URL("http://127.0.0.1:80/100.dat")
client=HTTPClient.from_url(url)
response=client.get(url.query_string)
assertresponse.status_code==200CHUNK_SIZE=1024*16# 16KBwithopen("/tmp/100.dat", "w") asf:
data=response.read(CHUNK_SIZE)
whiledata:
f.write(data)
data=response.read(CHUNK_SIZE)

Benchmarks

The benchmark runs 10000 GET requests against a local nginx server in the default configuration with a concurrency of 10. See benchmarks folder. The requests per second for a couple of popular clients is given in the table below. Please read benchmarks/README.md for more details. Also note, HTTPX is better be used with asyncio, not gevent.

HTTP ClientRPS
GeventHTTPClient7268.9
Httplib2 (patched)2323.9
Urllib32242.5
Requests1046.1
Httpx770.3

Linux(x86_64), Python 3.11.6 @ Intel i7-7560U

License

This package is distributed under the MIT license. Previous versions of geventhttpclient used http_parser.c, which in turn was based on http/ngx_http_parse.c from NGINX, copyright Igor Sysoev, Joyent, Inc., and other Node contributors. For more information, see http://github.com/joyent/http-parser

About

A high performance, concurrent http client library for python with gevent

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

GitHub Workflow CI StatusPyPIPython Version from PEP 621 TOMLPyPI - Downloads

geventhttpclient

A high performance, concurrent HTTP client library for python using gevent.

gevent.httplib support for patching http.client was removed in gevent 1.0, geventhttpclient now provides that missing functionality.

geventhttpclient uses a fast http parser, written in C.

geventhttpclient has been specifically designed for high concurrency, streaming and support HTTP 1.1 persistent connections. More generally it is designed for efficiently pulling from REST APIs and streaming APIs like Twitter's.

Safe SSL support is provided by default. geventhttpclient depends on the certifi CA Bundle. This is the same CA Bundle which ships with the Requests codebase, and is derived from Mozilla Firefox's canonical set.

Since version 2.3, geventhttpclient features a largely requests compatible interface. It covers basic HTTP usage including cookie management, form data encoding or decoding of compressed data, but otherwise isn't as feature rich as the original requests. For simple use-cases, it can serve as a drop-in replacement.

importgeventhttpclientasrequestsrequests.get("https://github.com").textrequests.post("http://httpbingo.org/post", data="asdfasd").json()
fromgeventhttpclientimportSessions=Session()
s.get("http://httpbingo.org/headers").json()
s.get("https://github.com").content

This interface builds on top of the lower level HTTPClient.

fromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURLurl=URL("http://gevent.org/")
client=HTTPClient(url.host)
response=client.get(url.request_uri)
response.status_codebody=response.read()
client.close()

httplib compatibility and monkey patch

geventhttpclient.httplib module contains classes for drop in replacement of http.client connection and response objects. If you use http.client directly you can replace the httplib imports by geventhttpclient.httplib.

# from http.client import HTTPConnectionfromgeventhttpclient.httplibimportHTTPConnection

If you use httplib2, urllib or urllib2; you can patch httplib to use the wrappers from geventhttpclient. For httplib2, make sure you patch before you import or the super() calls will fail.

importgeventhttpclient.httplibgeventhttpclient.httplib.patch()
importhttplib2

High Concurrency

HTTPClient has a connection pool built in and is greenlet safe by design. You can use the same instance among several greenlets. It is the low level building block of this library.

importgevent.poolimportjsonfromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURL# go to http://developers.facebook.com/tools/explorer and copy the access tokenTOKEN="<MY_DEV_TOKEN>"url=URL("https://graph.facebook.com/me/friends", params={"access_token": TOKEN})
# setting the concurrency to 10 allow to create 10 connections and# reuse them.client=HTTPClient.from_url(url, concurrency=10)
response=client.get(url.request_uri)
assertresponse.status_code==200# response comply to the read protocol. It passes the stream to# the json parser as it's being read.data=json.load(response)["data"]
defprint_friend_username(client, friend_id):
friend_url=URL(f"/{friend_id}", params={"access_token": TOKEN})
# the greenlet will block until a connection is availableresponse=client.get(friend_url.request_uri)
assertresponse.status_code==200friend=json.load(response)
if"username"infriend:
print(f"{friend['username']}: {friend['name']}")
else:
print(f"{friend['name']} has no username.")
# allow to run 20 greenlet at a time, this is more than concurrency# of the http client but isn't a problem since the client has its own# connection pool.pool=gevent.pool.Pool(20)
foritemindata:
friend_id=item["id"]
pool.spawn(print_friend_username, client, friend_id)
pool.join()
client.close()

Streaming

geventhttpclient supports streaming. Response objects have a read(n) and readline() method that read the stream incrementally. See examples/twitter_streaming.py for pulling twitter stream API.

Here is an example on how to download a big file chunk by chunk to save memory:

fromgeventhttpclientimportHTTPClient, URLurl=URL("http://127.0.0.1:80/100.dat")
client=HTTPClient.from_url(url)
response=client.get(url.query_string)
assertresponse.status_code==200CHUNK_SIZE=1024*16# 16KBwithopen("/tmp/100.dat", "w") asf:
data=response.read(CHUNK_SIZE)
whiledata:
f.write(data)
data=response.read(CHUNK_SIZE)

Benchmarks

The benchmark runs 10000 GET requests against a local nginx server in the default configuration with a concurrency of 10. See benchmarks folder. The requests per second for a couple of popular clients is given in the table below. Please read benchmarks/README.md for more details. Also note, HTTPX is better be used with asyncio, not gevent.

HTTP ClientRPS
GeventHTTPClient7268.9
Httplib2 (patched)2323.9
Urllib32242.5
Requests1046.1
Httpx770.3

Linux(x86_64), Python 3.11.6 @ Intel i7-7560U

License

This package is distributed under the MIT license. Previous versions of geventhttpclient used http_parser.c, which in turn was based on http/ngx_http_parse.c from NGINX, copyright Igor Sysoev, Joyent, Inc., and other Node contributors. For more information, see http://github.com/joyent/http-parser

About

A high performance, concurrent http client library for python with gevent

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

GitHub Workflow CI StatusPyPIPython Version from PEP 621 TOMLPyPI - Downloads

geventhttpclient

A high performance, concurrent HTTP client library for python using gevent.

gevent.httplib support for patching http.client was removed in gevent 1.0, geventhttpclient now provides that missing functionality.

geventhttpclient uses a fast http parser, written in C.

geventhttpclient has been specifically designed for high concurrency, streaming and support HTTP 1.1 persistent connections. More generally it is designed for efficiently pulling from REST APIs and streaming APIs like Twitter's.

Safe SSL support is provided by default. geventhttpclient depends on the certifi CA Bundle. This is the same CA Bundle which ships with the Requests codebase, and is derived from Mozilla Firefox's canonical set.

Since version 2.3, geventhttpclient features a largely requests compatible interface. It covers basic HTTP usage including cookie management, form data encoding or decoding of compressed data, but otherwise isn't as feature rich as the original requests. For simple use-cases, it can serve as a drop-in replacement.

importgeventhttpclientasrequestsrequests.get("https://github.com").textrequests.post("http://httpbingo.org/post", data="asdfasd").json()
fromgeventhttpclientimportSessions=Session()
s.get("http://httpbingo.org/headers").json()
s.get("https://github.com").content

This interface builds on top of the lower level HTTPClient.

fromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURLurl=URL("http://gevent.org/")
client=HTTPClient(url.host)
response=client.get(url.request_uri)
response.status_codebody=response.read()
client.close()

httplib compatibility and monkey patch

geventhttpclient.httplib module contains classes for drop in replacement of http.client connection and response objects. If you use http.client directly you can replace the httplib imports by geventhttpclient.httplib.

# from http.client import HTTPConnectionfromgeventhttpclient.httplibimportHTTPConnection

If you use httplib2, urllib or urllib2; you can patch httplib to use the wrappers from geventhttpclient. For httplib2, make sure you patch before you import or the super() calls will fail.

importgeventhttpclient.httplibgeventhttpclient.httplib.patch()
importhttplib2

High Concurrency

HTTPClient has a connection pool built in and is greenlet safe by design. You can use the same instance among several greenlets. It is the low level building block of this library.

importgevent.poolimportjsonfromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURL# go to http://developers.facebook.com/tools/explorer and copy the access tokenTOKEN="<MY_DEV_TOKEN>"url=URL("https://graph.facebook.com/me/friends", params={"access_token": TOKEN})
# setting the concurrency to 10 allow to create 10 connections and# reuse them.client=HTTPClient.from_url(url, concurrency=10)
response=client.get(url.request_uri)
assertresponse.status_code==200# response comply to the read protocol. It passes the stream to# the json parser as it's being read.data=json.load(response)["data"]
defprint_friend_username(client, friend_id):
friend_url=URL(f"/{friend_id}", params={"access_token": TOKEN})
# the greenlet will block until a connection is availableresponse=client.get(friend_url.request_uri)
assertresponse.status_code==200friend=json.load(response)
if"username"infriend:
print(f"{friend['username']}: {friend['name']}")
else:
print(f"{friend['name']} has no username.")
# allow to run 20 greenlet at a time, this is more than concurrency# of the http client but isn't a problem since the client has its own# connection pool.pool=gevent.pool.Pool(20)
foritemindata:
friend_id=item["id"]
pool.spawn(print_friend_username, client, friend_id)
pool.join()
client.close()

Streaming

geventhttpclient supports streaming. Response objects have a read(n) and readline() method that read the stream incrementally. See examples/twitter_streaming.py for pulling twitter stream API.

Here is an example on how to download a big file chunk by chunk to save memory:

fromgeventhttpclientimportHTTPClient, URLurl=URL("http://127.0.0.1:80/100.dat")
client=HTTPClient.from_url(url)
response=client.get(url.query_string)
assertresponse.status_code==200CHUNK_SIZE=1024*16# 16KBwithopen("/tmp/100.dat", "w") asf:
data=response.read(CHUNK_SIZE)
whiledata:
f.write(data)
data=response.read(CHUNK_SIZE)

Benchmarks

The benchmark runs 10000 GET requests against a local nginx server in the default configuration with a concurrency of 10. See benchmarks folder. The requests per second for a couple of popular clients is given in the table below. Please read benchmarks/README.md for more details. Also note, HTTPX is better be used with asyncio, not gevent.

HTTP ClientRPS
GeventHTTPClient7268.9
Httplib2 (patched)2323.9
Urllib32242.5
Requests1046.1
Httpx770.3

Linux(x86_64), Python 3.11.6 @ Intel i7-7560U

License

This package is distributed under the MIT license. Previous versions of geventhttpclient used http_parser.c, which in turn was based on http/ngx_http_parse.c from NGINX, copyright Igor Sysoev, Joyent, Inc., and other Node contributors. For more information, see http://github.com/joyent/http-parser

About

A high performance, concurrent http client library for python with gevent

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

GitHub Workflow CI StatusPyPIPython Version from PEP 621 TOMLPyPI - Downloads

geventhttpclient

A high performance, concurrent HTTP client library for python using gevent.

gevent.httplib support for patching http.client was removed in gevent 1.0, geventhttpclient now provides that missing functionality.

geventhttpclient uses a fast http parser, written in C.

geventhttpclient has been specifically designed for high concurrency, streaming and support HTTP 1.1 persistent connections. More generally it is designed for efficiently pulling from REST APIs and streaming APIs like Twitter's.

Safe SSL support is provided by default. geventhttpclient depends on the certifi CA Bundle. This is the same CA Bundle which ships with the Requests codebase, and is derived from Mozilla Firefox's canonical set.

Since version 2.3, geventhttpclient features a largely requests compatible interface. It covers basic HTTP usage including cookie management, form data encoding or decoding of compressed data, but otherwise isn't as feature rich as the original requests. For simple use-cases, it can serve as a drop-in replacement.

importgeventhttpclientasrequestsrequests.get("https://github.com").textrequests.post("http://httpbingo.org/post", data="asdfasd").json()
fromgeventhttpclientimportSessions=Session()
s.get("http://httpbingo.org/headers").json()
s.get("https://github.com").content

This interface builds on top of the lower level HTTPClient.

fromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURLurl=URL("http://gevent.org/")
client=HTTPClient(url.host)
response=client.get(url.request_uri)
response.status_codebody=response.read()
client.close()

httplib compatibility and monkey patch

geventhttpclient.httplib module contains classes for drop in replacement of http.client connection and response objects. If you use http.client directly you can replace the httplib imports by geventhttpclient.httplib.

# from http.client import HTTPConnectionfromgeventhttpclient.httplibimportHTTPConnection

If you use httplib2, urllib or urllib2; you can patch httplib to use the wrappers from geventhttpclient. For httplib2, make sure you patch before you import or the super() calls will fail.

importgeventhttpclient.httplibgeventhttpclient.httplib.patch()
importhttplib2

High Concurrency

HTTPClient has a connection pool built in and is greenlet safe by design. You can use the same instance among several greenlets. It is the low level building block of this library.

importgevent.poolimportjsonfromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURL# go to http://developers.facebook.com/tools/explorer and copy the access tokenTOKEN="<MY_DEV_TOKEN>"url=URL("https://graph.facebook.com/me/friends", params={"access_token": TOKEN})
# setting the concurrency to 10 allow to create 10 connections and# reuse them.client=HTTPClient.from_url(url, concurrency=10)
response=client.get(url.request_uri)
assertresponse.status_code==200# response comply to the read protocol. It passes the stream to# the json parser as it's being read.data=json.load(response)["data"]
defprint_friend_username(client, friend_id):
friend_url=URL(f"/{friend_id}", params={"access_token": TOKEN})
# the greenlet will block until a connection is availableresponse=client.get(friend_url.request_uri)
assertresponse.status_code==200friend=json.load(response)
if"username"infriend:
print(f"{friend['username']}: {friend['name']}")
else:
print(f"{friend['name']} has no username.")
# allow to run 20 greenlet at a time, this is more than concurrency# of the http client but isn't a problem since the client has its own# connection pool.pool=gevent.pool.Pool(20)
foritemindata:
friend_id=item["id"]
pool.spawn(print_friend_username, client, friend_id)
pool.join()
client.close()

Streaming

geventhttpclient supports streaming. Response objects have a read(n) and readline() method that read the stream incrementally. See examples/twitter_streaming.py for pulling twitter stream API.

Here is an example on how to download a big file chunk by chunk to save memory:

fromgeventhttpclientimportHTTPClient, URLurl=URL("http://127.0.0.1:80/100.dat")
client=HTTPClient.from_url(url)
response=client.get(url.query_string)
assertresponse.status_code==200CHUNK_SIZE=1024*16# 16KBwithopen("/tmp/100.dat", "w") asf:
data=response.read(CHUNK_SIZE)
whiledata:
f.write(data)
data=response.read(CHUNK_SIZE)

Benchmarks

The benchmark runs 10000 GET requests against a local nginx server in the default configuration with a concurrency of 10. See benchmarks folder. The requests per second for a couple of popular clients is given in the table below. Please read benchmarks/README.md for more details. Also note, HTTPX is better be used with asyncio, not gevent.

HTTP ClientRPS
GeventHTTPClient7268.9
Httplib2 (patched)2323.9
Urllib32242.5
Requests1046.1
Httpx770.3

Linux(x86_64), Python 3.11.6 @ Intel i7-7560U

License

This package is distributed under the MIT license. Previous versions of geventhttpclient used http_parser.c, which in turn was based on http/ngx_http_parse.c from NGINX, copyright Igor Sysoev, Joyent, Inc., and other Node contributors. For more information, see http://github.com/joyent/http-parser

About

A high performance, concurrent http client library for python with gevent

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

GitHub Workflow CI StatusPyPIPython Version from PEP 621 TOMLPyPI - Downloads

geventhttpclient

A high performance, concurrent HTTP client library for python using gevent.

gevent.httplib support for patching http.client was removed in gevent 1.0, geventhttpclient now provides that missing functionality.

geventhttpclient uses a fast http parser, written in C.

geventhttpclient has been specifically designed for high concurrency, streaming and support HTTP 1.1 persistent connections. More generally it is designed for efficiently pulling from REST APIs and streaming APIs like Twitter's.

Safe SSL support is provided by default. geventhttpclient depends on the certifi CA Bundle. This is the same CA Bundle which ships with the Requests codebase, and is derived from Mozilla Firefox's canonical set.

Since version 2.3, geventhttpclient features a largely requests compatible interface. It covers basic HTTP usage including cookie management, form data encoding or decoding of compressed data, but otherwise isn't as feature rich as the original requests. For simple use-cases, it can serve as a drop-in replacement.

importgeventhttpclientasrequestsrequests.get("https://github.com").textrequests.post("http://httpbingo.org/post", data="asdfasd").json()
fromgeventhttpclientimportSessions=Session()
s.get("http://httpbingo.org/headers").json()
s.get("https://github.com").content

This interface builds on top of the lower level HTTPClient.

fromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURLurl=URL("http://gevent.org/")
client=HTTPClient(url.host)
response=client.get(url.request_uri)
response.status_codebody=response.read()
client.close()

httplib compatibility and monkey patch

geventhttpclient.httplib module contains classes for drop in replacement of http.client connection and response objects. If you use http.client directly you can replace the httplib imports by geventhttpclient.httplib.

# from http.client import HTTPConnectionfromgeventhttpclient.httplibimportHTTPConnection

If you use httplib2, urllib or urllib2; you can patch httplib to use the wrappers from geventhttpclient. For httplib2, make sure you patch before you import or the super() calls will fail.

importgeventhttpclient.httplibgeventhttpclient.httplib.patch()
importhttplib2

High Concurrency

HTTPClient has a connection pool built in and is greenlet safe by design. You can use the same instance among several greenlets. It is the low level building block of this library.

importgevent.poolimportjsonfromgeventhttpclientimportHTTPClientfromgeventhttpclient.urlimportURL# go to http://developers.facebook.com/tools/explorer and copy the access tokenTOKEN="<MY_DEV_TOKEN>"url=URL("https://graph.facebook.com/me/friends", params={"access_token": TOKEN})
# setting the concurrency to 10 allow to create 10 connections and# reuse them.client=HTTPClient.from_url(url, concurrency=10)
response=client.get(url.request_uri)
assertresponse.status_code==200# response comply to the read protocol. It passes the stream to# the json parser as it's being read.data=json.load(response)["data"]
defprint_friend_username(client, friend_id):
friend_url=URL(f"/{friend_id}", params={"access_token": TOKEN})
# the greenlet will block until a connection is availableresponse=client.get(friend_url.request_uri)
assertresponse.status_code==200friend=json.load(response)
if"username"infriend:
print(f"{friend['username']}: {friend['name']}")
else:
print(f"{friend['name']} has no username.")
# allow to run 20 greenlet at a time, this is more than concurrency# of the http client but isn't a problem since the client has its own# connection pool.pool=gevent.pool.Pool(20)
foritemindata:
friend_id=item["id"]
pool.spawn(print_friend_username, client, friend_id)
pool.join()
client.close()

Streaming

geventhttpclient supports streaming. Response objects have a read(n) and readline() method that read the stream incrementally. See examples/twitter_streaming.py for pulling twitter stream API.

Here is an example on how to download a big file chunk by chunk to save memory:

fromgeventhttpclientimportHTTPClient, URLurl=URL("http://127.0.0.1:80/100.dat")
client=HTTPClient.from_url(url)
response=client.get(url.query_string)
assertresponse.status_code==200CHUNK_SIZE=1024*16# 16KBwithopen("/tmp/100.dat", "w") asf:
data=response.read(CHUNK_SIZE)
whiledata:
f.write(data)
data=response.read(CHUNK_SIZE)

Benchmarks

The benchmark runs 10000 GET requests against a local nginx server in the default configuration with a concurrency of 10. See benchmarks folder. The requests per second for a couple of popular clients is given in the table below. Please read benchmarks/README.md for more details. Also note, HTTPX is better be used with asyncio, not gevent.

HTTP ClientRPS
GeventHTTPClient7268.9
Httplib2 (patched)2323.9
Urllib32242.5
Requests1046.1
Httpx770.3

Linux(x86_64), Python 3.11.6 @ Intel i7-7560U

License

This package is distributed under the MIT license. Previous versions of geventhttpclient used http_parser.c, which in turn was based on http/ngx_http_parse.c from NGINX, copyright Igor Sysoev, Joyent, Inc., and other Node contributors. For more information, see http://github.com/joyent/http-parser

About

A high performance, concurrent http client library for python with gevent

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages