Giter Club home page Giter Club logo

drf_openapi's Introduction

DRF OpenAPI

Documentation Status Updates Join the chat at https://gitter.im/drf_openapi/Lobby

DEPRECATION NOTICE This project is deprecated in favour of https://github.com/axnsan12/drf-yasg/ or if you can wait https://github.com/encode/django-rest-framework/commit/e5781440fa6ccff09abc6e0566bdfdd9b84a80a1 :) :) :)

Generates OpenAPI-compatible schema from API made with Django Rest Framework. Use ReDoc as default interface instead of Swagger. First-class support for API versioning changelog & method-specific schema definition.

https://raw.githubusercontent.com/limdauto/drf_openapi/master/images/screenshot.png

Django Rest Framework has an API schema generation/declaration mechanism provided by coreapi standard. There are a couple of problems with the current ecosystem:

  • CoreAPI is not compatible out of the box with OpenAPI which is a much more popular API standard with superior tooling support, i.e. Swagger et. al.
  • The OpenAPI codec (compatibility layer) that CoreAPI team provides drops / doesn't support a number of useful OpenAPI features.
  • There is no support for versioning or method-specific schema.

This project was born to bridge the gap between DRF and OpenAPI. The high-level requirements are as followed:

  • Can be dropped into any existing DRF project without any code change necessary.
  • Provide clear disctinction between request schema and response schema.
  • Provide a versioning mechanism for each schema. Support defining schema by version range syntax, e.g. >1.0, <=2.0
  • Support multiple response codes, not just 200
  • All this information should be bound to view methods, not view classes.

It's important to stress the non-intrusiveness requirement, not least because I want to minimize what I will have to change when DRF itself decides to support OpenAPI officially, if at all.

  • Schema are automatically generated from serializers
    • From here onwards, schema and serializer are used interchangably
  • Versioned schema is supported by extending VersionedSerializers.
  • Metadata, i.e. versioning, response and request schema, are bound to a view method through the view_config decorator.
  • Extra schema information such as response status codes and their descriptions are bound to the serializer Meta class
  • Automatic response validation is optionally provided view_config(response_serializer=FooSerializer, validate_response=True)

Currently DRF OpenAPI only supports DRF project that has versioning enabled. I have only tested URLPathVersioning but I intend to suppor the full range of versioning scheme supported by DRF.

Please read the docs for a quickstart.

Also I have recreated the example in DRF tutorial with OpenAPI schema enabled in examples/.

MIT

drf_openapi's People

Contributors

gitter-badger avatar limdauto avatar pyup-bot avatar sloria avatar tuffnatty avatar werwty avatar yihengli 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  avatar  avatar  avatar  avatar  avatar  avatar

drf_openapi's Issues

Usage with GenericViewSet

  • DRF OpenAPI version: master
  • Python version: 3.6
  • Operating System: Linux

Description

I use GenericViewSet do define my views, therefore I am not able to use decorators.
Is there a way to achieve that currently or it needs some implementation ?

Nested serializer fields aren't described in the request body

  • DRF OpenAPI version: 1.3.0
  • Python version: 3.6.2
  • Operating System: Ubuntu 16.04

Description

