mainsequence 8.1.20.dev4__py3-none-any.whl → 8.1.20.dev8__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.
mainsequence/cli/cli.py CHANGED
@@ -5912,7 +5912,9 @@ def _meta_table_run_query_impl(
5912
5912
  try:
5913
5913
  payload = run_meta_table_query(meta_table_uid, sql, timeout=timeout)
5914
5914
  except ApiError as e:
5915
- error(f"MetaTable query failed: {e}")
5915
+ # The api layer already names the operation in the message; prefixing again
5916
+ # produces "MetaTable query failed: MetaTable query failed: ...".
5917
+ error(str(e))
5916
5918
  raise typer.Exit(1) from e
5917
5919
 
5918
5920
  ok = bool(payload.get("ok"))
@@ -5941,7 +5943,9 @@ def _time_index_table_run_query_impl(
5941
5943
  try:
5942
5944
  payload = run_time_index_table_query(table_uid, sql, timeout=timeout)
5943
5945
  except ApiError as e:
5944
- error(f"Time-index table query failed: {e}")
5946
+ # The api layer already names the operation in the message; prefixing again
5947
+ # produces "Time-index table query failed: Time-index table query failed: ...".
5948
+ error(str(e))
5945
5949
  raise typer.Exit(1) from e
5946
5950
 
5947
5951
  ok = bool(payload.get("ok"))
@@ -58,7 +58,9 @@ class HtmlSaveException(Exception):
58
58
 
59
59
 
60
60
  class BasePydanticModel(BaseModel):
61
- model_config = ConfigDict(extra="forbid") # Forbid extra fields in v2
61
+ # Tolerant reading (ADR 0032): a backend response that carries a field this
62
+ # SDK release does not declare parses, and the undeclared field is dropped.
63
+ model_config = ConfigDict(extra="ignore")
62
64
  orm_class: str = None # This will be set to the class that inherits
63
65
 
64
66
  @classmethod
@@ -780,10 +782,21 @@ class BaseObjectOrm:
780
782
 
781
783
  return raw_key
782
784
 
785
+ def _declares_field(obj, field_name: str) -> bool:
786
+ if not isinstance(obj, BaseModel):
787
+ return True
788
+ if field_name in type(obj).model_fields:
789
+ return True
790
+ # Tolerant reading (ADR 0032): a model that keeps undeclared keys can
791
+ # take them; every other model drops them, as parsing does.
792
+ return type(obj).model_config.get("extra") == "allow"
793
+
783
794
  def recursive_update(obj, update_dict, path=()):
784
795
  for k, v in update_dict.items():
785
796
  current_path = (*path, k)
786
797
  field_name = _resolve_model_field_name(obj, k)
798
+ if not _declares_field(obj, field_name):
799
+ continue
787
800
  # Get the existing nested object, defaulting to None if it doesn't exist
788
801
  nested_obj = getattr(obj, field_name, None)
789
802
 
@@ -1904,35 +1904,18 @@ class MetaTable(
1904
1904
 
1905
1905
  cls = type(self)
1906
1906
  url = f"{cls.get_object_url().rstrip('/')}/{self._public_uid()}/run-query/"
1907
- if cls.ENDPOINT == "time-index-meta-tables":
1908
- session = cls.build_session()
1909
- old_content_type = session.headers.get("Content-Type")
1910
- session.headers["Content-Type"] = "text/plain"
1911
- try:
1912
- response = make_request(
1913
- s=session,
1914
- loaders=cls.LOADERS,
1915
- r_type="POST",
1916
- url=url,
1917
- payload={"data": sql},
1918
- time_out=timeout,
1919
- )
1920
- finally:
1921
- if old_content_type is None:
1922
- session.headers.pop("Content-Type", None)
1923
- else:
1924
- session.headers["Content-Type"] = old_content_type
1925
- error_payload = {"data": sql}
1926
- else:
1927
- response = make_request(
1928
- s=cls.build_session(),
1929
- loaders=cls.LOADERS,
1930
- r_type="POST",
1931
- url=url,
1932
- payload={"json": sql},
1933
- time_out=timeout,
1934
- )
1935
- error_payload = {"json": sql}
1907
+ # The backend reads the request body as the raw SQL string and parses it with
1908
+ # DRF's JSON parser, for every MetaTable endpoint. Sending a JSON string is the
1909
+ # only transport it accepts; a text/plain body is rejected with HTTP 415.
1910
+ payload = {"json": sql}
1911
+ response = make_request(
1912
+ s=cls.build_session(),
1913
+ loaders=cls.LOADERS,
1914
+ r_type="POST",
1915
+ url=url,
1916
+ payload=payload,
1917
+ time_out=timeout,
1918
+ )
1936
1919
 
1937
1920
  try:
1938
1921
  data = response.json()
@@ -1942,57 +1925,9 @@ class MetaTable(
1942
1925
  if isinstance(data, dict) and "ok" in data:
1943
1926
  return data
1944
1927
 
1945
- raise_for_response(response, payload=error_payload)
1928
+ raise_for_response(response, payload=payload)
1946
1929
  return response.json()
1947
1930
 
1948
- @classmethod
1949
- def description_search(
1950
- cls,
1951
- q: str,
1952
- *,
1953
- q_embedding: Sequence[float] | None = None,
1954
- trigram_k: int = 200,
1955
- embed_k: int = 200,
1956
- w_trgm: float = 0.65,
1957
- w_emb: float = 0.35,
1958
- embedding_model: str = "default",
1959
- **filters,
1960
- ):
1961
- q = (q or "").strip()
1962
- if not q:
1963
- raise ValueError("q is required")
1964
- operation = f"{cls.__name__}.description_search"
1965
- cls._reject_sdk_context_overrides(filters, operation=operation)
1966
-
1967
- body = {
1968
- "q": q,
1969
- "trigram_k": trigram_k,
1970
- "embed_k": embed_k,
1971
- "w_trgm": w_trgm,
1972
- "w_emb": w_emb,
1973
- "embedding_model": embedding_model,
1974
- }
1975
-
1976
- if q_embedding is not None:
1977
- body["q_embedding"] = [float(x) for x in q_embedding]
1978
-
1979
- if filters:
1980
- body.update(filters)
1981
- body.update(cls._sdk_owned_query_context(operation))
1982
-
1983
- payload = {"params": serialize_to_json(body)}
1984
- response = make_request(
1985
- s=cls.build_session(),
1986
- loaders=cls.LOADERS,
1987
- r_type="GET",
1988
- url=f"{cls.get_object_url().rstrip('/')}/description-search/",
1989
- payload=payload,
1990
- )
1991
- if response.status_code != 200:
1992
- raise_for_response(response, payload=payload)
1993
-
1994
- return cls._deserialize_search_response(response.json())
1995
-
1996
1931
  @classmethod
1997
1932
  def column_search(cls, q: str, **filters):
1998
1933
  q = (q or "").strip()
@@ -2768,23 +2703,6 @@ class TimeIndexTableUpdate(TableUpdateNode, BaseObjectOrm):
2768
2703
  return None
2769
2704
  return r.json()
2770
2705
 
2771
- def verify_if_direct_dependencies_are_updated(self) -> dict:
2772
- """
2773
- Response({
2774
- "error_on_update_dependencies": False,
2775
- "updated": all_success,
2776
- })
2777
- """
2778
- s = self.build_session()
2779
- url = (
2780
- self.get_object_url()
2781
- + f"/{self._public_uid()}/verify-if-direct-dependencies-are-updated/"
2782
- )
2783
- r = make_request(s=s, loaders=None, r_type="GET", url=url)
2784
- if r.status_code != 200:
2785
- raise Exception(f"Error in request: {r.text}")
2786
- return r.json()
2787
-
2788
2706
  def get_data_between_dates_from_api(self, *args, **kwargs):
2789
2707
  return self.output_table.get_data_between_dates_from_api(*args, **kwargs)
2790
2708
 
@@ -3259,6 +3177,54 @@ class TimeIndexMetaTable(MetaTable):
3259
3177
  )
3260
3178
  return self
3261
3179
 
3180
+ @classmethod
3181
+ def description_search(
3182
+ cls,
3183
+ q: str,
3184
+ *,
3185
+ q_embedding: Sequence[float] | None = None,
3186
+ trigram_k: int = 200,
3187
+ embed_k: int = 200,
3188
+ w_trgm: float = 0.65,
3189
+ w_emb: float = 0.35,
3190
+ embedding_model: str = "default",
3191
+ **filters,
3192
+ ):
3193
+ q = (q or "").strip()
3194
+ if not q:
3195
+ raise ValueError("q is required")
3196
+ operation = f"{cls.__name__}.description_search"
3197
+ cls._reject_sdk_context_overrides(filters, operation=operation)
3198
+
3199
+ body = {
3200
+ "q": q,
3201
+ "trigram_k": trigram_k,
3202
+ "embed_k": embed_k,
3203
+ "w_trgm": w_trgm,
3204
+ "w_emb": w_emb,
3205
+ "embedding_model": embedding_model,
3206
+ }
3207
+
3208
+ if q_embedding is not None:
3209
+ body["q_embedding"] = [float(x) for x in q_embedding]
3210
+
3211
+ if filters:
3212
+ body.update(filters)
3213
+ body.update(cls._sdk_owned_query_context(operation))
3214
+
3215
+ payload = {"params": serialize_to_json(body)}
3216
+ response = make_request(
3217
+ s=cls.build_session(),
3218
+ loaders=cls.LOADERS,
3219
+ r_type="GET",
3220
+ url=f"{cls.get_object_url().rstrip('/')}/description-search/",
3221
+ payload=payload,
3222
+ )
3223
+ if response.status_code != 200:
3224
+ raise_for_response(response, payload=payload)
3225
+
3226
+ return cls._deserialize_search_response(response.json())
3227
+
3262
3228
  def _time_indexed_storage_layout(self) -> dict[str, Any]:
3263
3229
  profile = self.time_indexed_profile
3264
3230
  if profile is not None and isinstance(profile.storage_layout, Mapping):
@@ -697,13 +697,6 @@ class GitHubRepositoryBranchList(BasePydanticModel):
697
697
  results: list[GitHubRepositoryBranch]
698
698
 
699
699
 
700
- class GitHubRepositoryBranchImportResult(BasePydanticModel):
701
- repository_uid: str
702
- code_repository_branch_uid: str
703
- repository_branch: str
704
- is_initialized: bool
705
-
706
-
707
700
  class GitHubRepositoryBinding(BasePydanticModel, BaseObjectOrm):
708
701
  FILTERSET_FIELDS: ClassVar[dict[str, list[str]]] = {
709
702
  "uid": ["in", "exact"],
@@ -731,28 +724,6 @@ class GitHubRepositoryBinding(BasePydanticModel, BaseObjectOrm):
731
724
  raise_for_response(r)
732
725
  return GitHubRepositoryBranchList.model_validate(r.json())
733
726
 
734
- def import_branch(
735
- self,
736
- *,
737
- repository_branch: str,
738
- metatables_data_source_uid: str | None = None,
739
- timeout=None,
740
- ) -> GitHubRepositoryBranchImportResult:
741
- body: dict[str, Any] = {"repository_branch": repository_branch}
742
- if metatables_data_source_uid is not None:
743
- body["metatables_data_source_uid"] = str(metatables_data_source_uid)
744
- url = f"{type(self).get_object_url()}/{self._public_detail_reference()}/import-branch/"
745
- r = make_request(
746
- s=type(self).build_session(),
747
- loaders=type(self).LOADERS,
748
- r_type="POST",
749
- url=url,
750
- payload={"json": body},
751
- time_out=timeout,
752
- )
753
- raise_for_response(r)
754
- return GitHubRepositoryBranchImportResult.model_validate(r.json())
755
-
756
727
 
757
728
  class CodeRepositoryImageSourceProvenance(BasePydanticModel):
758
729
  verification_state: Literal["verified", "unverified", "building", "failed"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 8.1.20.dev4
3
+ Version: 8.1.20.dev8
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: LicenseRef-MainSequence-Proprietary
@@ -23,7 +23,7 @@ mainsequence/scaffold_skills.py,sha256=mhjn7Xy5BSp8711xf7jziOC-DgyI1QUNWDup-fg_7
23
23
  mainsequence/cli/__init__.py,sha256=TNxXsTPgb52OhakIda9wTRh91cqoBqgQRx5TxjzQQFU,21
24
24
  mainsequence/cli/api.py,sha256=MN1wsJrykUfzkq9wlcjY0I_v8Ls0Lk9jY9_z8mVWVwo,170143
25
25
  mainsequence/cli/browser_auth.py,sha256=C-Sbpt0Pr9Pv3Z9dO80TMk7zPcaaZ-4zvW0tbRVMrTU,9863
26
- mainsequence/cli/cli.py,sha256=DmgJHGHSA_GlnSzzDrtzNf4dDcjUX3veQhx2bciA3OY,376943
26
+ mainsequence/cli/cli.py,sha256=fuhL5BcK6EHGAB2DCNxaB58SUV_TkEdI9zoOKMDfF2I,377218
27
27
  mainsequence/cli/code_repository_status.py,sha256=SHEnU8YSWFowPG6dEdE4Yd8CS1tIcJSE1MXFLfvD3Os,5975
28
28
  mainsequence/cli/config.py,sha256=VTxa0sH-XRUlc_FnCILGlHbgaAMEaMqSJ5j1G9I6PRw,26190
29
29
  mainsequence/cli/docker_utils.py,sha256=MS2DOH-bLtpBHfw_JmYu3fx7aYP1uafF7cpsVsFxGhg,10687
@@ -37,13 +37,13 @@ mainsequence/cli/ssh_utils.py,sha256=cucQFeQoctMPhoghCyrrb04WR6DhRBQXAOSZ3jFQwow
37
37
  mainsequence/cli/ui.py,sha256=ATgpcIhzZ1CXGwPcvEWOrJ3OEWUIAHK-mRTuKJ0uzzc,3454
38
38
  mainsequence/client/__init__.py,sha256=Xl2ie3HEO00V1C2xurxbhlWp_nXyV4SZMkeJXh-zZ1Q,548
39
39
  mainsequence/client/agent_runtime_models.py,sha256=ZFWuZaR1Q1_25M-lamIKQtLJI3uikQsp3g3O9lxOORk,66622
40
- mainsequence/client/base.py,sha256=Ng07uBGyGd0m6_a0rFkiDvHthO_Oo0lRhWgjN2et18Q,42077
40
+ mainsequence/client/base.py,sha256=Xg9TXBx7IXglSWX-aRYtOMbftkXioBOZxFNwcHF5TF8,42730
41
41
  mainsequence/client/client.py,sha256=sUsJhjwKq4oZsEX2Ozm-7owcyQq0kgFNKUrtEYwf8cU,3907
42
42
  mainsequence/client/compute_validation.py,sha256=ByeX0CkIE7qq06ggZFfN92U3Qp2e9cvo2RTIGWa5_Vw,6662
43
43
  mainsequence/client/dtype_codec.py,sha256=0ydXPw0dWTVtUzmXoT6ilr2TM_vNC3WTiy3I8QI1ni8,16522
44
44
  mainsequence/client/exceptions.py,sha256=xx2L4l3OMNsTybbYkiTKK398ahnutEascM0It35tGr0,3815
45
45
  mainsequence/client/github_issues.py,sha256=1jNUJD_NZx25K0naUC23CUx6_Nm8kpriXc0DFjjqGKE,14477
46
- mainsequence/client/models_foundry.py,sha256=EQUp6zb09ostpxaWmxB9c9-qyiW4OId3AZ_i5umaB8U,45887
46
+ mainsequence/client/models_foundry.py,sha256=ODPdpFQ334hmD2wd_V0KoU9og6yk01nfHIJ24oWySfU,44872
47
47
  mainsequence/client/models_helpers.py,sha256=cgRtixfAq2N_IYr-rex0UNYxZDeB5HMomUhkbGUJ_f4,64959
48
48
  mainsequence/client/models_user.py,sha256=qrdT4ldNs4yZXpMGtl-8QEFY3rbM_SZLWUV6nRfjk7M,41137
49
49
  mainsequence/client/observability.py,sha256=onRFc5G3Y6omlkj86hTsPLV2q2NBd5uqtyu4YuH_GtY,15695
@@ -53,7 +53,7 @@ mainsequence/client/data_sources_interfaces/duckdb.py,sha256=JZHsN3fB2UQYpNQJnp2
53
53
  mainsequence/client/data_sources_interfaces/local_paths.py,sha256=aO7-pTGBWItcpY1MxoYYP0mbEgB3dDWqDOwniezNw5c,323
54
54
  mainsequence/client/data_sources_interfaces/sqlite.py,sha256=gWpuG9FbPWF69urRqU_K5yWX7vkHGPeOCYaJwVu8nG0,16392
55
55
  mainsequence/client/metatables/__init__.py,sha256=dLxgfvV8t5kb59SxBowXxLJJQAc1BPgNzVUl_7U6SeA,580
56
- mainsequence/client/metatables/core.py,sha256=9mlSnyfXEhIXnW-WSMNgbuQUcY_AfDl7LpBJ_0eo0mY,187070
56
+ mainsequence/client/metatables/core.py,sha256=FdYKoAU6AjIS3lFAOXT6GOJTgJvD01HFea9yb6-H1DM,185916
57
57
  mainsequence/instrumentation/__init__.py,sha256=K1W1vx2wu1QldzUD6tI4C8op9mFcVpS7D-Ina1O9TFc,152
58
58
  mainsequence/instrumentation/utils.py,sha256=b-ihjSioAepeLfMpudM2SqCtvnxMqIXileHx3klBCQU,3377
59
59
  mainsequence/meta_tables/__init__.py,sha256=aHwu6kRSunS3-ZiVnSS-8rBH09ZnWUu82hgrmnpeEf4,5267
@@ -83,9 +83,9 @@ mainsequence/meta_tables/time_index_table_updates/namespacing.py,sha256=obJfMnjL
83
83
  mainsequence/meta_tables/time_index_table_updates/runner.py,sha256=853p_iXJ835pI8pX3519HSdTw93Bqqd3JxHOfm3S6yg,34412
84
84
  mainsequence/meta_tables/time_index_table_updates/updaters.py,sha256=-6zJgi1sDRCyIyVxLwTfb2RLLZS4LC0syNJHnJRAtgU,31404
85
85
  mainsequence/meta_tables/time_index_table_updates/utils.py,sha256=O1iKp2tzCkqxyCblI6MKxez6XV180w87VszxDO9OfAE,621
86
- mainsequence-8.1.20.dev4.dist-info/licenses/LICENSE,sha256=fXoCKgEuZXmP84_QDXpvO18QHze_6AAhd-zvZBUjJxQ,4524
87
- mainsequence-8.1.20.dev4.dist-info/METADATA,sha256=BK7Y5Ew9g3Hh3c2F5kmQx3UXRYQEKOINwofoFIL19dg,7383
88
- mainsequence-8.1.20.dev4.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
89
- mainsequence-8.1.20.dev4.dist-info/entry_points.txt,sha256=XGAOq3-mF2lWWpeRJvoaWyMarRcK167mH1g124aGdUs,88
90
- mainsequence-8.1.20.dev4.dist-info/top_level.txt,sha256=BFeblM_Q9q0cUWBvTxnfWcWQEHtf5XZi9nOS-Gdfwus,28
91
- mainsequence-8.1.20.dev4.dist-info/RECORD,,
86
+ mainsequence-8.1.20.dev8.dist-info/licenses/LICENSE,sha256=fXoCKgEuZXmP84_QDXpvO18QHze_6AAhd-zvZBUjJxQ,4524
87
+ mainsequence-8.1.20.dev8.dist-info/METADATA,sha256=yvx3dZnhC2qjIGY7f4HZgNeqj0B0x69pm0oxaF1ecnQ,7383
88
+ mainsequence-8.1.20.dev8.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
89
+ mainsequence-8.1.20.dev8.dist-info/entry_points.txt,sha256=XGAOq3-mF2lWWpeRJvoaWyMarRcK167mH1g124aGdUs,88
90
+ mainsequence-8.1.20.dev8.dist-info/top_level.txt,sha256=BFeblM_Q9q0cUWBvTxnfWcWQEHtf5XZi9nOS-Gdfwus,28
91
+ mainsequence-8.1.20.dev8.dist-info/RECORD,,