py10x-core 0.1.12__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.
- core_10x/__init__.py +47 -0
- core_10x/apps/__init__.py +0 -0
- core_10x/apps/runme_1st_app.py +81 -0
- core_10x/attic/__init__.py +0 -0
- core_10x/attic/backbone/__init__.py +0 -0
- core_10x/attic/backbone/backbone_store.py +59 -0
- core_10x/attic/backbone/backbone_traitable.py +30 -0
- core_10x/attic/backbone/backbone_user.py +67 -0
- core_10x/attic/backbone/bound_data_domain.py +49 -0
- core_10x/attic/backbone/vault.py +38 -0
- core_10x/attic/data_domain.py +48 -0
- core_10x/attic/data_domain_binder.py +45 -0
- core_10x/attic/entity.py +8 -0
- core_10x/attic/package_manifest.py +85 -0
- core_10x/attic/vault/__init__.py +0 -0
- core_10x/attic/vault/sec_keys.py +133 -0
- core_10x/attic/vault/security_keys_old.py +168 -0
- core_10x/attic/vault/vault.py +56 -0
- core_10x/attic/vault/vault_traitable.py +56 -0
- core_10x/attic/vault/vault_user.py +70 -0
- core_10x/code_samples/__init__.py +0 -0
- core_10x/code_samples/directories.py +181 -0
- core_10x/code_samples/person.py +93 -0
- core_10x/concrete_traits.py +356 -0
- core_10x/conftest.py +12 -0
- core_10x/curve.py +224 -0
- core_10x/directory.py +250 -0
- core_10x/environment_variables.py +174 -0
- core_10x/exec_control.py +84 -0
- core_10x/experimental/__init__.py +0 -0
- core_10x/experimental/data_protocol_ex.py +34 -0
- core_10x/global_cache.py +121 -0
- core_10x/manual_tests/__init__.py +0 -0
- core_10x/manual_tests/calendar_test.py +35 -0
- core_10x/manual_tests/ctor_update_bug.py +58 -0
- core_10x/manual_tests/debug_graph_on.py +17 -0
- core_10x/manual_tests/debug_graphoff_inside_graph_on.py +28 -0
- core_10x/manual_tests/enum_bits_test.py +17 -0
- core_10x/manual_tests/env_vars_trivial_test.py +12 -0
- core_10x/manual_tests/existing_traitable.py +33 -0
- core_10x/manual_tests/k10x_test1.py +13 -0
- core_10x/manual_tests/named_constant_test.py +121 -0
- core_10x/manual_tests/nucleus_trivial_test.py +42 -0
- core_10x/manual_tests/polars_test.py +14 -0
- core_10x/manual_tests/py_class_test.py +4 -0
- core_10x/manual_tests/rc_test.py +42 -0
- core_10x/manual_tests/rdate_test.py +12 -0
- core_10x/manual_tests/reference_serialization_bug.py +19 -0
- core_10x/manual_tests/resource_trivial_test.py +10 -0
- core_10x/manual_tests/store_uri_test.py +6 -0
- core_10x/manual_tests/trait_definition_test.py +19 -0
- core_10x/manual_tests/trait_filter_test.py +15 -0
- core_10x/manual_tests/trait_flag_modification_test.py +42 -0
- core_10x/manual_tests/trait_modification_bug.py +26 -0
- core_10x/manual_tests/traitable_as_of_test.py +82 -0
- core_10x/manual_tests/traitable_heir_test.py +39 -0
- core_10x/manual_tests/traitable_history_test.py +41 -0
- core_10x/manual_tests/traitable_serialization_test.py +54 -0
- core_10x/manual_tests/traitable_trivial_test.py +76 -0
- core_10x/manual_tests/trivial_graph_test.py +16 -0
- core_10x/manual_tests/ts_class_association_test.py +64 -0
- core_10x/manual_tests/ts_trivial_test.py +35 -0
- core_10x/manual_tests/vault_test.py +11 -0
- core_10x/named_constant.py +425 -0
- core_10x/nucleus.py +81 -0
- core_10x/package_refactoring.py +153 -0
- core_10x/py_class.py +431 -0
- core_10x/rc.py +167 -0
- core_10x/rdate.py +339 -0
- core_10x/resource.py +166 -0
- core_10x/roman_number.py +67 -0
- core_10x/sec_keys.py +183 -0
- core_10x/testlib/__init__.py +0 -0
- core_10x/testlib/test_store.py +240 -0
- core_10x/testlib/traitable_history_tests.py +787 -0
- core_10x/testlib/ts_tests.py +280 -0
- core_10x/trait.py +385 -0
- core_10x/trait_definition.py +176 -0
- core_10x/trait_filter.py +205 -0
- core_10x/trait_method_error.py +36 -0
- core_10x/traitable.py +1164 -0
- core_10x/traitable_cli.py +153 -0
- core_10x/traitable_heir.py +33 -0
- core_10x/traitable_id.py +31 -0
- core_10x/ts_store.py +189 -0
- core_10x/ts_store_type.py +26 -0
- core_10x/ts_union.py +147 -0
- core_10x/ui_hint.py +153 -0
- core_10x/unit_tests/test_concrete_traits.py +156 -0
- core_10x/unit_tests/test_converters.py +46 -0
- core_10x/unit_tests/test_core_version.py +10 -0
- core_10x/unit_tests/test_curve.py +138 -0
- core_10x/unit_tests/test_directory.py +54 -0
- core_10x/unit_tests/test_documentation.py +172 -0
- core_10x/unit_tests/test_environment_variables.py +15 -0
- core_10x/unit_tests/test_filters.py +239 -0
- core_10x/unit_tests/test_graph.py +348 -0
- core_10x/unit_tests/test_named_constant.py +98 -0
- core_10x/unit_tests/test_rc.py +11 -0
- core_10x/unit_tests/test_rdate.py +484 -0
- core_10x/unit_tests/test_trait_method_error.py +80 -0
- core_10x/unit_tests/test_trait_modification.py +19 -0
- core_10x/unit_tests/test_traitable.py +1044 -0
- core_10x/unit_tests/test_traitable_history.py +1 -0
- core_10x/unit_tests/test_ts_store.py +1 -0
- core_10x/unit_tests/test_ts_union.py +369 -0
- core_10x/unit_tests/test_ui_nodes.py +81 -0
- core_10x/unit_tests/test_xxcalendar.py +471 -0
- core_10x/vault_utils.py +132 -0
- core_10x/xdate_time.py +136 -0
- core_10x/xnone.py +71 -0
- core_10x/xxcalendar.py +224 -0
- dev_10x/.gitignore +1 -0
- dev_10x/__init__.py +4 -0
- dev_10x/uv_sync.py +161 -0
- dev_10x/version.py +34 -0
- infra_10x/__init__.py +4 -0
- infra_10x/manual_tests/__init__.py +0 -0
- infra_10x/manual_tests/test_misc.py +16 -0
- infra_10x/manual_tests/test_prepare_filter_and_pipeline.py +25 -0
- infra_10x/mongodb_admin.py +111 -0
- infra_10x/mongodb_store.py +346 -0
- infra_10x/mongodb_utils.py +129 -0
- infra_10x/namespace.py +101 -0
- infra_10x/unit_tests/conftest.py +14 -0
- infra_10x/unit_tests/test_infra_version.py +10 -0
- infra_10x/unit_tests/test_mongo_db.py +36 -0
- infra_10x/unit_tests/test_mongo_history.py +1 -0
- py10x_core-0.1.12.dist-info/METADATA +479 -0
- py10x_core-0.1.12.dist-info/RECORD +226 -0
- py10x_core-0.1.12.dist-info/WHEEL +4 -0
- py10x_core-0.1.12.dist-info/entry_points.txt +2 -0
- py10x_core-0.1.12.dist-info/licenses/LICENSE +21 -0
- py10x_core-0.1.12.dist-info/licenses/NOTICE +88 -0
- ui_10x/__init__.py +4 -0
- ui_10x/apps/__init__.py +0 -0
- ui_10x/apps/collection_editor_app.py +100 -0
- ui_10x/choice.py +212 -0
- ui_10x/collection_editor.py +135 -0
- ui_10x/concrete_trait_widgets.py +220 -0
- ui_10x/conftest.py +8 -0
- ui_10x/entity_stocker.py +173 -0
- ui_10x/examples/__init__.py +0 -0
- ui_10x/examples/_guess_word_data.py +14076 -0
- ui_10x/examples/collection_editor.py +17 -0
- ui_10x/examples/date_selector.py +14 -0
- ui_10x/examples/entity_stocker.py +18 -0
- ui_10x/examples/guess_word.py +392 -0
- ui_10x/examples/message_box.py +20 -0
- ui_10x/examples/multi_choice.py +17 -0
- ui_10x/examples/py_data_browser.py +66 -0
- ui_10x/examples/radiobox.py +29 -0
- ui_10x/examples/single_choice.py +31 -0
- ui_10x/examples/style_sheet.py +47 -0
- ui_10x/examples/trivial_entity_editor.py +18 -0
- ui_10x/platform.py +20 -0
- ui_10x/platform_interface.py +517 -0
- ui_10x/py_data_browser.py +249 -0
- ui_10x/qt6/__init__.py +0 -0
- ui_10x/qt6/conftest.py +8 -0
- ui_10x/qt6/manual_tests/__init__.py +0 -0
- ui_10x/qt6/manual_tests/basic_test.py +35 -0
- ui_10x/qt6/platform_implementation.py +275 -0
- ui_10x/qt6/utils.py +665 -0
- ui_10x/rio/__init__.py +0 -0
- ui_10x/rio/apps/examples/examples/__init__.py +22 -0
- ui_10x/rio/apps/examples/examples/components/__init__.py +3 -0
- ui_10x/rio/apps/examples/examples/components/collection_editor.py +15 -0
- ui_10x/rio/apps/examples/examples/pages/collection_editor.py +21 -0
- ui_10x/rio/apps/examples/examples/pages/login_page.py +88 -0
- ui_10x/rio/apps/examples/examples/pages/style_sheet.py +21 -0
- ui_10x/rio/apps/examples/rio.toml +14 -0
- ui_10x/rio/component_builder.py +497 -0
- ui_10x/rio/components/__init__.py +9 -0
- ui_10x/rio/components/group_box.py +31 -0
- ui_10x/rio/components/labeled_checkbox.py +18 -0
- ui_10x/rio/components/line_edit.py +37 -0
- ui_10x/rio/components/radio_button.py +32 -0
- ui_10x/rio/components/separator.py +24 -0
- ui_10x/rio/components/splitter.py +121 -0
- ui_10x/rio/components/tree_view.py +75 -0
- ui_10x/rio/conftest.py +35 -0
- ui_10x/rio/internals/__init__.py +0 -0
- ui_10x/rio/internals/app.py +192 -0
- ui_10x/rio/manual_tests/__init__.py +0 -0
- ui_10x/rio/manual_tests/basic_test.py +24 -0
- ui_10x/rio/manual_tests/splitter.py +27 -0
- ui_10x/rio/platform_implementation.py +91 -0
- ui_10x/rio/style_sheet.py +53 -0
- ui_10x/rio/unit_tests/test_collection_editor.py +68 -0
- ui_10x/rio/unit_tests/test_internals.py +630 -0
- ui_10x/rio/unit_tests/test_style_sheet.py +37 -0
- ui_10x/rio/widgets/__init__.py +46 -0
- ui_10x/rio/widgets/application.py +109 -0
- ui_10x/rio/widgets/button.py +48 -0
- ui_10x/rio/widgets/button_group.py +60 -0
- ui_10x/rio/widgets/calendar.py +23 -0
- ui_10x/rio/widgets/checkbox.py +24 -0
- ui_10x/rio/widgets/dialog.py +137 -0
- ui_10x/rio/widgets/group_box.py +27 -0
- ui_10x/rio/widgets/layout.py +34 -0
- ui_10x/rio/widgets/line_edit.py +37 -0
- ui_10x/rio/widgets/list.py +105 -0
- ui_10x/rio/widgets/message_box.py +70 -0
- ui_10x/rio/widgets/scroll_area.py +31 -0
- ui_10x/rio/widgets/spacer.py +6 -0
- ui_10x/rio/widgets/splitter.py +45 -0
- ui_10x/rio/widgets/text_edit.py +28 -0
- ui_10x/rio/widgets/tree.py +89 -0
- ui_10x/rio/widgets/unit_tests/test_button.py +101 -0
- ui_10x/rio/widgets/unit_tests/test_button_group.py +33 -0
- ui_10x/rio/widgets/unit_tests/test_calendar.py +114 -0
- ui_10x/rio/widgets/unit_tests/test_checkbox.py +109 -0
- ui_10x/rio/widgets/unit_tests/test_group_box.py +158 -0
- ui_10x/rio/widgets/unit_tests/test_label.py +43 -0
- ui_10x/rio/widgets/unit_tests/test_line_edit.py +140 -0
- ui_10x/rio/widgets/unit_tests/test_list.py +146 -0
- ui_10x/table_header_view.py +305 -0
- ui_10x/table_view.py +174 -0
- ui_10x/trait_editor.py +189 -0
- ui_10x/trait_widget.py +131 -0
- ui_10x/traitable_editor.py +200 -0
- ui_10x/traitable_view.py +131 -0
- ui_10x/unit_tests/conftest.py +8 -0
- ui_10x/unit_tests/test_platform.py +9 -0
- ui_10x/utils.py +661 -0
core_10x/__init__.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# from os import path
|
|
2
|
+
#
|
|
3
|
+
# pp = path.dirname(path.abspath(__file__))
|
|
4
|
+
# path_to_core_10x = path.dirname(pp)
|
|
5
|
+
import atexit
|
|
6
|
+
|
|
7
|
+
from py10x_kernel import CORE_10X, PyLinkage, XCache
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# fmt: off
|
|
11
|
+
def cleanup():
|
|
12
|
+
XCache.clear()
|
|
13
|
+
PyLinkage.clear()
|
|
14
|
+
|
|
15
|
+
atexit.register(cleanup)
|
|
16
|
+
|
|
17
|
+
PyLinkage.init({
|
|
18
|
+
CORE_10X.PACKAGE_NAME: __name__,
|
|
19
|
+
|
|
20
|
+
CORE_10X.XNONE_MODULE_NAME: 'xnone',
|
|
21
|
+
CORE_10X.XNONE_CLASS_NAME: 'XNone',
|
|
22
|
+
|
|
23
|
+
CORE_10X.RC_MODULE_NAME: 'rc',
|
|
24
|
+
CORE_10X.RC_TRUE_NAME: 'RC_TRUE',
|
|
25
|
+
|
|
26
|
+
CORE_10X.NUCLEUS_MODULE_NAME: 'nucleus',
|
|
27
|
+
CORE_10X.NUCLEUS_CLASS_NAME: 'Nucleus',
|
|
28
|
+
|
|
29
|
+
CORE_10X.ANONYMOUS_MODULE_NAME: 'traitable',
|
|
30
|
+
CORE_10X.ANONYMOUS_CLASS_NAME: 'AnonymousTraitable',
|
|
31
|
+
|
|
32
|
+
CORE_10X.TRAITABLE_ID_MODULE_NAME: 'traitable_id',
|
|
33
|
+
CORE_10X.TRAITABLE_ID_CLASS_NAME: 'ID',
|
|
34
|
+
|
|
35
|
+
CORE_10X.TRAIT_METHOD_ERROR_MODULE_NAME: 'trait_method_error',
|
|
36
|
+
CORE_10X.TRAIT_METHOD_ERROR_CLASS_NAME: 'TraitMethodError',
|
|
37
|
+
|
|
38
|
+
CORE_10X.PACKAGE_REFACTORING_MODULE_NAME: 'package_refactoring',
|
|
39
|
+
CORE_10X.PACKAGE_REFACTORING_CLASS_NAME: 'PackageRefactoring',
|
|
40
|
+
CORE_10X.PACKAGE_REFACTORING_FIND_CLASS: 'find_class',
|
|
41
|
+
CORE_10X.PACKAGE_REFACTORING_FIND_CLASS_ID: 'find_class_id',
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
from dev_10x.version import __version__
|
|
46
|
+
except ImportError:
|
|
47
|
+
__version__ = '0.0.0+unknown' # fallback for dev envs
|
|
File without changes
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from core_10x.environment_variables import EnvVars
|
|
2
|
+
|
|
3
|
+
from core_10x.ts_store import TsStore, ResourceSpec
|
|
4
|
+
from core_10x.traitable import NamedTsStore, TsClassAssociation
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main(username: str = '', password: str = ''):
|
|
8
|
+
v_main_uri: EnvVars.Var = EnvVars.var.main_ts_store_uri
|
|
9
|
+
if not v_main_uri:
|
|
10
|
+
print(
|
|
11
|
+
f"""
|
|
12
|
+
Environment variable {EnvVars.var_name(v_main_uri.attr_name)} is not defined
|
|
13
|
+
Main Traitable Store is not specified, thus you must explicitly instantiate and use a particular Traitable Store, e.g.:
|
|
14
|
+
|
|
15
|
+
with TsStore.instance_from_uri('mongodb://public_mongo_host.abc.com/test'): #-- no authentication
|
|
16
|
+
# your code
|
|
17
|
+
...
|
|
18
|
+
|
|
19
|
+
or
|
|
20
|
+
|
|
21
|
+
#-- Authentication is required
|
|
22
|
+
password = 'a VeryStrongPassword!'
|
|
23
|
+
with TsStore.instance_from_uri('mongodb://protected_mongo_host.abc.com/test', username = 'xyz', password = password):
|
|
24
|
+
# your code
|
|
25
|
+
...
|
|
26
|
+
"""
|
|
27
|
+
)
|
|
28
|
+
#-- there is nothing more to do
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
print(
|
|
32
|
+
f"""
|
|
33
|
+
Main Traitable Store is specified (Environment variable {EnvVars.var_name(v_main_uri.attr_name)} = {v_main_uri.value})
|
|
34
|
+
It means that Traitable objects would be sought and saved in the above store.
|
|
35
|
+
"""
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
main_spec = TsStore.spec_from_uri(v_main_uri.value)
|
|
39
|
+
is_running, with_auth = main_spec.resource_class.is_running_with_auth(main_spec.hostname())
|
|
40
|
+
if not is_running:
|
|
41
|
+
print(f'Main Traitable Store {v_main_uri.value} is not running')
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
if with_auth:
|
|
45
|
+
print(f"Main Traitable Store {v_main_uri.value} requires authentication. Let's check if a Vault is specified." )
|
|
46
|
+
|
|
47
|
+
v_vault_uri = EnvVars.var.vault_ts_store_uri
|
|
48
|
+
if not v_vault_uri:
|
|
49
|
+
print(f"No Vault is specified (Environment variable {EnvVars.var_name(v_vault_uri.attr_name)} is not defined). Exiting...")
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
print(
|
|
53
|
+
f"""
|
|
54
|
+
Vault Store is specified (Environment variable {EnvVars.var_name(v_vault_uri.attr_name)} = {v_vault_uri.value})
|
|
55
|
+
It means that some Traitable Stores in use (as well as other resources) require authentication.
|
|
56
|
+
In order to use the Vault "automagically", you need to run "add_vault utiliry" entering your password to the Vault and your XX MasterPassword.
|
|
57
|
+
"""
|
|
58
|
+
)
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
main_store = main_spec.resource_class.instance(**main_spec.kwargs)
|
|
62
|
+
v_class_assoc = EnvVars.var.use_ts_store_per_class
|
|
63
|
+
if v_class_assoc:
|
|
64
|
+
print(
|
|
65
|
+
f"""
|
|
66
|
+
Different Traitable Stores may be used for different subclasses of Traitable (Environment variable {EnvVars.var_name(v_class_assoc.attr_name)} = {v_class_assoc.value})
|
|
67
|
+
Checking further...
|
|
68
|
+
"""
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
main_store.begin_using()
|
|
72
|
+
|
|
73
|
+
available_stores = NamedTsStore.load_many()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == '__main__':
|
|
77
|
+
|
|
78
|
+
import sys
|
|
79
|
+
|
|
80
|
+
main(*sys.argv[1:])
|
|
81
|
+
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from core_10x.environment_variables import EnvVars
|
|
2
|
+
from core_10x.global_cache import cache
|
|
3
|
+
from core_10x.ts_store import TsStore
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BackboneStore:
|
|
7
|
+
"""
|
|
8
|
+
Backbone Store instance should exist for every build area. It may be run with or without authentication required.
|
|
9
|
+
If authentication is required, it must have a special-purpose user SIDEKICK with read-only permissions and must have the following databases:
|
|
10
|
+
- admin
|
|
11
|
+
- _backbone_ - collections:
|
|
12
|
+
- bound data domains;
|
|
13
|
+
- users;
|
|
14
|
+
- user groups;
|
|
15
|
+
- ...
|
|
16
|
+
- _vault_ - collections of Resource Accessors (per username)
|
|
17
|
+
- _shadow_ - collections of 'Shadow' (user-password-encrypted private key) for each user (for exporting sec keys for a new user's computer)
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
# fmt: off
|
|
22
|
+
SIDEKICK_USER = 'sidekick'
|
|
23
|
+
BACKBONE_DB_NAME = '_backbone_'
|
|
24
|
+
VAULT_DB_NAME = '_vault_'
|
|
25
|
+
SHADOW_DB_NAME = '_shadow_'
|
|
26
|
+
# fmt: on
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
@cache
|
|
30
|
+
def bb_store(cls) -> TsStore: # -- BB Store
|
|
31
|
+
cls_name = EnvVars.backbone_store_class_name
|
|
32
|
+
cls.hostname = hostname = EnvVars.backbone_store_host_name
|
|
33
|
+
if not cls_name or not hostname:
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
cls.store_cls = store_cls = TsStore.store_class(cls_name)
|
|
37
|
+
|
|
38
|
+
is_running, with_auth = store_cls.is_running_with_auth(hostname)
|
|
39
|
+
if not is_running:
|
|
40
|
+
raise OSError(f'{store_cls.s_driver_name}({hostname}) is not running')
|
|
41
|
+
|
|
42
|
+
cls.with_auth = with_auth
|
|
43
|
+
if with_auth:
|
|
44
|
+
cls.username = cls.SIDEKICK_USER
|
|
45
|
+
cls.password = cls.SIDEKICK_USER
|
|
46
|
+
else:
|
|
47
|
+
cls.username = ''
|
|
48
|
+
cls.password = ''
|
|
49
|
+
|
|
50
|
+
return store_cls.instance(hostname=hostname, dbname=cls.BACKBONE_DB_NAME, username=cls.username, password=cls.password)
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
@cache
|
|
54
|
+
def store(cls, db_name: str) -> TsStore:
|
|
55
|
+
bb_store = cls.bb_store()
|
|
56
|
+
if db_name == cls.BACKBONE_DB_NAME:
|
|
57
|
+
return bb_store
|
|
58
|
+
|
|
59
|
+
return cls.store_cls.instance(hostname=cls.hostname, dbname=db_name, username=cls.username, password=cls.password)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from core_10x.attic.backbone.backbone_store import BackboneStore
|
|
6
|
+
from core_10x.traitable import T, Traitable, TraitDefinition
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from core_10x.traitable import RC
|
|
10
|
+
from core_10x.ts_store import TsStore
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BackboneTraitable(Traitable):
|
|
14
|
+
@classmethod
|
|
15
|
+
def build_trait_dir(cls) -> RC:
|
|
16
|
+
for trait_def in cls.__dict__.values():
|
|
17
|
+
if isinstance(trait_def, TraitDefinition):
|
|
18
|
+
trait_def.flags_change(T.EVAL_ONCE)
|
|
19
|
+
|
|
20
|
+
return Traitable.build_trait_dir()
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def store(cls) -> TsStore:
|
|
24
|
+
return BackboneStore.bb_store()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class VaultTraitable(BackboneTraitable):
|
|
28
|
+
@classmethod
|
|
29
|
+
def store(cls) -> TsStore:
|
|
30
|
+
return BackboneStore.store(BackboneStore.VAULT_DB_NAME)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from py10x_kernel import OsUser
|
|
4
|
+
|
|
5
|
+
from core_10x.traitable import RT, T
|
|
6
|
+
from core_10x.attic.backbone.backbone_traitable import BackboneTraitable
|
|
7
|
+
from infra_10x.namespace import FUNCTIONAL_ACCOUNT_PREFIX, USER_ADMIN_SUFFIX
|
|
8
|
+
from core_10x.global_cache import cache
|
|
9
|
+
from core_10x.trait_filter import f
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BackboneUserGroup(BackboneTraitable):
|
|
13
|
+
# fmt: off
|
|
14
|
+
name: str = T(T.ID)
|
|
15
|
+
description: str = T()
|
|
16
|
+
everyone: bool = T(False)
|
|
17
|
+
is_admin: bool = T(False)
|
|
18
|
+
is_reserved: bool = T(False)
|
|
19
|
+
builtin_roles: list = T()
|
|
20
|
+
user_ids: list = T()
|
|
21
|
+
|
|
22
|
+
users: set = RT()
|
|
23
|
+
# fmt: on
|
|
24
|
+
|
|
25
|
+
def users_get(self) -> set:
|
|
26
|
+
return set(self.user_ids)
|
|
27
|
+
|
|
28
|
+
def is_member(self, user_id: str) -> bool:
|
|
29
|
+
return user_id in self.users if not self.everyone else False
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class BackboneUser(BackboneTraitable):
|
|
33
|
+
# fmt: off
|
|
34
|
+
user_id: str = T(T.ID) // 'OS login'
|
|
35
|
+
suspended: bool = T(False)
|
|
36
|
+
public_key: bytes = T()
|
|
37
|
+
|
|
38
|
+
is_admin: bool = RT()
|
|
39
|
+
downloaded: bool = RT(False)
|
|
40
|
+
builtin_roles: list = RT()
|
|
41
|
+
# fmt: on
|
|
42
|
+
|
|
43
|
+
def user_id_get(self) -> str:
|
|
44
|
+
return OsUser.me.name()
|
|
45
|
+
|
|
46
|
+
def is_admin_get(self) -> bool:
|
|
47
|
+
for group in BackboneUserGroup.collection().find(f(is_admin=True)):
|
|
48
|
+
if group.is_member(self.user_id):
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
def admin_id(self) -> str:
|
|
54
|
+
return f'{self.user_id}_{USER_ADMIN_SUFFIX}' if self.is_admin else ''
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def regular_id(cls, admin_id: str) -> str:
|
|
58
|
+
return admin_id.split(f'_{USER_ADMIN_SUFFIX}')[0]
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def is_functional_account(cls, user_id: str) -> bool:
|
|
62
|
+
return user_id.split('-', 1) == FUNCTIONAL_ACCOUNT_PREFIX
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
@cache
|
|
66
|
+
def me(cls) -> BackboneUser:
|
|
67
|
+
return cls.existing_instance(user_id=OsUser.me.name())
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from core_10x.attic.backbone.backbone_traitable import RT, BackboneTraitable, T
|
|
2
|
+
from core_10x.attic.data_domain import DataDomain
|
|
3
|
+
from core_10x.environment_variables import EnvVars
|
|
4
|
+
from core_10x.resource import Resource
|
|
5
|
+
from core_10x.xnone import XNone
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ResourceSpec(BackboneTraitable):
|
|
9
|
+
# fmt: off
|
|
10
|
+
build_area: str = T(T.ID)
|
|
11
|
+
name: str = T(T.ID)
|
|
12
|
+
resource_class: type = T()
|
|
13
|
+
resource_kwargs: dict = T()
|
|
14
|
+
|
|
15
|
+
resource: Resource = RT()
|
|
16
|
+
# fmt: on
|
|
17
|
+
|
|
18
|
+
def build_area_get(self) -> str:
|
|
19
|
+
return EnvVars.sdlc_area
|
|
20
|
+
|
|
21
|
+
def name_get(self) -> str:
|
|
22
|
+
kwargs = self.resource_kwargs
|
|
23
|
+
return kwargs.get(Resource.HOSTNAME_TAG, XNone)
|
|
24
|
+
|
|
25
|
+
def resource_get(self) -> Resource:
|
|
26
|
+
cls = self.resource_class
|
|
27
|
+
assert issubclass(cls, Resource), f'{cls} is not a subclass of Resource'
|
|
28
|
+
return cls.instance(**self.resource_kwargs)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class BoundDataDomain(BackboneTraitable):
|
|
32
|
+
# fmt: off
|
|
33
|
+
domain: DataDomain.__class__ = T(T.ID)
|
|
34
|
+
build_area: str = T(T.ID)
|
|
35
|
+
bound_categories: dict = T()
|
|
36
|
+
# fmt: on
|
|
37
|
+
|
|
38
|
+
def build_area_get(self) -> str:
|
|
39
|
+
return EnvVars.sdlc_area
|
|
40
|
+
|
|
41
|
+
def resource(self, category: str, throw: bool = True) -> Resource:
|
|
42
|
+
r_spec_id: str = self.bound_categories.get(category)
|
|
43
|
+
if not r_spec_id:
|
|
44
|
+
if throw:
|
|
45
|
+
raise ValueError(f'{self.domain} - unknown category {category}')
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
r_spec = ResourceSpec(_id=r_spec_id)
|
|
49
|
+
return r_spec.resource
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
from core_10x.attic.backbone.backbone_traitable import RC, T, VaultTraitable
|
|
4
|
+
from core_10x.attic.vault import SecKeys
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ResourceAccessor(VaultTraitable):
|
|
8
|
+
# fmt: off
|
|
9
|
+
resource_name: str = T(T.ID)
|
|
10
|
+
#username: str = T(T.ID)
|
|
11
|
+
|
|
12
|
+
login: str = T()
|
|
13
|
+
password: bytes = T()
|
|
14
|
+
last_updated: datetime = T()
|
|
15
|
+
# fmt: on
|
|
16
|
+
|
|
17
|
+
def last_updated_get(self) -> datetime:
|
|
18
|
+
return datetime.utcnow()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Vault:
|
|
22
|
+
ANY_HOST = '.'
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def save_resource_accessor(username: str, hostname: str, login: str, password: str, public_key: bytes = None) -> RC:
|
|
26
|
+
assert login and password, 'login and password must not be empty'
|
|
27
|
+
|
|
28
|
+
pwd = SecKeys.encrypt(password, public_key=public_key)
|
|
29
|
+
if pwd is None:
|
|
30
|
+
return RC(False, 'Security Keys are missing. If you are using a new computer, please run "xx user new machine" from your shell')
|
|
31
|
+
|
|
32
|
+
ra = ResourceAccessor(hostname=hostname)
|
|
33
|
+
ra.reload()
|
|
34
|
+
rc = ra.set_values(login=login, password=pwd)
|
|
35
|
+
if not rc:
|
|
36
|
+
return rc
|
|
37
|
+
|
|
38
|
+
ra.save()
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from core_10x.resource import TS_STORE, ResourceRequirements
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _raise_type_error(cls, **kwargs):
|
|
7
|
+
raise TypeError(f'{cls} - subclassing is not allowed')
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DataDomain:
|
|
11
|
+
s_dir = {}
|
|
12
|
+
|
|
13
|
+
s_resource_requirements = {}
|
|
14
|
+
|
|
15
|
+
def __init_subclass__(cls, **kwargs):
|
|
16
|
+
name = cls.name()
|
|
17
|
+
ed = DataDomain.s_dir.get(name)
|
|
18
|
+
assert ed is None, f"DataDomain '{name}' is already registered in {ed}"
|
|
19
|
+
DataDomain.s_dir[name] = cls
|
|
20
|
+
|
|
21
|
+
cls.__init_subclass__ = lambda **kwargs: _raise_type_error(cls, **kwargs)
|
|
22
|
+
category: str
|
|
23
|
+
rrs = cls.s_resource_requirements
|
|
24
|
+
for category, resource_reqs in cls.__dict__.items():
|
|
25
|
+
if isinstance(resource_reqs, ResourceRequirements):
|
|
26
|
+
assert category.isupper(), f"Category '{category}' must be an uppercase name"
|
|
27
|
+
resource_reqs.domain = cls
|
|
28
|
+
resource_reqs.category = category
|
|
29
|
+
rrs[category] = resource_reqs
|
|
30
|
+
|
|
31
|
+
assert rrs, f"DataDomain '{cls} must define at least one category"
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def name(cls: str) -> str:
|
|
35
|
+
return re.sub(r'([a-z])([A-Z])', r'\1_\2', cls.__qualname__).upper()
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
def resource_requirement(cls, category: str, throw: bool = True) -> ResourceRequirements:
|
|
39
|
+
rr = cls.s_resource_requirements.get(category)
|
|
40
|
+
if rr is None and throw:
|
|
41
|
+
raise ValueError(f"DataDomain {cls} - unknown category '{category}'")
|
|
42
|
+
|
|
43
|
+
return rr
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class GeneralDomain(DataDomain):
|
|
47
|
+
GENERAL = TS_STORE()
|
|
48
|
+
...
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from core_10x.environment_variables import EnvVars
|
|
2
|
+
from core_10x.global_cache import cache
|
|
3
|
+
from core_10x.py_class import PyClass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# ===================================================================================================================================
|
|
7
|
+
# Data Domain Bindings
|
|
8
|
+
#
|
|
9
|
+
# from core_10x.data_domain import GeneralDomain
|
|
10
|
+
# from xxx.yyy.mdu_domain import MDU
|
|
11
|
+
# ...
|
|
12
|
+
# DATA_DOMAIN_BINDINGS = dict(
|
|
13
|
+
# dev = {
|
|
14
|
+
# GeneralDomain: dict(
|
|
15
|
+
# GENERAL = R(TS_STORE.MONGO_DB, hostname = 'dev.mongo.general.io', tsl = True, ...),
|
|
16
|
+
# ),
|
|
17
|
+
#
|
|
18
|
+
# MDU: dict(
|
|
19
|
+
# SYMBOLOGY = R(REL_DB.ORACLE_DB, hostname = 'dev.oracle.io', a = '...', b = '...'),
|
|
20
|
+
# MKT_CLOSE_CLUSTER = R(CLOUD_CLUSTER.RAY_CLUSTER, hostname = 'dev.ray1.io', ...),
|
|
21
|
+
# ),
|
|
22
|
+
# },
|
|
23
|
+
#
|
|
24
|
+
# prod = {
|
|
25
|
+
# GeneralDomain: dict(
|
|
26
|
+
# GENERAL = R(TS_STORE.MONGO_DB, hostname = 'prod.mongo.general.io', tsl = True, ...),
|
|
27
|
+
# ),
|
|
28
|
+
#
|
|
29
|
+
# MDU: dict(
|
|
30
|
+
# SYMBOLOGY = R(REL_DB.ORACLE_DB, hostname = 'prod.oracle.io', a = '...', b = '...'),
|
|
31
|
+
# MKT_CLOSE_CLUSTER = R(CLOUD_CLUSTER.RAY_CLUSTER, hostname = 'prod.ray2.io', ...),
|
|
32
|
+
# ),
|
|
33
|
+
# },
|
|
34
|
+
#
|
|
35
|
+
# )
|
|
36
|
+
# ===================================================================================================================================
|
|
37
|
+
class DataDomainBinder:
|
|
38
|
+
@staticmethod
|
|
39
|
+
@cache
|
|
40
|
+
def all_bindings() -> dict:
|
|
41
|
+
dd_bindings_symbol = EnvVars.data_domain_bindings
|
|
42
|
+
if not dd_bindings_symbol:
|
|
43
|
+
return None
|
|
44
|
+
|
|
45
|
+
return PyClass.find_symbol(dd_bindings_symbol)
|
core_10x/attic/entity.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from core_10x.attic.data_domain import GeneralDomain
|
|
6
|
+
from core_10x.py_class import PyClass
|
|
7
|
+
from core_10x.resource import TS_STORE
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from core_10x.resource import ResourceRequirements
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PackageManifest:
|
|
14
|
+
"""
|
|
15
|
+
To associate a subclass of Traitable to a particular Data Domain Category
|
|
16
|
+
it must have a record in a package manifest file.
|
|
17
|
+
Example:
|
|
18
|
+
# module x.etrading_domain
|
|
19
|
+
class ETradingDomain(DataDomain):
|
|
20
|
+
GENERAL = TS_STORE()
|
|
21
|
+
ORDERS = TS_STORE()
|
|
22
|
+
ALGO_ORDERS = TS_STORE()
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
#module x.y.order
|
|
26
|
+
class Order(Traitable):
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
class AlgoOrder(Order):
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
#module x.y._package_manifest
|
|
34
|
+
from x.etrading_domain import ETradingDomain as ET
|
|
35
|
+
|
|
36
|
+
manifest = dict( #-- variable manifest: dict must be defined as follows
|
|
37
|
+
_category = ET.GENERAL, #-- default category for Traitables in x.y package, if any
|
|
38
|
+
|
|
39
|
+
order = dict( #-- specific association(s) for any module inside x.y package, if any
|
|
40
|
+
_category = ET.ORDERS #-- default category for Traitables in x.y.order, if any
|
|
41
|
+
|
|
42
|
+
AlgoOrder = ET.ALGO_ORDERS #-- specific association class x.y.order.AlgoOrder, if any
|
|
43
|
+
...
|
|
44
|
+
),
|
|
45
|
+
...
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
If no association could be found for a subclass of Traitable, the default association will be used: GeneralDomain.GENERAL
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
# fmt: off
|
|
52
|
+
SYMBOL = '_package_manifest.manifest'
|
|
53
|
+
CATEGORY = '_category'
|
|
54
|
+
# fmt: on
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def _resource_requirements(cls) -> ResourceRequirements:
|
|
58
|
+
module = cls.__module__
|
|
59
|
+
parts = module.split('.')
|
|
60
|
+
if len(parts) < 2:
|
|
61
|
+
return None # -- should be at least package.module, so it's most probably '__main__.Class'
|
|
62
|
+
|
|
63
|
+
package = '.'.join(parts[:-1])
|
|
64
|
+
man_def: dict = PyClass.find_symbol(f'{package}.{PackageManifest.SYMBOL}')
|
|
65
|
+
if not man_def:
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
short_module = parts[-1]
|
|
69
|
+
module_entry = man_def.get(short_module)
|
|
70
|
+
if module_entry:
|
|
71
|
+
rr: ResourceRequirements = module_entry.get(cls.__name__)
|
|
72
|
+
if not rr:
|
|
73
|
+
rr = module_entry.get(PackageManifest.CATEGORY)
|
|
74
|
+
if rr:
|
|
75
|
+
return rr
|
|
76
|
+
|
|
77
|
+
return man_def.get(PackageManifest.CATEGORY)
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def resource_requirements(cls) -> ResourceRequirements:
|
|
81
|
+
rr = PackageManifest._resource_requirements(cls) or GeneralDomain.GENERAL
|
|
82
|
+
assert rr.resource_type is TS_STORE, f'{cls} - invalid category in the _package_manifest'
|
|
83
|
+
return rr
|
|
84
|
+
|
|
85
|
+
# -- TODO: handle parent classes, if ResourceRequirements for the class in not found
|
|
File without changes
|