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.
Files changed (226) hide show
  1. core_10x/__init__.py +47 -0
  2. core_10x/apps/__init__.py +0 -0
  3. core_10x/apps/runme_1st_app.py +81 -0
  4. core_10x/attic/__init__.py +0 -0
  5. core_10x/attic/backbone/__init__.py +0 -0
  6. core_10x/attic/backbone/backbone_store.py +59 -0
  7. core_10x/attic/backbone/backbone_traitable.py +30 -0
  8. core_10x/attic/backbone/backbone_user.py +67 -0
  9. core_10x/attic/backbone/bound_data_domain.py +49 -0
  10. core_10x/attic/backbone/vault.py +38 -0
  11. core_10x/attic/data_domain.py +48 -0
  12. core_10x/attic/data_domain_binder.py +45 -0
  13. core_10x/attic/entity.py +8 -0
  14. core_10x/attic/package_manifest.py +85 -0
  15. core_10x/attic/vault/__init__.py +0 -0
  16. core_10x/attic/vault/sec_keys.py +133 -0
  17. core_10x/attic/vault/security_keys_old.py +168 -0
  18. core_10x/attic/vault/vault.py +56 -0
  19. core_10x/attic/vault/vault_traitable.py +56 -0
  20. core_10x/attic/vault/vault_user.py +70 -0
  21. core_10x/code_samples/__init__.py +0 -0
  22. core_10x/code_samples/directories.py +181 -0
  23. core_10x/code_samples/person.py +93 -0
  24. core_10x/concrete_traits.py +356 -0
  25. core_10x/conftest.py +12 -0
  26. core_10x/curve.py +224 -0
  27. core_10x/directory.py +250 -0
  28. core_10x/environment_variables.py +174 -0
  29. core_10x/exec_control.py +84 -0
  30. core_10x/experimental/__init__.py +0 -0
  31. core_10x/experimental/data_protocol_ex.py +34 -0
  32. core_10x/global_cache.py +121 -0
  33. core_10x/manual_tests/__init__.py +0 -0
  34. core_10x/manual_tests/calendar_test.py +35 -0
  35. core_10x/manual_tests/ctor_update_bug.py +58 -0
  36. core_10x/manual_tests/debug_graph_on.py +17 -0
  37. core_10x/manual_tests/debug_graphoff_inside_graph_on.py +28 -0
  38. core_10x/manual_tests/enum_bits_test.py +17 -0
  39. core_10x/manual_tests/env_vars_trivial_test.py +12 -0
  40. core_10x/manual_tests/existing_traitable.py +33 -0
  41. core_10x/manual_tests/k10x_test1.py +13 -0
  42. core_10x/manual_tests/named_constant_test.py +121 -0
  43. core_10x/manual_tests/nucleus_trivial_test.py +42 -0
  44. core_10x/manual_tests/polars_test.py +14 -0
  45. core_10x/manual_tests/py_class_test.py +4 -0
  46. core_10x/manual_tests/rc_test.py +42 -0
  47. core_10x/manual_tests/rdate_test.py +12 -0
  48. core_10x/manual_tests/reference_serialization_bug.py +19 -0
  49. core_10x/manual_tests/resource_trivial_test.py +10 -0
  50. core_10x/manual_tests/store_uri_test.py +6 -0
  51. core_10x/manual_tests/trait_definition_test.py +19 -0
  52. core_10x/manual_tests/trait_filter_test.py +15 -0
  53. core_10x/manual_tests/trait_flag_modification_test.py +42 -0
  54. core_10x/manual_tests/trait_modification_bug.py +26 -0
  55. core_10x/manual_tests/traitable_as_of_test.py +82 -0
  56. core_10x/manual_tests/traitable_heir_test.py +39 -0
  57. core_10x/manual_tests/traitable_history_test.py +41 -0
  58. core_10x/manual_tests/traitable_serialization_test.py +54 -0
  59. core_10x/manual_tests/traitable_trivial_test.py +76 -0
  60. core_10x/manual_tests/trivial_graph_test.py +16 -0
  61. core_10x/manual_tests/ts_class_association_test.py +64 -0
  62. core_10x/manual_tests/ts_trivial_test.py +35 -0
  63. core_10x/manual_tests/vault_test.py +11 -0
  64. core_10x/named_constant.py +425 -0
  65. core_10x/nucleus.py +81 -0
  66. core_10x/package_refactoring.py +153 -0
  67. core_10x/py_class.py +431 -0
  68. core_10x/rc.py +167 -0
  69. core_10x/rdate.py +339 -0
  70. core_10x/resource.py +166 -0
  71. core_10x/roman_number.py +67 -0
  72. core_10x/sec_keys.py +183 -0
  73. core_10x/testlib/__init__.py +0 -0
  74. core_10x/testlib/test_store.py +240 -0
  75. core_10x/testlib/traitable_history_tests.py +787 -0
  76. core_10x/testlib/ts_tests.py +280 -0
  77. core_10x/trait.py +385 -0
  78. core_10x/trait_definition.py +176 -0
  79. core_10x/trait_filter.py +205 -0
  80. core_10x/trait_method_error.py +36 -0
  81. core_10x/traitable.py +1164 -0
  82. core_10x/traitable_cli.py +153 -0
  83. core_10x/traitable_heir.py +33 -0
  84. core_10x/traitable_id.py +31 -0
  85. core_10x/ts_store.py +189 -0
  86. core_10x/ts_store_type.py +26 -0
  87. core_10x/ts_union.py +147 -0
  88. core_10x/ui_hint.py +153 -0
  89. core_10x/unit_tests/test_concrete_traits.py +156 -0
  90. core_10x/unit_tests/test_converters.py +46 -0
  91. core_10x/unit_tests/test_core_version.py +10 -0
  92. core_10x/unit_tests/test_curve.py +138 -0
  93. core_10x/unit_tests/test_directory.py +54 -0
  94. core_10x/unit_tests/test_documentation.py +172 -0
  95. core_10x/unit_tests/test_environment_variables.py +15 -0
  96. core_10x/unit_tests/test_filters.py +239 -0
  97. core_10x/unit_tests/test_graph.py +348 -0
  98. core_10x/unit_tests/test_named_constant.py +98 -0
  99. core_10x/unit_tests/test_rc.py +11 -0
  100. core_10x/unit_tests/test_rdate.py +484 -0
  101. core_10x/unit_tests/test_trait_method_error.py +80 -0
  102. core_10x/unit_tests/test_trait_modification.py +19 -0
  103. core_10x/unit_tests/test_traitable.py +1044 -0
  104. core_10x/unit_tests/test_traitable_history.py +1 -0
  105. core_10x/unit_tests/test_ts_store.py +1 -0
  106. core_10x/unit_tests/test_ts_union.py +369 -0
  107. core_10x/unit_tests/test_ui_nodes.py +81 -0
  108. core_10x/unit_tests/test_xxcalendar.py +471 -0
  109. core_10x/vault_utils.py +132 -0
  110. core_10x/xdate_time.py +136 -0
  111. core_10x/xnone.py +71 -0
  112. core_10x/xxcalendar.py +224 -0
  113. dev_10x/.gitignore +1 -0
  114. dev_10x/__init__.py +4 -0
  115. dev_10x/uv_sync.py +161 -0
  116. dev_10x/version.py +34 -0
  117. infra_10x/__init__.py +4 -0
  118. infra_10x/manual_tests/__init__.py +0 -0
  119. infra_10x/manual_tests/test_misc.py +16 -0
  120. infra_10x/manual_tests/test_prepare_filter_and_pipeline.py +25 -0
  121. infra_10x/mongodb_admin.py +111 -0
  122. infra_10x/mongodb_store.py +346 -0
  123. infra_10x/mongodb_utils.py +129 -0
  124. infra_10x/namespace.py +101 -0
  125. infra_10x/unit_tests/conftest.py +14 -0
  126. infra_10x/unit_tests/test_infra_version.py +10 -0
  127. infra_10x/unit_tests/test_mongo_db.py +36 -0
  128. infra_10x/unit_tests/test_mongo_history.py +1 -0
  129. py10x_core-0.1.12.dist-info/METADATA +479 -0
  130. py10x_core-0.1.12.dist-info/RECORD +226 -0
  131. py10x_core-0.1.12.dist-info/WHEEL +4 -0
  132. py10x_core-0.1.12.dist-info/entry_points.txt +2 -0
  133. py10x_core-0.1.12.dist-info/licenses/LICENSE +21 -0
  134. py10x_core-0.1.12.dist-info/licenses/NOTICE +88 -0
  135. ui_10x/__init__.py +4 -0
  136. ui_10x/apps/__init__.py +0 -0
  137. ui_10x/apps/collection_editor_app.py +100 -0
  138. ui_10x/choice.py +212 -0
  139. ui_10x/collection_editor.py +135 -0
  140. ui_10x/concrete_trait_widgets.py +220 -0
  141. ui_10x/conftest.py +8 -0
  142. ui_10x/entity_stocker.py +173 -0
  143. ui_10x/examples/__init__.py +0 -0
  144. ui_10x/examples/_guess_word_data.py +14076 -0
  145. ui_10x/examples/collection_editor.py +17 -0
  146. ui_10x/examples/date_selector.py +14 -0
  147. ui_10x/examples/entity_stocker.py +18 -0
  148. ui_10x/examples/guess_word.py +392 -0
  149. ui_10x/examples/message_box.py +20 -0
  150. ui_10x/examples/multi_choice.py +17 -0
  151. ui_10x/examples/py_data_browser.py +66 -0
  152. ui_10x/examples/radiobox.py +29 -0
  153. ui_10x/examples/single_choice.py +31 -0
  154. ui_10x/examples/style_sheet.py +47 -0
  155. ui_10x/examples/trivial_entity_editor.py +18 -0
  156. ui_10x/platform.py +20 -0
  157. ui_10x/platform_interface.py +517 -0
  158. ui_10x/py_data_browser.py +249 -0
  159. ui_10x/qt6/__init__.py +0 -0
  160. ui_10x/qt6/conftest.py +8 -0
  161. ui_10x/qt6/manual_tests/__init__.py +0 -0
  162. ui_10x/qt6/manual_tests/basic_test.py +35 -0
  163. ui_10x/qt6/platform_implementation.py +275 -0
  164. ui_10x/qt6/utils.py +665 -0
  165. ui_10x/rio/__init__.py +0 -0
  166. ui_10x/rio/apps/examples/examples/__init__.py +22 -0
  167. ui_10x/rio/apps/examples/examples/components/__init__.py +3 -0
  168. ui_10x/rio/apps/examples/examples/components/collection_editor.py +15 -0
  169. ui_10x/rio/apps/examples/examples/pages/collection_editor.py +21 -0
  170. ui_10x/rio/apps/examples/examples/pages/login_page.py +88 -0
  171. ui_10x/rio/apps/examples/examples/pages/style_sheet.py +21 -0
  172. ui_10x/rio/apps/examples/rio.toml +14 -0
  173. ui_10x/rio/component_builder.py +497 -0
  174. ui_10x/rio/components/__init__.py +9 -0
  175. ui_10x/rio/components/group_box.py +31 -0
  176. ui_10x/rio/components/labeled_checkbox.py +18 -0
  177. ui_10x/rio/components/line_edit.py +37 -0
  178. ui_10x/rio/components/radio_button.py +32 -0
  179. ui_10x/rio/components/separator.py +24 -0
  180. ui_10x/rio/components/splitter.py +121 -0
  181. ui_10x/rio/components/tree_view.py +75 -0
  182. ui_10x/rio/conftest.py +35 -0
  183. ui_10x/rio/internals/__init__.py +0 -0
  184. ui_10x/rio/internals/app.py +192 -0
  185. ui_10x/rio/manual_tests/__init__.py +0 -0
  186. ui_10x/rio/manual_tests/basic_test.py +24 -0
  187. ui_10x/rio/manual_tests/splitter.py +27 -0
  188. ui_10x/rio/platform_implementation.py +91 -0
  189. ui_10x/rio/style_sheet.py +53 -0
  190. ui_10x/rio/unit_tests/test_collection_editor.py +68 -0
  191. ui_10x/rio/unit_tests/test_internals.py +630 -0
  192. ui_10x/rio/unit_tests/test_style_sheet.py +37 -0
  193. ui_10x/rio/widgets/__init__.py +46 -0
  194. ui_10x/rio/widgets/application.py +109 -0
  195. ui_10x/rio/widgets/button.py +48 -0
  196. ui_10x/rio/widgets/button_group.py +60 -0
  197. ui_10x/rio/widgets/calendar.py +23 -0
  198. ui_10x/rio/widgets/checkbox.py +24 -0
  199. ui_10x/rio/widgets/dialog.py +137 -0
  200. ui_10x/rio/widgets/group_box.py +27 -0
  201. ui_10x/rio/widgets/layout.py +34 -0
  202. ui_10x/rio/widgets/line_edit.py +37 -0
  203. ui_10x/rio/widgets/list.py +105 -0
  204. ui_10x/rio/widgets/message_box.py +70 -0
  205. ui_10x/rio/widgets/scroll_area.py +31 -0
  206. ui_10x/rio/widgets/spacer.py +6 -0
  207. ui_10x/rio/widgets/splitter.py +45 -0
  208. ui_10x/rio/widgets/text_edit.py +28 -0
  209. ui_10x/rio/widgets/tree.py +89 -0
  210. ui_10x/rio/widgets/unit_tests/test_button.py +101 -0
  211. ui_10x/rio/widgets/unit_tests/test_button_group.py +33 -0
  212. ui_10x/rio/widgets/unit_tests/test_calendar.py +114 -0
  213. ui_10x/rio/widgets/unit_tests/test_checkbox.py +109 -0
  214. ui_10x/rio/widgets/unit_tests/test_group_box.py +158 -0
  215. ui_10x/rio/widgets/unit_tests/test_label.py +43 -0
  216. ui_10x/rio/widgets/unit_tests/test_line_edit.py +140 -0
  217. ui_10x/rio/widgets/unit_tests/test_list.py +146 -0
  218. ui_10x/table_header_view.py +305 -0
  219. ui_10x/table_view.py +174 -0
  220. ui_10x/trait_editor.py +189 -0
  221. ui_10x/trait_widget.py +131 -0
  222. ui_10x/traitable_editor.py +200 -0
  223. ui_10x/traitable_view.py +131 -0
  224. ui_10x/unit_tests/conftest.py +8 -0
  225. ui_10x/unit_tests/test_platform.py +9 -0
  226. 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)
@@ -0,0 +1,8 @@
1
+ from core_10x.rc import RC, RC_TRUE
2
+ from core_10x.trait import Trait
3
+ from core_10x.trait_definition import RT, M, T, Ui
4
+ from core_10x.traitable import Traitable
5
+
6
+
7
+ # -- A higher-level Traitable to be used for general purposes
8
+ class Entity(Traitable): ...
@@ -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