If main serializer has any nested serializers except ListSerializer (it's handled correctly), fields of this sub-serializers doesn't shown on html page with api description.

What I Did

class PersonSerializer(serializers.Serializer):
    first_name = serializers.CharField()
    last_name = serializers.CharField()

class DocumentSerializer(serializers.Serializer):
    doc_type= serializers.IntegerField()
    number = serializers.CharField()

class CheckDocRequestSerializer(serializers.Serializer):
    person = PersonSerializer()
    documents = serializers.ListField(child=DocumentSerializer())

Main serializer is CheckDocRequestSerializer and in this case fields doc_type, number will be shown for DocumentSerializer but PersonSerializer will be described as object without any sub-elements.

"Request example":

{
  "person": {},
  "documents": [
    {
      "doc_type": 0,
      "number": "string"
    }
  ]
}

Support other versioning schemes

  • DRF OpenAPI version: master
  • Python version: 3.6.3
  • Operating System: Alpine Linux

Description

Tried using this with my setup which uses HostNameVersioning instead of URLPathVersioning and it breaks (obviously). Are there any plans to support different versioning schemes?

The error was raised in templates/drf_openapi/index.html:15:

Reverse for 'api_schema' with keyword arguments '{'version': 'v1'}' not found. 1 pattern(s) tried: ['docs\\/schema/$']

Proxy label can't be decoded

File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/drf_openapi/entities.py", line 298, in fallback_schema_from_field
title = force_text(field.label) if field.label else ''
File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/coreapi/compat.py", line 50, in force_text
return string.decode('utf-8')
AttributeError: 'proxy' object has no attribute 'decode'

python3 str no decode

Deal with custom permissions

  • DRF OpenAPI version: 0.9.7
  • Python version: 3.5
  • Operating System: Linux

Description

My views use custom permission to control users access but I want to allow everyone to see the schema/doc. How do I configure drf_openapi to override views permission in schema generation ?

Thanks for this nice lib !

Feature implementation: Deep request serializer & different serializers for specific response codes

  • DRF OpenAPI version: based on 1.0.0
  • Python version: *
  • Operating System: *

Description

I extended the drf_openapi Django app to support detailed request serializers for requests. Then I also needed different serializers for different status codes (e.g. 200 has a specific response and some error, maybe 503 has a completely different one).
This is already done, but I am not sure if this is compatible to the OpenAPI spec.
If you are interested in this feature, then I would fork this and create a pull request.

What I Did

Implemented the above functionality.
The drf_openapi module searches automatically for the correct serializer depending on the response code of the views' method.
Here are some screenshots of the extended usage:
image
image

Here is the django code for defining the views' serializers:

@view_config(request_serializer=UserLoginSerializer,
                 response_serializer={
                     200: (UserLoginResponseSerializer, 'Success'),
                     423: (UserLoginFailedResponseSerializer, 'Device not yet verified'),
                     400: (NoValidation, 'Bad Request - Invalid data given')
                 },
                 validate_response=True)
    def create(self, request, *args, **kwargs):
        """
        The user wants to authenticate against the backend and receives a token and his/her user ID on success.
        """
        ..... the views' code .....
        .....
        if something_went_wrong:
            return Response({'message': _('Verify device - email sent'), 'activation_id': device_activation_pin.pk},
                            status=status.HTTP_423_LOCKED)
        .....
        return Response({'message': _('logged in'), 'token': token.key, 'user_id': user.pk,
                         'created': token.created, 'device_id': device.pk},
                        status=status.HTTP_200_OK)

The "NoValidation" class passed as a serializer deactivates response validation for the specific response code.

Oauth2 token authentication not recognized

  • DRF OpenAPI version: newest
  • Python version: 3.6

I try to get a schema documentation for my django-oauth2-toolkit oauth2 authenticated app. DRF Open Api doesn't recognize the oauth2 token authentication but recognizes it as the Basic Django authentication. I need a proper schema.json file

These are my DRF settings:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
        # 'rest_framework.authentication.SessionAuthentication',
    ],
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    'DEFAULT_VERSION': '0.1',
    'ALLOWED_VERSIONS': ['0.1'],
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100,
}

What did I do wrong or does DRF Open API just not recognize oauth2? How could I solve this?

Compatibility issue with 'django-rest-auth' package

  • DRF OpenAPI version: 1.0 (installed from pypi)
  • Python version: 2.7
  • Operating System: macOS Sierra 10.12.4

Description

When enabling 'django-rest-auth' package (v0.9.1) with drf, drf_openapi UI cannot be rendered and throw a Traceback to console.

What I Did

2017-10-05 15:50:05,213 [ERROR  ] django.request - Internal Server Error: /v1/schema/
Traceback (most recent call last):
  File "/Users/blake/service/venv/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/blake/service/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 217, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/blake/service/venv/lib/python2.7/site-packages/channels/handler.py", line 243, in process_exception_by_middleware
    return super(AsgiHandler, self).process_exception_by_middleware(exception, request)
  File "/Users/blake/service/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 215, in _get_response
    response = response.render()
  File "/Users/blake/service/venv/lib/python2.7/site-packages/django/template/response.py", line 107, in render
    self.content = self.rendered_content
  File "/Users/blake/service/venv/lib/python2.7/site-packages/rest_framework/response.py", line 72, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "/Users/blake/service/drf_openapi/codec.py", line 113, in render
    return OpenAPICodec().encode(data, extra=extra)
  File "/Users/blake/service/drf_openapi/codec.py", line 103, in encode
    return force_bytes(json.dumps(data))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 243, in dumps
    return _default_encoder.encode(obj)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: u'Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.' is not JSON serializable
  1. Install 'django-rest-auth' package and enable it in the urls.py
  2. Login as superuser via Django Admin Console
  3. Back to drf_openapi UI and the page will not be rendered, error message is shown as above.

