Skip to content

Commit

Permalink
Merge pull request #351 from nickgaya/byte-format-base64
Browse files Browse the repository at this point in the history
Add option to automatically encode/decode strings with byte format
  • Loading branch information
sjaensch authored Oct 21, 2019
2 parents 81d9dca + 2a0e6c0 commit d9bc7c5
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Changelog
=========
.. Make sure to link Issue and PR information as `(PR|Issue) #xxx`_ and with a link at the bottom of the document
- Add option to automatically base64-encode/decode strings with byte format - `PR #351`_

5.13.2 (2019-09-04)
-------------------
- Improve header validation error message - `PR #347`_ Thanks brycedrennan for your contribution!
Expand Down Expand Up @@ -534,6 +536,7 @@ Changelog
.. _PR #345: https://github.com/Yelp/bravado-core/pull/345
.. _PR #347: https://github.com/Yelp/bravado-core/pull/347
.. _PR #350: https://github.com/Yelp/bravado-core/pull/350
.. _PR #351: https://github.com/Yelp/bravado-core/pull/351


.. Link To Documentation pages
Expand Down
12 changes: 12 additions & 0 deletions bravado_core/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Support for the 'format' key in the swagger spec as outlined in
https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#dataTypeFormat
"""
import base64
import functools
from collections import namedtuple

Expand Down Expand Up @@ -106,6 +107,17 @@ def wrapper(validatable_primitive):
return wrapper


BASE64_BYTE_FORMAT = SwaggerFormat(
format='byte',
# Note: In Python 3, this requires a bytes-like object as input
to_wire=lambda b: six.ensure_str(base64.b64encode(b), encoding='ascii'),
to_python=lambda s: base64.b64decode(
six.ensure_binary(s, encoding='ascii'),
),
validate=NO_OP, # jsonschema validates string
description='Converts [wire]string:byte <=> python bytes',
)

DEFAULT_FORMATS = {
'byte': SwaggerFormat(
format='byte',
Expand Down
6 changes: 6 additions & 0 deletions bravado_core/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
# If True, use the 'path' element of the URL the spec was retrieved from
# If False, set basePath to '/' (conforms to Swagger 2.0 specification)
'use_spec_url_for_base_path': False,

# If False, use str() function for 'byte' format
# If True, encode/decode base64 data for 'byte' format
'use_base64_for_byte_format': False,
}


Expand Down Expand Up @@ -285,6 +289,8 @@ def get_format(self, name):
user_defined_format = self.user_defined_formats.get(name)
if user_defined_format is None:
user_defined_format = formatter.DEFAULT_FORMATS.get(name)
if name == 'byte' and self.config['use_base64_for_byte_format']:
user_defined_format = formatter.BASE64_BYTE_FORMAT

if user_defined_format is None:
warnings.warn(
Expand Down
3 changes: 3 additions & 0 deletions docs/source/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,7 @@ Config key Type Default Description
| spec was retrieved from.
| If disabled, set `basePath` to `/` (conforms to
| the Swagger 2.0 specification)
----------------------------- --------------- --------- ----------------------------------------------------
*use_base64_for_byte_format* boolean False | If true, base64-encode binary data to wire and
| base64-decode from wire for data with byte format.
============================= =============== ========= ====================================================
10 changes: 10 additions & 0 deletions tests/formatter/to_python_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ def test_byte(minimal_swagger_spec):
assert isinstance(result, str)


def test_byte_base64(minimal_swagger_dict):
swagger_spec = Spec.from_dict(
minimal_swagger_dict, config={'use_base64_for_byte_format': True},
)
schema = {'type': 'string', 'format': 'byte'}
result = to_python(swagger_spec, schema, 'YWJj/w==')
assert b'abc\xff' == result
assert isinstance(result, bytes)


def test_ref(minimal_swagger_dict):
minimal_swagger_dict['definitions']['Int32'] = {
'type': 'integer', 'format': 'int32',
Expand Down
10 changes: 10 additions & 0 deletions tests/formatter/to_wire_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ def test_byte_unicode(minimal_swagger_spec):
assert isinstance(result, str)


def test_byte_base64(minimal_swagger_dict):
swagger_spec = Spec.from_dict(
minimal_swagger_dict, config={'use_base64_for_byte_format': True},
)
schema = {'type': 'string', 'format': 'byte'}
result = to_wire(swagger_spec, schema, b'abc\xff')
assert 'YWJj/w==' == result
assert isinstance(result, str)


def test_ref(minimal_swagger_dict):
minimal_swagger_dict['definitions']['Int32'] = {
'type': 'integer', 'format': 'int32',
Expand Down

0 comments on commit d9bc7c5

Please sign in to comment.