onetick-py 1.177.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- locator_parser/__init__.py +0 -0
- locator_parser/acl.py +73 -0
- locator_parser/actions.py +262 -0
- locator_parser/common.py +368 -0
- locator_parser/io.py +43 -0
- locator_parser/locator.py +150 -0
- onetick/__init__.py +101 -0
- onetick/doc_utilities/__init__.py +3 -0
- onetick/doc_utilities/napoleon.py +40 -0
- onetick/doc_utilities/ot_doctest.py +140 -0
- onetick/doc_utilities/snippets.py +279 -0
- onetick/lib/__init__.py +4 -0
- onetick/lib/instance.py +141 -0
- onetick/py/__init__.py +293 -0
- onetick/py/_stack_info.py +89 -0
- onetick/py/_version.py +2 -0
- onetick/py/aggregations/__init__.py +11 -0
- onetick/py/aggregations/_base.py +648 -0
- onetick/py/aggregations/_docs.py +948 -0
- onetick/py/aggregations/compute.py +286 -0
- onetick/py/aggregations/functions.py +2216 -0
- onetick/py/aggregations/generic.py +104 -0
- onetick/py/aggregations/high_low.py +80 -0
- onetick/py/aggregations/num_distinct.py +83 -0
- onetick/py/aggregations/order_book.py +501 -0
- onetick/py/aggregations/other.py +1014 -0
- onetick/py/backports.py +26 -0
- onetick/py/cache.py +374 -0
- onetick/py/callback/__init__.py +5 -0
- onetick/py/callback/callback.py +276 -0
- onetick/py/callback/callbacks.py +131 -0
- onetick/py/compatibility.py +798 -0
- onetick/py/configuration.py +771 -0
- onetick/py/core/__init__.py +0 -0
- onetick/py/core/_csv_inspector.py +93 -0
- onetick/py/core/_internal/__init__.py +0 -0
- onetick/py/core/_internal/_manually_bound_value.py +6 -0
- onetick/py/core/_internal/_nodes_history.py +250 -0
- onetick/py/core/_internal/_op_utils/__init__.py +0 -0
- onetick/py/core/_internal/_op_utils/every_operand.py +9 -0
- onetick/py/core/_internal/_op_utils/is_const.py +10 -0
- onetick/py/core/_internal/_per_tick_scripts/tick_list_sort_template.script +121 -0
- onetick/py/core/_internal/_proxy_node.py +140 -0
- onetick/py/core/_internal/_state_objects.py +2312 -0
- onetick/py/core/_internal/_state_vars.py +93 -0
- onetick/py/core/_source/__init__.py +0 -0
- onetick/py/core/_source/_symbol_param.py +95 -0
- onetick/py/core/_source/schema.py +97 -0
- onetick/py/core/_source/source_methods/__init__.py +0 -0
- onetick/py/core/_source/source_methods/aggregations.py +809 -0
- onetick/py/core/_source/source_methods/applyers.py +296 -0
- onetick/py/core/_source/source_methods/columns.py +141 -0
- onetick/py/core/_source/source_methods/data_quality.py +301 -0
- onetick/py/core/_source/source_methods/debugs.py +272 -0
- onetick/py/core/_source/source_methods/drops.py +120 -0
- onetick/py/core/_source/source_methods/fields.py +619 -0
- onetick/py/core/_source/source_methods/filters.py +1002 -0
- onetick/py/core/_source/source_methods/joins.py +1413 -0
- onetick/py/core/_source/source_methods/merges.py +605 -0
- onetick/py/core/_source/source_methods/misc.py +1455 -0
- onetick/py/core/_source/source_methods/pandases.py +155 -0
- onetick/py/core/_source/source_methods/renames.py +356 -0
- onetick/py/core/_source/source_methods/sorts.py +183 -0
- onetick/py/core/_source/source_methods/switches.py +142 -0
- onetick/py/core/_source/source_methods/symbols.py +117 -0
- onetick/py/core/_source/source_methods/times.py +627 -0
- onetick/py/core/_source/source_methods/writes.py +986 -0
- onetick/py/core/_source/symbol.py +205 -0
- onetick/py/core/_source/tmp_otq.py +222 -0
- onetick/py/core/column.py +209 -0
- onetick/py/core/column_operations/__init__.py +0 -0
- onetick/py/core/column_operations/_methods/__init__.py +4 -0
- onetick/py/core/column_operations/_methods/_internal.py +28 -0
- onetick/py/core/column_operations/_methods/conversions.py +216 -0
- onetick/py/core/column_operations/_methods/methods.py +292 -0
- onetick/py/core/column_operations/_methods/op_types.py +160 -0
- onetick/py/core/column_operations/accessors/__init__.py +0 -0
- onetick/py/core/column_operations/accessors/_accessor.py +28 -0
- onetick/py/core/column_operations/accessors/decimal_accessor.py +104 -0
- onetick/py/core/column_operations/accessors/dt_accessor.py +537 -0
- onetick/py/core/column_operations/accessors/float_accessor.py +184 -0
- onetick/py/core/column_operations/accessors/str_accessor.py +1367 -0
- onetick/py/core/column_operations/base.py +1121 -0
- onetick/py/core/cut_builder.py +150 -0
- onetick/py/core/db_constants.py +20 -0
- onetick/py/core/eval_query.py +245 -0
- onetick/py/core/lambda_object.py +441 -0
- onetick/py/core/multi_output_source.py +232 -0
- onetick/py/core/per_tick_script.py +2256 -0
- onetick/py/core/query_inspector.py +464 -0
- onetick/py/core/source.py +1744 -0
- onetick/py/db/__init__.py +2 -0
- onetick/py/db/_inspection.py +1128 -0
- onetick/py/db/db.py +1327 -0
- onetick/py/db/utils.py +64 -0
- onetick/py/docs/__init__.py +0 -0
- onetick/py/docs/docstring_parser.py +112 -0
- onetick/py/docs/utils.py +81 -0
- onetick/py/functions.py +2398 -0
- onetick/py/license.py +190 -0
- onetick/py/log.py +88 -0
- onetick/py/math.py +935 -0
- onetick/py/misc.py +470 -0
- onetick/py/oqd/__init__.py +22 -0
- onetick/py/oqd/eps.py +1195 -0
- onetick/py/oqd/sources.py +325 -0
- onetick/py/otq.py +216 -0
- onetick/py/pyomd_mock.py +47 -0
- onetick/py/run.py +916 -0
- onetick/py/servers.py +173 -0
- onetick/py/session.py +1347 -0
- onetick/py/sources/__init__.py +19 -0
- onetick/py/sources/cache.py +167 -0
- onetick/py/sources/common.py +128 -0
- onetick/py/sources/csv.py +642 -0
- onetick/py/sources/custom.py +85 -0
- onetick/py/sources/data_file.py +305 -0
- onetick/py/sources/data_source.py +1045 -0
- onetick/py/sources/empty.py +94 -0
- onetick/py/sources/odbc.py +337 -0
- onetick/py/sources/order_book.py +271 -0
- onetick/py/sources/parquet.py +168 -0
- onetick/py/sources/pit.py +191 -0
- onetick/py/sources/query.py +495 -0
- onetick/py/sources/snapshots.py +419 -0
- onetick/py/sources/split_query_output_by_symbol.py +198 -0
- onetick/py/sources/symbology_mapping.py +123 -0
- onetick/py/sources/symbols.py +374 -0
- onetick/py/sources/ticks.py +825 -0
- onetick/py/sql.py +70 -0
- onetick/py/state.py +251 -0
- onetick/py/types.py +2131 -0
- onetick/py/utils/__init__.py +70 -0
- onetick/py/utils/acl.py +93 -0
- onetick/py/utils/config.py +186 -0
- onetick/py/utils/default.py +49 -0
- onetick/py/utils/file.py +38 -0
- onetick/py/utils/helpers.py +76 -0
- onetick/py/utils/locator.py +94 -0
- onetick/py/utils/perf.py +498 -0
- onetick/py/utils/query.py +49 -0
- onetick/py/utils/render.py +1374 -0
- onetick/py/utils/script.py +244 -0
- onetick/py/utils/temp.py +471 -0
- onetick/py/utils/types.py +120 -0
- onetick/py/utils/tz.py +84 -0
- onetick_py-1.177.0.dist-info/METADATA +137 -0
- onetick_py-1.177.0.dist-info/RECORD +152 -0
- onetick_py-1.177.0.dist-info/WHEEL +5 -0
- onetick_py-1.177.0.dist-info/entry_points.txt +2 -0
- onetick_py-1.177.0.dist-info/licenses/LICENSE +21 -0
- onetick_py-1.177.0.dist-info/top_level.txt +2 -0
onetick/py/license.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import abc
|
|
3
|
+
import subprocess
|
|
4
|
+
import pandas as pd
|
|
5
|
+
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
import onetick.py as otp
|
|
8
|
+
|
|
9
|
+
from . import utils, configuration
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class _LicenseBase(abc.ABC):
|
|
13
|
+
def __init__(self, file, dir):
|
|
14
|
+
self._dir = dir
|
|
15
|
+
self._file = file
|
|
16
|
+
|
|
17
|
+
if otp.__webapi__:
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
if self._file is None:
|
|
21
|
+
raise ValueError("Something goes wrong, you pass None instead of path to license file")
|
|
22
|
+
|
|
23
|
+
if self._dir is not None and not os.path.exists(self._dir):
|
|
24
|
+
raise FileNotFoundError(f'"{self._dir}" license directory does not exist')
|
|
25
|
+
if not os.path.exists(self._file):
|
|
26
|
+
raise FileNotFoundError(f'"{self._file}" license file does not exist')
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def dir(self):
|
|
30
|
+
return self._dir
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def file(self):
|
|
34
|
+
return self._file
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Default(_LicenseBase):
|
|
38
|
+
"""
|
|
39
|
+
Default license path
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self):
|
|
43
|
+
default_file = configuration.config.default_license_file
|
|
44
|
+
default_dir = configuration.config.default_license_dir
|
|
45
|
+
if default_file is None and not otp.__webapi__:
|
|
46
|
+
raise ValueError(
|
|
47
|
+
"I can't understand the default license path :( Please, use "
|
|
48
|
+
"onetick.py.license.Custom to specify a path to license."
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
super().__init__(default_file, default_dir)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class Remote(_LicenseBase):
|
|
55
|
+
|
|
56
|
+
def __init__(self):
|
|
57
|
+
# remote license doesn't use local files
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def dir(self):
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def file(self):
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class Custom(_LicenseBase):
|
|
70
|
+
"""
|
|
71
|
+
Custom license path
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
# it is not useless
|
|
75
|
+
# pylint: disable=useless-parent-delegation
|
|
76
|
+
def __init__(self, file, directory=None):
|
|
77
|
+
"""
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
file: str, os.PathLike
|
|
81
|
+
Path to license file.
|
|
82
|
+
directory: str, os.PathLike, optional
|
|
83
|
+
Path to license directory. Default is None, that means it is not used.
|
|
84
|
+
"""
|
|
85
|
+
super().__init__(file, directory)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class Server(_LicenseBase):
|
|
89
|
+
"""
|
|
90
|
+
License that is based on license server. It generates new license file
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
def __init__(self, addresses=None, file=None, directory=None, reload=0):
|
|
94
|
+
"""
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
addresses: list of strings
|
|
98
|
+
List of ip address or domain names with ports where a license server is running.
|
|
99
|
+
For example: ['license.server.A:123', 'license.server.B:345']
|
|
100
|
+
file: str or PathLike, optional
|
|
101
|
+
License file path. Passed file path should exist. If file is not set or equal to None,
|
|
102
|
+
then temporary file will be used (temporary file lives while an instance lives).
|
|
103
|
+
NOTE: passed license file might be updated according to the 'reload' parameter.
|
|
104
|
+
directory: str or PathLike, optional
|
|
105
|
+
License directory path. Passed directory should exist. If directory is not set or
|
|
106
|
+
equal to None, then temporary directory will be used.
|
|
107
|
+
reload: 0 or offsets from onetick.py, ie onetick.py.Day, Hour, Month etc
|
|
108
|
+
Indicator to reload license from license server. 0 means that reload on creation,
|
|
109
|
+
offset means that if license file modification time more than offset, then it will
|
|
110
|
+
be updated from the server.
|
|
111
|
+
"""
|
|
112
|
+
self._generated = False
|
|
113
|
+
|
|
114
|
+
if file is None:
|
|
115
|
+
file = utils.TmpFile()
|
|
116
|
+
else:
|
|
117
|
+
if isinstance(reload, pd.tseries.offsets.Tick):
|
|
118
|
+
modify = datetime.fromtimestamp(os.path.getmtime(file))
|
|
119
|
+
current = datetime.now()
|
|
120
|
+
diff_ms = (current - modify).total_seconds() * 1000000
|
|
121
|
+
expire_ms = reload.nanos / 1000
|
|
122
|
+
|
|
123
|
+
if diff_ms < expire_ms:
|
|
124
|
+
self._generated = True
|
|
125
|
+
elif isinstance(reload, int):
|
|
126
|
+
if reload == 0:
|
|
127
|
+
# always generate
|
|
128
|
+
self._generated = False
|
|
129
|
+
else:
|
|
130
|
+
raise ValueError("You've passed not supported value to the 'reload' parameter")
|
|
131
|
+
else:
|
|
132
|
+
raise ValueError("You've passed not supported value to the 'reload' parameter")
|
|
133
|
+
|
|
134
|
+
if directory is None:
|
|
135
|
+
directory = utils.TmpDir()
|
|
136
|
+
|
|
137
|
+
super().__init__(file, directory)
|
|
138
|
+
|
|
139
|
+
self._servers = ",".join(addresses)
|
|
140
|
+
|
|
141
|
+
if not self._generated:
|
|
142
|
+
self.__generate()
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def servers(self):
|
|
146
|
+
return self._servers
|
|
147
|
+
|
|
148
|
+
def __generate(self):
|
|
149
|
+
class EnvVarScope:
|
|
150
|
+
def __init__(self, cfg):
|
|
151
|
+
self._env = None
|
|
152
|
+
self._cfg = cfg
|
|
153
|
+
|
|
154
|
+
def __enter__(self):
|
|
155
|
+
if "ONE_TICK_CONFIG" in os.environ:
|
|
156
|
+
self._env = os.environ["ONE_TICK_CONFIG"]
|
|
157
|
+
os.environ["ONE_TICK_CONFIG"] = str(self._cfg)
|
|
158
|
+
|
|
159
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
160
|
+
if self._env is None:
|
|
161
|
+
if "ONE_TICK_CONFIG" in os.environ:
|
|
162
|
+
del os.environ["ONE_TICK_CONFIG"]
|
|
163
|
+
else:
|
|
164
|
+
os.environ["ONE_TICK_CONFIG"] = self._env
|
|
165
|
+
|
|
166
|
+
tmp_locator = utils.tmp_locator(empty=True)
|
|
167
|
+
tmp_config = utils.tmp_config(
|
|
168
|
+
locator=tmp_locator, license_path=str(self.file), license_dir=self.dir, license_servers=self.servers
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
with EnvVarScope(tmp_config):
|
|
172
|
+
self.__generate_license()
|
|
173
|
+
|
|
174
|
+
self._generated = True
|
|
175
|
+
|
|
176
|
+
def __generate_license(self):
|
|
177
|
+
lic_generator = self.__license_getter_path(os.path.join(utils.omd_dist_path(), "one_tick", "bin"))
|
|
178
|
+
|
|
179
|
+
subprocess.run(
|
|
180
|
+
[lic_generator, "-features", "COLL,QUERY,LOAD"],
|
|
181
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
182
|
+
check=True,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
@staticmethod
|
|
186
|
+
def __license_getter_path(omd_dist_path):
|
|
187
|
+
license_getter = os.path.join(omd_dist_path, "local_license_getter.exe")
|
|
188
|
+
assert os.path.exists(license_getter), f"license getter is not found by {license_getter}"
|
|
189
|
+
|
|
190
|
+
return license_getter
|
onetick/py/log.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
import warnings
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from .configuration import config
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CustomStreamHandler(logging.StreamHandler):
|
|
11
|
+
# workaround for https://github.com/pytest-dev/pytest/issues/5502
|
|
12
|
+
# pytest doesn't work well when you initialize logging at import time
|
|
13
|
+
# and then try logging to stdout at application exit
|
|
14
|
+
# (we do it when deleting temporary files)
|
|
15
|
+
# in this case logging system writes very cumbersome error messages,
|
|
16
|
+
# so here we override them
|
|
17
|
+
def handleError(self, record):
|
|
18
|
+
if logging.raiseExceptions and sys.stderr:
|
|
19
|
+
try:
|
|
20
|
+
msg = self.format(record)
|
|
21
|
+
sys.stderr.write(msg + self.terminator)
|
|
22
|
+
sys.stderr.flush()
|
|
23
|
+
except Exception:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_stream_handler():
|
|
28
|
+
handler = CustomStreamHandler()
|
|
29
|
+
formatter = logging.Formatter('[%(asctime)s] %(levelname)s (%(name)s): %(message)s')
|
|
30
|
+
handler.setFormatter(formatter)
|
|
31
|
+
return handler
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
ROOT_LOGGER_NAME = 'onetick.py'
|
|
35
|
+
ROOT_LOGGER = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def __init_root_logger():
|
|
39
|
+
global ROOT_LOGGER
|
|
40
|
+
|
|
41
|
+
if ROOT_LOGGER is not None:
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
ROOT_LOGGER = logging.getLogger(ROOT_LOGGER_NAME)
|
|
45
|
+
ROOT_LOGGER.addHandler(logging.NullHandler())
|
|
46
|
+
|
|
47
|
+
if not config.logging:
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
if os.sep in config.logging:
|
|
51
|
+
config_file = Path(config.logging)
|
|
52
|
+
if not config_file.exists():
|
|
53
|
+
warnings.warn(f"Configuration file '{config_file}' doesn't exist, can't initialize logging system")
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
# Config file is crafted and loaded by user, so we can ignore SonarQube warnings
|
|
57
|
+
if config_file.suffix == '.json':
|
|
58
|
+
with config_file.open() as f:
|
|
59
|
+
json_data = json.load(f)
|
|
60
|
+
logging.config.dictConfig(json_data) # NOSONAR
|
|
61
|
+
else:
|
|
62
|
+
logging.config.fileConfig(config_file) # NOSONAR
|
|
63
|
+
else:
|
|
64
|
+
try:
|
|
65
|
+
ROOT_LOGGER.setLevel(config.logging)
|
|
66
|
+
except ValueError:
|
|
67
|
+
warnings.warn(f"Unknown logging level name: '{config.logging}', can't initialize logging system")
|
|
68
|
+
return
|
|
69
|
+
ROOT_LOGGER.addHandler(get_stream_handler())
|
|
70
|
+
|
|
71
|
+
ROOT_LOGGER.debug(f'Initialized {ROOT_LOGGER_NAME} logging system')
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
__init_root_logger()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_logger(*parts):
|
|
78
|
+
name = '.'.join(parts)
|
|
79
|
+
if not name.startswith(ROOT_LOGGER_NAME):
|
|
80
|
+
raise ValueError(f"Logger name '{name}' must start with root logger name '{ROOT_LOGGER_NAME}'")
|
|
81
|
+
logger = logging.getLogger(name)
|
|
82
|
+
return logger
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def get_debug_logger():
|
|
86
|
+
logger = logging.getLogger('onetick.py.otq_debug_mode')
|
|
87
|
+
logger.setLevel("DEBUG" if config.otq_debug_mode else "INFO")
|
|
88
|
+
return logger
|