ImportError: No module named generators

  • DRF OpenAPI version: 1.3.0
  • DRF version: 3.6.4
  • Python version: 2.7
  • Operating System: Ubuntu 16.04 (Docker) and MacOS

Description

I tried to add drf_openapi to an existing project.

What I Did

I have added drf-openapi==1.3.0 to my requirements.txt and installed it. I've added 'drf_openapi', to INSTALLED_APPS and url(r'^/docs/', include('drf_openapi.urls')) to the urlpatterns.

When starting the Docker image (or just runserver locally) this results in the following error:

 File "/usr/local/lib/python2.7/dist-packages/drf_openapi/views.py", line 7, in <module>
   from drf_openapi.entities import OpenApiSchemaGenerator
 File "/usr/local/lib/python2.7/dist-packages/drf_openapi/entities.py", line 16, in <module>
   from rest_framework.schemas.generators import insert_into, distribute_links, LinkNode
ImportError: No module named generators

If it makes any difference our DEFAULT_VERSIONING_CLASS is set to AcceptHeaderVersioning.

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning',
    'DEFAULT_VERSION': API_VERSION,
}

Obviously I'm missing something out in the open here. The default documentation in DRF does work for us.

NameError: name 'API_PREFIX' is not defined // Incomplete Quickstart

The "quickstart" example in the docs is incomplete. Running it as described with a fresh DRF and fresh drf_openapi will give:

NameError: name 'API_PREFIX' is not defined

Fixing that then gives:

NameError: name 'include' is not defined

The Quickstart example should be updated to include everything necessary to actually run drf_openapi (ex, API_PREFIX='blah', from django.conf.urls import url, include)

AttributeError: 'ManyToOneRel' object has no attribute 'verbose_name'

  • DRF OpenAPI version: master
  • Python version: 3.6.4
  • Operating System: MacOS

Description

Open docs

What I Did

Just open docs url in browser

AttributeError at /api/schema/
'ManyToOneRel' object has no attribute 'verbose_name'

Request Method: GET
Request URL: http://localhost:8000/api/schema/
Django Version: 2.0.2
Python Executable: /Users/roman/virtualenvs/project/bin/python
Python Version: 3.6.4

Traceback:

File "/Users/roman/virtualenvs/project/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  35.             response = get_response(request)

File "/Users/roman/virtualenvs/project/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "/Users/roman/virtualenvs/project/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/roman/virtualenvs/project/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/Users/roman/virtualenvs/project/lib/python3.6/site-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)

File "/Users/roman/virtualenvs/project/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  494.             response = self.handle_exception(exc)

File "/Users/roman/virtualenvs/project/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
  454.             self.raise_uncaught_exception(exc)

File "/Users/roman/virtualenvs/project/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  491.             response = handler(request, *args, **kwargs)

File "/Users/roman/work/drf_openapi/drf_openapi/views.py" in get
  22.         return response.Response(generator.get_schema(request))

File "/Users/roman/work/drf_openapi/drf_openapi/entities.py" in get_schema
  96.         links = self.get_links(None if public else request)

File "/Users/roman/work/drf_openapi/drf_openapi/entities.py" in get_links
  137.             link = self.get_link(path, method, view, version=getattr(request, 'version', None))

File "/Users/roman/work/drf_openapi/drf_openapi/entities.py" in get_link
  159.         fields = self.get_path_fields(path, method, view)

File "/Users/roman/work/drf_openapi/drf_openapi/entities.py" in get_path_fields
  255.                 if model_field is not None and model_field.verbose_name:

Exception Type: AttributeError at /api/schema/
Exception Value: 'ManyToOneRel' object has no attribute 'verbose_name'

Showing write_only field in GET method when it should show only POST method.

  • DRF OpenAPI version: 1.0.0
  • Python version: 3.6.3
  • Operating System: OS X

Description

I have a serializer which has a write_only field and it is appearing to GET method.

models.py

class Template(models.Model):
    name = models.CharField(
        verbose_name=_('Name'), max_length=200, blank=False, null=False, unique=True,
        help_text=_('A string describing the template name.'))
    user = models.ForeignKey(
        User, verbose_name=_('User'), blank=True,
        null=True, related_name='templates')

