mainsequence 4.1.6__tar.gz → 4.1.7__tar.gz

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 (121) hide show
  1. {mainsequence-4.1.6 → mainsequence-4.1.7}/PKG-INFO +1 -1
  2. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +10 -0
  3. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +19 -4
  4. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/models_metatables.py +61 -2
  5. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/__init__.py +0 -4
  6. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/sqlalchemy_contracts.py +263 -66
  7. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence.egg-info/PKG-INFO +1 -1
  8. {mainsequence-4.1.6 → mainsequence-4.1.7}/pyproject.toml +1 -1
  9. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_build_operations_hashing.py +3 -3
  10. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_meta_tables_client_models.py +46 -0
  11. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_meta_tables_sqlalchemy_contracts.py +271 -26
  12. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_run_configuration.py +1 -1
  13. {mainsequence-4.1.6 → mainsequence-4.1.7}/LICENSE +0 -0
  14. {mainsequence-4.1.6 → mainsequence-4.1.7}/README.md +0 -0
  15. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/AGENTS.md +0 -0
  16. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
  17. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  18. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
  19. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
  20. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
  21. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
  22. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
  23. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
  24. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
  25. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
  26. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  27. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  28. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
  29. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  30. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  31. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
  32. {mainsequence-4.1.6 → mainsequence-4.1.7}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
  33. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/__init__.py +0 -0
  34. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/__main__.py +0 -0
  35. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/bootstrap.py +0 -0
  36. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/__init__.py +0 -0
  37. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/api.py +0 -0
  38. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/browser_auth.py +0 -0
  39. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/cli.py +0 -0
  40. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/config.py +0 -0
  41. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/docker_utils.py +0 -0
  42. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/doctor.py +0 -0
  43. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/local_ops.py +0 -0
  44. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/model_filters.py +0 -0
  45. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/project_status.py +0 -0
  46. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/pydantic_cli.py +0 -0
  47. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/sdk_utils.py +0 -0
  48. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/ssh_utils.py +0 -0
  49. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/cli/ui.py +0 -0
  50. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/__init__.py +0 -0
  51. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/agent_runtime_models.py +0 -0
  52. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/base.py +0 -0
  53. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/client.py +0 -0
  54. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/command_center/__init__.py +0 -0
  55. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/command_center/app_component.py +0 -0
  56. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/command_center/connections.py +0 -0
  57. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/command_center/data_models.py +0 -0
  58. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/command_center/workspace.py +0 -0
  59. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
  60. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/compute_validation.py +0 -0
  61. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  62. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  63. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  64. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  65. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/dtype_codec.py +0 -0
  66. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/exceptions.py +0 -0
  67. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/fastapi/__init__.py +0 -0
  68. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/fastapi/auth.py +0 -0
  69. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/models_foundry.py +0 -0
  70. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/models_helpers.py +0 -0
  71. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/models_user.py +0 -0
  72. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/client/utils.py +0 -0
  73. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/defaults.py +0 -0
  74. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/instrumentation/__init__.py +0 -0
  75. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/instrumentation/utils.py +0 -0
  76. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/logconf.py +0 -0
  77. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/__main__.py +0 -0
  78. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  79. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  80. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
  81. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
  82. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
  83. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/data_nodes/models.py +0 -0
  84. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
  85. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
  86. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
  87. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
  88. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/future_registry.py +0 -0
  89. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/hashing.py +0 -0
  90. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
  91. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence/runtime_flags.py +0 -0
  92. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence.egg-info/SOURCES.txt +0 -0
  93. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence.egg-info/dependency_links.txt +0 -0
  94. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence.egg-info/entry_points.txt +0 -0
  95. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence.egg-info/requires.txt +0 -0
  96. {mainsequence-4.1.6 → mainsequence-4.1.7}/mainsequence.egg-info/top_level.txt +0 -0
  97. {mainsequence-4.1.6 → mainsequence-4.1.7}/setup.cfg +0 -0
  98. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_auth_precedence.py +0 -0
  99. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_cli.py +0 -0
  100. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_cli_browser_auth.py +0 -0
  101. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_client.py +0 -0
  102. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_command_center_app_component_models.py +0 -0
  103. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_command_center_data_models.py +0 -0
  104. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_command_center_models.py +0 -0
  105. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_data_access_mixin_dimension_audit.py +0 -0
  106. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_data_node_storage_dimension_queries.py +0 -0
  107. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_data_node_update_flow.py +0 -0
  108. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_dependency_extras.py +0 -0
  109. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_duckdb_interface_dimensions.py +0 -0
  110. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_filter_normalization.py +0 -0
  111. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_logconf.py +0 -0
  112. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_models_user_request_bound_auth.py +0 -0
  113. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_pod_project_resolution.py +0 -0
  114. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_project_batch_jobs_from_file.py +0 -0
  115. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_secret_client_model.py +0 -0
  116. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_source_table_configuration.py +0 -0
  117. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_sqlite_interface_dimensions.py +0 -0
  118. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_update_runner_uid_runtime.py +0 -0
  119. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_update_statistics.py +0 -0
  120. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_update_uid_guards.py +0 -0
  121. {mainsequence-4.1.6 → mainsequence-4.1.7}/tests/test_workspace_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.1.6
