Created
July 29, 2016 17:47
-
-
Save ninapavlich/b299b8ea1320ec4a4ad8d8f65ad9f079 to your computer and use it in GitHub Desktop.
Optimized proxy view for Django
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf import settings | |
from django.conf.urls import patterns, url, include | |
from django.conf.urls import patterns | |
from django.views.decorators.csrf import csrf_exempt | |
from .views cached_api_proxy_view | |
urlpatterns = patterns('') | |
urlpatterns += patterns('', | |
url('proxy/(?P<path>.*)', csrf_exempt(cached_api_proxy_view)), | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf import settings | |
from django.core.cache import cache | |
from django.core.urlresolvers import resolve | |
#NOTE -- this requires django-proxy==1.0.2 | |
from proxy.views import proxy_view | |
def cached_api_proxy_view(request, path): | |
""" | |
This function handles caching logic for the proxy | |
""" | |
cache_eligible = is_proxy_cache_eligible(request, path) | |
if cache_eligible: | |
cachekey = get_proxy_cache_key(request, path) | |
response = cache.get( cachekey ) | |
if not response: | |
response = api_proxy_view(request, path) | |
""" | |
Only cache it if it was successful, no one wants broken things | |
""" | |
if( response.status_code == 200 ): | |
cache.set( cachekey, response, get_proxy_cache_duration(request, path) ) | |
else: | |
response = api_proxy_view(request, path) | |
return response | |
def api_proxy_view(request, path): | |
""" | |
This function handles executing the actual proxy | |
""" | |
if is_internal_view(request, path): | |
view, args, kwargs = resolve("/"+path) | |
kwargs['request'] = request | |
request.GET = request.GET.copy() | |
request.GET.update(get_extra_params(request, path)) | |
return view(*args, **kwargs) | |
else: | |
extra_requests_args = { | |
'params':get_extra_params(request, path) | |
} | |
return proxy_view(request, get_remote_url(request, path), extra_requests_args) | |
def is_proxy_cache_eligible(request, path): | |
#Override this logic! | |
""" | |
Typically we don't want to cache a POST method, but there may be other | |
custom view you don't want to cache either. | |
""" | |
if request.method == "GET": | |
return True | |
else: | |
return False | |
def get_proxy_cache_key(request, path): | |
#Override this logic! | |
""" | |
If GET variables return custom content, then include them in the cache key: | |
""" | |
full_path = "%s?%s"%(path, request.GET.urlencode()) | |
""" | |
If users get user-specific content, then you can include the user's session | |
key in the cache key. This obviously creates a lot more cache entries, so | |
use carefully. | |
""" | |
return 'proxy-view-%s-for-%s'%(full_path, request.session._session_key) | |
def get_extra_params(request, path): | |
#Override this logic! | |
if request.user.is_authenticated(): | |
username = request.user.username | |
return { | |
"api_key" : request.user.api_key.key, | |
"username" : request.user.username | |
} | |
else: | |
return {} | |
def is_internal_view(request, path): | |
#Override this logic! | |
return True | |
def get_remote_url(request, path): | |
#Override this logic! | |
return settings.PROXY_HOST+'/'+path | |
def get_proxy_cache_duration(request, path): | |
#Override this logic! | |
return settings.CACHE_API_SECONDS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment