py10x-universe 0.1.3__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 (214) hide show
  1. core_10x/__init__.py +42 -0
  2. core_10x/backbone/__init__.py +0 -0
  3. core_10x/backbone/backbone_store.py +59 -0
  4. core_10x/backbone/backbone_traitable.py +30 -0
  5. core_10x/backbone/backbone_user.py +66 -0
  6. core_10x/backbone/bound_data_domain.py +49 -0
  7. core_10x/backbone/namespace.py +101 -0
  8. core_10x/backbone/vault.py +38 -0
  9. core_10x/code_samples/__init__.py +0 -0
  10. core_10x/code_samples/_package_manifest.py +3 -0
  11. core_10x/code_samples/directories.py +181 -0
  12. core_10x/code_samples/person.py +76 -0
  13. core_10x/concrete_traits.py +356 -0
  14. core_10x/conftest.py +12 -0
  15. core_10x/curve.py +321 -0
  16. core_10x/data_domain.py +48 -0
  17. core_10x/data_domain_binder.py +45 -0
  18. core_10x/directory.py +250 -0
  19. core_10x/entity.py +8 -0
  20. core_10x/entity_filter.py +5 -0
  21. core_10x/environment_variables.py +147 -0
  22. core_10x/exec_control.py +84 -0
  23. core_10x/experimental/__init__.py +0 -0
  24. core_10x/experimental/data_protocol_ex.py +34 -0
  25. core_10x/global_cache.py +121 -0
  26. core_10x/manual_tests/__init__.py +0 -0
  27. core_10x/manual_tests/calendar_test.py +35 -0
  28. core_10x/manual_tests/ctor_update_bug.py +58 -0
  29. core_10x/manual_tests/debug_graph_on.py +17 -0
  30. core_10x/manual_tests/debug_graphoff_inside_graph_on.py +28 -0
  31. core_10x/manual_tests/enum_bits_test.py +17 -0
  32. core_10x/manual_tests/env_vars_trivial_test.py +12 -0
  33. core_10x/manual_tests/existing_traitable.py +33 -0
  34. core_10x/manual_tests/k10x_test1.py +13 -0
  35. core_10x/manual_tests/named_constant_test.py +121 -0
  36. core_10x/manual_tests/nucleus_trivial_test.py +42 -0
  37. core_10x/manual_tests/polars_test.py +14 -0
  38. core_10x/manual_tests/py_class_test.py +4 -0
  39. core_10x/manual_tests/rc_test.py +42 -0
  40. core_10x/manual_tests/rdate_test.py +12 -0
  41. core_10x/manual_tests/reference_serialization_bug.py +19 -0
  42. core_10x/manual_tests/resource_trivial_test.py +10 -0
  43. core_10x/manual_tests/store_uri_test.py +6 -0
  44. core_10x/manual_tests/trait_definition_test.py +19 -0
  45. core_10x/manual_tests/trait_filter_test.py +15 -0
  46. core_10x/manual_tests/trait_flag_modification_test.py +42 -0
  47. core_10x/manual_tests/trait_modification_bug.py +26 -0
  48. core_10x/manual_tests/traitable_as_of_test.py +82 -0
  49. core_10x/manual_tests/traitable_heir_test.py +39 -0
  50. core_10x/manual_tests/traitable_history_test.py +41 -0
  51. core_10x/manual_tests/traitable_serialization_test.py +54 -0
  52. core_10x/manual_tests/traitable_trivial_test.py +71 -0
  53. core_10x/manual_tests/trivial_graph_test.py +16 -0
  54. core_10x/manual_tests/ts_class_association_test.py +64 -0
  55. core_10x/manual_tests/ts_trivial_test.py +35 -0
  56. core_10x/named_constant.py +425 -0
  57. core_10x/nucleus.py +81 -0
  58. core_10x/package_manifest.py +85 -0
  59. core_10x/package_refactoring.py +153 -0
  60. core_10x/py_class.py +431 -0
  61. core_10x/rc.py +155 -0
  62. core_10x/rdate.py +339 -0
  63. core_10x/resource.py +189 -0
  64. core_10x/roman_number.py +67 -0
  65. core_10x/testlib/__init__.py +0 -0
  66. core_10x/testlib/test_store.py +240 -0
  67. core_10x/testlib/traitable_history_tests.py +787 -0
  68. core_10x/testlib/ts_tests.py +280 -0
  69. core_10x/trait.py +377 -0
  70. core_10x/trait_definition.py +176 -0
  71. core_10x/trait_filter.py +205 -0
  72. core_10x/trait_method_error.py +36 -0
  73. core_10x/traitable.py +1082 -0
  74. core_10x/traitable_cli.py +153 -0
  75. core_10x/traitable_heir.py +33 -0
  76. core_10x/traitable_id.py +31 -0
  77. core_10x/ts_store.py +172 -0
  78. core_10x/ts_store_type.py +26 -0
  79. core_10x/ts_union.py +147 -0
  80. core_10x/ui_hint.py +153 -0
  81. core_10x/unit_tests/test_concrete_traits.py +156 -0
  82. core_10x/unit_tests/test_converters.py +51 -0
  83. core_10x/unit_tests/test_curve.py +157 -0
  84. core_10x/unit_tests/test_directory.py +54 -0
  85. core_10x/unit_tests/test_documentation.py +172 -0
  86. core_10x/unit_tests/test_environment_variables.py +15 -0
  87. core_10x/unit_tests/test_filters.py +239 -0
  88. core_10x/unit_tests/test_graph.py +348 -0
  89. core_10x/unit_tests/test_named_constant.py +98 -0
  90. core_10x/unit_tests/test_rc.py +11 -0
  91. core_10x/unit_tests/test_rdate.py +484 -0
  92. core_10x/unit_tests/test_trait_method_error.py +80 -0
  93. core_10x/unit_tests/test_trait_modification.py +19 -0
  94. core_10x/unit_tests/test_traitable.py +959 -0
  95. core_10x/unit_tests/test_traitable_history.py +1 -0
  96. core_10x/unit_tests/test_ts_store.py +1 -0
  97. core_10x/unit_tests/test_ts_union.py +369 -0
  98. core_10x/unit_tests/test_ui_nodes.py +81 -0
  99. core_10x/unit_tests/test_xxcalendar.py +471 -0
  100. core_10x/vault/__init__.py +0 -0
  101. core_10x/vault/sec_keys.py +133 -0
  102. core_10x/vault/security_keys_old.py +168 -0
  103. core_10x/vault/vault.py +56 -0
  104. core_10x/vault/vault_traitable.py +56 -0
  105. core_10x/vault/vault_user.py +70 -0
  106. core_10x/xdate_time.py +136 -0
  107. core_10x/xnone.py +71 -0
  108. core_10x/xxcalendar.py +228 -0
  109. infra_10x/__init__.py +0 -0
  110. infra_10x/manual_tests/__init__.py +0 -0
  111. infra_10x/manual_tests/test_misc.py +16 -0
  112. infra_10x/manual_tests/test_prepare_filter_and_pipeline.py +25 -0
  113. infra_10x/mongodb_admin.py +111 -0
  114. infra_10x/mongodb_store.py +346 -0
  115. infra_10x/mongodb_utils.py +129 -0
  116. infra_10x/unit_tests/conftest.py +13 -0
  117. infra_10x/unit_tests/test_mongo_db.py +36 -0
  118. infra_10x/unit_tests/test_mongo_history.py +1 -0
  119. py10x_universe-0.1.3.dist-info/METADATA +406 -0
  120. py10x_universe-0.1.3.dist-info/RECORD +214 -0
  121. py10x_universe-0.1.3.dist-info/WHEEL +4 -0
  122. py10x_universe-0.1.3.dist-info/licenses/LICENSE +21 -0
  123. ui_10x/__init__.py +0 -0
  124. ui_10x/apps/__init__.py +0 -0
  125. ui_10x/apps/collection_editor_app.py +100 -0
  126. ui_10x/choice.py +212 -0
  127. ui_10x/collection_editor.py +135 -0
  128. ui_10x/concrete_trait_widgets.py +220 -0
  129. ui_10x/conftest.py +8 -0
  130. ui_10x/entity_stocker.py +173 -0
  131. ui_10x/examples/__init__.py +0 -0
  132. ui_10x/examples/_guess_word_data.py +14076 -0
  133. ui_10x/examples/collection_editor.py +17 -0
  134. ui_10x/examples/date_selector.py +14 -0
  135. ui_10x/examples/entity_stocker.py +18 -0
  136. ui_10x/examples/guess_word.py +392 -0
  137. ui_10x/examples/message_box.py +20 -0
  138. ui_10x/examples/multi_choice.py +17 -0
  139. ui_10x/examples/py_data_browser.py +66 -0
  140. ui_10x/examples/radiobox.py +29 -0
  141. ui_10x/examples/single_choice.py +31 -0
  142. ui_10x/examples/style_sheet.py +47 -0
  143. ui_10x/examples/trivial_entity_editor.py +18 -0
  144. ui_10x/platform.py +20 -0
  145. ui_10x/platform_interface.py +517 -0
  146. ui_10x/py_data_browser.py +249 -0
  147. ui_10x/qt6/__init__.py +0 -0
  148. ui_10x/qt6/conftest.py +8 -0
  149. ui_10x/qt6/manual_tests/__init__.py +0 -0
  150. ui_10x/qt6/manual_tests/basic_test.py +35 -0
  151. ui_10x/qt6/platform_implementation.py +275 -0
  152. ui_10x/qt6/utils.py +665 -0
  153. ui_10x/rio/__init__.py +0 -0
  154. ui_10x/rio/apps/examples/examples/__init__.py +22 -0
  155. ui_10x/rio/apps/examples/examples/components/__init__.py +3 -0
  156. ui_10x/rio/apps/examples/examples/components/collection_editor.py +15 -0
  157. ui_10x/rio/apps/examples/examples/pages/collection_editor.py +21 -0
  158. ui_10x/rio/apps/examples/examples/pages/login_page.py +88 -0
  159. ui_10x/rio/apps/examples/examples/pages/style_sheet.py +21 -0
  160. ui_10x/rio/apps/examples/rio.toml +14 -0
  161. ui_10x/rio/component_builder.py +497 -0
  162. ui_10x/rio/components/__init__.py +9 -0
  163. ui_10x/rio/components/group_box.py +31 -0
  164. ui_10x/rio/components/labeled_checkbox.py +18 -0
  165. ui_10x/rio/components/line_edit.py +37 -0
  166. ui_10x/rio/components/radio_button.py +32 -0
  167. ui_10x/rio/components/separator.py +24 -0
  168. ui_10x/rio/components/splitter.py +121 -0
  169. ui_10x/rio/components/tree_view.py +75 -0
  170. ui_10x/rio/conftest.py +35 -0
  171. ui_10x/rio/internals/__init__.py +0 -0
  172. ui_10x/rio/internals/app.py +192 -0
  173. ui_10x/rio/manual_tests/__init__.py +0 -0
  174. ui_10x/rio/manual_tests/basic_test.py +24 -0
  175. ui_10x/rio/manual_tests/splitter.py +27 -0
  176. ui_10x/rio/platform_implementation.py +91 -0
  177. ui_10x/rio/style_sheet.py +53 -0
  178. ui_10x/rio/unit_tests/test_collection_editor.py +68 -0
  179. ui_10x/rio/unit_tests/test_internals.py +630 -0
  180. ui_10x/rio/unit_tests/test_style_sheet.py +37 -0
  181. ui_10x/rio/widgets/__init__.py +46 -0
  182. ui_10x/rio/widgets/application.py +109 -0
  183. ui_10x/rio/widgets/button.py +48 -0
  184. ui_10x/rio/widgets/button_group.py +60 -0
  185. ui_10x/rio/widgets/calendar.py +23 -0
  186. ui_10x/rio/widgets/checkbox.py +24 -0
  187. ui_10x/rio/widgets/dialog.py +137 -0
  188. ui_10x/rio/widgets/group_box.py +27 -0
  189. ui_10x/rio/widgets/layout.py +34 -0
  190. ui_10x/rio/widgets/line_edit.py +37 -0
  191. ui_10x/rio/widgets/list.py +105 -0
  192. ui_10x/rio/widgets/message_box.py +70 -0
  193. ui_10x/rio/widgets/scroll_area.py +31 -0
  194. ui_10x/rio/widgets/spacer.py +6 -0
  195. ui_10x/rio/widgets/splitter.py +45 -0
  196. ui_10x/rio/widgets/text_edit.py +28 -0
  197. ui_10x/rio/widgets/tree.py +89 -0
  198. ui_10x/rio/widgets/unit_tests/test_button.py +101 -0
  199. ui_10x/rio/widgets/unit_tests/test_button_group.py +33 -0
  200. ui_10x/rio/widgets/unit_tests/test_calendar.py +114 -0
  201. ui_10x/rio/widgets/unit_tests/test_checkbox.py +109 -0
  202. ui_10x/rio/widgets/unit_tests/test_group_box.py +158 -0
  203. ui_10x/rio/widgets/unit_tests/test_label.py +43 -0
  204. ui_10x/rio/widgets/unit_tests/test_line_edit.py +140 -0
  205. ui_10x/rio/widgets/unit_tests/test_list.py +146 -0
  206. ui_10x/table_header_view.py +305 -0
  207. ui_10x/table_view.py +174 -0
  208. ui_10x/trait_editor.py +189 -0
  209. ui_10x/trait_widget.py +131 -0
  210. ui_10x/traitable_editor.py +200 -0
  211. ui_10x/traitable_view.py +131 -0
  212. ui_10x/unit_tests/conftest.py +8 -0
  213. ui_10x/unit_tests/test_platform.py +9 -0
  214. ui_10x/utils.py +661 -0