3
+ Version: 4.1.7
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -108,6 +108,10 @@ The following are storage-contract decisions:
108
108
  - foreign keys
109
109
  - table description and labels
110
110
 
111
+ Every storage class must include `__metatable_description__`. The description
112
+ should explain the table's intention, row grain, and downstream use, not only
113
+ list columns or schema mechanics.
114
+
111
115
  Do not put those concerns in `DataNodeConfiguration`.
112
116
 
113
117
  Minimal pattern:
@@ -128,6 +132,10 @@ class Base(DeclarativeBase):
128
132
  class PricesTable(PlatformTimeIndexMetaData, Base):
129
133
  __metatable_namespace__ = "<domain_namespace>"
130
134
  __metatable_identifier__ = "<table_identifier>"
135
+ __metatable_description__ = (
136
+ "Daily close prices keyed by asset unique identifier for portfolio and "
137
+ "risk analytics."
138
+ )
131
139
  __time_index_name__ = "time_index"
132
140
  __index_names__ = ["time_index", "unique_identifier"]
133
141
 
@@ -319,6 +327,7 @@ Do not put schema or published table metadata on the DataNode configuration.
319
327
  When reviewing an existing DataNode, look for:
320
328
 
321
329
  - output storage contract hidden in `DataNodeConfiguration`
330
+ - missing `__metatable_description__` on the storage table
322
331
  - dependency storage table passed as an ad hoc constructor argument
323
332
  - schema or published table metadata hidden in DataNode configuration
324
333
  - `update_only`, `runtime_only`, or `ignore_from_storage_hash`
@@ -339,6 +348,7 @@ Do not claim success until you have checked:
339
348
 
340
349
  - the relevant docs were read first
341
350
  - storage is a registered `PlatformTimeIndexMetaData` class
351
+ - storage has an intention-rich `__metatable_description__`
342
352
  - the DataNode constructor requires `storage_table`
343
353
  - dependency storage-table references live in config and are registered
344
354
  - config fields are updater-scoped by default
@@ -99,15 +99,28 @@ The mixin derives the SQLAlchemy physical table name from storage-relevant confi
99
99
 
100
100
  Schema must come from SQLAlchemy table metadata, usually `__table_args__ = {"schema": "public"}` or the tuple form ending in `{"schema": ...}`. Do not add a separate MetaTable-specific schema attribute.
101
101
 
102
+ Always declare `__metatable_description__` on the model. The description must
103
+ explain the table's business intention, row grain, and expected use, not only
104
+ the schema. Column-level descriptions stay in `mapped_column(info={...})`.
105
+
102
106
  Register through the class API:
103
107
 
104
108
  ```python
105
- account_meta_table = Account.register(
106
- description="Example account table.",
107
- labels=["sdk-example"],
108
- )
109
+ class Account(PlatformManagedMetaTable, Base):
110
+ __metatable_namespace__ = "sdk-examples"
111
+ __metatable_identifier__ = "Account"
112
+ __metatable_description__ = (
113
+ "Customer account master records used to scope balances, holdings, and "
114
+ "account-level limits."
115
+ )
116
+
117
+
118
+ account_meta_table = Account.register(labels=["sdk-example"])
109
119
  ```
110
120
 
121
+ Pass `description=...` only when the call intentionally overrides the class
122
+ default.
123
+
111
124
  For platform-managed registration, the data source is resolved from the active Main Sequence project/session, the same way DataNode does. Do not require or thread a `data_source_uid` through normal platform-managed example code.
112
125
 
113
126
  Only call `build_registration_request()` when the task explicitly needs to inspect or validate the payload before registration.
@@ -172,6 +185,7 @@ Do not hardcode platform-managed physical names manually.
172
185
  When reviewing an existing MetaTable workflow, look for:
173
186
 
174
187
  - missing namespace or identifier
188
+ - missing `__metatable_description__`, or a description that only repeats column names instead of table intention
175
189
  - backend-managed models that do not inherit `PlatformManagedMetaTable`
176
190
  - backend-managed examples that use namespace environment variables instead of a plain `sdk-examples` namespace
177
191
  - duplicate schema sources outside SQLAlchemy table metadata
