Coder Social home page Coder Social logo

django-rest-framework-proxy's Introduction

Django Rest Framework Proxy

PyPI version Build Status Coverage Status

Provides views to redirect incoming request to another API server.

Features:

  • Masquerade paths
  • HTTP Basic Auth (between your API and backend API)
  • Token Auth
  • Supported methods: GET/POST/PUT/PATCH
  • File uploads

TODO:

  • Pass auth information from original client to backend API

#Installation#

$ pip install django-rest-framework-proxy

#Usage# There are couple of ways to use proxies. You can either use provided views as is or subclass them.

Settings

# settings.py
REST_PROXY = {
    'HOST': 'https://api.example.com',
    'AUTH': {
        'user': 'myuser',
        'password': 'mypassword',
        # Or alternatively:
        'token': 'Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b',
    },
}

Simple way

# urls.py
from rest_framework_proxy.views import ProxyView

# Basic
url(r'^item/$', ProxyView.as_view(source='items/'), name='item-list'),

# With captured URL parameters
url(r'^item/(?P<pk>[0-9]+)$', ProxyView.as_view(source='items/%(pk)s'), name='item-detail'),

Complex way

# views.py
from rest_framework_proxy.views import ProxyView

class ItemListProxy(ProxyView):
  """
  List of items
  """
  source = 'items/'

class ItemDetailProxy(ProxyView):
  """
  Item detail
  """
  source = 'items/%(pk)s'
# urls.py
from views import ProxyListView, ProxyDetailView

url(r'^item/$', ProxyListView.as_view(), name='item-list'),
url(r'^item/(?P<pk>[0-9]+)$', ProxyDetailView.as_view(), name='item-detail'),

Settings

