From 5bd115fa6576647122172bfd1eaeb68d3b9ad4fc Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 26 Sep 2016 14:48:27 +0100 Subject: [PATCH 1/2] Add format argument --- coreapi/__init__.py | 2 +- coreapi/client.py | 14 ++++++++++---- coreapi/codecs/corejson.py | 1 + coreapi/codecs/download.py | 1 + coreapi/codecs/jsondata.py | 1 + coreapi/codecs/text.py | 1 + docs/api-guide/client.md | 1 + docs/api-guide/codecs.md | 8 ++++++-- 8 files changed, 22 insertions(+), 7 deletions(-) diff --git a/coreapi/__init__.py b/coreapi/__init__.py index 038795a..71395a5 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.0.7' +__version__ = '2.0.8' __all__ = [ 'Array', 'Document', 'Link', 'Object', 'Error', 'Field', 'Client', diff --git a/coreapi/client.py b/coreapi/client.py index f5c1f62..1275f4b 100644 --- a/coreapi/client.py +++ b/coreapi/client.py @@ -112,16 +112,22 @@ def decoders(self): def transports(self): return self._transports - def get(self, url, force_codec=False): + def get(self, url, format=None, force_codec=False): link = Link(url, action='get') + decoders = self.decoders + if format: + decoders = [decoder for decoder in self.decoders if decoder.format==format] + if not decoders: + raise ValueError("No decoder available with format='%s'" % format) + # Perform the action, and return a new document. transport = determine_transport(self.transports, link.url) - return transport.transition(link, self.decoders, force_codec=force_codec) + return transport.transition(link, decoders, force_codec=force_codec) - def reload(self, document, force_codec=False): + def reload(self, document, format=None, force_codec=False): # Fallback for v1.x. To be removed in favour of explict `get` style. - return self.get(document.url, force_codec=force_codec) + return self.get(document.url, format=format, force_codec=force_codec) def action(self, document, keys, params=None, validate=True, overrides=None, action=None, encoding=None, transform=None): diff --git a/coreapi/codecs/corejson.py b/coreapi/codecs/corejson.py index 5c7045f..819a482 100644 --- a/coreapi/codecs/corejson.py +++ b/coreapi/codecs/corejson.py @@ -231,6 +231,7 @@ def _primative_to_document(data, base_url=None): class CoreJSONCodec(BaseCodec): media_type = 'application/coreapi+json' + format = 'corejson' # The following is due to be deprecated... media_types = ['application/coreapi+json', 'application/vnd.coreapi+json'] diff --git a/coreapi/codecs/download.py b/coreapi/codecs/download.py index 16e5a13..0995690 100644 --- a/coreapi/codecs/download.py +++ b/coreapi/codecs/download.py @@ -100,6 +100,7 @@ class DownloadCodec(BaseCodec): A codec to handle raw file downloads, such as images and other media. """ media_type = '*/*' + format = 'download' def __init__(self, download_dir=None): """ diff --git a/coreapi/codecs/jsondata.py b/coreapi/codecs/jsondata.py index 494f975..9fa1732 100644 --- a/coreapi/codecs/jsondata.py +++ b/coreapi/codecs/jsondata.py @@ -7,6 +7,7 @@ class JSONCodec(BaseCodec): media_type = 'application/json' + format = 'json' def decode(self, bytestring, **options): """ diff --git a/coreapi/codecs/text.py b/coreapi/codecs/text.py index f52b1de..7760498 100644 --- a/coreapi/codecs/text.py +++ b/coreapi/codecs/text.py @@ -4,6 +4,7 @@ class TextCodec(BaseCodec): media_type = 'text/*' + format = 'text' def decode(self, bytestring, **options): return bytestring.decode('utf-8') diff --git a/docs/api-guide/client.md b/docs/api-guide/client.md index 4349b11..ea07c80 100644 --- a/docs/api-guide/client.md +++ b/docs/api-guide/client.md @@ -74,6 +74,7 @@ Make a network request to the given URL. If fetching an API schema or hypermedia resource, then this should typically return a decoded `Document`. * `url` - The URL that should be retrieved. +* `format` - Optional. Force the given codec to be used when decoding the response. For example: diff --git a/docs/api-guide/codecs.md b/docs/api-guide/codecs.md index ac1c6eb..ee85bfa 100644 --- a/docs/api-guide/codecs.md +++ b/docs/api-guide/codecs.md @@ -64,6 +64,7 @@ The following attribute is available on codec instances: Supports decoding or encoding the Core JSON format. **.media_type**: `application/coreapi+json` +**.format**: `openapi` Example of decoding a Core JSON bytestring into a `Document` instance: @@ -99,6 +100,7 @@ URLs in the document. Supports decoding JSON data. **.media_type**: `application/json` +**.format**: `json` Example: @@ -116,6 +118,7 @@ Example: Supports decoding plain-text responses. **.media_type**: `text/*` +**.format**: `text` Example: @@ -133,6 +136,7 @@ Supports decoding arbitrary media as a download file. Returns a [temporary file] that will be deleted once it goes out of scope. **.media_type**: `*/*` +**.format**: `download` Example: @@ -183,7 +187,7 @@ indicate the download filename][content-disposition-filename]. ## Custom codecs Custom codec classes may be created by inheriting from `BaseCodec`, setting -the `media_type` and `supports` properties, and implementing one or both +the `media_type` and `format` properties, and implementing one or both of the `decode` or `encode` methods. For example: @@ -193,7 +197,7 @@ For example: class YAMLCodec(codecs.BaseCodec): media_type = 'application/yaml' - supports = ['data'] + format = 'yaml' def decode(content, **options): return yaml.safe_load(content) From 0f7db6cf9fc4039e310731962b1dfb26b2fc55ce Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 26 Sep 2016 14:59:31 +0100 Subject: [PATCH 2/2] Pep8 cleanup --- coreapi/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/client.py b/coreapi/client.py index 1275f4b..fab9c37 100644 --- a/coreapi/client.py +++ b/coreapi/client.py @@ -117,7 +117,7 @@ def get(self, url, format=None, force_codec=False): decoders = self.decoders if format: - decoders = [decoder for decoder in self.decoders if decoder.format==format] + decoders = [decoder for decoder in self.decoders if decoder.format == format] if not decoders: raise ValueError("No decoder available with format='%s'" % format)