serializers.py

class TemplateSerializer(serializers.ModelSerializer):

    class Meta:
        model = Template
        extra_kwargs = {'user': {'write_only': True}}
        fields = '__all__'

Current behavior

GET /api/templates

{
  "count": 0,
  "next": "string",
  "previous": "string",
  "results": [
    {
      "id": 0,
      "name": "string",
      "user": "string"
    }
  ]
}

Expected behavior

GET /api/templates

{
  "count": 0,
  "next": "string",
  "previous": "string",
  "results": [
    {
      "id": 0,
      "name": "string",
    }
  ]
}

This expected behavior is the real behavior of DRF but the drf_openapi hasn't this behavior.

Is there a way to drf_openapi to have the same behavior as drf?

Fails to import distribute_links

  • DRF OpenAPI version: 1.3.0
  • Python version: 3.5
  • Operating System: Linux
  • rest_framework version: 3.6.4

Description

I was attempted to run the quick start guide to use the drf openapi module. When I added the lines, first the example is for Python 3.6 only, and not compatible w/ previous versions, but it does not state the requirements. I expect that after applying the lines from quick start, that I would still have a working django project. I do not as I have an import error.

I expect that it would detect the version and give me a warning about incorrect or unsupported versions so that I can adjust as needed, or at least trace this down.

What I Did

# python manage.py runserver
Performing system checks...

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x7f5543adbae8>
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/site-packages/django/utils/autoreload.py", line 227, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
    self.check(display_num_errors=True)
  File "/usr/local/lib/python3.5/site-packages/django/core/management/base.py", line 359, in check
    include_deployment_checks=include_deployment_checks,
  File "/usr/local/lib/python3.5/site-packages/django/core/management/base.py", line 346, in _run_checks
    return checks.run_checks(**kwargs)
  File "/usr/local/lib/python3.5/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/usr/local/lib/python3.5/site-packages/django/core/checks/urls.py", line 16, in check_url_config
    return check_resolver(resolver)
  File "/usr/local/lib/python3.5/site-packages/django/core/checks/urls.py", line 26, in check_resolver
    return check_method()
  File "/usr/local/lib/python3.5/site-packages/django/urls/resolvers.py", line 254, in check
    for pattern in self.url_patterns:
  File "/usr/local/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.5/site-packages/django/urls/resolvers.py", line 405, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/usr/local/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.5/site-packages/django/urls/resolvers.py", line 398, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/local/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 665, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/app/api/urls.py", line 30, in <module>
    include('foo.urls')),
  File "/usr/local/lib/python3.5/site-packages/django/conf/urls/__init__.py", line 50, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/local/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 665, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/app/foo/urls.py", line 41, in <module>
    urlpatterns += [url(r'^', include('drf_openapi.urls'))]
  File "/usr/local/lib/python3.5/site-packages/django/conf/urls/__init__.py", line 50, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/local/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 665, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/usr/local/lib/python3.5/site-packages/drf_openapi/urls.py", line 3, in <module>
    from drf_openapi.views import SchemaView
  File "/usr/local/lib/python3.5/site-packages/drf_openapi/views.py", line 7, in <module>
    from drf_openapi.entities import OpenApiSchemaGenerator
  File "/usr/local/lib/python3.5/site-packages/drf_openapi/entities.py", line 16, in <module>
    from rest_framework.schemas.generators import insert_into, distribute_links, LinkNode
ImportError: cannot import name 'distribute_links'

Public access error

  • DRF OpenAPI version: 1.3.0
  • Python version: 3.6.3
  • Operating System: x86_64 GNU/Linux

Description

Can't access to SchemaView without being logged in, in spite of using AllowAny permissions.

The only way to be able to use this is to set public=True when using the generator, the working code is:

class SchemaView(APIView):
    renderer_classes = (CoreJSONRenderer, SwaggerUIRenderer, OpenAPIRenderer)
    permission_classes = (permissions.AllowAny, )
    url = ''
    title = 'API Documentation'

    def get(self, request, version):
        generator = OpenApiSchemaGenerator(
            version=version,
            url=self.url,
            title=self.title
        )
        return response.Response(generator.get_schema(request, public=True))

What I Did

The error traceback is:

