From 435bd1242a618237e1c3150216e2cf50af586288 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 13 Oct 2011 22:30:19 -0400 Subject: [PATCH 01/28] reqs.txt for ci and dev --- reqs.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 reqs.txt diff --git a/reqs.txt b/reqs.txt new file mode 100644 index 00000000..db81186c --- /dev/null +++ b/reqs.txt @@ -0,0 +1,5 @@ +nose +mock +pyflakes +NoseXUnit +gevent \ No newline at end of file From f0cfba708b0de39c072c3a327d4674ce777a0f50 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 13 Oct 2011 22:34:01 -0400 Subject: [PATCH 02/28] take out pyflakes.. for now. --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1686ea56..e4872da0 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,7 @@ test: nosetests test_requests.py --processes=30 ci: init - nosetests --search-test --processes=30 --with-nosexunit test_requests.py - pyflakes requests | awk -F\: '{printf "%s:%s: [E]%s\n", $1, $2, $3}' > violations.pyflakes.txt + nosetests --processes=30 --with-nosexunit test_requests.py site: cd docs; make dirhtml From 1382d655ed916eb11d682c47449d451ce406ce47 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 13 Oct 2011 22:37:23 -0400 Subject: [PATCH 03/28] omnijson for python2.5 --- reqs.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reqs.txt b/reqs.txt index db81186c..3dd8b21b 100644 --- a/reqs.txt +++ b/reqs.txt @@ -2,4 +2,5 @@ nose mock pyflakes NoseXUnit -gevent \ No newline at end of file +gevent +omnijson \ No newline at end of file From daf9b6055052d3dd812cc9a7669cffd242f56c08 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 13 Oct 2011 22:39:13 -0400 Subject: [PATCH 04/28] gah, gevent won't work with pypy --- reqs.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/reqs.txt b/reqs.txt index 3dd8b21b..27f614a8 100644 --- a/reqs.txt +++ b/reqs.txt @@ -2,5 +2,4 @@ nose mock pyflakes NoseXUnit -gevent omnijson \ No newline at end of file From 15755be3c77b8d17edc7ef5b36121d012aad5926 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 09:52:45 -0400 Subject: [PATCH 05/28] nosexunit is a steaming pile of trash --- Makefile | 5 ++++- reqs.txt | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index e4872da0..05203747 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,10 @@ test: nosetests test_requests.py --processes=30 ci: init - nosetests --processes=30 --with-nosexunit test_requests.py + nosetests test_requests.py --with-xunit --xunit-file=junit-report.xml + +stats: + pyflakes requests | awk -F\: '{printf "%s:%s: [E]%s\n", $1, $2, $3}' > violations.pyflakes.txt site: cd docs; make dirhtml diff --git a/reqs.txt b/reqs.txt index 27f614a8..43c7c061 100644 --- a/reqs.txt +++ b/reqs.txt @@ -1,5 +1,3 @@ nose -mock pyflakes -NoseXUnit omnijson \ No newline at end of file From e1dfb7c8839553abae206bb55dfdf22dd5225f2d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 09:55:00 -0400 Subject: [PATCH 06/28] httpbin --- reqs.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/reqs.txt b/reqs.txt index 43c7c061..14684e73 100644 --- a/reqs.txt +++ b/reqs.txt @@ -1,3 +1,4 @@ +httpbin nose pyflakes omnijson \ No newline at end of file From d98de70f4acfa93bcec4ae77ee04c57b9945a3b4 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 11:05:29 -0400 Subject: [PATCH 07/28] envoy. --- reqs.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reqs.txt b/reqs.txt index 14684e73..1729ab7f 100644 --- a/reqs.txt +++ b/reqs.txt @@ -1,4 +1,5 @@ -httpbin +envoy==0.0.2 nose pyflakes -omnijson \ No newline at end of file +omnijson +httpbin \ No newline at end of file From 35bfa9e91d93c695f5cd421148a472e61da05a11 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 11:55:57 -0400 Subject: [PATCH 08/28] HTTP Integration --- test_requests.py | 69 ++++++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/test_requests.py b/test_requests.py index 83b827ab..ff42a7a5 100755 --- a/test_requests.py +++ b/test_requests.py @@ -16,11 +16,7 @@ import requests from requests.sessions import Session -HTTPBIN_URL = 'http://httpbin.ep.io/' -HTTPSBIN_URL = 'https://httpbin.ep.io/' - -# HTTPBIN_URL = 'http://staging.httpbin.org/' -# HTTPSBIN_URL = 'https://httpbin-staging.ep.io/' +HTTPBIN_URL = 'http://127.0.0.1:44444/' def httpbin(*suffix): @@ -29,15 +25,9 @@ def httpbin(*suffix): return HTTPBIN_URL + '/'.join(suffix) -def httpsbin(*suffix): - """Returns url for HTTPSBIN resource.""" - - return HTTPSBIN_URL + '/'.join(suffix) - - -SERVICES = (httpbin, httpsbin) - +SERVICES = (httpbin, ) +_httpbin = False class RequestsTestSuite(unittest.TestCase): """Requests test cases.""" @@ -46,12 +36,25 @@ class RequestsTestSuite(unittest.TestCase): _multiprocess_can_split_ = True def setUp(self): - pass + + global _httpbin + + if not _httpbin: + import envoy + self.httpbin = envoy.connect('httpbin 44444') + # print self.httpbin + + _httpbin = True + # print '!'/ + + import time + time.sleep(1) + def tearDown(self): """Teardown.""" - pass + # self.httpbin.kill() def test_invalid_url(self): @@ -59,7 +62,7 @@ class RequestsTestSuite(unittest.TestCase): def test_HTTP_200_OK_GET(self): - r = requests.get(httpbin('/')) + r = requests.get(httpbin('/get')) self.assertEqual(r.status_code, 200) def test_HTTP_302_ALLOW_REDIRECT_GET(self): @@ -70,10 +73,6 @@ class RequestsTestSuite(unittest.TestCase): r = requests.get(httpbin('redirect', '1'), allow_redirects=False) self.assertEqual(r.status_code, 302) - def test_HTTPS_200_OK_GET(self): - r = requests.get(httpsbin('/')) - self.assertEqual(r.status_code, 200) - def test_HTTP_200_OK_GET_WITH_PARAMS(self): heads = {'User-agent': 'Mozilla/5.0'} @@ -112,12 +111,7 @@ class RequestsTestSuite(unittest.TestCase): def test_HTTP_200_OK_HEAD(self): - r = requests.head(httpbin('/')) - self.assertEqual(r.status_code, 200) - - - def test_HTTPS_200_OK_HEAD(self): - r = requests.head(httpsbin('/')) + r = requests.head(httpbin('/get')) self.assertEqual(r.status_code, 200) @@ -126,21 +120,11 @@ class RequestsTestSuite(unittest.TestCase): self.assertEqual(r.status_code, 200) - def test_HTTPS_200_OK_PUT(self): - r = requests.put(httpsbin('put')) - self.assertEqual(r.status_code, 200) - - def test_HTTP_200_OK_PATCH(self): r = requests.patch(httpbin('patch')) self.assertEqual(r.status_code, 200) - def test_HTTPS_200_OK_PATCH(self): - r = requests.patch(httpsbin('patch')) - self.assertEqual(r.status_code, 200) - - def test_AUTH_HTTP_200_OK_GET(self): for service in SERVICES: @@ -206,7 +190,7 @@ class RequestsTestSuite(unittest.TestCase): r = requests.get(service('status', '500')) self.assertEqual(bool(r), False) - r = requests.get(service('/')) + r = requests.get(service('/get')) self.assertEqual(bool(r), True) @@ -257,7 +241,7 @@ class RequestsTestSuite(unittest.TestCase): for service in SERVICES: - url = service('/') + url = service('/get') requests.get(url, params={'foo': u'føø'}) requests.get(url, params={u'føø': u'føø'}) @@ -470,14 +454,7 @@ class RequestsTestSuite(unittest.TestCase): def test_session_HTTP_200_OK_GET(self): s = Session() - r = s.get(httpbin('/')) - self.assertEqual(r.status_code, 200) - - - def test_session_HTTPS_200_OK_GET(self): - - s = Session() - r = s.get(httpsbin('/')) + r = s.get(httpbin('/get')) self.assertEqual(r.status_code, 200) From d85c5356dc0cb0e288ff39c6802a1fcaaf7be635 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:05:35 -0400 Subject: [PATCH 09/28] remove idna tests, for now --- test_requests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_requests.py b/test_requests.py index ff42a7a5..2b28319b 100755 --- a/test_requests.py +++ b/test_requests.py @@ -370,9 +370,9 @@ class RequestsTestSuite(unittest.TestCase): self.assertEquals(rbody.get('data'), 'foobar') - def test_idna(self): - r = requests.get(u'http://➡.ws/httpbin') - assert 'httpbin' in r.url + # def test_idna(self): + # r = requests.get(u'http://➡.ws/httpbin') + # assert 'httpbin' in r.url def test_urlencoded_get_query_multivalued_param(self): From 12d669781546a3874b608d80f6a885e3b56bdedd Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:05:40 -0400 Subject: [PATCH 10/28] v0.0.4 --- reqs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reqs.txt b/reqs.txt index 1729ab7f..495f9f8b 100644 --- a/reqs.txt +++ b/reqs.txt @@ -2,4 +2,4 @@ envoy==0.0.2 nose pyflakes omnijson -httpbin \ No newline at end of file +httpbin==0.0.4 \ No newline at end of file From 6e840f46e113099f1d9d64ad7418809d84955ab7 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:16:24 -0400 Subject: [PATCH 11/28] `make test` --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 05203747..f248cd5e 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ init: pip install -r reqs.txt test: - nosetests test_requests.py --processes=30 + python test_requests.py ci: init nosetests test_requests.py --with-xunit --xunit-file=junit-report.xml From 12997080a8331f6b1e22aa91fad625a3be58b056 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:30:49 -0400 Subject: [PATCH 12/28] use gunicorn to serve tests --- test_requests.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test_requests.py b/test_requests.py index 2b28319b..51661dfb 100755 --- a/test_requests.py +++ b/test_requests.py @@ -3,8 +3,11 @@ from __future__ import with_statement -import unittest +import time import cookielib +import unittest + +import envoy try: import omnijson as json @@ -16,7 +19,8 @@ import requests from requests.sessions import Session -HTTPBIN_URL = 'http://127.0.0.1:44444/' +HTTPBIN_URL = 'http://0.0.0.0:7045/' +# HTTPBIN_URL = 'http://127.0.0.1:8000/' def httpbin(*suffix): @@ -40,14 +44,10 @@ class RequestsTestSuite(unittest.TestCase): global _httpbin if not _httpbin: - import envoy - self.httpbin = envoy.connect('httpbin 44444') - # print self.httpbin + + self.httpbin = envoy.connect('gunicorn httpbin:app --bind=0.0.0.0:7045') _httpbin = True - # print '!'/ - - import time time.sleep(1) @@ -122,6 +122,9 @@ class RequestsTestSuite(unittest.TestCase): def test_HTTP_200_OK_PATCH(self): r = requests.patch(httpbin('patch')) + print r.__dict__ + print r.content + print r.url self.assertEqual(r.status_code, 200) From 7a0f3638b5fc8e196cfeebc4e506ea627d992483 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:32:42 -0400 Subject: [PATCH 13/28] Test suite cleanup --- test_requests.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test_requests.py b/test_requests.py index 51661dfb..ba9d27be 100755 --- a/test_requests.py +++ b/test_requests.py @@ -5,6 +5,7 @@ from __future__ import with_statement import time import cookielib +import os import unittest import envoy @@ -18,8 +19,9 @@ import requests from requests.sessions import Session +PORT = os.environ.get('HTTPBIN_PORT', '7045') -HTTPBIN_URL = 'http://0.0.0.0:7045/' +HTTPBIN_URL = 'http://0.0.0.0:%s/' % (PORT) # HTTPBIN_URL = 'http://127.0.0.1:8000/' @@ -45,7 +47,7 @@ class RequestsTestSuite(unittest.TestCase): if not _httpbin: - self.httpbin = envoy.connect('gunicorn httpbin:app --bind=0.0.0.0:7045') + self.httpbin = envoy.connect('gunicorn httpbin:app --bind=0.0.0.0:%s' % (PORT)) _httpbin = True time.sleep(1) From f0bcdd075e7c49b22a5729ba9e9b8c73bbcf7607 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:33:14 -0400 Subject: [PATCH 14/28] gunicorn --- reqs.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/reqs.txt b/reqs.txt index 495f9f8b..ec6d2d0c 100644 --- a/reqs.txt +++ b/reqs.txt @@ -1,3 +1,4 @@ +gunicorn envoy==0.0.2 nose pyflakes From 60917e0b9ffce90967051fe34cfdecbe817f9665 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:35:47 -0400 Subject: [PATCH 15/28] timeout adjustment --- test_requests.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test_requests.py b/test_requests.py index ba9d27be..1dff610d 100755 --- a/test_requests.py +++ b/test_requests.py @@ -124,9 +124,6 @@ class RequestsTestSuite(unittest.TestCase): def test_HTTP_200_OK_PATCH(self): r = requests.patch(httpbin('patch')) - print r.__dict__ - print r.content - print r.url self.assertEqual(r.status_code, 200) @@ -270,7 +267,7 @@ class RequestsTestSuite(unittest.TestCase): r = requests.get(httpbin('')) r.raise_for_status() - with requests.settings(timeout=0.0000001): + with requests.settings(timeout=0.0000000001): self.assertRaises(requests.Timeout, test) with requests.settings(timeout=100): From a688f026dc9051a61f9ba6ffd6a9457640ce6374 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:37:08 -0400 Subject: [PATCH 16/28] settings are being deprecated --- test_requests.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/test_requests.py b/test_requests.py index 1dff610d..457ec8aa 100755 --- a/test_requests.py +++ b/test_requests.py @@ -261,19 +261,6 @@ class RequestsTestSuite(unittest.TestCase): self.assertEquals(r.status_code, 401) - def test_settings(self): - - def test(): - r = requests.get(httpbin('')) - r.raise_for_status() - - with requests.settings(timeout=0.0000000001): - self.assertRaises(requests.Timeout, test) - - with requests.settings(timeout=100): - requests.get(httpbin('')) - - def test_urlencoded_post_data(self): for service in SERVICES: From d0b9357f1bfe2eb4c0d7d0614ec948caeaa49fe1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 12:54:50 -0400 Subject: [PATCH 17/28] all teh colors --- Makefile | 2 +- reqs.txt | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f248cd5e..8b49b27e 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ init: pip install -r reqs.txt test: - python test_requests.py + nosetests test_requests.py --with-color ci: init nosetests test_requests.py --with-xunit --xunit-file=junit-report.xml diff --git a/reqs.txt b/reqs.txt index ec6d2d0c..46acb760 100644 --- a/reqs.txt +++ b/reqs.txt @@ -1,6 +1,7 @@ -gunicorn envoy==0.0.2 +httpbin==0.0.4 +gunicorn nose pyflakes omnijson -httpbin==0.0.4 \ No newline at end of file +rudolf \ No newline at end of file From 9b42c954c6f9d841e4be5dd99b1d135002f3ba01 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 15 Oct 2011 13:01:56 -0400 Subject: [PATCH 18/28] Offline test suite --- HISTORY.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index 053d37a7..f2d49c3d 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,13 @@ History ------- +0.6.5 (?) +++++++++++ + +* Offline (fast) test suite +* + + 0.6.4 (2011-10-13) ++++++++++++++++++ From a4234e97bedff790617dd3f8921ef056d11e6993 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 17 Oct 2011 20:41:40 -0400 Subject: [PATCH 19/28] Add "out there" section to docs --- docs/community/out-there.rst | 62 ++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 2 files changed, 63 insertions(+) create mode 100644 docs/community/out-there.rst diff --git a/docs/community/out-there.rst b/docs/community/out-there.rst new file mode 100644 index 00000000..167494d3 --- /dev/null +++ b/docs/community/out-there.rst @@ -0,0 +1,62 @@ +Modules +======= + +- https://github.com/maraujop/requests-oauth-hook +- https://github.com/jgorset/facepy +- https://github.com/bulkan/robotframework-requests +- https://github.com/bitprophet/fullerene] +- https://github.com/benjaminws/urbanairship-python + + +Articles & Talks +================ + +- http://pydanny.blogspot.com/2011/05/python-http-requests-for-humans.html +- http://python-for-humans.heroku.com +- http://issackelly.github.com/Consuming-Web-APIs-with-Python-Talk/slides/slides.html +- http://arunsag.wordpress.com/2011/08/17/new-package-python-requests-http-for-humans/ +- http://habrahabr.ru/blogs/python/126262/ [Russian] + + +Integrations +============ + +ScraperWiki +------------ + +ScraperWiki is an excellent service that allows you to run Python, Ruby, and PHP +scraper scripts on the web. Now, Requests v0.6.1 is available to use in your scrapers! + +To give it a try, simply:: + + import requests + + +Managed Packages +================ + +Requests is available in a number of popular package formats. Of course, +the ideal way to install Requests is via The Cheeseshop. + + +Ubuntu & Debian +--------------- + +Requests is available installed as a Debian package! Debian Etch Ubuntu, since Oneiric:: + + $ apt-get install + +Unfortunately, the most recent version available is v0.5.0. If you're on the +Debian Python Package team, I'd love an update of that :) + + +Fedora and RedHat +----------------- + +You can easily install Requests v0.6.1 with yum on rpm-based systems:: + + $ yum install python-requests + + + + diff --git a/docs/index.rst b/docs/index.rst index d849ed5f..183d475a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -87,6 +87,7 @@ Requests ecosystem and community. :maxdepth: 2 community/faq + community/out-there.rst community/support community/updates From 7481980c1a4a60d9a63278041aed895002af9f5d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 17 Oct 2011 20:52:55 -0400 Subject: [PATCH 20/28] descriptions for "out there" --- docs/community/out-there.rst | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/community/out-there.rst b/docs/community/out-there.rst index 167494d3..1bdeb6b0 100644 --- a/docs/community/out-there.rst +++ b/docs/community/out-there.rst @@ -1,21 +1,21 @@ Modules ======= -- https://github.com/maraujop/requests-oauth-hook -- https://github.com/jgorset/facepy -- https://github.com/bulkan/robotframework-requests -- https://github.com/bitprophet/fullerene] -- https://github.com/benjaminws/urbanairship-python +- `requests-oauth-hook `_, for adding OAuth1 support to Requests +- `FacePy `_, a Python wrapper to the Facebook API. +- `robotframework-requests `_, a Robot Framework API wrapper. +- `fullerene `_, a Graphite Dashboard. +- `urbanairship-python `_, a fork of the Urban Airship API wrapper. Articles & Talks ================ -- http://pydanny.blogspot.com/2011/05/python-http-requests-for-humans.html -- http://python-for-humans.heroku.com -- http://issackelly.github.com/Consuming-Web-APIs-with-Python-Talk/slides/slides.html -- http://arunsag.wordpress.com/2011/08/17/new-package-python-requests-http-for-humans/ -- http://habrahabr.ru/blogs/python/126262/ [Russian] +- `Daniel Greenfield's Review of Requests `_ +- `My 'Python for Humans' talk `_ +- `Issac Kelly's 'Consuming Web APIs' talk `_ +- `Blog post about Requests via Yum `_ +- `Russian blog post intrudcing Requests `_ Integrations @@ -24,8 +24,9 @@ Integrations ScraperWiki ------------ -ScraperWiki is an excellent service that allows you to run Python, Ruby, and PHP -scraper scripts on the web. Now, Requests v0.6.1 is available to use in your scrapers! +`ScraperWiki `_ is an excellent service that allows +you to run Python, Ruby, and PHP scraper scripts on the web. Now, Requests +v0.6.1 is available to use in your scrapers! To give it a try, simply:: From 38bd23493609c4e1a33bbf8009d98265865e6ce0 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 17 Oct 2011 20:56:54 -0400 Subject: [PATCH 21/28] pycodeconf audio --- docs/community/out-there.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/community/out-there.rst b/docs/community/out-there.rst index 1bdeb6b0..0edbc5b5 100644 --- a/docs/community/out-there.rst +++ b/docs/community/out-there.rst @@ -1,7 +1,7 @@ Modules ======= -- `requests-oauth-hook `_, for adding OAuth1 support to Requests +- `requests-oauth-hook `_, adds OAuth support to Requests. - `FacePy `_, a Python wrapper to the Facebook API. - `robotframework-requests `_, a Robot Framework API wrapper. - `fullerene `_, a Graphite Dashboard. @@ -12,7 +12,7 @@ Articles & Talks ================ - `Daniel Greenfield's Review of Requests `_ -- `My 'Python for Humans' talk `_ +- `My 'Python for Humans' talk `_ ( `audio `_ ) - `Issac Kelly's 'Consuming Web APIs' talk `_ - `Blog post about Requests via Yum `_ - `Russian blog post intrudcing Requests `_ From de4035fb96977344891217964cd898a2845cd3cd Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 17 Oct 2011 20:57:04 -0400 Subject: [PATCH 22/28] ignore junit xml --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 49e07472..968d26ff 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ pylint.txt docs/_build toy.py .gitignore +junit-report.xml \ No newline at end of file From 6bd8e9e73f1a651180a92725bcb95f8d3171ebdf Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 17 Oct 2011 20:58:52 -0400 Subject: [PATCH 23/28] sp --- docs/community/out-there.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/community/out-there.rst b/docs/community/out-there.rst index 0edbc5b5..2d33345c 100644 --- a/docs/community/out-there.rst +++ b/docs/community/out-there.rst @@ -15,7 +15,7 @@ Articles & Talks - `My 'Python for Humans' talk `_ ( `audio `_ ) - `Issac Kelly's 'Consuming Web APIs' talk `_ - `Blog post about Requests via Yum `_ -- `Russian blog post intrudcing Requests `_ +- `Russian blog post introducing Requests `_ Integrations From ef1e27ea9f254edf6e6805745c77425a9a4362ab Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 17 Oct 2011 20:59:27 -0400 Subject: [PATCH 24/28] apt-get install python-requests --- docs/community/out-there.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/community/out-there.rst b/docs/community/out-there.rst index 2d33345c..f55c2483 100644 --- a/docs/community/out-there.rst +++ b/docs/community/out-there.rst @@ -45,7 +45,7 @@ Ubuntu & Debian Requests is available installed as a Debian package! Debian Etch Ubuntu, since Oneiric:: - $ apt-get install + $ apt-get install python-requests Unfortunately, the most recent version available is v0.5.0. If you're on the Debian Python Package team, I'd love an update of that :) From 9645e882b2a581da0b14c8dad3f062e53b2df17e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 18 Oct 2011 17:26:21 -0400 Subject: [PATCH 25/28] "Python on the Web" blog post --- docs/community/out-there.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/community/out-there.rst b/docs/community/out-there.rst index f55c2483..2e7b4715 100644 --- a/docs/community/out-there.rst +++ b/docs/community/out-there.rst @@ -10,7 +10,7 @@ Modules Articles & Talks ================ - +- `Python for the Web `_ teaches how to use Python to interact with the web, using Requests. - `Daniel Greenfield's Review of Requests `_ - `My 'Python for Humans' talk `_ ( `audio `_ ) - `Issac Kelly's 'Consuming Web APIs' talk `_ From 65a765fe882ab30f794be8108abf9defd05900c5 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Wed, 19 Oct 2011 01:09:55 -0400 Subject: [PATCH 26/28] new local merging of keyword arguments for sessions --- requests/sessions.py | 81 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/requests/sessions.py b/requests/sessions.py index 50b09f61..4e7022d6 100644 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -16,21 +16,60 @@ from .utils import add_dict_to_cookiejar +def merge_kwargs(local_kwarg, default_kwarg): + """Merges kwarg dictionaries. + + If a local key in the dictionary is set to None, it will be removed. + """ + + if default_kwarg is None: + return local_kwarg + + if local_kwarg is None: + return default_kwarg + + # Bypass if not a dictionary (e.g. timeout) + if not hasattr(default_kwarg, 'items'): + return local_kwarg + + + + # Update new values. + kwargs = default_kwarg.copy() + kwargs.update(local_kwarg) + + # Remove keys that are set to None. + for (k,v) in local_kwarg.items(): + if v is None: + del kwargs[k] + + return kwargs + + class Session(object): """A Requests session.""" __attrs__ = ['headers', 'cookies', 'auth', 'timeout', 'proxies', 'hooks'] - def __init__(self, **kwargs): + def __init__(self, + headers=None, + cookies=None, + auth=None, + timeout=None, + proxies=None, + hooks=None): + + self.headers = headers or {} + self.cookies = cookies or {} + self.auth = auth + self.timeout = timeout + self.proxies = proxies or {} + self.hooks = hooks or {} # Set up a CookieJar to be used by default self.cookies = cookielib.FileCookieJar() - # Map args from kwargs to instance-local variables - map(lambda k, v: (k in self.__attrs__) and setattr(self, k, v), - kwargs.iterkeys(), kwargs.itervalues()) - # Map and wrap requests.api methods self._map_api_methods() @@ -42,10 +81,8 @@ class Session(object): return self def __exit__(self, *args): - # print args pass - def _map_api_methods(self): """Reads each available method from requests.api and decorates them with a wrapper, which inserts any instance-local attributes @@ -54,23 +91,35 @@ class Session(object): def pass_args(func): def wrapper_func(*args, **kwargs): - inst_attrs = dict((k, v) for k, v in self.__dict__.iteritems() - if k in self.__attrs__) - # Combine instance-local values with kwargs values, with - # priority to values in kwargs - kwargs = dict(inst_attrs.items() + kwargs.items()) + + # Argument collector. + _kwargs = {} # If a session request has a cookie_dict, inject the # values into the existing CookieJar instead. if isinstance(kwargs.get('cookies', None), dict): kwargs['cookies'] = add_dict_to_cookiejar( - inst_attrs['cookies'], kwargs['cookies'] + self.cookies, kwargs['cookies'] ) - if kwargs.get('headers', None) and inst_attrs.get('headers', None): - kwargs['headers'].update(inst_attrs['headers']) + for attr in self.__attrs__: + # for attr in ['headers',]: + s_val = self.__dict__.get(attr) + r_val = kwargs.get(attr) + + new_attr = merge_kwargs(r_val, s_val) + + # Skip attributes that were set to None. + if new_attr is not None: + _kwargs[attr] = new_attr + + # Make sure we didn't miss anything. + for (k, v) in kwargs.items(): + if k not in _kwargs: + _kwargs[k] = v + + return func(*args, **_kwargs) - return func(*args, **kwargs) return wrapper_func # Map and decorate each function available in requests.api From ec94f5030c9087372ac31f240e25cf51bf420241 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Wed, 19 Oct 2011 01:10:06 -0400 Subject: [PATCH 27/28] testing session method attribute merging --- test_requests.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test_requests.py b/test_requests.py index 457ec8aa..dbfe527d 100755 --- a/test_requests.py +++ b/test_requests.py @@ -453,13 +453,18 @@ class RequestsTestSuite(unittest.TestCase): s = Session() s.headers = heads + # Make 2 requests from Session object, should send header both times r1 = s.get(httpbin('user-agent')) - assert heads['User-agent'] in r1.content - r2 = s.get(httpbin('user-agent')) + r2 = s.get(httpbin('user-agent')) assert heads['User-agent'] in r2.content + + new_heads = {'User-agent': 'blah'} + r3 = s.get(httpbin('user-agent'), headers=new_heads) + assert new_heads['User-agent'] in r3.content + self.assertEqual(r2.status_code, 200) From b37b977d205d8619b057d3e017083e42498692be Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Wed, 19 Oct 2011 01:30:45 -0400 Subject: [PATCH 28/28] v0.6.5 --- HISTORY.rst | 8 ++++---- requests/core.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index f2d49c3d..5f1b6a3a 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,11 +1,11 @@ History ------- -0.6.5 (?) -++++++++++ +0.6.5 (2011-10-19) +++++++++++++++++++ -* Offline (fast) test suite -* +* Offline (fast) test suite. +* Session dictionary argument merging. 0.6.4 (2011-10-13) diff --git a/requests/core.py b/requests/core.py index de05cf9f..9e518357 100644 --- a/requests/core.py +++ b/requests/core.py @@ -12,8 +12,8 @@ This module implements the main Requests system. """ __title__ = 'requests' -__version__ = '0.6.4' -__build__ = 0x000604 +__version__ = '0.6.5' +__build__ = 0x000605 __author__ = 'Kenneth Reitz' __license__ = 'ISC' __copyright__ = 'Copyright 2011 Kenneth Reitz'