Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SEO_JS_PRERENDER_TIMEOUT functionality #22

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ denisvlr - https://github.com/denisvlr
mattrobenolt - https://github.com/mattrobenolt
thoop - https://github.com/thoop
rchrd2 - https://github.com/rchrd2
chazcb - https://github.com/chazcb
chazcb - https://github.com/chazcb
clifff - https://github.com/clifff
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ To use [prerender.io](http://prerender.io),
```python
# Prerender.io token
SEO_JS_PRERENDER_TOKEN = "123456789abcdefghijkl"

# Optional timeout option (following requests timeout format)
SEO_JS_PRERENDER_TIMEOUT = (5,5)
```

You don't need to set `SEO_JS_BACKEND`, since it defaults to `"django_seo_js.backends.PrerenderIO"`.
Expand Down
5 changes: 5 additions & 0 deletions django_seo_js/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,8 @@ def build_django_response_from_requests_response(self, response):
r['content-length'] = len(response.content)
r.status_code = response.status_code
return r

def build_request_timeout_response(self):
r = HttpResponse()
r.status_code = 408
return r
19 changes: 16 additions & 3 deletions django_seo_js/backends/prerender.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django_seo_js import settings
from base import SEOBackendBase, RequestsBasedBackend
import requests


class PrerenderIO(SEOBackendBase, RequestsBasedBackend):
Expand All @@ -16,6 +17,11 @@ def _get_token(self):
raise ValueError("Missing SEO_JS_PRERENDER_TOKEN in settings.")
return settings.PRERENDER_TOKEN

def _request_kwargs(self, kwargs):
if settings.PRERENDER_TIMEOUT is not False:
kwargs['timeout'] = settings.PRERENDER_TIMEOUT
return kwargs

def get_response_for_url(self, url):
"""
Accepts a fully-qualified url.
Expand All @@ -29,10 +35,17 @@ def get_response_for_url(self, url):
headers = {
'X-Prerender-Token': self.token,
}
r = self.session.get(render_url, headers=headers, allow_redirects=False)
assert r.status_code < 500
get_options = {
'headers': headers,
'allow_redirects': False
}

return self.build_django_response_from_requests_response(r)
try:
r = self.session.get(render_url, **self._request_kwargs(get_options))
assert r.status_code < 500
return self.build_django_response_from_requests_response(r)
except requests.exceptions.Timeout:
return self.build_request_timeout_response()

def update_url(self, url=None, regex=None):
"""
Expand Down
1 change: 1 addition & 0 deletions django_seo_js/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@
BACKEND = getattr(django_settings, 'SEO_JS_BACKEND', 'django_seo_js.backends.PrerenderIO')

PRERENDER_TOKEN = getattr(django_settings, 'SEO_JS_PRERENDER_TOKEN', None)
PRERENDER_TIMEOUT = getattr(django_settings, 'SEO_JS_PRERENDER_TIMEOUT', False)
PRERENDER_URL = getattr(django_settings, 'SEO_JS_PRERENDER_URL', None)
PRERENDER_RECACHE_URL = getattr(django_settings, 'SEO_JS_PRERENDER_RECACHE_URL', None)
19 changes: 19 additions & 0 deletions django_seo_js/tests/backends/test_prerender_io.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from django.test import TestCase
from httmock import all_requests, HTTMock
from mock import MagicMock
import requests

from django_seo_js.tests.utils import override_settings
from django_seo_js.backends import PrerenderIO
Expand Down Expand Up @@ -43,6 +45,23 @@ def test_get_token(self):
self.assertEqual(self.backend.token, "123124341adfsaf")


class PrerenderTimeout(TestCase):

@override_settings(PRERENDER_TIMEOUT=5)
def test_timeout_setting(self):
self.backend = PrerenderIO()
self.assertEqual(self.backend._request_kwargs({}), {'timeout': 5})

@override_settings(PRERENDER_TIMEOUT=5)
def test_timeout_response(self):
self.backend = PrerenderIO()
self.backend.session.get = MagicMock(
side_effect=requests.exceptions.Timeout()
)
resp = self.backend.get_response_for_url("http://www.example.com")
self.assertEqual(resp.status_code, 408)


class PrerenderIOTestMethods(TestCase):

def setUp(self):
Expand Down