Module moexalgo.utils
Expand source code
import decimal
import json as _json
from datetime import datetime, date, time
class RequiredImport:
def __init__(self, name):
self.__name = name
def __getattr__(self, item):
raise ImportError(f'Required `{self.__name}`')
try:
import pandas
except ImportError:
pandas = RequiredImport('pandas')
def is_interactive():
""" Возвращает `True` если код исполняется в интерактивном режиме, например в jupiter notebook
"""
import __main__ as main
return not hasattr(main, '__file__')
class json:
""" Расширение JSON енкодера
"""
loads = _json.loads
JSONDecodeError = _json.JSONDecodeError
@staticmethod
def dumps(*args, **kwargs):
"""
Parameters
----------
args
kwargs
Returns
-------
"""
def default(obj):
"""
Parameters
----------
obj
Returns
-------
"""
if isinstance(obj, decimal.Decimal):
return float(str(obj))
elif isinstance(obj, (datetime, date, time)):
return obj.isoformat()
raise TypeError
return _json.dumps(*args, **kwargs, default=default)
def result_deserializer(data: dict, *sections, key=None):
"""
Parameters
----------
data
sections
key
Returns
-------
"""
result = dict()
sections = sections or ('securities', 'marketdata')
for section in sections:
metadata = data[section]['metadata']
columns = data[section]['columns']
for values in data[section]['data']:
item = item_normalizer(metadata, dict(zip(columns, values)))
if key:
result.setdefault(section, dict())[key(item)] = item
else:
result.setdefault(section, list()).append(item)
return result
def item_normalizer(metadata, item):
"""
Parameters
----------
metadata
item
Returns
-------
"""
conv = {'int32': lambda s: int(s) if s is not None else None,
'int64': lambda s: int(s) if s is not None else None,
'double': lambda s: float(s) if s is not None else None,
'date': lambda s: date.fromisoformat(s.strip()) if s is not None and s != '0000-00-00' else None,
'datetime': lambda s: datetime.fromisoformat(s.strip()) if s is not None else None,
'time': lambda s: time.fromisoformat(s.strip()) if s is not None else None}
return dict((key, conv.get(metadata[key]['type'], str)(value)) for key, value in item.items())
Functions
def is_interactive()
-
Возвращает
True
если код исполняется в интерактивном режиме, например в jupiter notebookExpand source code
def is_interactive(): """ Возвращает `True` если код исполняется в интерактивном режиме, например в jupiter notebook """ import __main__ as main return not hasattr(main, '__file__')
def item_normalizer(metadata, item)
-
Parameters
metadata
item
Returns
Expand source code
def item_normalizer(metadata, item): """ Parameters ---------- metadata item Returns ------- """ conv = {'int32': lambda s: int(s) if s is not None else None, 'int64': lambda s: int(s) if s is not None else None, 'double': lambda s: float(s) if s is not None else None, 'date': lambda s: date.fromisoformat(s.strip()) if s is not None and s != '0000-00-00' else None, 'datetime': lambda s: datetime.fromisoformat(s.strip()) if s is not None else None, 'time': lambda s: time.fromisoformat(s.strip()) if s is not None else None} return dict((key, conv.get(metadata[key]['type'], str)(value)) for key, value in item.items())
def result_deserializer(data: dict, *sections, key=None)
-
Parameters
data
sections
key
Returns
Expand source code
def result_deserializer(data: dict, *sections, key=None): """ Parameters ---------- data sections key Returns ------- """ result = dict() sections = sections or ('securities', 'marketdata') for section in sections: metadata = data[section]['metadata'] columns = data[section]['columns'] for values in data[section]['data']: item = item_normalizer(metadata, dict(zip(columns, values))) if key: result.setdefault(section, dict())[key(item)] = item else: result.setdefault(section, list()).append(item) return result
Classes
class RequiredImport (name)
-
Expand source code
class RequiredImport: def __init__(self, name): self.__name = name def __getattr__(self, item): raise ImportError(f'Required `{self.__name}`')
class json
-
Расширение JSON енкодера
Expand source code
class json: """ Расширение JSON енкодера """ loads = _json.loads JSONDecodeError = _json.JSONDecodeError @staticmethod def dumps(*args, **kwargs): """ Parameters ---------- args kwargs Returns ------- """ def default(obj): """ Parameters ---------- obj Returns ------- """ if isinstance(obj, decimal.Decimal): return float(str(obj)) elif isinstance(obj, (datetime, date, time)): return obj.isoformat() raise TypeError return _json.dumps(*args, **kwargs, default=default)
Class variables
var JSONDecodeError
-
Subclass of ValueError with the following additional properties:
msg: The unformatted error message doc: The JSON document being parsed pos: The start index of doc where parsing failed lineno: The line corresponding to pos colno: The column corresponding to pos
Static methods
def dumps(*args, **kwargs)
-
Parameters
args
kwargs
Returns
Expand source code
@staticmethod def dumps(*args, **kwargs): """ Parameters ---------- args kwargs Returns ------- """ def default(obj): """ Parameters ---------- obj Returns ------- """ if isinstance(obj, decimal.Decimal): return float(str(obj)) elif isinstance(obj, (datetime, date, time)): return obj.isoformat() raise TypeError return _json.dumps(*args, **kwargs, default=default)
Methods
def loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
-
Deserialize
s
(astr
,bytes
orbytearray
instance containing a JSON document) to a Python object.object_hook
is an optional function that will be called with the result of any object literal decode (adict
). The return value ofobject_hook
will be used instead of thedict
. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting).object_pairs_hook
is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value ofobject_pairs_hook
will be used instead of thedict
. This feature can be used to implement custom decoders. Ifobject_hook
is also defined, theobject_pairs_hook
takes priority.parse_float
, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal).parse_int
, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float).parse_constant
, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered.To use a custom
JSONDecoder
subclass, specify it with thecls
kwarg; otherwiseJSONDecoder
is used.Expand source code
def loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ if isinstance(s, str): if s.startswith('\ufeff'): raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0) else: if not isinstance(s, (bytes, bytearray)): raise TypeError(f'the JSON object must be str, bytes or bytearray, ' f'not {s.__class__.__name__}') s = s.decode(detect_encoding(s), 'surrogatepass') if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s)