@@ -0,0 +1,67 @@
1
+ from core_10x.named_constant import Enum, NamedConstantTable
2
+
3
+
4
+ # ruff: noqa: E741
5
+ class R:
6
+ # fmt: off
7
+ class Symbol(Enum):
8
+ I = ()
9
+ V = ()
10
+ X = ()
11
+ L = ()
12
+ C = ()
13
+ D = ()
14
+ M = ()
15
+
16
+ class Attr(Enum):
17
+ VALUE = ()
18
+ REPEAT = ()
19
+ SUBTRACTABLE = ()
20
+
21
+ SYMBOL_TABLE = NamedConstantTable(Symbol, Attr,
22
+ # VALUE REPEAT SUBTRACTABLE
23
+ I = ( 1, 3, True ),
24
+ V = ( 5, 1, False ),
25
+ X = ( 10, 3, True ),
26
+ L = ( 50, 1, False ),
27
+ C = ( 100, 3, True ),
28
+ D = ( 500, 1, False ),
29
+ M = ( 1000, 3, True ),
30
+ )
31
+ # fmt: on
32
+ def __init__(self, text: str):
33
+ text = text.upper()
34
+ x = 0
35
+ prev_values = [0, 0, 0]
36
+ for i, symbol in enumerate(reversed(text)):
37
+ ref = R.SYMBOL_TABLE[symbol]
38
+ v = ref.VALUE
39
+
40
+ # -- Rules
41
+ repeat = ref.REPEAT
42
+ over_repeated = all(v == prev_values[i] for i in range(repeat))
43
+ assert not over_repeated, f"'{symbol}' is repeated more than {repeat} times"
44
+
45
+ subtractable = ref.SUBTRACTABLE
46
+ if not subtractable and v < prev_values[0]:
47
+ raise AssertionError(f"'{symbol}' may not occur before '{text[-i]}'")
48
+
49
+ if v >= prev_values[0]:
50
+ x += v
51
+ else:
52
+ x -= v
53
+
54
+ prev_values[2] = prev_values[1]
55
+ prev_values[1] = prev_values[0]
56
+ prev_values[0] = v
57
+
58
+ self.roman = text
59
+ self.value = x
60
+
61
+ def __repr__(self):
62
+ return f'{self.roman} = {self.value}'
63
+
64
+
65
+ if __name__ == '__main__':
66
+ x = R('IX')
67
+ y = R('MCMLXXXIV')
File without changes
@@ -0,0 +1,240 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ In-memory TestStore for testing TraitableHistory and other storage functionality.
4
+
5
+ This provides a lightweight, in-memory implementation of the TsStore interface
6
+ that can be used for unit tests without external dependencies like MongoDB.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import copy
12
+ import re
13
+ from typing import TYPE_CHECKING
14
+
15
+ from py10x_core import BTraitable, BTraitableProcessor
16
+
17
+ from core_10x.nucleus import Nucleus
18
+ from core_10x.ts_store import TsCollection, TsDuplicateKeyError, TsStore
19
+
20
+ if TYPE_CHECKING:
21
+ from collections.abc import Iterable
22
+
23
+ from core_10x.trait_filter import f
24
+
25
+
26
+ class TestCollection(TsCollection):
27
+ """In-memory collection implementation for testing."""
28
+
29
+ s_id_tag = '_id'
30
+
31
+ def __init__(self, store: TestStore, collection_name: str):
32
+ self.store = store
33
+ self._collection_name = collection_name
34
+ self._documents = {} # id -> document
35
+ self._indexes = {} # index_name -> index_info
36
+
37
+ def collection_name(self) -> str:
38
+ return self._collection_name
39
+
40
+ def id_exists(self, id_value: str) -> bool:
41
+ """Check if a document with the given ID exists."""
42
+ return id_value in self._documents
43
+
44
+ def _eval(self, doc, query):
45
+ bclass = query.traitable_class
46
+ try:
47
+ return query.eval(doc)
48
+ except AttributeError:
49
+ # TODO: fix - need to deserialize as dictionary-based eval doesn't support nested objects
50
+ if not bclass:
51
+ raise # likely and ID query from load(ID)
52
+ coll = self._collection_name if bclass.is_custom_collection() else None
53
+ with BTraitableProcessor.create_root():
54
+ return query.eval(BTraitable.deserialize_object(bclass, coll, copy.copy(doc)))
55
+
56
+ def find(self, query: f = None, _at_most: int = 0, _order: dict = None) -> Iterable:
57
+ """Find documents matching the query."""
58
+ documents = list(self._documents.values())
59
+
60
+ # Apply query filter if provided
61
+ if query:
62
+ documents = [doc for doc in documents if self._eval(doc, query)]
63
+
64
+ # Apply ordering if provided
65
+ if _order:
66
+ # Sort by all fields at once, with the last field taking precedence
67
+ # We need to reverse the order of fields so the last one is applied first
68
+ sort_fields = list(_order.items())
69
+ sort_fields.reverse() # Last field first
70
+
71
+ for field, direction in sort_fields:
72
+ documents.sort(key=lambda x: x.get(field, ''), reverse=(direction == -1))
73
+
74
+ # Apply limit if specified
75
+ if _at_most > 0:
76
+ documents = documents[:_at_most]
77
+
78
+ return (dict(doc) for doc in documents)
79
+
80
+ def count(self, query: f = None) -> int:
81
+ """Count documents matching the query."""
82
+ return len(list(self.find(query)))
83
+
84
+ def save_new(self, serialized_traitable: dict, overwrite: bool = False) -> int:
85
+ """Save a new document."""
86
+
87
+ # Handle MongoDB-style operations
88
+ if '$set' in serialized_traitable:
89
+ # This is a MongoDB-style update operation
90
+ from datetime import datetime
91
+
92
+ # Extract the data from $set
93
+ data = serialized_traitable['$set'].copy()
94
+
95
+ # Handle $currentDate operations
96
+ if '$currentDate' in serialized_traitable:
97
+ current_date_fields = serialized_traitable['$currentDate']
98
+ for field in current_date_fields:
99
+ if current_date_fields[field] is True:
100
+ data[field] = datetime.utcnow()
101
+
102
+ serialized_traitable = data
103
+
104
+ serialized_traitable[Nucleus.REVISION_TAG()] = 1
105
+
106
+ id_tag = self.s_id_tag
107
+ id_value = serialized_traitable.get(id_tag)
108
+
109
+ if not id_value:
110
+ return 0
111
+
112
+ if id_value in self._documents and not overwrite:
113
+ raise TsDuplicateKeyError(self.collection_name(), {id_tag: id_value})
114
+
115
+ self._documents[id_value] = serialized_traitable
116
+ return 1
117
+
118
+ def save(self, serialized_traitable: dict) -> int:
119
+ """Save or update a document."""
120
+ rev_tag = Nucleus.REVISION_TAG()
121
+ revision = serialized_traitable[rev_tag]
122
+ if revision == 0:
123
+ return self.save_new(serialized_traitable)
124
+
125
+ undef_variable = next((k[1:] for k in serialized_traitable if k.startswith('$')), None)
126
+ if undef_variable:
127
+ raise RuntimeError(f'Use of undefined variable: {undef_variable}')
128
+ doc_id = serialized_traitable.get(self.s_id_tag)
129
+ assert doc_id
130
+
131
+ existing_doc = self._documents.get(doc_id)
132
+ existing_revision = existing_doc[rev_tag] if existing_doc else 0
133
+ assert revision == existing_revision
134
+
135
+ if existing_doc == serialized_traitable:
136
+ return existing_revision
137
+
138
+ revision += 1
139
+ self._documents[doc_id] = serialized_traitable | {rev_tag: revision}
140
+
141
+ return revision
142
+
143
+ def delete(self, id_value: str) -> bool:
144
+ """Delete a document by ID."""
145
+ if id_value in self._documents:
146
+ del self._documents[id_value]
147
+ return True
148
+ return False
149
+
150
+ def create_index(self, name: str, trait_name: str | list[tuple[str, int]], **index_args) -> str:
151
+ """Create an index (in-memory implementation just stores the index info)."""
152
+ self._indexes[name] = {'trait_name': trait_name, 'args': index_args}
153
+ return name
154
+
155
+ def max(self, trait_name: str, filter: f = None) -> dict:
156
+ """Find the document with the maximum value for the given trait."""
157
+ documents = list(self.find(filter))
158
+ if not documents:
159
+ return {}
160
+
161
+ max_doc = max(documents, key=lambda x: x.get(trait_name, ''))
162
+ return max_doc
163
+
164
+ def min(self, trait_name: str, filter: f = None) -> dict:
165
+ """Find the document with the minimum value for the given trait."""
166
+ documents = list(self.find(filter))
167
+ if not documents:
168
+ return {}
169
+
170
+ min_doc = min(documents, key=lambda x: x.get(trait_name, ''))
171
+ return min_doc
172
+
173
+
174
+ class TestStore(TsStore, resource_name='TEST_DB'):
175
+ """In-memory store implementation for testing."""
176
+
177
+ s_driver_name = 'TestStore'
178
+
179
+ def __init__(self, *args, **kwargs):
180
+ super().__init__()
181
+ self._collections = {}
182
+ self._collection_names = set()
183
+ # Set a default username for testing
184
+ self.username = kwargs.get('username', 'test_user')
185
+
186
+ @classmethod
187
+ def new_instance(cls, *args, password: str = '', **kwargs) -> TestStore:
188
+ """Create a new TestStore instance."""
189
+ return cls(*args, **kwargs)
190
+
191
+ def collection_names(self, regexp: str = None) -> list:
192
+ """Get collection names, optionally filtered by regexp."""
193
+ names = list(self._collection_names)
194
+
195
+ if regexp:
196
+ pattern = re.compile(regexp)
197
+ names = [name for name in names if pattern.match(name)]
198
+
199
+ return sorted(names)
200
+
201
+ def collection(self, collection_name: str) -> TestCollection:
202
+ """Get or create a collection."""
203
+ if collection_name not in self._collections:
204
+ self._collections[collection_name] = TestCollection(self, collection_name)
205
+ self._collection_names.add(collection_name)
206
+
207
+ return self._collections[collection_name]
208
+
209
+ def delete_collection(self, collection_name: str) -> bool:
210
+ """Delete a collection."""
211
+ if collection_name in self._collections:
212
+ del self._collections[collection_name]
213
+ self._collection_names.discard(collection_name)
214
+ return True
215
+ return False
216
+
217
+ @classmethod
218
+ def is_running_with_auth(cls, host_name: str) -> tuple:
219
+ """TestStore doesn't require authentication."""
220
+ return True, False
221
+
222
+ def clear(self):
223
+ """Clear all collections (useful for test cleanup)."""
224
+ self._collections.clear()
225
+ self._collection_names.clear()
226
+
227
+ def get_document_count(self, collection_name: str) -> int:
228
+ """Get the number of documents in a collection (for testing)."""
229
+ if collection_name in self._collections:
230
+ return len(self._collections[collection_name]._documents)
231
+ return 0
232
+
233
+ def get_documents(self, collection_name: str) -> list:
234
+ """Get all documents in a collection (for testing)."""
235
+ if collection_name in self._collections:
236
+ return list(self._collections[collection_name]._documents.values())
237
+ return []
238
+
239
+ def auth_user(self) -> str | None:
240
+ return self.username