@@ -187,6 +201,7 @@ When reviewing an existing MetaTable workflow, look for:
187
201
  Do not claim success until you have checked:
188
202
 
189
203
  - the table contract matches the intended row contract
204
+ - the table has an intention-rich `__metatable_description__`
190
205
  - indexes are intentional
191
206
  - foreign keys resolve to the correct dependency targets
192
207
  - management mode is correct
@@ -220,7 +220,13 @@ class MetaTablePhysicalContract(BasePydanticModel):
220
220
  exclude=True,
221
221
  description=("Input-only schema alias. MetaTable uses the data source default schema."),
222
222
  )
223
- table_name: str = Field(..., description="Physical database table name.")
223
+ table_name: str | None = Field(
224
+ default=None,
225
+ description=(
226
+ "Physical database table name. Required for external_registered tables; "
227
+ "omitted by platform_managed client requests because the backend owns it."
228
+ ),
229
+ )
224
230
 
225
231
  model_config = ConfigDict(populate_by_name=True)
226
232
 
@@ -1090,6 +1096,55 @@ class MetaTable(BasePydanticModel, LabelableObjectMixin, ShareableObjectMixin, B
1090
1096
  self.introspection_snapshot = snapshot
1091
1097
  return response_json
1092
1098
 
1099
+ def get_schema_graph(
1100
+ self,
1101
+ *,
1102
+ depth: int = 1,
1103
+ include_incoming: bool = False,
1104
+ timeout: int | float | tuple[float, float] | None = None,
1105
+ ) -> dict[str, Any]:
1106
+ """
1107
+ Return the MetaTable foreign-key schema graph rooted at this table.
1108
+
1109
+ The graph is the client API for dependency analysis. Outgoing edges are
1110
+ foreign keys declared by this table. When ``include_incoming`` is true,
1111
+ the response also includes visible tables that depend on this table.
1112
+
1113
+ Args:
1114
+ depth: Relationship traversal depth. The backend clamps this to its
1115
+ supported range.
1116
+ include_incoming: Include inbound relationships where another
1117
+ visible MetaTable has a foreign key targeting this table.
1118
+ timeout: Optional request timeout in seconds or ``requests`` timeout
1119
+ tuple form.
1120
+
1121
+ Returns:
1122
+ A dictionary with ``root_uid``, ``depth``, ``include_incoming``,
1123
+ ``nodes``, and ``edges``. Inbound dependencies are edges where
1124
+ ``edge["target_uid"] == self.uid``; the dependent table UID is
1125
+ ``edge["source_uid"]``.
1126
+ """
1127
+ url = f"{type(self).get_object_url().rstrip('/')}/{self._public_uid()}/schema-graph/"
1128
+ payload = {
1129
+ "params": serialize_to_json(
1130
+ {
1131
+ "depth": depth,
1132
+ "include_incoming": include_incoming,
1133
+ }
1134
+ )
1135
+ }
1136
+ response = make_request(
1137
+ s=type(self).build_session(),
1138
+ loaders=type(self).LOADERS,
1139
+ r_type="GET",
1140
+ url=url,
1141
+ payload=payload,
1142
+ time_out=timeout,
1143
+ )
1144
+ if response.status_code != 200:
1145
+ raise_for_response(response, payload=payload)
1146
+ return response.json()
1147
+
1093
1148
  def refresh_table_search_index(
1094
1149
  self,
1095
1150
  *,
@@ -1335,7 +1390,11 @@ class TimeIndexMetaTableRegistrationRequest(BasePydanticModel):
1335
1390
  model_config = ConfigDict(extra="forbid")
1336
1391
 
1337
1392
  data_source_uid: str = Field(..., description="Public uid of the storage data source")
1338
- storage_hash: str = Field(..., max_length=63, description="Canonical physical table name")
1393
+ storage_hash: str = Field(
1394
+ ...,
1395
+ max_length=63,
1396
+ description="Canonical logical storage identity for the time-indexed MetaTable",
1397
+ )
1339
1398
  identifier: str | None = Field(None, description="Optional published storage identifier")
1340
1399
  namespace: str | None = Field(None, description="Optional published storage namespace")
1341
1400
  description: str | None = Field(None, description="Optional storage description")
@@ -38,10 +38,6 @@ _LAZY_IMPORTS = {
38
38
  ".sqlalchemy_contracts",
39
39
  "register_external_sqlalchemy_model",
40
40
  ),
41
- "register_platform_managed_sqlalchemy_model": (
42
- ".sqlalchemy_contracts",
43
- "register_platform_managed_sqlalchemy_model",
44
- ),
45
41
  "slugify_identifier": (".hashing", "slugify_identifier"),
46
42
  "table_contract_from_sqlalchemy_model": (
47
43
  ".sqlalchemy_contracts",