Hello community,
here is the log from the commit of package python-Flask-RESTful for
openSUSE:Factory checked in at 2019-01-03 18:08:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Flask-RESTful (Old)
and /work/SRC/openSUSE:Factory/.python-Flask-RESTful.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Flask-RESTful"
Thu Jan 3 18:08:16 2019 rev:3 rq:662399 version:0.3.7
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-Flask-RESTful/python-Flask-RESTful.changes
2018-08-24 17:12:09.030645425 +0200
+++
/work/SRC/openSUSE:Factory/.python-Flask-RESTful.new.28833/python-Flask-RESTful.changes
2019-01-03 18:08:25.624044470 +0100
@@ -1,0 +2,17 @@
+Sun Dec 30 19:05:00 UTC 2018 - Arun Persaud <[email protected]>
+
+- specfile:
+ * be more specific in %files section
+ * removed python-devel
+
+- update to version 0.3.7:
+ * Fix error handling in python3 (#696)
+ * Fix arguments with type=list (#705)
+ * Return code for parse_args() is now configurable (#722)
+ * Removed flask_restful.paging module.
+ * Removed misleading help_on_404 functionality (#722)
+ * JSON keys are no longer sorted by default in debug mode in python3
+ (#680)
+ * Various small fixes and updates to documentation
+
+-------------------------------------------------------------------
Old:
----
Flask-RESTful-0.3.6.tar.gz
New:
----
Flask-RESTful-0.3.7.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-Flask-RESTful.spec ++++++
--- /var/tmp/diff_new_pack.D2ZrrD/_old 2019-01-03 18:08:26.096044051 +0100
+++ /var/tmp/diff_new_pack.D2ZrrD/_new 2019-01-03 18:08:26.100044048 +0100
@@ -12,28 +12,27 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-Flask-RESTful
-Version: 0.3.6
+Version: 0.3.7
Release: 0
-License: BSD-3-Clause
Summary: Framework for creating REST APIs
-Url: https://www.github.com/flask-restful/flask-restful/
+License: BSD-3-Clause
Group: Development/Languages/Python
+URL: https://www.github.com/flask-restful/flask-restful/
Source:
https://files.pythonhosted.org/packages/source/F/Flask-RESTful/Flask-RESTful-%{version}.tar.gz
-BuildRequires: python-rpm-macros
-BuildRequires: %{python_module devel}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
-Requires: python-aniso8601 >= 0.82
+BuildRequires: python-rpm-macros
Requires: python-Flask >= 0.8
-Requires: python-six >= 1.3.0
+Requires: python-aniso8601 >= 0.82
Requires: python-pytz
+Requires: python-six >= 1.3.0
BuildArch: noarch
-
%python_subpackages
%description
@@ -45,8 +44,6 @@
%build
%python_build
-
-
%install
%python_install
%py_compile %{buildroot}%{python_sitelib}
@@ -54,6 +51,8 @@
%python_expand %fdupes %{buildroot}%{$python_sitelib}/flask_restful/
%files %{python_files}
-%{python_sitelib}/*
+%dir %{python_sitelib}/flask_restful
+%{python_sitelib}/flask_restful/*
+%{python_sitelib}/Flask_RESTful-%{version}-py*.egg-info
%changelog
++++++ Flask-RESTful-0.3.6.tar.gz -> Flask-RESTful-0.3.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/Flask_RESTful.egg-info/PKG-INFO
new/Flask-RESTful-0.3.7/Flask_RESTful.egg-info/PKG-INFO
--- old/Flask-RESTful-0.3.6/Flask_RESTful.egg-info/PKG-INFO 2017-05-31
14:13:31.000000000 +0200
+++ new/Flask-RESTful-0.3.7/Flask_RESTful.egg-info/PKG-INFO 2018-12-18
14:02:12.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: Flask-RESTful
-Version: 0.3.6
+Version: 0.3.7
Summary: Simple framework for creating REST APIs
Home-page: https://www.github.com/flask-restful/flask-restful/
Author: Twilio API Team
@@ -10,11 +10,11 @@
Platform: any
Classifier: Framework :: Flask
Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
Classifier: License :: OSI Approved :: BSD License
+Provides-Extra: docs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-RESTful-0.3.6/Flask_RESTful.egg-info/SOURCES.txt
new/Flask-RESTful-0.3.7/Flask_RESTful.egg-info/SOURCES.txt
--- old/Flask-RESTful-0.3.6/Flask_RESTful.egg-info/SOURCES.txt 2017-05-31
14:13:31.000000000 +0200
+++ new/Flask-RESTful-0.3.7/Flask_RESTful.egg-info/SOURCES.txt 2018-12-18
14:02:12.000000000 +0100
@@ -2,6 +2,7 @@
LICENSE
MANIFEST.in
Makefile
+README.md
setup.cfg
setup.py
Flask_RESTful.egg-info/PKG-INFO
@@ -34,7 +35,6 @@
flask_restful/__version__.py
flask_restful/fields.py
flask_restful/inputs.py
-flask_restful/paging.py
flask_restful/reqparse.py
flask_restful/representations/__init__.py
flask_restful/representations/json.py
@@ -48,8 +48,6 @@
tests/test_api.py
tests/test_api_with_blueprint.py
tests/test_cors.py
-tests/test_crypto.py
tests/test_fields.py
tests/test_inputs.py
-tests/test_paging.py
tests/test_reqparse.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-RESTful-0.3.6/Flask_RESTful.egg-info/requires.txt
new/Flask-RESTful-0.3.7/Flask_RESTful.egg-info/requires.txt
--- old/Flask-RESTful-0.3.6/Flask_RESTful.egg-info/requires.txt 2017-05-31
14:13:31.000000000 +0200
+++ new/Flask-RESTful-0.3.7/Flask_RESTful.egg-info/requires.txt 2018-12-18
14:02:12.000000000 +0100
@@ -5,6 +5,3 @@
[docs]
sphinx
-
-[paging]
-pycrypto>=2.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/Makefile
new/Flask-RESTful-0.3.7/Makefile
--- old/Flask-RESTful-0.3.6/Makefile 2016-12-28 16:23:58.000000000 +0100
+++ new/Flask-RESTful-0.3.7/Makefile 2018-12-18 13:49:18.000000000 +0100
@@ -88,7 +88,7 @@
.PHONY: .depends-test
.depends-test: env Makefile $(DEPENDS_TEST)
$(DEPENDS_TEST): Makefile tests/requirements.txt
- $(PIP) install -e .[paging]
+ $(PIP) install -e .
$(PIP) install -r tests/requirements.txt
touch $(DEPENDS_TEST) # flag to indicate dependencies are installed
@@ -139,17 +139,17 @@
test: .depends-test .clean-test
$(NOSE) tests --with-coverage --cover-package=$(PACKAGE)
-test-all: test-py26 test-py27 test-py33 test-py34 test-py35
-test-py26:
- PYTHON_MAJOR=2 PYTHON_MINOR=6 $(MAKE) test
+test-all: test-py27 test-py34 test-py35 test-py36 test-py37
test-py27:
PYTHON_MAJOR=2 PYTHON_MINOR=7 $(MAKE) test
-test-py33:
- PYTHON_MAJOR=3 PYTHON_MINOR=3 $(MAKE) test
test-py34:
PYTHON_MAJOR=3 PYTHON_MINOR=4 $(MAKE) test
test-py35:
PYTHON_MAJOR=3 PYTHON_MINOR=5 $(MAKE) test
+test-py36:
+ PYTHON_MAJOR=3 PYTHON_MINOR=6 $(MAKE) test
+test-py37:
+ PYTHON_MAJOR=3 PYTHON_MINOR=7 $(MAKE) test
.PHONY: htmlcov
htmlcov: test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/PKG-INFO
new/Flask-RESTful-0.3.7/PKG-INFO
--- old/Flask-RESTful-0.3.6/PKG-INFO 2017-05-31 14:13:31.000000000 +0200
+++ new/Flask-RESTful-0.3.7/PKG-INFO 2018-12-18 14:02:12.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: Flask-RESTful
-Version: 0.3.6
+Version: 0.3.7
Summary: Simple framework for creating REST APIs
Home-page: https://www.github.com/flask-restful/flask-restful/
Author: Twilio API Team
@@ -10,11 +10,11 @@
Platform: any
Classifier: Framework :: Flask
Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
Classifier: License :: OSI Approved :: BSD License
+Provides-Extra: docs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/README.md
new/Flask-RESTful-0.3.7/README.md
--- old/Flask-RESTful-0.3.6/README.md 1970-01-01 01:00:00.000000000 +0100
+++ new/Flask-RESTful-0.3.7/README.md 2018-03-29 20:45:50.000000000 +0200
@@ -0,0 +1,12 @@
+# Flask-RESTful
+
+[](http://travis-ci.org/flask-restful/flask-restful)
+[](https://coveralls.io/r/flask-restful/flask-restful)
+[](https://pypi.python.org/pypi/Flask-RESTful)
+
+Flask-RESTful provides the building blocks for creating a great REST API.
+
+## User Guide
+
+You'll find the user guide and all documentation
[here](https://flask-restful.readthedocs.io/)
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/docs/conf.py
new/Flask-RESTful-0.3.7/docs/conf.py
--- old/Flask-RESTful-0.3.6/docs/conf.py 2016-12-28 16:23:56.000000000
+0100
+++ new/Flask-RESTful-0.3.7/docs/conf.py 2017-09-20 15:10:34.000000000
+0200
@@ -51,7 +51,20 @@
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
-from flask_restful.__version__ import __version__
+
+__namespace = {}
+__version_path = os.path.join('..', 'flask_restful', '__version__.py')
+
+if sys.version[0] == '2':
+ execfile(__version_path, __namespace)
+elif sys.version[0] == '3':
+ with open(__version_path, 'rb') as fh:
+ __version_contents = fh.read()
+ exec(__version_contents, __namespace)
+else:
+ raise Exception(u'Unsupported version of Python.')
+
+__version__ = __namespace['__version__']
vparts = __version__.split('.')
# The short X.Y version.
version = '.'.join(vparts[:2])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/docs/extending.rst
new/Flask-RESTful-0.3.7/docs/extending.rst
--- old/Flask-RESTful-0.3.6/docs/extending.rst 2017-04-02 23:29:53.000000000
+0200
+++ new/Flask-RESTful-0.3.7/docs/extending.rst 2018-03-29 20:45:50.000000000
+0200
@@ -36,7 +36,7 @@
Flask-RESTful uses the :mod:`json` module from the Python standard library
instead of :mod:`flask.json` because the Flask JSON serializer includes
- serializtion capabilities which are not in the JSON spec. If your
+ serialization capabilities which are not in the JSON spec. If your
application needs these customizations, you can replace the default JSON
representation with one using the Flask JSON module as described above.
@@ -182,11 +182,11 @@
if acct:
return func(*args, **kwargs)
- restful.abort(401)
+ flask_restful.abort(401)
return wrapper
- class Resource(restful.Resource):
+ class Resource(flask_restful.Resource):
method_decorators = [authenticate] # applies to all inherited
resources
Alternatively, you can specify a dictionary of iterables that map to HTTP
methods
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/docs/fields.rst
new/Flask-RESTful-0.3.7/docs/fields.rst
--- old/Flask-RESTful-0.3.6/docs/fields.rst 2017-04-02 23:29:53.000000000
+0200
+++ new/Flask-RESTful-0.3.7/docs/fields.rst 2017-11-01 13:46:26.000000000
+0100
@@ -103,7 +103,7 @@
-------------------------------
Sometimes you have your own custom formatting needs. You can subclass the
-:class:`fields.Raw` class and implement the format function. This is
especially
+:class:`fields.Raw` class and implement the ``format`` function. This is
especially
useful when an attribute stores multiple pieces of information. e.g. a
bit-field whose individual bits represent distinct values. You can use fields
to multiplex a single attribute to multiple output values.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/docs/installation.rst
new/Flask-RESTful-0.3.7/docs/installation.rst
--- old/Flask-RESTful-0.3.6/docs/installation.rst 2016-12-28
16:23:56.000000000 +0100
+++ new/Flask-RESTful-0.3.7/docs/installation.rst 2018-12-18
13:49:18.000000000 +0100
@@ -22,6 +22,6 @@
installed if you use ``pip``):
-* `Flask <http://flask.pocoo.org>`_ version 0.8 or greater
+* `Flask <http://flask.pocoo.org>`_ version 0.10 or greater
-Flask-RESTful requires Python version 2.6, 2.7, 3.3, or 3.4.
+Flask-RESTful requires Python version 2.7, 3.4, 3.5, 3.6 or 3.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/docs/quickstart.rst
new/Flask-RESTful-0.3.7/docs/quickstart.rst
--- old/Flask-RESTful-0.3.6/docs/quickstart.rst 2016-12-28 16:23:56.000000000
+0100
+++ new/Flask-RESTful-0.3.7/docs/quickstart.rst 2018-12-18 13:49:18.000000000
+0100
@@ -138,12 +138,6 @@
api.add_resource(Todo,
'/todo/<int:todo_id>', endpoint='todo_ep')
-.. note ::
-
- If a request does not match any of your application's endpoints,
- Flask-RESTful will return a 404 error message with suggestions of other
- endpoints that closely match the requested endpoint. This can be disabled
- by setting ``ERROR_404_HELP`` to ``False`` in your application config.
Argument Parsing
----------------
@@ -190,7 +184,6 @@
:meth:`marshal_with` decorator. Similar to the Django ORM and WTForm, you
use the ``fields`` module to describe the structure of your response. ::
- from collections import OrderedDict
from flask_restful import fields, marshal_with
resource_fields = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/docs/testing.rst
new/Flask-RESTful-0.3.7/docs/testing.rst
--- old/Flask-RESTful-0.3.6/docs/testing.rst 2016-12-28 16:23:56.000000000
+0100
+++ new/Flask-RESTful-0.3.7/docs/testing.rst 2018-12-18 13:49:18.000000000
+0100
@@ -26,6 +26,6 @@
for your branch automatically.
A Tox config file is also provided so you can test against multiple python
-versions locally (2.6, 2.7, 3.3, and 3.4) ::
+versions locally (2.7, 3.4, 3.5, 3.6, 3.7) ::
$ tox
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/flask_restful/__init__.py
new/Flask-RESTful-0.3.7/flask_restful/__init__.py
--- old/Flask-RESTful-0.3.6/flask_restful/__init__.py 2017-04-02
23:29:53.000000000 +0200
+++ new/Flask-RESTful-0.3.7/flask_restful/__init__.py 2018-12-18
13:49:18.000000000 +0100
@@ -1,7 +1,5 @@
from __future__ import absolute_import
-import difflib
from functools import wraps, partial
-import re
from flask import request, url_for, current_app
from flask import abort as original_flask_abort
from flask import make_response as original_flask_make_response
@@ -9,7 +7,6 @@
from flask.signals import got_request_exception
from werkzeug.datastructures import Headers
from werkzeug.exceptions import HTTPException, MethodNotAllowed, NotFound,
NotAcceptable, InternalServerError
-from werkzeug.http import HTTP_STATUS_CODES
from werkzeug.wrappers import Response as ResponseBase
from flask_restful.utils import http_status_message, unpack, OrderedDict
from flask_restful.representations.json import output_json
@@ -50,8 +47,7 @@
after it has been constructed.
:param app: the Flask application object
- :type app: flask.Flask
- :type app: flask.Blueprint
+ :type app: flask.Flask or flask.Blueprint
:param prefix: Prefix all routes with a value, eg v1 or 2010-04-01
:type prefix: str
:param default_mediatype: The default media type to return
@@ -312,30 +308,12 @@
data = getattr(e, 'data', default_data)
- if code >= 500:
+ if code and code >= 500:
exc_info = sys.exc_info()
if exc_info[1] is None:
exc_info = None
current_app.log_exception(exc_info)
- help_on_404 = current_app.config.get("ERROR_404_HELP", True)
- if code == 404 and help_on_404:
- rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule)
- for rule in current_app.url_map.iter_rules()])
- close_matches = difflib.get_close_matches(request.path,
rules.keys())
- if close_matches:
- # If we already have a message, add punctuation and continue
it.
- if "message" in data:
- data["message"] = data["message"].rstrip('.') + '. '
- else:
- data["message"] = ""
-
- data['message'] += 'You have requested this URI [' +
request.path + \
- '] but did you mean ' + \
- ' or '.join((
- rules[match] for match in close_matches)
- ) + ' ?'
-
error_cls_name = type(e).__name__
if error_cls_name in self.errors:
custom_data = self.errors.get(error_cls_name, {})
@@ -371,7 +349,7 @@
"""Adds a resource to the api.
:param resource: the class name of your resource
- :type resource: :class:`Resource`
+ :type resource: :class:`Type[Resource]`
:param urls: one or more url routes to match for the resource, standard
flask routing rules apply. Any url variables will be
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/flask_restful/__version__.py
new/Flask-RESTful-0.3.7/flask_restful/__version__.py
--- old/Flask-RESTful-0.3.6/flask_restful/__version__.py 2017-05-31
14:03:02.000000000 +0200
+++ new/Flask-RESTful-0.3.7/flask_restful/__version__.py 2018-12-18
13:58:51.000000000 +0100
@@ -1,3 +1,3 @@
#!/usr/bin/env python
-__version__ = '0.3.6'
+__version__ = '0.3.7'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/flask_restful/fields.py
new/Flask-RESTful-0.3.7/flask_restful/fields.py
--- old/Flask-RESTful-0.3.6/flask_restful/fields.py 2016-12-28
16:23:58.000000000 +0100
+++ new/Flask-RESTful-0.3.7/flask_restful/fields.py 2017-09-20
15:10:28.000000000 +0200
@@ -294,8 +294,8 @@
:param scheme: URL scheme specifier (e.g. ``http``, ``https``)
:type scheme: str
"""
- def __init__(self, endpoint=None, absolute=False, scheme=None):
- super(Url, self).__init__()
+ def __init__(self, endpoint=None, absolute=False, scheme=None, **kwargs):
+ super(Url, self).__init__(**kwargs)
self.endpoint = endpoint
self.absolute = absolute
self.scheme = scheme
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/flask_restful/paging.py
new/Flask-RESTful-0.3.7/flask_restful/paging.py
--- old/Flask-RESTful-0.3.6/flask_restful/paging.py 2016-12-28
16:23:58.000000000 +0100
+++ new/Flask-RESTful-0.3.7/flask_restful/paging.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,29 +0,0 @@
-from flask_restful.utils.crypto import decrypt, encrypt
-DEFAULT_PAGE_SIZE = 50
-
-
-def retrieve_next_page(key, seed, args, callback, initial_bookmark=None):
- """
- A helper for the bookmark pager.
-
- :param key: the private key of you API
- :param seed: the crypo seed for this session
- :param args: the verbatim filtering+paging arguments
- :param callback: a function that takes (a dictionary of filters, the
current bookmark, the page size)
- and return a tuple (next_results,
dictionary_ready_for_next_iteration, approx_number_of_element_left)
- :param initial_bookmark: pass here an optional initial bookmark for the
first request
- :return: the tuple result_list and new encrypted bookmark
- """
- filter = dict(args)
- if 'pager_info' in filter:
- initial_bookmark = decrypt(filter.pop('pager_info'), key, seed)
-
- page_size = filter.pop('page_size', DEFAULT_PAGE_SIZE)
-
- result_list, new_bookmark, approx_result_size = callback(filter,
initial_bookmark, page_size)
-
- # restore for the next iteration
- filter['pager_info'] = encrypt(new_bookmark, key, seed)
- filter['page_size'] = page_size
-
- return result_list, filter, approx_result_size
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/flask_restful/reqparse.py
new/Flask-RESTful-0.3.7/flask_restful/reqparse.py
--- old/Flask-RESTful-0.3.6/flask_restful/reqparse.py 2017-04-02
23:29:53.000000000 +0200
+++ new/Flask-RESTful-0.3.7/flask_restful/reqparse.py 2018-12-18
13:49:18.000000000 +0100
@@ -19,6 +19,7 @@
def __setattr__(self, name, value):
self[name] = value
+
_friendly_location = {
u'json': u'the JSON body',
u'form': u'the post body',
@@ -88,6 +89,23 @@
self.trim = trim
self.nullable = nullable
+ def __str__(self):
+ if len(self.choices) > 5:
+ choices = self.choices[0:3]
+ choices.append('...')
+ choices.append(self.choices[-1])
+ else:
+ choices = self.choices
+ return 'Name: {0}, type: {1}, choices: {2}'.format(self.name,
self.type, choices)
+
+ def __repr__(self):
+ return "{0}('{1}', default={2}, dest={3}, required={4}, ignore={5},
location={6}, " \
+ "type=\"{7}\", choices={8}, action='{9}', help={10},
case_sensitive={11}, " \
+ "operators={12}, store_missing={13}, trim={14},
nullable={15})".format(
+ self.__class__.__name__, self.name, self.default, self.dest,
self.required, self.ignore, self.location,
+ self.type, self.choices, self.action, self.help,
self.case_sensitive,
+ self.operators, self.store_missing, self.trim, self.nullable)
+
def source(self, request):
"""Pulls values off the request in the provided location
:param request: The flask request object to parse arguments from
@@ -156,7 +174,7 @@
the argument's type.
:param request: The flask request object to parse arguments from
- :param do not abort when first error occurs, return a
+ :param bundle_errors: Do not abort when first error occurs, return a
dict with the name of the argument and the error message to be
bundled
"""
@@ -176,7 +194,7 @@
values = source.getlist(name)
else:
values = source.get(name)
- if not isinstance(values, collections.MutableSequence):
+ if not (isinstance(values, collections.MutableSequence)
and self.action == 'append'):
values = [values]
for value in values:
@@ -257,7 +275,7 @@
"""
def __init__(self, argument_class=Argument, namespace_class=Namespace,
- trim=False, bundle_errors=False):
+ trim=False, bundle_errors=False):
self.args = []
self.argument_class = argument_class
self.namespace_class = namespace_class
@@ -279,18 +297,20 @@
else:
self.args.append(self.argument_class(*args, **kwargs))
- #Do not know what other argument classes are out there
+ # Do not know what other argument classes are out there
if self.trim and self.argument_class is Argument:
- #enable trim for appended element
+ # enable trim for appended element
self.args[-1].trim = kwargs.get('trim', self.trim)
return self
- def parse_args(self, req=None, strict=False):
+ def parse_args(self, req=None, strict=False, http_error_code=400):
"""Parse all arguments from the provided request and return the results
as a Namespace
+ :param req: Can be used to overwrite request from Flask
:param strict: if req includes args not in parser, throw 400
BadRequest exception
+ :param http_error_code: use custom error code for
`flask_restful.abort()`
"""
if req is None:
req = request
@@ -309,7 +329,7 @@
if found or arg.store_missing:
namespace[arg.dest or arg.name] = value
if errors:
- flask_restful.abort(400, message=errors)
+ flask_restful.abort(http_error_code, message=errors)
if strict and req.unparsed_arguments:
raise exceptions.BadRequest('Unknown arguments: %s'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/setup.py
new/Flask-RESTful-0.3.7/setup.py
--- old/Flask-RESTful-0.3.6/setup.py 2017-05-31 14:06:00.000000000 +0200
+++ new/Flask-RESTful-0.3.7/setup.py 2018-12-18 13:49:18.000000000 +0100
@@ -5,7 +5,6 @@
from os import path
from setuptools import setup, find_packages
-PY26 = sys.version_info[:2] == (2, 6,)
requirements = [
'aniso8601>=0.82',
@@ -13,8 +12,6 @@
'six>=1.3.0',
'pytz',
]
-if PY26:
- requirements.append('ordereddict')
version_file = path.join(
@@ -43,13 +40,12 @@
classifiers=[
'Framework :: Flask',
'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
'License :: OSI Approved :: BSD License',
],
zip_safe=False,
@@ -57,10 +53,9 @@
platforms='any',
test_suite = 'nose.collector',
install_requires=requirements,
- tests_require=['Flask-RESTful[paging]', 'mock>=0.8', 'blinker'],
- # Install these with "pip install -e '.[paging]'" or '.[docs]'
+ tests_require=['Flask-RESTful', 'mock>=0.8', 'blinker'],
+ # Install these with "pip install -e '.[docs]'
extras_require={
- 'paging': 'pycrypto>=2.6',
'docs': 'sphinx',
}
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/tests/test_api.py
new/Flask-RESTful-0.3.7/tests/test_api.py
--- old/Flask-RESTful-0.3.6/tests/test_api.py 2017-05-31 13:48:12.000000000
+0200
+++ new/Flask-RESTful-0.3.7/tests/test_api.py 2018-12-18 13:49:18.000000000
+0100
@@ -21,7 +21,6 @@
import six
-
def check_unpack(expected, value):
assert_equals(expected, value)
@@ -40,6 +39,16 @@
return {}
+class BadMojoError(HTTPException):
+ pass
+
+
+# Resource that always errors out
+class HelloBomb(flask_restful.Resource):
+ def get(self):
+ raise BadMojoError("It burns..")
+
+
class APITestCase(unittest.TestCase):
def test_http_code(self):
@@ -82,7 +91,7 @@
with app.test_request_context('/foo'):
resp = api.handle_error(Unauthorized())
self.assertEquals(resp.status_code, 401)
- assert_false('WWW-Autheneticate' in resp.headers)
+ assert_false('WWW-Authenticate' in resp.headers)
def test_handle_error_401_sends_challege_default_realm(self):
app = Flask(__name__)
@@ -119,6 +128,20 @@
self.assertEquals(resp.get_data(), b'{"message": "x"}\n')
+ def test_handle_error_does_not_swallow_custom_exceptions(self):
+ app = Flask(__name__)
+ errors = {'BadMojoError': {'status': 409, 'message': 'go away'}}
+ api = flask_restful.Api(app, errors=errors)
+ api.add_resource(HelloBomb, '/bomb')
+
+ app = app.test_client()
+ resp = app.get('/bomb')
+ self.assertEquals(resp.status_code, 409)
+ self.assertEquals(resp.content_type, api.default_mediatype)
+ resp_dict = json.loads(resp.data.decode())
+ self.assertEqual(resp_dict.get('status'), 409)
+ self.assertEqual(resp_dict.get('message'), 'go away')
+
def test_marshal(self):
fields = OrderedDict([('foo', flask_restful.fields.Raw)])
marshal_dict = OrderedDict([('foo', 'bar'), ('bat', 'baz')])
@@ -458,36 +481,6 @@
'message': BadRequest.description,
}) + "\n")
- def test_handle_smart_errors(self):
- app = Flask(__name__)
- api = flask_restful.Api(app)
- view = flask_restful.Resource
-
- api.add_resource(view, '/foo', endpoint='bor')
- api.add_resource(view, '/fee', endpoint='bir')
- api.add_resource(view, '/fii', endpoint='ber')
-
- with app.test_request_context("/faaaaa"):
- resp = api.handle_error(NotFound())
- self.assertEquals(resp.status_code, 404)
- self.assertEquals(resp.data.decode(), dumps({
- "message": NotFound.description,
- }) + "\n")
-
- with app.test_request_context("/fOo"):
- resp = api.handle_error(NotFound())
- self.assertEquals(resp.status_code, 404)
- self.assertTrue('did you mean /foo ?' in resp.data.decode())
-
- app.config['ERROR_404_HELP'] = False
-
- with app.test_request_context("/fOo"):
- resp = api.handle_error(NotFound())
- self.assertEquals(resp.status_code, 404)
- self.assertEquals(resp.data.decode(), dumps({
- "message": NotFound.description
- }) + "\n")
-
def test_error_router_falls_back_to_original(self):
"""Verify that if an exception occurs in the Flask-RESTful error
handler,
the error_router will call the original flask error handler instead.
@@ -660,14 +653,14 @@
def test_output_func(self):
- def make_empty_resposne():
+ def make_empty_response():
return flask.make_response('')
app = Flask(__name__)
api = flask_restful.Api(app)
with app.test_request_context("/foo"):
- wrapper = api.output(make_empty_resposne)
+ wrapper = api.output(make_empty_response)
resp = wrapper()
self.assertEquals(resp.status_code, 200)
self.assertEquals(resp.data.decode(), '')
@@ -784,7 +777,7 @@
allow = ', '.join(set(resp.headers.get_all('Allow')))
allow = set(method.strip() for method in allow.split(','))
self.assertEquals(allow,
- set(['HEAD', 'OPTIONS'] + HelloWorld.methods))
+ {'HEAD', 'OPTIONS'}.union(HelloWorld.methods))
def test_exception_header_forwarded(self):
"""Test that HTTPException's headers are extended properly"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/tests/test_cors.py
new/Flask-RESTful-0.3.7/tests/test_cors.py
--- old/Flask-RESTful-0.3.6/tests/test_cors.py 2016-12-28 16:23:58.000000000
+0100
+++ new/Flask-RESTful-0.3.7/tests/test_cors.py 2018-12-18 13:49:18.000000000
+0100
@@ -45,6 +45,29 @@
assert_true('X-MY-HEADER' in
res.headers['Access-Control-Expose-Headers'])
assert_true('X-ANOTHER-HEADER' in
res.headers['Access-Control-Expose-Headers'])
+ def test_access_control_allow_methods(self):
+
+ class Foo(flask_restful.Resource):
+ @cors.crossdomain(origin='*',
+ methods={"HEAD","OPTIONS","GET"})
+ def get(self):
+ return "data"
+
+ def post(self):
+ return "data"
+
+ app = Flask(__name__)
+ api = flask_restful.Api(app)
+ api.add_resource(Foo, '/')
+
+ with app.test_client() as client:
+ res = client.get('/')
+ assert_equals(res.status_code, 200)
+ assert_true('HEAD' in res.headers['Access-Control-Allow-Methods'])
+ assert_true('OPTIONS' in
res.headers['Access-Control-Allow-Methods'])
+ assert_true('GET' in res.headers['Access-Control-Allow-Methods'])
+ assert_true('POST' not in
res.headers['Access-Control-Allow-Methods'])
+
def test_no_crossdomain(self):
class Foo(flask_restful.Resource):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/tests/test_crypto.py
new/Flask-RESTful-0.3.7/tests/test_crypto.py
--- old/Flask-RESTful-0.3.6/tests/test_crypto.py 2016-12-28
16:23:58.000000000 +0100
+++ new/Flask-RESTful-0.3.7/tests/test_crypto.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,10 +0,0 @@
-import unittest
-from flask_restful.utils.crypto import encrypt, decrypt
-
-
-class CryptoTestCase(unittest.TestCase):
- def test_encrypt_decrypt(self):
- key = '0123456789abcdef0123456789abcdef'
- seed = 'deadbeefcafebabe'
- message = 'It should go through'
- self.assertEqual(decrypt(encrypt(message, key, seed), key, seed),
message)
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/tests/test_fields.py
new/Flask-RESTful-0.3.7/tests/test_fields.py
--- old/Flask-RESTful-0.3.6/tests/test_fields.py 2016-12-28
16:23:58.000000000 +0100
+++ new/Flask-RESTful-0.3.7/tests/test_fields.py 2017-09-20
15:10:04.000000000 +0200
@@ -280,6 +280,14 @@
with app.test_request_context("/foo/hey", base_url="http://localhost"):
self.assertEquals("https://localhost/foo/3", field.output("hey",
Foo()))
+ def test_url_superclass_kwargs(self):
+ app = Flask(__name__)
+ app.add_url_rule("/<hey>", "foobar", view_func=lambda x: x)
+ field = fields.Url(absolute=True, attribute='hey')
+
+ with app.test_request_context("/hey"):
+ self.assertEquals("http://localhost/3", field.output("hey", Foo()))
+
def test_int(self):
field = fields.Integer()
self.assertEquals(3, field.output("hey", {'hey': 3}))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/tests/test_inputs.py
new/Flask-RESTful-0.3.7/tests/test_inputs.py
--- old/Flask-RESTful-0.3.6/tests/test_inputs.py 2017-04-02
23:29:53.000000000 +0200
+++ new/Flask-RESTful-0.3.7/tests/test_inputs.py 2018-03-29
20:51:59.000000000 +0200
@@ -417,7 +417,7 @@
for bad_interval in bad_intervals:
yield (
assert_raises,
- ValueError,
+ Exception,
inputs.iso8601interval,
bad_interval,
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/tests/test_paging.py
new/Flask-RESTful-0.3.7/tests/test_paging.py
--- old/Flask-RESTful-0.3.6/tests/test_paging.py 2016-12-28
16:23:58.000000000 +0100
+++ new/Flask-RESTful-0.3.7/tests/test_paging.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,27 +0,0 @@
-import unittest
-from flask_restful.paging import retrieve_next_page
-
-
-class PagingTestCase(unittest.TestCase):
- def test_bookmark_paging(self):
- key = '0123456789abcdef0123456789abcdef'
- seed = 'deadbeefcafebabe'
-
- def fetch_data(filters, bookmark, page_size):
- self.assertEquals(filters['my_filter'], 'yes')
- self.assertEquals(len(filters), 1) # we don't want extraneous
paging metadata in there
- if bookmark is None:
- bookmark = 0
- return [i for i in range(bookmark, bookmark + page_size)],
bookmark + page_size, 100000
-
- filter = {'my_filter': 'yes', 'page_size': 3}
-
- result, filter, approx_result_size = retrieve_next_page(key, seed,
filter, fetch_data)
-
- self.assertEquals(result, [0, 1, 2])
- self.assertEquals(approx_result_size, 100000)
-
- result, filter, approx_result_size = retrieve_next_page(key, seed,
filter, fetch_data)
-
- self.assertEquals(approx_result_size, 100000)
- self.assertEquals(result, [3, 4, 5])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-RESTful-0.3.6/tests/test_reqparse.py
new/Flask-RESTful-0.3.7/tests/test_reqparse.py
--- old/Flask-RESTful-0.3.6/tests/test_reqparse.py 2017-04-02
23:29:53.000000000 +0200
+++ new/Flask-RESTful-0.3.7/tests/test_reqparse.py 2018-12-18
13:49:18.000000000 +0100
@@ -41,7 +41,6 @@
expected = {'foo': u'Bad choice: \xf0\x9f\x8d\x95 is not a valid
choice'}
abort.assert_called_with(400, message=expected)
-
@patch('flask_restful.abort')
def test_help_no_error_msg(self, abort):
app = Flask(__name__)
@@ -441,7 +440,7 @@
def test_parse_error_bundling(self):
app = Flask(__name__)
- app.config['BUNDLE_ERRORS']=True
+ app.config['BUNDLE_ERRORS'] = True
with app.app_context():
req = Request.from_values("/bubble")
@@ -463,7 +462,7 @@
def test_parse_error_bundling_w_parser_arg(self):
app = Flask(__name__)
- app.config['BUNDLE_ERRORS']=False
+ app.config['BUNDLE_ERRORS'] = False
with app.app_context():
req = Request.from_values("/bubble")
@@ -698,8 +697,6 @@
self.assertEquals(args['foo'].filename, 'baz.txtaaaa')
self.assertEquals(args['foo'].read(), fdata)
-
-
def test_passing_arguments_object(self):
req = Request.from_values("/bubble?foo=bar")
parser = RequestParser()
@@ -891,5 +888,55 @@
self.assertEquals(args['int1'], 1)
self.assertEquals(args['int2'], 2)
+ def test_list_argument(self):
+ app = Flask(__name__)
+
+ parser = RequestParser()
+ parser.add_argument('arg1', location='json', type=list)
+
+ with app.test_request_context('/bubble', method="post",
+ data=json.dumps({'arg1': ['foo',
'bar']}),
+ content_type='application/json'):
+ args = parser.parse_args()
+ self.assertEquals(args['arg1'], ['foo', 'bar'])
+
+ def test_list_argument_dict(self):
+ app = Flask(__name__)
+
+ parser = RequestParser()
+ parser.add_argument('arg1', location='json', type=list)
+
+ with app.test_request_context('/bubble', method="post",
+ data=json.dumps({'arg1': [{'foo': 1,
'bar': 2}]}),
+ content_type='application/json'):
+ args = parser.parse_args()
+ self.assertEquals(args['arg1'], [{'foo': 1, 'bar': 2}])
+
+ def test_argument_repr(self):
+ arg = Argument('foo')
+ try: # Python 2.6 compatibility
+ self.assertIn('foo', arg.__repr__())
+ except AttributeError:
+ self.assertTrue('foo' in arg.__repr__())
+ self.assertTrue(arg.__repr__().startswith("Argument('foo'"))
+
+ def test_argument_str(self):
+ arg = Argument('foo', choices=[1, 2, 3, 4, 5])
+ try: # Python 2.6 compatibility
+ self.assertIn('foo', str(arg))
+ except AttributeError:
+ self.assertTrue('foo' in str(arg))
+ self.assertTrue(str(arg).startswith('Name: foo'))
+ try: # Python 2.6 compatibility
+ self.assertIn('choices: [1, 2, 3, 4, 5]', str(arg))
+ except AttributeError:
+ self.assertTrue('choices: [1, 2, 3, 4, 5]' in str(arg))
+ arg = Argument('foo', choices=[1, 2, 3, 4, 5, 6])
+ try: # Python 2.6 compatibility
+ self.assertIn("choices: [1, 2, 3, '...', 6]", str(arg))
+ except AttributeError:
+ self.assertTrue("choices: [1, 2, 3, '...', 6]" in str(arg))
+
+
if __name__ == '__main__':
unittest.main()