TypeError: Expected a `coreapi.Document` instance
  File "django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 217, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "django/core/handlers/base.py", line 215, in _get_response
    response = response.render()
  File "django/template/response.py", line 107, in render
    self.content = self.rendered_content
  File "rest_framework/response.py", line 72, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "drf_openapi/codec.py", line 113, in render
    return OpenAPICodec().encode(data, extra=extra)
  File "drf_openapi/codec.py", line 97, in encode
    raise TypeError('Expected a `coreapi.Document` instance')

TypeError: issubclass() arg 1 must be a class

  • DRF OpenAPI version: 1.0.0
  • Python version: 3.4.3
  • Operating System: Ubuntu (vagrant VM)

Trying to access the URL of the rendered schema produces the following error:

Traceback (most recent call last):
  File "/home/ubuntu/virt/lib/python3.4/site-packages/django/core/handlers/exception.py", line 42, in inner
    response = get_response(request)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/rest_framework/views.py", line 483, in dispatch
    response = self.handle_exception(exc)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/rest_framework/views.py", line 443, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/rest_framework/views.py", line 480, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/rest_framework/decorators.py", line 52, in handler
    return func(*args, **kwargs)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/drf_openapi/views.py", line 22, in schema_view
    return response.Response(generator.get_schema(request))
  File "/home/ubuntu/virt/lib/python3.4/site-packages/drf_openapi/entities.py", line 93, in get_schema
    links = self.get_links(None if public else request)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/drf_openapi/entities.py", line 133, in get_links
    link = self.get_link(path, method, view, version=request.version)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/drf_openapi/entities.py", line 187, in get_link
    response_serializer_class)
  File "/home/ubuntu/virt/lib/python3.4/site-packages/drf_openapi/entities.py", line 214, in get_paginator_serializer
    if issubclass(pager, (PageNumberPagination, LimitOffsetPagination)):
TypeError: issubclass() arg 1 must be a class

String with 'f' prefix not work with python2.7 by run examples

  • DRF OpenAPI version: 1.0.0
  • Python version: 2.7.11
  • Operating System: windows

Description

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(f'{API_PREFIX}/schema/', MySchemaView.as_view(), name='api_schema'),
    url(f'{API_PREFIX}/snippets/', include('snippets.urls')),
]

String with 'f' prefix not work in python2.7

What I Did

python examples/manage.py runserver

API urls without versions

I know versioning your APIs is a good practice, but is there a way to use this library without putting a version in the URL, just like this:

url(r'^api/docs/', include('drf_openapi.urls')),

When using /api/<version>/ as API_PREFIX the navigation sidebar only shows one entry

  • DRF OpenAPI version: 1.0 (pypi)
  • Python version: 3.6
  • Operating System: Fedora 26

Description

I decided to use the URL schema /api/<version>/<app>/<view_name>/. Now the generated documentation does not list the apps in the navigation but only shows one entry called "API". When changing the schema to /api-<version>/<app>/<view_name>/ it is picked up and the navigation is generated properly.

Question: Is it even a good idea to use the URL to generate the documentation. The actual app name would be more useful, wouln't it. At least it would get rid of this problem.

Compare with django-rest-swagger

It will be better to compare this project with the django-rest-swagger in DOCS.
As for me, drf_openapi have killer feature: "generate the response schema from a serializer"

if you have time please take a look and update DOCS.

Failed to work on Viewset that doesn't have pagination_class

  • DRF OpenAPI version: v1.0.0
  • Python version: 3.6.2
  • Operating System: Mac 10.13.1

Description

drf-openapi doesn't work on Viewset with pagination_class=None and Viewset that doesn't have pageniation_class

What I Did

# Settings.py

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    'DEFAULT_PAGINATION_CLASS': None,
    'PAGE_SIZE': None
}

The following error occurs:

Exception Type: TypeError at /v1.0/schema/
Exception Value: issubclass() arg 1 must be a class

Possible Solution

Add the following codes in entities.py may solve this issue:

    def get_paginator_serializer(self, view, child_serializer_class):
        ...

        if not (hasattr(view, 'pagination_class')) or view.pagination_class is None:
            return BaseFakeListSerializer

        pager = view.pagination_class

        ...

Add to REST framework documentation.

This looks awesome! โœจ

A pull request to add it to the third party documentation packages would be a great idea. It should include a screenshot including the rather nice redoc theme.

You're welcome to list it as the first in that set of packages.

We probably also want a "Third party packages" section in our schema docs. - http://www.django-rest-framework.org/api-guide/schemas/