Setting Default Comment
HOST None Proxy request to this host (e.g. https://example.com/api/).
AUTH {'user': None, 'password': None, 'token': None} Proxy requests using HTTP Basic or Token Authentication. Token is only used if user & password are not provided.
TIMEOUT None Timeout value for proxy requests.
ACCEPT_MAPS {'text/html': 'application/json'} Modify Accept-headers before proxying them. You can use this to disallow certain types. By default text/html is translated to return JSON data.
DISALLOWED_PARAMS ('format',) Remove defined query parameters from proxy request.

SSL Verification

By default, django-rest-framework-proxy will verify the SSL certificates when proxying requests, defaulting to security. In some cases, it may be desirable to not verify SSL certificates. This setting can be modified by overriding the VERIFY_SSL value in the REST_PROXY settings.

Additionally, one may set the verify_proxy settings on their proxy class:

# views.py
from rest_framework_proxy.views import ProxyView

class ItemListProxy(ProxyView):
  """
  List of items
  """
  source = 'items/'
  verify_ssl = False

Finally, if there is complex business logic needed to determine if one should verify SSL, then you can override the get_verify_ssl() method on your proxy view class:

# views.py
from rest_framework_proxy.views import ProxyView

class ItemListProxy(ProxyView):
  """
  List of items
  """
  source = 'items/'

  def get_verify_ssl(self, request):
    host = self.get_proxy_host(request)
    if host.startswith('intranet.'):
      return True
    return False

Permissions

You can limit access by using Permission classes and custom Views. See http://django-rest-framework.org/api-guide/permissions.html for more information

# permissions.py
from rest_framework.permissions import BasePermission, SAFE_METHODS

class AdminOrReadOnly(BasePermission):
    """
    Read permission for everyone. Only admins can modify content.
    """
    def has_permission(self, request, view, obj=None):
        if (request.method in SAFE_METHODS or
            request.user and request.user.is_staff):
            return True
        return False
# views.py
from rest_framework_proxy.views import ProxyView
from permissions import AdminOrReadOnly

class ItemListProxy(ProxyView):
    permission_classes = (AdminOrReadOnly,)

#License#

Copyright (c) 2014, Tomi Pajunen All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

django-rest-framework-proxy's People

Contributors

ashchristopher avatar eofs avatar jbkahn avatar jfilipe avatar m3brown avatar mmasashi avatar piotr-szachewicz avatar pistolero avatar smileychris avatar weeliat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-rest-framework-proxy's Issues

MultiPart, file, got error "TypeError: sequence item 0: expected a bytes-like object, str found"

Hi there.
Are you testing file proxying?

I'm faced with this error.
I'm little diving in the problem, and found this place:
rest_framework_proxy/utils.py:61

return b'\r\n'.join(output)

Maybe I don't understand something, but output contains strings => we got this error.

P.S. Also, there is something strange with package releases. In pypi actual version 1.6, but in this repo I see 1.4 as latest.

Abandoned project

Taking into consideration of the activity in this project, it does seem abandoned to me.

There is an alternative to it?

Release python 3 auth fix on PyPI

Current PyPI version 1.6.0 is broken when using "AUTH" on python 3. This was fixed when #16 was merged to master, but it was not yet released.

In the mean time I'm using following workaround to get it working under python 3:

setup(
    ...
    install_requires=[
        ...
        'django-rest-framework-proxy >= 1.6.0',
        ...
    ],
    dependency_links=[
        'git+ssh://[email protected]/eofs/django-rest-framework-proxy.git'
        '@624823b4#egg=django-rest-framework-proxy-1.6.0',
    ],
)

Cannot import name 'six' from 'django.utils'

File "/usr/local/lib/python3.7/site-packages/rest_framework_proxy/views.py", line 5, in <module>
backend-dataportal-backend-1  |     from django.utils import six
backend-dataportal-backend-1  | ImportError: cannot import name 'six' from 'django.utils'

GET parameters are not being send in Python3

I was forced to rewrote get_request_params method to:

    def get_request_params(self, request):
        """
        Fixing returning DICT
        :param request:
        :return:
        """
        if request.query_params:
            qp = request.query_params.copy()
            for param in self.proxy_settings.DISALLOWED_PARAMS:
                if param in qp:
                    del qp[param]
            # was return six.iterlists(qp)
            return qp
        return {}

Unable to proxy binary responses like images

We are trying to proxy a third-party image service and we need the proxy library to respond with the raw binary payload it received from the service. Even after setting the 'return_raw' flag, the payload is converted to text before further responding.

It works when I change response.text to response.content on the marked line.

return HttpResponse(response.text, status=response.status_code,

request.QUERY_PARAMS and request.DATA deprecated

Installed without previously having django-rest-framework installed, this pulled in the latest version (3.2.4). This gave errors about request.QUERY_PARAMS and request.DATA being deprecated.

I checked the code, and replacing your calls to these functions with lowercase names seems to work.
request.QUERY_PARAMS -> request.query_params
request.DATA -> request.data

I would send you a pull request, but I don't quite understand what you are doing here, and I don't want to break some logic going on:
return request.DATA if request.DATA else request.data

The earliest relase that works with the lowercase names seems to be 3.0.1, if you want to update the requirements.

No_content responce parsing incorrectly

NO_CONTENT_204 response has no content. There is no need to call function self.parse_proxy_response(response) in that case, just return Response(status=204).

Add the ability to pass through cookies?

In order to interface this with a system that uses headers for auth and a system that uses cookies for auth I had to copy the definition of proxy into the View we are inheriting from and modify it so that it had something like:

def proxy(self, request, *args, **kwargs):
    # top of function
    cookies = self.get_request_cookies(request)
    # wrapped try/except call
    request(
        request.method
        url,
        params=params,
        data=body,
        headers=headers
        timeout=self.proxy_settings.TIMEOUT,
        verify=verify_ssl,
        cookies=cookies
    )
def get_request_cookies(self, request):
    return None

And then I just override get_request_cookies in the view.

Is there a style/way that I could add the ability to send cookies through? I'd be happy to write the code. Currently, I don't want to send a cookie from the original request, but I want to attach a cookie to be sent to the proxy host. I'm not sure what this package should do by default if the ability to specify cookies is added.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.