Test with Django 2.1 and Python 3.7 (#176)

* Test with Django 2.1 and Python 3.7
* Fix lint errors
* Remove setuptools-scm hack
* Factor out coverage script
* Cache .tox in travis
* Update README & docs
openapi3
Cristi Vîjdea 2018-08-06 12:24:56 +03:00 committed by GitHub
parent 904895ba3c
commit 16b6ed7fd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 82 additions and 107 deletions

View File

@ -1,24 +1,30 @@
language: python language: python
cache: pip sudo: false
python: python:
- '2.7'
- '3.4' - '3.4'
- '3.5' - '3.5'
- '3.6' - '3.6'
env: cache:
- DRF=3.7 directories:
- DRF=3.8 - $HOME/.cache/pip
- .tox
before_cache:
- rm -f $HOME/.cache/pip/log/debug.log
- rm -fr .tox/log/ .tox/*/log/ .tox/*/tmp/ .tox/dist .tox/*/lib/*/site-packages/drf_yasg*
jobs: jobs:
include: include:
- stage: test - # workaround for python 3.7 on travis https://github.com/travis-ci/travis-ci/issues/9815#issuecomment-401756442
python: '2.7' stage: test
env: DRF=3.7 python: '3.7'
dist: xenial
sudo: required
- -
python: '3.6' python: '3.6'
env: DRF=master env: TOXENV=djmaster
- - # readthedocs uses python 3.5 for building
python: '3.5' python: '3.5'
env: TOXENV=docs env: TOXENV=docs
- -
@ -40,29 +46,26 @@ jobs:
allow_failures: allow_failures:
- env: TOXENV=lint - env: TOXENV=lint
- env: DRF=master - env: TOXENV=djmaster
fast_finish: true fast_finish: true
install: install:
- pip install -r requirements/ci.txt - python -m pip install -U pip
- pip install -U -r requirements/ci.txt
before_script: before_script:
- coverage erase - coverage erase
- |
[[ -z "$TOXENV" && -z "$PYPI_DEPLOY" ]] && REPORT_COVERAGE="yes" || REPORT_COVERAGE="no";
echo "Reporting coverage: ${REPORT_COVERAGE}"
- |
[[ -z "$TOXENV" && ! -z "$DRF" && "$DRF" != "master" ]] && USE_DETOX="yes" || USE_DETOX="no";
echo "Using detox: ${USE_DETOX}"
script: script:
- 'if [[ "$USE_DETOX" == "yes" ]]; then detox; else tox; fi' - tox
after_success: after_success:
- coverage combine - |
- 'if [[ "$REPORT_COVERAGE" == "yes" ]]; then coverage report; fi' if [[ -z "$TOXENV" && -z "$PYPI_DEPLOY" ]]; then
- 'if [[ "$REPORT_COVERAGE" == "yes" ]]; then codecov; fi' chmod +x coverage.sh
./coverage.sh
fi
branches: branches:
only: only:

View File

@ -35,8 +35,8 @@ You want to contribute some code? Great! Here are a few steps to get you started
$ virtualenv venv $ virtualenv venv
$ source venv/bin/activate $ source venv/bin/activate
(venv) $ pip install -e .[validation] (venv) $ pip install -U -e .[validation]
(venv) $ pip install -r requirements/dev.txt (venv) $ pip install -U -r requirements/dev.txt
#. **Make your changes and check them against the test project** #. **Make your changes and check them against the test project**

View File

@ -11,9 +11,9 @@ Generate **real** Swagger/OpenAPI 2.0 specifications from a Django Rest Framewor
Compatible with Compatible with
- **Django Rest Framework**: 3.7.7, 3.8.x - **Django Rest Framework**: 3.7.7, 3.8
- **Django**: 1.11.x, 2.0.x - **Django**: 1.11, 2.0, 2.1
- **Python**: 2.7, 3.4, 3.5, 3.6 - **Python**: 2.7, 3.4, 3.5, 3.6, 3.7
Resources: Resources:
@ -85,14 +85,14 @@ The preferred instalation method is directly from pypi:
.. code:: console .. code:: console
pip install drf-yasg pip install -U drf-yasg
Additionally, if you want to use the built-in validation mechanisms (see `4. Validation`_), you need to install Additionally, if you want to use the built-in validation mechanisms (see `4. Validation`_), you need to install
some extra requirements: some extra requirements:
.. code:: console .. code:: console
pip install drf-yasg[validation] pip install -U drf-yasg[validation]
.. _readme-quickstart: .. _readme-quickstart:
@ -294,7 +294,7 @@ For additional usage examples, you can take a look at the test project in the ``
$ virtualenv venv $ virtualenv venv
$ source venv/bin/activate $ source venv/bin/activate
(venv) $ cd testproj (venv) $ cd testproj
(venv) $ pip install -r requirements.txt (venv) $ pip install -U -r requirements.txt
(venv) $ python manage.py migrate (venv) $ python manage.py migrate
(venv) $ python manage.py shell -c "import createsuperuser" (venv) $ python manage.py shell -c "import createsuperuser"
(venv) $ python manage.py runserver (venv) $ python manage.py runserver
@ -315,8 +315,8 @@ From here on, the terms “OpenAPI” and “Swagger” are used interchangeably
Swagger in Django Rest Framework Swagger in Django Rest Framework
================================ ================================
Since Django Rest 3.7, there is now `built in support <http://www.django-rest-framework.org/api-guide/schemas/>`__ for Since Django Rest Framework 3.7, there is now `built in support <http://www.django-rest-framework.org/api-guide/schemas/>`__
automatic OpenAPI 2.0 schema generation. However, this generation is based on the `coreapi <http://www.coreapi.org/>`__ for automatic OpenAPI 2.0 schema generation. However, this generation is based on the `coreapi <http://www.coreapi.org/>`__
standard, which for the moment is vastly inferior to OpenAPI in both features and tooling support. In particular, standard, which for the moment is vastly inferior to OpenAPI in both features and tooling support. In particular,
the OpenAPI codec/compatibility layer provided has a few major problems: the OpenAPI codec/compatibility layer provided has a few major problems:
@ -329,18 +329,15 @@ In short this makes the generated schema unusable for code generation, and medio
Other libraries Other libraries
=============== ===============
There are currently two decent Swagger schema generators that I could There are currently two decent Swagger schema generators that I could find for django-rest-framework:
find for django-rest-framework:
* `django-rest-swagger <https://github.com/marcgibbons/django-rest-swagger>`__ * `django-rest-swagger <https://github.com/marcgibbons/django-rest-swagger>`__
* `drf-openapi <https://github.com/limdauto/drf_openapi>`__ * `drf-openapi <https://github.com/limdauto/drf_openapi>`__
Out of the two, ``django-rest-swagger`` is just a wrapper around DRF 3.7 schema generation with an added UI, and ``django-rest-swagger`` is just a wrapper around DRF 3.7 schema generation with an added UI, and
thus presents the same problems. ``drf-openapi`` is a bit more involved and implements some custom handling for response thus presents the same problems, while also being unmaintained. ``drf-openapi`` was
schemas, but ultimately still falls short in code generation because the responses are plain of lacking support for `discontinued by the author <https://github.com/limdauto/drf_openapi/commit/1673c6e039eec7f089336a83bdc31613f32f7e21>`_
named schemas. on April 3rd, 2018.
Both projects are also currently unmantained.
************************ ************************
Third-party integrations Third-party integrations

6
coverage.sh 100755
View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -ex
coverage combine
coverage report
codecov

View File

@ -1,2 +1,3 @@
-r requirements/setup.txt
.[validation] .[validation]
-r requirements/heroku.txt -r requirements/heroku.txt

View File

@ -1,6 +1,4 @@
# requirements for local development to be installed via pip install -r requirements/dev.txt # requirements for local development to be installed via pip install -U -r requirements/dev.txt
-r tox.txt -r tox.txt
-r test.txt -r test.txt
-r lint.txt -r lint.txt
tox-battery>=0.5

View File

@ -4,5 +4,5 @@ sphinx_rtd_theme>=0.2.4
Pillow>=4.3.0 Pillow>=4.3.0
readme_renderer>=17.2 readme_renderer>=17.2
Django>=2.0,<2.1 Django>=2.0
djangorestframework_camel_case>=0.2.0 djangorestframework_camel_case>=0.2.0

View File

@ -1,4 +1,3 @@
# needed to build the package setup_requires in setup.py # needed to build the package setup_requires in setup.py
# do not unpin this (see setup.py) setuptools-scm>=3.0.6
setuptools_scm==1.15.6

View File

@ -1,5 +1,5 @@
# requirements for running the tests via pytest # requirements for running the tests via pytest
pytest>=2.9 pytest>=2.9,<3.7 # <3.7 because of incompatible pluggy requirement
pytest-pythonpath>=0.7.1 pytest-pythonpath>=0.7.1
pytest-cov>=2.5.1 pytest-cov>=2.5.1
pytest-xdist>=1.22.0 pytest-xdist>=1.22.0

View File

@ -1,5 +1,5 @@
# requirements for building and running tox # requirements for building and running tox
tox>=2.9.1,<3.0.0 tox>=3.1.2
detox>=0.11 tox-battery>=0.5
-r setup.txt -r setup.txt

51
setup.py 100644 → 100755
View File

@ -1,10 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import distutils.core
import io import io
import os import os
import random
import string
import sys import sys
from setuptools import find_packages, setup from setuptools import find_packages, setup
@ -22,50 +19,24 @@ requirements_setup = read_req('setup.txt')
requirements_validation = read_req('validation.txt') requirements_validation = read_req('validation.txt')
def _install_setup_requires(attrs):
# copied from setuptools
dist = distutils.core.Distribution(dict(
(k, v) for k, v in attrs.items()
if k in ('dependency_links', 'setup_requires')
))
# Honor setup.cfg's options.
dist.parse_config_files(ignore_option_errors=True)
if dist.setup_requires:
dist.fetch_build_eggs(dist.setup_requires)
try:
# try to install setuptools_scm before setuptools does it, otherwise our monkey patch below will come too early
# (setuptools_scm adds find_files hooks into setuptools on install)
_install_setup_requires({'setup_requires': requirements_setup})
except Exception:
pass
if 'sdist' in sys.argv:
try:
# see https://github.com/pypa/setuptools_scm/issues/190, setuptools_scm includes ALL versioned files from
# the git repo into the sdist by default, and there is no easy way to provide an opt-out;
# this hack is ugly but does the job; because this is not really a documented interface of the module,
# the setuptools_scm version should remain pinned to ensure it keeps working
import setuptools_scm.integration
setuptools_scm.integration.find_files = lambda _: []
except ImportError:
pass
try: try:
# this is a workaround for being able to install the package from source without working from a git checkout # this is a workaround for being able to install the package from source without working from a git checkout
# it is needed for building succesfully on Heroku # it is needed for building succesfully on Heroku
from setuptools_scm import get_version from setuptools_scm import get_version
except ImportError:
get_version = None
try:
version = get_version() version = get_version()
version_kwargs = {'use_scm_version': True} version_kwargs = {'use_scm_version': True}
except LookupError: except Exception:
if 'sdist' in sys.argv or 'bdist_wheel' in sys.argv: if any(any(dist in arg for dist in ['sdist', 'bdist']) for arg in sys.argv):
raise raise
rnd = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(16)) import time
version_kwargs = {'version': '0.0.0.dummy+' + rnd} timestamp_ms = int(time.time() * 1000)
timestamp_str = hex(timestamp_ms)[2:].zfill(16)
version_kwargs = {'version': '0.0.0.dummy+' + timestamp_str}
setup( setup(
name='drf-yasg', name='drf-yasg',
@ -89,7 +60,7 @@ setup(
classifiers=[ classifiers=[
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License', 'License :: OSI Approved :: BSD License',
'Development Status :: 4 - Beta', 'Development Status :: 5 - Production/Stable',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Environment :: Web Environment', 'Environment :: Web Environment',
'Programming Language :: Python', 'Programming Language :: Python',
@ -99,9 +70,11 @@ setup(
'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Framework :: Django', 'Framework :: Django',
'Framework :: Django :: 1.11', 'Framework :: Django :: 1.11',
'Framework :: Django :: 2.0', 'Framework :: Django :: 2.0',
'Framework :: Django :: 2.1',
'Topic :: Documentation', 'Topic :: Documentation',
'Topic :: Software Development :: Code Generators', 'Topic :: Software Development :: Code Generators',
], ],

View File

@ -5,7 +5,6 @@ import json
from collections import OrderedDict from collections import OrderedDict
from coreapi.compat import force_bytes from coreapi.compat import force_bytes
from django.utils.safestring import SafeData, SafeText
from ruamel import yaml from ruamel import yaml
from . import openapi from . import openapi

View File

@ -117,7 +117,7 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=unset, request_bo
# no overrides to set, no use in doing more work # no overrides to set, no use in doing more work
return return
# if the method is an @action, it will have a bind_to_methods attribute # if the method is an @action, it will have a bind_to_methods attribute, or a mapper attribute for drf>3.8
bind_to_methods = getattr(view_method, 'bind_to_methods', []) bind_to_methods = getattr(view_method, 'bind_to_methods', [])
# if the method is actually a function based view (@api_view), it will have a 'cls' attribute # if the method is actually a function based view (@api_view), it will have a 'cls' attribute
view_cls = getattr(view_method, 'cls', None) view_cls = getattr(view_method, 'cls', None)

0
testproj/manage.py 100644 → 100755
View File

View File

@ -1,5 +1,3 @@
from six import StringIO
import json import json
import os import os
import random import random

25
tox.ini
View File

@ -1,28 +1,29 @@
[tox] [tox]
# https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django
envlist = envlist =
py27-django111-drf37, py{27,34,35,36}-django111-drf37,
py{34,35,36}-django{111,20}-drf{37,38}, py{27,34,35,36}-django111-drf38,
py36-django20-drfmaster, py{34,35,36,37}-django20-drf37,
lint, docs py{34,35,36,37}-django20-drf38,
py{35,36,37}-django21-drf37,
[travis:env] py{35,36,37}-django21-drf38,
DRF = djmaster, lint, docs
3.7: drf37
3.8: drf38
master: drfmaster
[testenv] [testenv]
deps = deps =
django111: Django>=1.11,<2.0 django111: Django>=1.11,<2.0
django20: Django>=2.0,<2.1 django20: Django>=2.0,<2.1
django21: Django>=2.1,<2.2
drf37: djangorestframework>=3.7.7,<3.8 drf37: djangorestframework>=3.7.7,<3.8
drf38: djangorestframework>=3.8.0,<3.9 drf38: djangorestframework>=3.8.0,<3.9
# test with the latest build of django-rest-framework to get early warning of compatibility issues # test with the latest build of django-rest-framework to get early warning of compatibility issues
drfmaster: https://github.com/encode/django-rest-framework/archive/master.tar.gz djmaster: https://github.com/encode/django-rest-framework/archive/master.tar.gz
djmaster: https://github.com/django/django/archive/master.tar.gz
# other dependencies # other dependencies
-rrequirements/setup.txt
-rrequirements/validation.txt -rrequirements/validation.txt
-rrequirements/test.txt -rrequirements/test.txt
@ -46,7 +47,7 @@ commands =
[pytest] [pytest]
DJANGO_SETTINGS_MODULE = testproj.settings.local DJANGO_SETTINGS_MODULE = testproj.settings.local
python_paths = testproj python_paths = testproj
addopts = -n 3 --ignore=node_modules addopts = -n 2 --ignore=node_modules
[flake8] [flake8]
max-line-length = 120 max-line-length = 120

0
update-ui.sh 100644 → 100755
View File