You could add this as an item there too, (tho use a shorter style without the screenshot there)

If you've not already done so it's also worth making sure to add it to the "REST framework" grid on the "django packages" site.

Nice work!!! ๐Ÿ˜Ž

Feature request: Adding sections to the head of a document

You might have already implemented this. but looking at the code and docs for both this package and django-rest-swagger, I can't tell if there Is an easy way to add sections to the head of the document, a la the Errors section in the Docker Engine docs.

Am I missing something obvious, or is this something that can't currently be done?

token authentication

  • DRF OpenAPI version: 0.9.9 (from source, the latest the version number haven't been changed)
  • Python version: 3.6
  • Operating System: linux

Description

When using token authentication, the api endpoint cannot be rendered, all my endpoint are protected by an IsAuthenticated and TokenAuthentication permissions. using sessions permissions it work well as soon as i am logged in (using swagger rendering) but I want to use token based authentication..

maybe is this an improvement to make ?

serializer_class must be specified even when using @view_config(request_serializer=...)

  • DRF OpenAPI version: 1.0 (installed from pypi)
  • Python version: 3.6
  • Operating System: Fedora 26

Description

When adding a view_config decorator to a APIView method the request_serializer parameter is ignored when viewing the schema. The only way to get the request body rendered is by adding a serializer_class to the APIView

What I Did

from django.conf.urls import url
from drf_openapi.utils import view_config
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework.response import Response

from . import serializers

class UploadView(APIView):
    serializer_class = serializers.UploadRequestSerializer # <---- should not be needed
    parser_classes = (FormParser, MultiPartParser)

    @view_config(
        request_serializer=serializers.UploadRequestSerializer,
        response_serializer=serializers.UploadResponseSerializer)
    def post(self, request, version, format=None):
        req = self.request_serializer(data=request.data)
        req.is_valid(raise_exception=True)
        upload = req.save()
        res = self.response_serializer(upload)
        return Response(res.data, status=status.HTTP_201_CREATED)

When leaving out the serializer_class no request body is shown in the schema. This is obviously a limitation when post and put do not use the same request serializer.

As the example in the documentation does not use the serializer_class I think this must be a bug: https://drf-openapi.readthedocs.io/en/latest/usage.html#add-schema-to-a-view-method

Can we customize the Sample Request and Response ?

  • DRF OpenAPI version: 1.3.0
  • Python version: 3.6
  • Operating System: osX

Description

I really like the right panel with the sample requests and responses.
I was wondering if we can customize it. Instead of having 'string', I would like to provide a default value. Couldn't find any documentation about it.
Thanks a lot !

ImportError: cannot import name '_get_field_description'

  • DRF OpenAPI version: 1.0.0
  • Python version: 3.5
  • Operating System: OSX

Description

Trying to implement DRF OpenAPI on a Python 3.5 django project.
Ran into error: ImportError: cannot import name '_get_field_description'
Requirements do not say anything about supported Python versions but I'm guessing now 3.6 is required.

EDIT:
Adding some additional version information:
openapi-codec==1.2.1
djangorestframework==3.5.3
django-rest-swagger==2.1.0

What I Did

Followed instructions as described.
Ran into trouble due to example using Python f-strings which are unsupported on Python 3.5 .
Attempted to correct example to supported Python 3.5.
Ran into the error.

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x107465a60>
Traceback (most recent call last):
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
    self.check(display_num_errors=True)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/core/management/base.py", line 374, in check
    include_deployment_checks=include_deployment_checks,
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/core/management/base.py", line 361, in _run_checks
    return checks.run_checks(**kwargs)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/core/checks/urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/core/checks/urls.py", line 24, in check_resolver
    for pattern in resolver.url_patterns:
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/urls/resolvers.py", line 313, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/django/urls/resolvers.py", line 306, in urlconf_module
    return import_module(self.urlconf_name)
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 665, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/Users/admin/Documents/GIT/workflows_service/workflows/urls.py", line 18, in <module>
    from drf_openapi import urls
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/drf_openapi/urls.py", line 3, in <module>
    from drf_openapi.views import SchemaView
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/drf_openapi/views.py", line 6, in <module>
    from drf_openapi.codec import OpenAPIRenderer, SwaggerUIRenderer
  File "/Users/admin/Documents/GIT/virtualenvs/workflows/lib/python3.5/site-packages/drf_openapi/codec.py", line 12, in <module>
    from openapi_codec.encode import _get_links, _get_field_description
ImportError: cannot import name '_get_field_description'

TypeError: Object of type '__proxy__' is not JSON serializable

  • drf-openapi==1.0.0
  • Python 3.6.1
  • Django==1.11.5
  • MacOSX

Description

Using ugettext_lazy inside Models break the Open API.

Traceback

Internal Server Error: /api/v1.0/docs/
Traceback (most recent call last):
  File "/Users/.../lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/.../lib/python3.6/site-packages/django/core/handlers/base.py", line 217, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/.../lib/python3.6/site-packages/django/core/handlers/base.py", line 215, in _get_response
    response = response.render()
  File "/Users/.../lib/python3.6/site-packages/django/template/response.py", line 107, in render
    self.content = self.rendered_content
  File "/Users/.../lib/python3.6/site-packages/rest_framework/response.py", line 72, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "/Users/.../lib/python3.6/site-packages/drf_openapi/codec.py", line 113, in render
    return OpenAPICodec().encode(data, extra=extra)
  File "/Users/.../lib/python3.6/site-packages/drf_openapi/codec.py", line 103, in encode
    return force_bytes(json.dumps(data))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type '__proxy__' is not JSON serializable

What I Did

Inside all my Models, i have set i18n strings using ugettext_lazy functional to translate it. If i use the ugettext instead of the lazy version, everything works fine.

from django.utils.translation import ugettext_lazy as _
from django.db import models

class MyModel(models.Model):
    title = models.CharField(
        verbose_name=_('Title'),
        max_length=200, blank=False, null=False,
        help_text=_('A string describing the MyModel title.'))

cc @fernandolins

Nested serializer on response schema

  • DRF OpenAPI version: 1.0.0
  • Python version: 3.6.3
  • Operating System: OS X

Description

I have a model which has two relationship with two different models one is a ForeignKey and the other is a ManyToMany.
The list view of this model shows only two depth levels, but I would like to see all depth levels or choose the level that I want passing depth=3 in class Meta

Current Behavior:

{
  "count": 0,
  "next": "string",
  "previous": "string",
  "results": [
    {
      "id": 0,
      "countries": [ ],
      "category": { },
      "title": "string",
      "description": "string"
    }
  ]
}

Expected behavior:

{
  "count": 0,
  "next": "string",
  "previous": "string",
  "results": [
    {
      "id": 0,
      "countries": [
        {
          "id": 0,
          "code": "string"
        }
      ],
      "category": {
        "id": 0,
        "name": "string"
      },
      "title": "string",
      "description": "string"
    }
  ]
}

Is there a way to do that? Or do you think it's may be a new feature?

Using the Django 2.0 path function for routes results in backslash escaped paths in OpenAPI output

  • DRF OpenAPI version: 1.1.0
  • Python version: 3.6.2
  • Operating System: macOS 10.13.1

Description

I updated some Django 1.x code to Django 2.0 and changed a number of url routes to the new-style path function ( https://docs.djangoproject.com/en/2.0/ref/urls/#path ). The Swagger HTML output and OpenAPI JSON (?format=openapi) output now contains 'backslash escaped' forward slashes, like /v2.0\/schema\/ instead of the expected /v2.0/schema/.

What I Did

You can reproduce the issue from the drf_openapi/example by changing urls.py to:

from django.urls import path, re_path
from django.conf.urls import include
from django.contrib import admin

from examples.views import MySchemaView

API_PREFIX = r'^(?P<version>[0-9]+\.[0-9]+)'

urlpatterns = [
    re_path(r'^admin/', admin.site.urls),
    path(f'<str:version>/schema/', MySchemaView.as_view(), name='api_schema'),
    re_path(f'{API_PREFIX}/snippets/', include('snippets.urls')),
]

This uses the new Django 2.x path function for routes as an example.

screen shot 2017-12-18 at 2 51 42 pm

Custom schema's on APIView classes are not picked up by the schema generation.

  • DRF OpenAPI version: 1.3
  • Python version: 3.6

Description

Custom schema's on APIView classes are not picked up by the schema generation.

What I Did

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    schema = AutoSchema(
        manual_fields=[
            coreapi.Field('fields', description='Which field(s) to show.'),
        ]
    )

The UserViewSet.schema is not picked up by the documentation. You would expect to have it show the "fields" parameter.

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.