Skip to content

Commit

Permalink
Test with Django 2.1 and Python 3.7 (#176)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
axnsan12 committed Aug 6, 2018
1 parent 904895b commit 16b6ed7
Show file tree
Hide file tree
Showing 17 changed files with 82 additions and 107 deletions.
53 changes: 28 additions & 25 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
language: python
cache: pip

sudo: false
python:
- '3.4'
- '3.5'
- '3.6'
- '2.7'
- '3.4'
- '3.5'
- '3.6'

env:
- DRF=3.7
- DRF=3.8
cache:
directories:
- $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:
include:
- stage: test
python: '2.7'
env: DRF=3.7
- # workaround for python 3.7 on travis https://github.com/travis-ci/travis-ci/issues/9815#issuecomment-401756442
stage: test
python: '3.7'
dist: xenial
sudo: required
-
python: '3.6'
env: DRF=master
-
env: TOXENV=djmaster
- # readthedocs uses python 3.5 for building
python: '3.5'
env: TOXENV=docs
-
Expand All @@ -40,29 +46,26 @@ jobs:

allow_failures:
- env: TOXENV=lint
- env: DRF=master
- env: TOXENV=djmaster

fast_finish: true

install:
- pip install -r requirements/ci.txt
- python -m pip install -U pip
- pip install -U -r requirements/ci.txt

before_script:
- 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:
- 'if [[ "$USE_DETOX" == "yes" ]]; then detox; else tox; fi'
- tox

after_success:
- coverage combine
- 'if [[ "$REPORT_COVERAGE" == "yes" ]]; then coverage report; fi'
- 'if [[ "$REPORT_COVERAGE" == "yes" ]]; then codecov; fi'
- |
if [[ -z "$TOXENV" && -z "$PYPI_DEPLOY" ]]; then
chmod +x coverage.sh
./coverage.sh
fi
branches:
only:
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ You want to contribute some code? Great! Here are a few steps to get you started
$ virtualenv venv
$ source venv/bin/activate
(venv) $ pip install -e .[validation]
(venv) $ pip install -r requirements/dev.txt
(venv) $ pip install -U -e .[validation]
(venv) $ pip install -U -r requirements/dev.txt
#. **Make your changes and check them against the test project**

Expand Down
29 changes: 13 additions & 16 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ Generate **real** Swagger/OpenAPI 2.0 specifications from a Django Rest Framewor

Compatible with

- **Django Rest Framework**: 3.7.7, 3.8.x
- **Django**: 1.11.x, 2.0.x
- **Python**: 2.7, 3.4, 3.5, 3.6
- **Django Rest Framework**: 3.7.7, 3.8
- **Django**: 1.11, 2.0, 2.1
- **Python**: 2.7, 3.4, 3.5, 3.6, 3.7

Resources:

Expand Down Expand Up @@ -85,14 +85,14 @@ The preferred instalation method is directly from pypi:

.. 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
some extra requirements:

.. code:: console
pip install drf-yasg[validation]
pip install -U drf-yasg[validation]
.. _readme-quickstart:

Expand Down Expand Up @@ -294,7 +294,7 @@ For additional usage examples, you can take a look at the test project in the ``
$ virtualenv venv
$ source venv/bin/activate
(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 shell -c "import createsuperuser"
(venv) $ python manage.py runserver
Expand All @@ -315,8 +315,8 @@ From here on, the terms “OpenAPI” and “Swagger” are used interchangeably
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
automatic OpenAPI 2.0 schema generation. However, this generation is based on the `coreapi <http://www.coreapi.org/>`__
Since Django Rest Framework 3.7, there is now `built in support <http://www.django-rest-framework.org/api-guide/schemas/>`__
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,
the OpenAPI codec/compatibility layer provided has a few major problems:

Expand All @@ -329,18 +329,15 @@ In short this makes the generated schema unusable for code generation, and medio
Other libraries
===============

There are currently two decent Swagger schema generators that I could
find for django-rest-framework:
There are currently two decent Swagger schema generators that I could find for django-rest-framework:

* `django-rest-swagger <https://github.com/marcgibbons/django-rest-swagger>`__
* `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
thus presents the same problems. ``drf-openapi`` is a bit more involved and implements some custom handling for response
schemas, but ultimately still falls short in code generation because the responses are plain of lacking support for
named schemas.

Both projects are also currently unmantained.
``django-rest-swagger`` is just a wrapper around DRF 3.7 schema generation with an added UI, and
thus presents the same problems, while also being unmaintained. ``drf-openapi`` was
`discontinued by the author <https://github.com/limdauto/drf_openapi/commit/1673c6e039eec7f089336a83bdc31613f32f7e21>`_
on April 3rd, 2018.

************************
Third-party integrations
Expand Down
6 changes: 6 additions & 0 deletions coverage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -ex

coverage combine
coverage report
codecov
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
-r requirements/setup.txt
.[validation]
-r requirements/heroku.txt
4 changes: 1 addition & 3 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -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 test.txt
-r lint.txt

tox-battery>=0.5
2 changes: 1 addition & 1 deletion requirements/docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ sphinx_rtd_theme>=0.2.4
Pillow>=4.3.0
readme_renderer>=17.2

Django>=2.0,<2.1
Django>=2.0
djangorestframework_camel_case>=0.2.0
3 changes: 1 addition & 2 deletions requirements/setup.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# needed to build the package setup_requires in setup.py

# do not unpin this (see setup.py)
setuptools_scm==1.15.6
setuptools-scm>=3.0.6
2 changes: 1 addition & 1 deletion requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 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-cov>=2.5.1
pytest-xdist>=1.22.0
Expand Down
4 changes: 2 additions & 2 deletions requirements/tox.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# requirements for building and running tox
tox>=2.9.1,<3.0.0
detox>=0.11
tox>=3.1.2
tox-battery>=0.5

-r setup.txt
51 changes: 12 additions & 39 deletions setup.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import distutils.core
import io
import os
import random
import string
import sys
from setuptools import find_packages, setup

Expand All @@ -22,50 +19,24 @@ def read_req(req_file):
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:
# 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
from setuptools_scm import get_version
except ImportError:
get_version = None

try:
version = get_version()
version_kwargs = {'use_scm_version': True}
except LookupError:
if 'sdist' in sys.argv or 'bdist_wheel' in sys.argv:
except Exception:
if any(any(dist in arg for dist in ['sdist', 'bdist']) for arg in sys.argv):
raise

rnd = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(16))
version_kwargs = {'version': '0.0.0.dummy+' + rnd}
import time
timestamp_ms = int(time.time() * 1000)
timestamp_str = hex(timestamp_ms)[2:].zfill(16)
version_kwargs = {'version': '0.0.0.dummy+' + timestamp_str}

setup(
name='drf-yasg',
Expand All @@ -89,7 +60,7 @@ def _install_setup_requires(attrs):
classifiers=[
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Development Status :: 4 - Beta',
'Development Status :: 5 - Production/Stable',
'Operating System :: OS Independent',
'Environment :: Web Environment',
'Programming Language :: Python',
Expand All @@ -99,9 +70,11 @@ def _install_setup_requires(attrs):
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Framework :: Django',
'Framework :: Django :: 1.11',
'Framework :: Django :: 2.0',
'Framework :: Django :: 2.1',
'Topic :: Documentation',
'Topic :: Software Development :: Code Generators',
],
Expand Down
1 change: 0 additions & 1 deletion src/drf_yasg/codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from collections import OrderedDict

from coreapi.compat import force_bytes
from django.utils.safestring import SafeData, SafeText
from ruamel import yaml

from . import openapi
Expand Down
2 changes: 1 addition & 1 deletion src/drf_yasg/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def decorator(view_method):
# no overrides to set, no use in doing more work
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', [])
# if the method is actually a function based view (@api_view), it will have a 'cls' attribute
view_cls = getattr(view_method, 'cls', None)
Expand Down
Empty file modified testproj/manage.py
100644 → 100755
Empty file.
2 changes: 0 additions & 2 deletions tests/test_management.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from six import StringIO

import json
import os
import random
Expand Down
25 changes: 13 additions & 12 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
[tox]
# https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django
envlist =
py27-django111-drf37,
py{34,35,36}-django{111,20}-drf{37,38},
py36-django20-drfmaster,
lint, docs

[travis:env]
DRF =
3.7: drf37
3.8: drf38
master: drfmaster
py{27,34,35,36}-django111-drf37,
py{27,34,35,36}-django111-drf38,
py{34,35,36,37}-django20-drf37,
py{34,35,36,37}-django20-drf38,
py{35,36,37}-django21-drf37,
py{35,36,37}-django21-drf38,
djmaster, lint, docs

[testenv]
deps =
django111: Django>=1.11,<2.0
django20: Django>=2.0,<2.1
django21: Django>=2.1,<2.2

drf37: djangorestframework>=3.7.7,<3.8
drf38: djangorestframework>=3.8.0,<3.9

# 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
-rrequirements/setup.txt
-rrequirements/validation.txt
-rrequirements/test.txt

Expand All @@ -46,7 +47,7 @@ commands =
[pytest]
DJANGO_SETTINGS_MODULE = testproj.settings.local
python_paths = testproj
addopts = -n 3 --ignore=node_modules
addopts = -n 2 --ignore=node_modules

[flake8]
max-line-length = 120
Expand Down
Empty file modified update-ui.sh
100644 → 100755
Empty file.

0 comments on commit 16b6ed7

Please sign in to comment.