Python (2.7) で 3 つの要件を持つ HTTP リクエストを実行する方法を探しています。
- タイムアウト (信頼性のため)
- コンテンツの最大サイズ (セキュリティのため)
- 接続プーリング (パフォーマンスのため)
私はかなりすべての python HTTP ライブラリをチェックしましたが、どれも私の要件を満たしていません。例えば:
urllib2: 良いですが、プーリングはありません
import urllib2
import json
r = urllib2.urlopen('https://github.com/timeline.json', timeout=5)
content = r.read(100+1)
if len(content) > 100:
print 'too large'
r.close()
else:
print json.loads(content)
r = urllib2.urlopen('https://github.com/timeline.json', timeout=5)
content = r.read(100000+1)
if len(content) > 100000:
print 'too large'
r.close()
else:
print json.loads(content)
リクエスト: 最大サイズなし
import requests
r = requests.get('https://github.com/timeline.json', timeout=5, stream=True)
r.headers['content-length'] # does not exists for this request, and not safe
content = r.raw.read(100000+1)
print content # ARF this is gzipped, so not the real size
print json.loads(content) # content is gzipped so pretty useless
print r.json() # Does not work anymore since raw.read was used
urllib3: 50Mo ファイルであっても、「読み取り」メソッドが機能しませんでした ...
httplib: httplib.HTTPConnection はプールではありません (1 つの接続のみ)
urllib2 が私が使用できる最高の HTTP ライブラリであるとは信じられません。したがって、これを行うことができるライブラリや、以前のライブラリのいずれかを使用する方法を誰かが知っている場合...
編集:
Martijn Pieters のおかげで私が見つけた最良の解決策 (StringIO は、str の追加が多くのことを行う巨大なファイルでも遅くなりません)。
r = requests.get('https://github.com/timeline.json', stream=True)
size = 0
ctt = StringIO()
for chunk in r.iter_content(2048):
size += len(chunk)
ctt.write(chunk)
if size > maxsize:
r.close()
raise ValueError('Response too large')
content = ctt.getvalue()