Skip to content

Commit

Permalink
Added support for base64url serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
annatisch committed May 17, 2016
1 parent 3e08cfa commit 914f60f
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ def test_array(self):
with self.assertRaises(DeserializationError):
client.array.get_date_time_invalid_chars()

test_array = ['a string that gets encoded with base64url', 'test string', 'Lorem ipsum']
self.assertEqual(client.array.get_base64_url(), test_array)


if __name__ == '__main__':
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

tests = realpath(join(cwd, pardir, "Expected", "AcceptanceTests"))
sys.path.append(join(tests, "CustomBaseUri"))
sys.path.append(join(tests, "CustomBaseUriMoreOptions"))

from msrest.exceptions import (
DeserializationError,
Expand All @@ -48,6 +49,7 @@

from autorestparameterizedhosttestclient import AutoRestParameterizedHostTestClient
from autorestparameterizedhosttestclient.models import Error, ErrorException
from autorestparameterizedcustomhosttestclient import AutoRestParameterizedCustomHostTestClient


class CustomBaseUriTests(unittest.TestCase):
Expand All @@ -70,6 +72,10 @@ def test_custom_base_uri_negative(self):
with self.assertRaises(ClientRequestError):
client.paths.get_empty("local")

def test_custom_base_uri_more_optiopns(self):
client = AutoRestParameterizedCustomHostTestClient("test12", "host.:3000")
client.paths.get_empty("http://lo", "cal", "key1")

if __name__ == '__main__':


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ def test_dictionary_primitive_types(self):
bytes_result = self.client.dictionary.get_byte_invalid_null()
self.assertEqual(bytes_null, bytes_result)

test_dict = {'0': 'a string that gets encoded with base64url',
'1': 'test string',
'2': 'Lorem ipsum'}
self.assertEqual(self.client.dictionary.get_base64_url(), test_dict)

def test_basic_dictionary_parsing(self):

self.assertEqual({}, self.client.dictionary.get_empty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ def test_string(self):
self.assertEqual(Colors.redcolor, client.enum.get_not_expandable())
client.enum.put_not_expandable(Colors.redcolor)

self.assertEqual(client.string.get_base64_encoded(), 'a string that gets encoded with base64')
self.assertEqual(client.string.get_base64_url_encoded(), 'a string that gets encoded with base64url')
self.assertIsNone(client.string.get_null_base64_url_encoded())
client.string.put_base64_url_encoded('a string that gets encoded with base64url')


if __name__ == '__main__':
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ def test_url_path(self):
with self.assertRaises(ValidationError):
self.client.paths.enum_null(None)

self.client.paths.base64_url("lorem")

def test_url_query(self):

self.client.config.global_string_path = ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2090,7 +2090,7 @@ def get_base64_url(
deserialized = None

if response.status_code == 200:
deserialized = self._deserialize('[str]', response)
deserialized = self._deserialize('[base64]', response)

if raw:
client_raw_response = ClientRawResponse(deserialized, response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2095,7 +2095,7 @@ def get_base64_url(
deserialized = None

if response.status_code == 200:
deserialized = self._deserialize('{str}', response)
deserialized = self._deserialize('{base64}', response)

if raw:
client_raw_response = ClientRawResponse(deserialized, response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ def get_base64_encoded(
deserialized = None

if response.status_code == 200:
deserialized = self._deserialize('str', response)
deserialized = self._deserialize('base64', response)

if raw:
client_raw_response = ClientRawResponse(deserialized, response)
Expand Down Expand Up @@ -517,7 +517,7 @@ def get_base64_url_encoded(
deserialized = None

if response.status_code == 200:
deserialized = self._deserialize('str', response)
deserialized = self._deserialize('base64', response)

if raw:
client_raw_response = ClientRawResponse(deserialized, response)
Expand Down Expand Up @@ -554,7 +554,7 @@ def put_base64_url_encoded(
header_parameters.update(custom_headers)

# Construct body
body_content = self._serialize.body(string_body, 'str')
body_content = self._serialize.body(string_body, 'base64')

# Construct and send request
request = self._client.put(url, query_parameters)
Expand Down Expand Up @@ -604,7 +604,7 @@ def get_null_base64_url_encoded(
deserialized = None

if response.status_code == 200:
deserialized = self._deserialize('str', response)
deserialized = self._deserialize('base64', response)

if raw:
client_raw_response = ClientRawResponse(deserialized, response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,7 @@ def base64_url(
# Construct URL
url = '/paths/string/bG9yZW0/{base64UrlPath}'
path_format_arguments = {
'base64UrlPath': self._serialize.url("base64_url_path", base64_url_path, 'str')
'base64UrlPath': self._serialize.url("base64_url_path", base64_url_path, 'base64')
}
url = self._client.format_url(url, **path_format_arguments)

Expand Down
8 changes: 7 additions & 1 deletion AutoRest/Generators/Python/Python/ClientModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ public static string ToPythonRuntimeTypeString(this IType type)
{
return "unix-time";
}

if (known.Type == KnownPrimaryType.Base64Url)
{
return "base64";
}
}

var sequenceType = type as SequenceType;
Expand Down Expand Up @@ -252,7 +257,8 @@ public static string GetPythonSerializationType(IType type)
{ KnownPrimaryType.DateTime, "iso-8601" },
{ KnownPrimaryType.DateTimeRfc1123, "rfc-1123" },
{ KnownPrimaryType.TimeSpan, "duration" },
{ KnownPrimaryType.UnixTime, "unix-time" }
{ KnownPrimaryType.UnixTime, "unix-time" },
{ KnownPrimaryType.Base64Url, "base64" }
};
PrimaryType primaryType = type as PrimaryType;
if (primaryType != null)
Expand Down
6 changes: 3 additions & 3 deletions AutoRest/TestServer/server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ var coverage = {
"ConstantsInPath": 0,
"ConstantsInBody": 0,
"CustomBaseUri": 0,
//Once all the languages implement this test, the scenario counter should be reset to zero. It is currently implemented in C# and node.js
//Once all the languages implement this test, the scenario counter should be reset to zero. It is currently implemented in C#, Python and node.js
"CustomBaseUriMoreOptions": 1,
'getModelFlattenArray': 0,
'putModelFlattenArray': 0,
Expand All @@ -430,7 +430,7 @@ var coverage = {
'putModelFlattenCustomBase': 0,
'postModelFlattenCustomParameter': 0,
'putModelFlattenCustomGroupedParameter': 0,
/* TODO: only C# and node.js support the base64url format currently. Exclude these tests from code coverage until it is implemented in other languages */
/* TODO: only C#, Python and node.js support the base64url format currently. Exclude these tests from code coverage until it is implemented in other languages */
"getStringBase64Encoded": 1,
"getStringBase64UrlEncoded": 1,
"putStringBase64UrlEncoded": 1,
Expand All @@ -439,7 +439,7 @@ var coverage = {
"getDictionaryBase64Url": 1,
"UrlPathsStringBase64Url": 1,
"UrlPathsArrayCSVInPath": 1,
/* TODO: only C# supports the unixtime format currently. Exclude these tests from code coverage until it is implemented in other languages */
/* TODO: only C# and Python support the unixtime format currently. Exclude these tests from code coverage until it is implemented in other languages */
"getUnixTime": 1,
"getInvalidUnixTime": 1,
"getNullUnixTime": 1,
Expand Down
26 changes: 26 additions & 0 deletions ClientRuntimes/Python/msrest/msrest/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ def __init__(self, classes=None):
'decimal': Serializer.serialize_decimal,
'long': Serializer.serialize_long,
'bytearray': Serializer.serialize_bytearray,
'base64': Serializer.serialize_base64,
'object': self.serialize_object,
'[]': self.serialize_iter,
'{}': self.serialize_dict
Expand Down Expand Up @@ -541,6 +542,16 @@ def serialize_bytearray(attr, **kwargs):
"""
return b64encode(attr).decode()

@staticmethod
def serialize_base64(attr, **kwargs):
"""Serialize str into base-64 string.
:param attr: Object to be serialized.
:rtype: str
"""
encoded = b64encode(attr.encode()).decode()
return encoded.strip('=').replace('+', '-').replace('/', '_')

@staticmethod
def serialize_decimal(attr, **kwargs):
"""Serialize Decimal object to float.
Expand Down Expand Up @@ -675,6 +686,7 @@ def __init__(self, classes=None):
'decimal': Deserializer.deserialize_decimal,
'long': Deserializer.deserialize_long,
'bytearray': Deserializer.deserialize_bytearray,
'base64': Deserializer.deserialize_base64,
'object': self.deserialize_object,
'[]': self.deserialize_iter,
'{}': self.deserialize_dict
Expand Down Expand Up @@ -985,6 +997,20 @@ def deserialize_bytearray(attr):
"""
return bytearray(b64decode(attr))

@staticmethod
def deserialize_base64(attr):
"""Deserialize base64 encoded string into string.
:param str attr: response string to be deserialized.
:rtype: bytearray
:raises: TypeError if string format invalid.
"""
pad_count = 3 - (len(attr) + 3) % 4
padding = ['='] * pad_count
attr = attr + ''.join(padding)
encoded = attr.replace('-', '+').replace('_', '/')
return b64decode(encoded).decode()

@staticmethod
def deserialize_decimal(attr):
"""Deserialize string into Decimal object.
Expand Down

0 comments on commit 914f60f

Please sign in to comment.