Skip to content

Commit

Permalink
Prepare for 1.1.0 (#30)
Browse files Browse the repository at this point in the history
* refactor the view inspection process to be more modular and allow recursive customization
* add operation_id argument to @swagger_auto_
* add inspections for min/max validators
* add support for URLPathVersioning and NamespaceVersioning
* integrate with djangorestframework-camel-case
* fix bugs, improve tests and documentation
  • Loading branch information
axnsan12 committed Dec 26, 2017
1 parent 73adc49 commit c89f96f
Show file tree
Hide file tree
Showing 52 changed files with 2,086 additions and 773 deletions.
6 changes: 3 additions & 3 deletions .codecov.yml
Expand Up @@ -11,15 +11,15 @@ coverage:
default:
enabled: yes
target: auto
threshold: 0%
threshold: 100%
if_no_uploads: error
if_ci_failed: error

patch:
default:
enabled: yes
target: 80%
threshold: 0%
target: 100%
threshold: 100%
if_no_uploads: error
if_ci_failed: error

Expand Down
2 changes: 2 additions & 0 deletions .coveragerc
Expand Up @@ -17,6 +17,8 @@ exclude_lines =
raise TypeError
raise NotImplementedError
warnings.warn
logger.warning
return NotHandled

# Don't complain if non-runnable code isn't run:
if 0:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -156,3 +156,5 @@ com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

testproj/db\.sqlite3
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -40,6 +40,7 @@ after_success:
branches:
only:
- master
- /^release\/.*$/

notifications:
email:
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTING.rst
Expand Up @@ -43,6 +43,8 @@ You want to contribute some code? Great! Here are a few steps to get you started
.. code:: console
(venv) $ cd testproj
(venv) $ python manage.py migrate
(venv) $ cat createsuperuser.py | python manage.py shell
(venv) $ python manage.py runserver
(venv) $ curl localhost:8000/swagger.yaml
Expand Down
38 changes: 35 additions & 3 deletions README.rst
Expand Up @@ -141,6 +141,7 @@ This exposes 4 cached, validated and publicly available endpoints:
2. Configuration
================

---------------------------------
a. ``get_schema_view`` parameters
---------------------------------

Expand All @@ -153,6 +154,7 @@ a. ``get_schema_view`` parameters
- ``authentication_classes`` - authentication classes for the schema view itself
- ``permission_classes`` - permission classes for the schema view itself

-------------------------------
b. ``SchemaView`` options
-------------------------------

Expand All @@ -169,6 +171,7 @@ All of the first 3 methods take two optional arguments,
to Django’s :python:`cached_page` decorator in order to enable caching on the
resulting view. See `3. Caching`_.

----------------------------------------------
c. ``SWAGGER_SETTINGS`` and ``REDOC_SETTINGS``
----------------------------------------------

Expand All @@ -178,6 +181,26 @@ The possible settings and their default values are as follows:
.. code:: python
SWAGGER_SETTINGS = {
# default inspector classes, see advanced documentation
'DEFAULT_AUTO_SCHEMA_CLASS': 'drf_yasg.inspectors.SwaggerAutoSchema',
'DEFAULT_FIELD_INSPECTORS': [
'drf_yasg.inspectors.CamelCaseJSONFilter',
'drf_yasg.inspectors.ReferencingSerializerInspector',
'drf_yasg.inspectors.RelatedFieldInspector',
'drf_yasg.inspectors.ChoiceFieldInspector',
'drf_yasg.inspectors.FileFieldInspector',
'drf_yasg.inspectors.DictFieldInspector',
'drf_yasg.inspectors.SimpleFieldInspector',
'drf_yasg.inspectors.StringDefaultFieldInspector',
],
'DEFAULT_FILTER_INSPECTORS': [
'drf_yasg.inspectors.CoreAPICompatInspector',
],
'DEFAULT_PAGINATOR_INSPECTORS': [
'drf_yasg.inspectors.DjangoRestResponsePagination',
'drf_yasg.inspectors.CoreAPICompatInspector',
],
'USE_SESSION_AUTH': True, # add Django Login and Django Logout buttons, CSRF token to swagger UI page
'LOGIN_URL': getattr(django.conf.settings, 'LOGIN_URL', None), # URL for the login button
'LOGOUT_URL': getattr(django.conf.settings, 'LOGOUT_URL', None), # URL for the logout button
Expand Down Expand Up @@ -241,6 +264,7 @@ Caching can mitigate the speed impact of validation.
The provided validation will catch syntactic errors, but more subtle violations of the spec might slip by them. To
ensure compatibility with code generation tools, it is recommended to also employ one or more of the following methods:

-------------------------------
``swagger-ui`` validation badge
-------------------------------

Expand Down Expand Up @@ -271,6 +295,7 @@ If your schema is not accessible from the internet, you can run a local copy of
$ curl http://localhost:8189/debug?url=http://test.local:8002/swagger/?format=openapi
{}
---------------------
Using ``swagger-cli``
---------------------

Expand All @@ -283,6 +308,7 @@ https://www.npmjs.com/package/swagger-cli
$ swagger-cli validate http://test.local:8002/swagger.yaml
http://test.local:8002/swagger.yaml is valid
--------------------------------------------------------------
Manually on `editor.swagger.io <https://editor.swagger.io/>`__
--------------------------------------------------------------

Expand Down Expand Up @@ -345,10 +371,16 @@ named schemas.

Both projects are also currently unmantained.

Documentation, advanced usage
=============================
************************
Third-party integrations
************************

djangorestframework-camel-case
===============================

https://drf-yasg.readthedocs.io/en/latest/
Integration with `djangorestframework-camel-case <https://github.com/vbabiy/djangorestframework-camel-case>`_ is
provided out of the box - if you have ``djangorestframework-camel-case`` installed and your ``APIView`` uses
``CamelCaseJSONParser`` or ``CamelCaseJSONRenderer``, all property names will be converted to *camelCase* by default.

.. |travis| image:: https://img.shields.io/travis/axnsan12/drf-yasg/master.svg
:target: https://travis-ci.org/axnsan12/drf-yasg
Expand Down
18 changes: 18 additions & 0 deletions docs/_static/css/style.css
@@ -0,0 +1,18 @@
.versionadded, .versionchanged, .deprecated {
font-family: "Roboto", Corbel, Avenir, "Lucida Grande", "Lucida Sans", sans-serif;
padding: 10px 13px;
border: 1px solid rgb(137, 191, 4);
border-radius: 4px;
margin-bottom: 10px;
}

.versionmodified {
font-weight: bold;
display: block;
}

.versionadded p, .versionchanged p, .deprecated p,
/*override fucking !important by being more specific */
.rst-content dl .versionadded p, .rst-content dl .versionchanged p {
margin: 0 !important;
}
4 changes: 4 additions & 0 deletions docs/_templates/layout.html
@@ -0,0 +1,4 @@
{% extends "!layout.html" %}
{% block extrahead %}
<meta name="google-site-verification" content="saewLzcrUS1lAAgNVIikKWc3DUbFcE-TWtpyw3AW8CA" />
{% endblock %}
15 changes: 15 additions & 0 deletions docs/changelog.rst
Expand Up @@ -3,6 +3,21 @@ Changelog
#########


*********
**1.1.0**
*********

- **ADDED:** added support for APIs versioned with ``URLPathVersioning`` or ``NamespaceVersioning``
- **ADDED:** added ability to recursively customize schema generation
:ref:`using pluggable inspector classes <custom-spec-inspectors>`
- **ADDED:** added ``operation_id`` parameter to :func:`@swagger_auto_schema <.swagger_auto_schema>`
- **ADDED:** integration with `djangorestframework-camel-case
<https://github.com/vbabiy/djangorestframework-camel-case>`_ (:issue:`28`)
- **IMPROVED:** strings, arrays and integers will now have min/max validation attributes inferred from the
field-level validators
- **FIXED:** fixed a bug that caused ``title`` to never be generated for Schemas; ``title`` is now correctly
populated from the field's ``label`` property

*********
**1.0.6**
*********
Expand Down
47 changes: 44 additions & 3 deletions docs/conf.py
Expand Up @@ -3,6 +3,7 @@
#
# drf-yasg documentation build configuration file, created by
# sphinx-quickstart on Sun Dec 10 15:20:34 2017.
import inspect
import os
import re
import sys
Expand Down Expand Up @@ -68,9 +69,6 @@

modindex_common_prefix = ['drf_yasg.']

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False

# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
Expand Down Expand Up @@ -186,18 +184,23 @@
('py:obj', 'callable'),
('py:obj', 'type'),
('py:obj', 'OrderedDict'),
('py:obj', 'None'),

('py:obj', 'coreapi.Field'),
('py:obj', 'BaseFilterBackend'),
('py:obj', 'BasePagination'),
('py:obj', 'Request'),
('py:obj', 'rest_framework.request.Request'),
('py:obj', 'rest_framework.serializers.Field'),
('py:obj', 'serializers.Field'),
('py:obj', 'serializers.BaseSerializer'),
('py:obj', 'Serializer'),
('py:obj', 'BaseSerializer'),
('py:obj', 'APIView'),
]

# TODO: inheritance aliases in sphinx 1.7

# even though the package should be already installed, the sphinx build on RTD
# for some reason needs the sources dir to be in the path in order for viewcode to work
sys.path.insert(0, os.path.abspath('../src'))
Expand All @@ -215,6 +218,40 @@

drf_yasg.views.SchemaView = drf_yasg.views.get_schema_view(None)

# monkey patch to stop sphinx from trying to find classes by their real location instead of the
# top-level __init__ alias; this allows us to document only `drf_yasg.inspectors` and avoid broken references or
# double documenting

import drf_yasg.inspectors # noqa: E402


def redirect_cls(cls):
if cls.__module__.startswith('drf_yasg.inspectors'):
return getattr(drf_yasg.inspectors, cls.__name__)
return cls


for cls_name in drf_yasg.inspectors.__all__:
# first pass - replace all classes' module with the top level module
real_cls = getattr(drf_yasg.inspectors, cls_name)
if not inspect.isclass(real_cls):
continue

patched_dict = dict(real_cls.__dict__)
patched_dict.update({'__module__': 'drf_yasg.inspectors'})
patched_cls = type(cls_name, real_cls.__bases__, patched_dict)
setattr(drf_yasg.inspectors, cls_name, patched_cls)

for cls_name in drf_yasg.inspectors.__all__:
# second pass - replace the inheritance bases for all classes to point to the new clean classes
real_cls = getattr(drf_yasg.inspectors, cls_name)
if not inspect.isclass(real_cls):
continue

patched_bases = tuple(redirect_cls(base) for base in real_cls.__bases__)
patched_cls = type(cls_name, patched_bases, dict(real_cls.__dict__))
setattr(drf_yasg.inspectors, cls_name, patched_cls)

# custom interpreted role for linking to GitHub issues and pull requests
# use as :issue:`14` or :pr:`17`
gh_issue_uri = "https://github.com/axnsan12/drf-yasg/issues/{}"
Expand Down Expand Up @@ -273,3 +310,7 @@ def role_github_pull_request_or_issue(name, rawtext, text, lineno, inliner, opti
roles.register_local_role('pr', role_github_pull_request_or_issue)
roles.register_local_role('issue', role_github_pull_request_or_issue)
roles.register_local_role('ghuser', role_github_user)


def setup(app):
app.add_stylesheet('css/style.css')

0 comments on commit c89f96f

Please sign in to comment.