diff --git a/azure/functions/_cosmosdb.py b/azure/functions/_cosmosdb.py index b9a4de1c..dcdf01c6 100644 --- a/azure/functions/_cosmosdb.py +++ b/azure/functions/_cosmosdb.py @@ -2,9 +2,9 @@ # Licensed under the MIT License. import collections -import json from . import _abc +from ._jsonutils import json class Document(_abc.Document, collections.UserDict): diff --git a/azure/functions/_http.py b/azure/functions/_http.py index 7e349b1b..267425c4 100644 --- a/azure/functions/_http.py +++ b/azure/functions/_http.py @@ -4,10 +4,10 @@ import collections.abc import http import io -import json import types import typing +from ._jsonutils import json from werkzeug import formparser as _wk_parser from werkzeug import http as _wk_http from werkzeug.datastructures import (Headers, FileStorage, MultiDict, diff --git a/azure/functions/_jsonutils.py b/azure/functions/_jsonutils.py new file mode 100644 index 00000000..2ee0e256 --- /dev/null +++ b/azure/functions/_jsonutils.py @@ -0,0 +1,78 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +from abc import ABC, abstractmethod +from typing import Any, Union +from types import SimpleNamespace + + +""" +Azure Functions JSON utilities. +This module provides a JSON interface that can be used to serialize and +deserialize objects to and from JSON format. It supports both the `orjson` +and the standard `json` libraries, falling back to the standard library +if `orjson` is not available (installed). +""" + + +try: + import orjson as _orjson +except ImportError: + _orjson = None + +# Standard library is always present +import json as _std_json + + +class JsonInterface(ABC): + @abstractmethod + def dumps(self, obj: Any) -> str: + pass + + @abstractmethod + def loads(self, s: Union[str, bytes, bytearray]) -> Any: + pass + + +class OrJsonAdapter(JsonInterface): + def __init__(self): + assert _orjson is not None + self.orjson = _orjson + + def dumps(self, obj: Any) -> str: + # orjson.dumps returns bytes, decode to str + return self.orjson.dumps(obj).decode("utf-8") + + def loads(self, s: Union[str, bytes, bytearray]) -> Any: + return self.orjson.loads(s) + + +class StdJsonAdapter(JsonInterface): + def __init__(self): + self.json = _std_json + + def dumps(self, obj: Any) -> str: + return self.json.dumps(obj) + + def loads(self, s: Union[str, bytes, bytearray]) -> Any: + return self.json.loads(s) + + +if _orjson is not None: + json_impl = OrJsonAdapter() +else: + json_impl = StdJsonAdapter() + + +def dumps(obj: Any) -> str: + return json_impl.dumps(obj) + + +def loads(s: Union[str, bytes, bytearray]) -> Any: + return json_impl.loads(s) + + +json = SimpleNamespace( + dumps=dumps, + loads=loads +) diff --git a/azure/functions/_mysql.py b/azure/functions/_mysql.py index 9c7515d9..1f6b4072 100644 --- a/azure/functions/_mysql.py +++ b/azure/functions/_mysql.py @@ -2,7 +2,8 @@ # Licensed under the MIT License. import abc import collections -import json + +from ._jsonutils import json class BaseMySqlRow(abc.ABC): diff --git a/azure/functions/_queue.py b/azure/functions/_queue.py index c6c7d094..85d574ce 100644 --- a/azure/functions/_queue.py +++ b/azure/functions/_queue.py @@ -2,10 +2,10 @@ # Licensed under the MIT License. import datetime -import json import typing from . import _abc +from ._jsonutils import json class QueueMessage(_abc.QueueMessage): diff --git a/azure/functions/_sql.py b/azure/functions/_sql.py index 3d70a1a9..166b3af4 100644 --- a/azure/functions/_sql.py +++ b/azure/functions/_sql.py @@ -2,7 +2,8 @@ # Licensed under the MIT License. import abc import collections -import json + +from ._jsonutils import json class BaseSqlRow(abc.ABC): diff --git a/azure/functions/cosmosdb.py b/azure/functions/cosmosdb.py index 1edc78af..e8dc139f 100644 --- a/azure/functions/cosmosdb.py +++ b/azure/functions/cosmosdb.py @@ -2,10 +2,10 @@ # Licensed under the MIT License. import collections.abc -import json import typing from azure.functions import _cosmosdb as cdb +from ._jsonutils import json from . import meta diff --git a/azure/functions/eventgrid.py b/azure/functions/eventgrid.py index e76f5dde..3cddd9e1 100644 --- a/azure/functions/eventgrid.py +++ b/azure/functions/eventgrid.py @@ -3,10 +3,10 @@ import collections import datetime -import json from typing import Optional, List, Any, Dict, Union from azure.functions import _eventgrid as azf_eventgrid +from ._jsonutils import json from . import meta from .meta import Datum diff --git a/azure/functions/eventhub.py b/azure/functions/eventhub.py index 6aab2be5..8888aaed 100644 --- a/azure/functions/eventhub.py +++ b/azure/functions/eventhub.py @@ -1,10 +1,10 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -import json from typing import Dict, Any, List, Union, Optional, Mapping from azure.functions import _eventhub +from ._jsonutils import json from . import meta diff --git a/azure/functions/extension/extension_meta.py b/azure/functions/extension/extension_meta.py index 2536d6fb..fde3622f 100644 --- a/azure/functions/extension/extension_meta.py +++ b/azure/functions/extension/extension_meta.py @@ -3,12 +3,12 @@ from typing import Optional, Union, Dict, List import abc -import json from .app_extension_hooks import AppExtensionHooks from .func_extension_hooks import FuncExtensionHooks from .extension_hook_meta import ExtensionHookMeta from .extension_scope import ExtensionScope from .function_extension_exception import FunctionExtensionException +from .._jsonutils import json class ExtensionMeta(abc.ABCMeta): diff --git a/azure/functions/http.py b/azure/functions/http.py index 734f43eb..5a9e10c3 100644 --- a/azure/functions/http.py +++ b/azure/functions/http.py @@ -1,7 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -import json import logging import sys import typing @@ -10,6 +9,7 @@ from azure.functions import _abc as azf_abc from azure.functions import _http as azf_http from . import meta +from ._jsonutils import json from werkzeug.datastructures import Headers diff --git a/azure/functions/kafka.py b/azure/functions/kafka.py index 4693e9d1..f71bb2c4 100644 --- a/azure/functions/kafka.py +++ b/azure/functions/kafka.py @@ -2,11 +2,11 @@ # Licensed under the MIT License. import typing -import json from typing import Any, List from . import meta +from ._jsonutils import json from ._kafka import AbstractKafkaEvent diff --git a/azure/functions/meta.py b/azure/functions/meta.py index 2ca92563..09314f8d 100644 --- a/azure/functions/meta.py +++ b/azure/functions/meta.py @@ -4,10 +4,10 @@ import abc import collections.abc import datetime -import json import re from typing import Dict, Optional, Union, Tuple, Mapping, Any +from ._jsonutils import json from ._thirdparty import typing_inspect from ._utils import ( try_parse_datetime_with_formats, diff --git a/azure/functions/mysql.py b/azure/functions/mysql.py index 06a04a56..cbaf18e7 100644 --- a/azure/functions/mysql.py +++ b/azure/functions/mysql.py @@ -2,12 +2,12 @@ # Licensed under the MIT License. import collections.abc -import json import typing from azure.functions import _mysql as mysql from . import meta +from ._jsonutils import json class MySqlConverter(meta.InConverter, meta.OutConverter, diff --git a/azure/functions/queue.py b/azure/functions/queue.py index d39c56e5..77b8354d 100644 --- a/azure/functions/queue.py +++ b/azure/functions/queue.py @@ -3,13 +3,13 @@ import collections.abc import datetime -import json from typing import List, Dict, Any, Union, Optional from azure.functions import _abc as azf_abc from azure.functions import _queue as azf_queue from . import meta +from ._jsonutils import json class QueueMessage(azf_queue.QueueMessage): diff --git a/azure/functions/servicebus.py b/azure/functions/servicebus.py index 72a9d254..bc04bfde 100644 --- a/azure/functions/servicebus.py +++ b/azure/functions/servicebus.py @@ -2,12 +2,12 @@ # Licensed under the MIT License. import datetime -import json from typing import Dict, Any, List, Union, Optional, Mapping, cast from azure.functions import _servicebus as azf_sbus from . import meta +from ._jsonutils import json class ServiceBusMessage(azf_sbus.ServiceBusMessage): diff --git a/azure/functions/sql.py b/azure/functions/sql.py index f8288303..d385ee6e 100644 --- a/azure/functions/sql.py +++ b/azure/functions/sql.py @@ -2,12 +2,12 @@ # Licensed under the MIT License. import collections.abc -import json import typing from azure.functions import _sql as sql from . import meta +from ._jsonutils import json class SqlConverter(meta.InConverter, meta.OutConverter, diff --git a/azure/functions/timer.py b/azure/functions/timer.py index 92ef71c3..87d0fd36 100644 --- a/azure/functions/timer.py +++ b/azure/functions/timer.py @@ -1,11 +1,11 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -import json import typing from azure.functions import _abc as azf_abc from . import meta +from ._jsonutils import json class TimerRequest(azf_abc.TimerRequest):