From 82afc12e48ad2efa24cf0c06de731b774f243c37 Mon Sep 17 00:00:00 2001 From: Dmitry Dygalo Date: Thu, 27 Apr 2017 16:23:42 +0200 Subject: [PATCH 01/11] Fix typos --- coreapi/document.py | 2 +- coreapi/utils.py | 2 +- runtests | 4 ++-- tests/test_document.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/coreapi/document.py b/coreapi/document.py index 0fb62a7..c6c9ceb 100644 --- a/coreapi/document.py +++ b/coreapi/document.py @@ -44,7 +44,7 @@ def _key_sorting(item): # The field class, as used by Link objects: -# NOTE: 'type', 'description' and 'examaple' are now deprecated, +# NOTE: 'type', 'description' and 'example' are now deprecated, # in favor of 'schema'. Field = namedtuple('Field', ['name', 'required', 'location', 'schema', 'description', 'type', 'example']) Field.__new__.__defaults__ = (False, '', None, None, None, None) diff --git a/coreapi/utils.py b/coreapi/utils.py index 0b27d46..fb7ade4 100644 --- a/coreapi/utils.py +++ b/coreapi/utils.py @@ -237,7 +237,7 @@ def negotiate_encoder(encoders, accept=None): raise exceptions.NoCodecAvailable(msg) -# Validation utilities. Used to ensure that we get consitent validation +# Validation utilities. Used to ensure that we get consistent validation # exceptions when invalid types are passed as a parameter, rather than # an exception occuring when the request is made. diff --git a/runtests b/runtests index 54a984d..8b260d9 100755 --- a/runtests +++ b/runtests @@ -35,10 +35,10 @@ def flake8_main(args): def report_coverage(cov, fail_if_not_100=False): - precent_covered = cov.report( + percent_covered = cov.report( file=NullFile(), **COVERAGE_OPTIONS ) - if precent_covered == 100: + if percent_covered == 100: print('100% coverage') return if fail_if_not_100: diff --git a/tests/test_document.py b/tests/test_document.py index db1d1c1..6b06de7 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -50,7 +50,7 @@ def error(): def _dedent(string): """ - Convience function for dedenting multiline strings, + Convenience function for dedenting multiline strings, for string comparison purposes. """ lines = string.splitlines() From dbec97a44b332c4f8e40019a4c96a06dcf11d7b8 Mon Sep 17 00:00:00 2001 From: Tommy Beadle Date: Wed, 5 Apr 2017 13:06:11 -0400 Subject: [PATCH 02/11] Fix the encoding/decoding of Enum types. The 'enum' argument is a required parameter to creating an Enum. Store it in an 'extra' dict that can be passed as **kwargs during its creation. --- coreapi/codecs/corejson.py | 8 ++++-- tests/test_codecs.py | 55 +++++++++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/coreapi/codecs/corejson.py b/coreapi/codecs/corejson.py index 091e7a3..37d312c 100644 --- a/coreapi/codecs/corejson.py +++ b/coreapi/codecs/corejson.py @@ -33,19 +33,23 @@ def encode_schema_to_corejson(schema): type_id = SCHEMA_CLASS_TO_TYPE_ID.get(schema.__class__, 'anything') - return { + retval = { '_type': type_id, 'title': schema.title, 'description': schema.description } + if isinstance(schema, coreschema.Enum): + retval['extra'] = {'enum': schema.enum} + return retval def decode_schema_from_corejson(data): type_id = _get_string(data, '_type') title = _get_string(data, 'title') description = _get_string(data, 'description') + extra = _get_dict(data, 'extra') schema_cls = TYPE_ID_TO_SCHEMA_CLASS.get(type_id, coreschema.Anything) - return schema_cls(title=title, description=description) + return schema_cls(title=title, description=description, **extra) # Robust dictionary lookups, that always return an item of the correct diff --git a/tests/test_codecs.py b/tests/test_codecs.py index 8ebbd63..7529aa9 100644 --- a/tests/test_codecs.py +++ b/tests/test_codecs.py @@ -4,6 +4,7 @@ from coreapi.document import Document, Link, Error, Field from coreapi.exceptions import ParseError, NoCodecAvailable from coreapi.utils import negotiate_decoder, negotiate_encoder +from coreschema import Enum, String import pytest @@ -21,7 +22,13 @@ def doc(): 'integer': 123, 'dict': {'key': 'value'}, 'list': [1, 2, 3], - 'link': Link(url='http://example.org/', fields=[Field(name='example')]), + 'link': Link( + url='http://example.org/', + fields=[ + Field(name='noschema'), + Field(name='string_example', schema=String()), + Field(name='enum_example', schema=Enum(['a', 'b', 'c'])), + ]), 'nested': {'child': Link(url='http://example.org/123')}, '_type': 'needs escaping' }) @@ -40,7 +47,26 @@ def test_document_to_primitive(doc): 'integer': 123, 'dict': {'key': 'value'}, 'list': [1, 2, 3], - 'link': {'_type': 'link', 'fields': [{'name': 'example'}]}, + 'link': {'_type': 'link', 'fields': [ + {'name': 'noschema'}, + { + 'name': 'string_example', + 'schema': { + '_type': 'string', + 'title': '', + 'description': '', + }, + }, + { + 'name': 'enum_example', + 'schema': { + '_type': 'enum', + 'title': '', + 'description': '', + 'extra': {'enum': ['a', 'b', 'c']}, + }, + }, + ]}, 'nested': {'child': {'_type': 'link', 'url': '/123'}}, '__type': 'needs escaping' } @@ -56,7 +82,30 @@ def test_primitive_to_document(doc): 'integer': 123, 'dict': {'key': 'value'}, 'list': [1, 2, 3], - 'link': {'_type': 'link', 'url': 'http://example.org/', 'fields': [{'name': 'example'}]}, + 'link': { + '_type': 'link', + 'url': 'http://example.org/', + 'fields': [ + {'name': 'noschema'}, + { + 'name': 'string_example', + 'schema': { + '_type': 'string', + 'title': '', + 'description': '', + }, + }, + { + 'name': 'enum_example', + 'schema': { + '_type': 'enum', + 'title': '', + 'description': '', + 'extra': {'enum': ['a', 'b', 'c']}, + }, + }, + ], + }, 'nested': {'child': {'_type': 'link', 'url': 'http://example.org/123'}}, '__type': 'needs escaping' } From 13fa37f58d08c87028a4a87149b15b5e833582f1 Mon Sep 17 00:00:00 2001 From: Jesse Riggins Date: Tue, 23 May 2017 10:46:52 -0700 Subject: [PATCH 03/11] Fix the encoding/decoding of Enum types. This is an update from tbeadle/enum branch with changes that tomchriste suggested. --- coreapi/codecs/corejson.py | 10 +++++++--- tests/test_codecs.py | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/coreapi/codecs/corejson.py b/coreapi/codecs/corejson.py index 37d312c..fd88a58 100644 --- a/coreapi/codecs/corejson.py +++ b/coreapi/codecs/corejson.py @@ -39,7 +39,7 @@ def encode_schema_to_corejson(schema): 'description': schema.description } if isinstance(schema, coreschema.Enum): - retval['extra'] = {'enum': schema.enum} + retval['enum'] = schema.enum return retval @@ -47,9 +47,13 @@ def decode_schema_from_corejson(data): type_id = _get_string(data, '_type') title = _get_string(data, 'title') description = _get_string(data, 'description') - extra = _get_dict(data, 'extra') + + kwargs = {} + if type_id == 'enum': + kwargs['enum'] = _get_list(data, 'enum') + schema_cls = TYPE_ID_TO_SCHEMA_CLASS.get(type_id, coreschema.Anything) - return schema_cls(title=title, description=description, **extra) + return schema_cls(title=title, description=description, **kwargs) # Robust dictionary lookups, that always return an item of the correct diff --git a/tests/test_codecs.py b/tests/test_codecs.py index 7529aa9..32458cd 100644 --- a/tests/test_codecs.py +++ b/tests/test_codecs.py @@ -63,7 +63,7 @@ def test_document_to_primitive(doc): '_type': 'enum', 'title': '', 'description': '', - 'extra': {'enum': ['a', 'b', 'c']}, + 'enum': ['a', 'b', 'c'], }, }, ]}, @@ -101,7 +101,7 @@ def test_primitive_to_document(doc): '_type': 'enum', 'title': '', 'description': '', - 'extra': {'enum': ['a', 'b', 'c']}, + 'enum': ['a', 'b', 'c'], }, }, ], From 24d59f4b796a8b30764f54ce539e1e6eee793e2a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 23 May 2017 12:08:59 -0700 Subject: [PATCH 04/11] Version 2.3.1 --- coreapi/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/__init__.py b/coreapi/__init__.py index 5f069ba..af3be54 100644 --- a/coreapi/__init__.py +++ b/coreapi/__init__.py @@ -4,7 +4,7 @@ from coreapi.document import Array, Document, Link, Object, Error, Field -__version__ = '2.3.0' +__version__ = '2.3.1' __all__ = [ 'Array', 'Document', 'Link', 'Object', 'Error', 'Field', 'Client', From b550a2dc69497b80960fd3cb2acbc67c9b6ecfcf Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Mon, 7 Aug 2017 12:54:57 +0100 Subject: [PATCH 05/11] Test against Python 3.5 and 3.6 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index af709cd..f132d06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ python: - "2.7" - "3.3" - "3.4" + - "3.5" + - "3.6" install: - pip install -r requirements.txt From 64fd5f1dd37789b6635b83a9790983f013adfd00 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Mon, 7 Aug 2017 12:55:25 +0100 Subject: [PATCH 06/11] Add Python 2/3 trove classifiers to setup.py Fixes #130. --- setup.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup.py b/setup.py index ef91e7f..7dabead 100755 --- a/setup.py +++ b/setup.py @@ -86,6 +86,13 @@ def get_package_data(package): 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + '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', 'Topic :: Internet :: WWW/HTTP', ] ) From 27f4f6ed71703fe4787364090158a542ca954eb1 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 5 Oct 2017 15:02:10 +0100 Subject: [PATCH 07/11] Version 2.3.2 (Compat with API Star schemas) --- coreapi/__init__.py | 2 +- coreapi/codecs/corejson.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/coreapi/__init__.py b/coreapi/__init__.py index af3be54..c368812 100644 --- a/coreapi/__init__.py +++ b/coreapi/__init__.py @@ -4,7 +4,7 @@ from coreapi.document import Array, Document, Link, Object, Error, Field -__version__ = '2.3.1' +__version__ = '2.3.2' __all__ = [ 'Array', 'Document', 'Link', 'Object', 'Error', 'Field', 'Client', diff --git a/coreapi/codecs/corejson.py b/coreapi/codecs/corejson.py index fd88a58..f025533 100644 --- a/coreapi/codecs/corejson.py +++ b/coreapi/codecs/corejson.py @@ -32,13 +32,16 @@ def encode_schema_to_corejson(schema): - type_id = SCHEMA_CLASS_TO_TYPE_ID.get(schema.__class__, 'anything') + if hasattr(schema, 'typename'): + type_id = schema.typename + else: + type_id = SCHEMA_CLASS_TO_TYPE_ID.get(schema.__class__, 'anything') retval = { '_type': type_id, 'title': schema.title, 'description': schema.description } - if isinstance(schema, coreschema.Enum): + if hasattr(schema, 'enum'): retval['enum'] = schema.enum return retval From 2685e5dc7e2d3a56fffb4d680f58de6e9446a5ab Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 5 Oct 2017 15:04:25 +0100 Subject: [PATCH 08/11] Version 2.3.3 (Clean up PyPI package) --- coreapi/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/__init__.py b/coreapi/__init__.py index c368812..92ac890 100644 --- a/coreapi/__init__.py +++ b/coreapi/__init__.py @@ -4,7 +4,7 @@ from coreapi.document import Array, Document, Link, Object, Error, Field -__version__ = '2.3.2' +__version__ = '2.3.3' __all__ = [ 'Array', 'Document', 'Link', 'Object', 'Error', 'Field', 'Client', From 687542679f64eafea4120de2fdeb92eefce5feb9 Mon Sep 17 00:00:00 2001 From: Damien Toma Date: Tue, 16 Jan 2018 14:36:15 +0800 Subject: [PATCH 09/11] Merge environment settings for SSL requests When using requests' builder, we bypass the environment settings, which include information about SSL certificates. This makes requests to a SSL endpoint fail. This commit adds a call to `session.merge_environment_settings` to fix this issue, and updates the test suite accordingly. --- coreapi/transports/http.py | 3 ++- tests/test_integration.py | 8 ++++---- tests/test_transport.py | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/coreapi/transports/http.py b/coreapi/transports/http.py index a548024..7338e61 100644 --- a/coreapi/transports/http.py +++ b/coreapi/transports/http.py @@ -376,7 +376,8 @@ def transition(self, link, decoders, params=None, link_ancestors=None, force_cod headers.update(self.headers) request = _build_http_request(session, url, method, headers, encoding, params) - response = session.send(request) + settings = session.merge_environment_settings(request.url, None, None, None, None) + response = session.send(request, **settings) result = _decode_result(response, decoders, force_codec) if isinstance(result, Document) and link_ancestors: diff --git a/tests/test_integration.py b/tests/test_integration.py index b38de9a..0a2e602 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -41,7 +41,7 @@ def test_dump(document): def test_get(monkeypatch): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): return MockResponse(b'{"_type": "document", "example": 123}') monkeypatch.setattr(requests.Session, 'send', mockreturn) @@ -52,7 +52,7 @@ def mockreturn(self, request): def test_follow(monkeypatch, document): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): return MockResponse(b'{"_type": "document", "example": 123}') monkeypatch.setattr(requests.Session, 'send', mockreturn) @@ -63,7 +63,7 @@ def mockreturn(self, request): def test_reload(monkeypatch): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): return MockResponse(b'{"_type": "document", "example": 123}') monkeypatch.setattr(requests.Session, 'send', mockreturn) @@ -75,7 +75,7 @@ def mockreturn(self, request): def test_error(monkeypatch, document): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): return MockResponse(b'{"_type": "error", "message": ["failed"]}') monkeypatch.setattr(requests.Session, 'send', mockreturn) diff --git a/tests/test_transport.py b/tests/test_transport.py index 09cb849..eeeb17a 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -47,7 +47,7 @@ def test_missing_hostname(): # Test basic transition types. def test_get(monkeypatch, http): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): return MockResponse(b'{"_type": "document", "example": 123}') monkeypatch.setattr(requests.Session, 'send', mockreturn) @@ -58,7 +58,7 @@ def mockreturn(self, request): def test_get_with_parameters(monkeypatch, http): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): insert = request.path_url.encode('utf-8') return MockResponse( b'{"_type": "document", "url": "' + insert + b'"}' @@ -72,7 +72,7 @@ def mockreturn(self, request): def test_get_with_path_parameter(monkeypatch, http): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): insert = request.url.encode('utf-8') return MockResponse( b'{"_type": "document", "example": "' + insert + b'"}' @@ -90,7 +90,7 @@ def mockreturn(self, request): def test_post(monkeypatch, http): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): codec = CoreJSONCodec() body = force_text(request.body) content = codec.encode(Document(content={'data': json.loads(body)})) @@ -104,7 +104,7 @@ def mockreturn(self, request): def test_delete(monkeypatch, http): - def mockreturn(self, request): + def mockreturn(self, request, *args, **kwargs): return MockResponse(b'') monkeypatch.setattr(requests.Session, 'send', mockreturn) From c4000c26fcaca35f72ae3274049f76f24903d487 Mon Sep 17 00:00:00 2001 From: Saeed Esfandi Date: Tue, 30 Jan 2018 12:48:51 +0330 Subject: [PATCH 10/11] use input session for get default transports --- coreapi/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/client.py b/coreapi/client.py index d02a59c..00b0057 100644 --- a/coreapi/client.py +++ b/coreapi/client.py @@ -105,7 +105,7 @@ def __init__(self, decoders=None, transports=None, auth=None, session=None): if decoders is None: decoders = get_default_decoders() if transports is None: - transports = get_default_transports(auth=auth) + transports = get_default_transports(auth=auth, session=session) self._decoders = itypes.List(decoders) self._transports = itypes.List(transports) From d264fd277a878ea40f9f75755e461f8a9418671f Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 4 Jun 2018 09:19:12 +0100 Subject: [PATCH 11/11] Create LICENSE.md --- LICENSE.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..e92b342 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,29 @@ +# License + +Copyright © 2017-present, Tom Christie. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.