sqlmesh 0.188.2.dev23__py3-none-any.whl → 0.188.2.dev25__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.
sqlmesh/__init__.py CHANGED
@@ -197,6 +197,10 @@ def configure_logging(
197
197
  level = logging.DEBUG if debug else logging.INFO
198
198
  logger.setLevel(level)
199
199
 
200
+ if debug:
201
+ # Remove noisy snowflake connector logs that are not useful for users
202
+ logging.getLogger("snowflake.connector").setLevel(logging.INFO)
203
+
200
204
  if write_to_stdout:
201
205
  stdout_handler = logging.StreamHandler(sys.stdout)
202
206
  stdout_handler.setFormatter(CustomFormatter())
sqlmesh/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.188.2.dev23'
21
- __version_tuple__ = version_tuple = (0, 188, 2, 'dev23')
20
+ __version__ = version = '0.188.2.dev25'
21
+ __version_tuple__ = version_tuple = (0, 188, 2, 'dev25')
sqlmesh/core/console.py CHANGED
@@ -3184,6 +3184,12 @@ class MarkdownConsole(CaptureTerminalConsole):
3184
3184
 
3185
3185
  def log_warning(self, short_message: str, long_message: t.Optional[str] = None) -> None:
3186
3186
  logger.warning(long_message or short_message)
3187
+
3188
+ if not short_message.endswith("\n"):
3189
+ short_message += (
3190
+ "\n" # so that the closing ``` ends up on a newline which is important for GitHub
3191
+ )
3192
+
3187
3193
  self._print(f"```\n\\[WARNING] {short_message}```\n\n")
3188
3194
 
3189
3195
  def _print(self, value: t.Any, **kwargs: t.Any) -> None:
@@ -22,6 +22,7 @@ logger = logging.getLogger(__name__)
22
22
  @click.option(
23
23
  "--token",
24
24
  type=str,
25
+ envvar="GITHUB_TOKEN",
25
26
  help="The Github Token to be used. Pass in `${{ secrets.GITHUB_TOKEN }}` if you want to use the one created by Github actions",
26
27
  )
27
28
  @click.pass_context
@@ -11,6 +11,7 @@ import typing as t
11
11
  import unittest
12
12
  from enum import Enum
13
13
  from typing import List
14
+ from pathlib import Path
14
15
 
15
16
  import requests
16
17
  from hyperscript import Element, h
@@ -28,11 +29,11 @@ from sqlmesh.core.snapshot.definition import (
28
29
  SnapshotTableInfo,
29
30
  format_intervals,
30
31
  )
32
+ from sqlglot.errors import SqlglotError
31
33
  from sqlmesh.core.user import User
32
34
  from sqlmesh.core.config import Config
33
35
  from sqlmesh.integrations.github.cicd.config import GithubCICDBotConfig
34
36
  from sqlmesh.utils import word_characters_only, Verbosity
35
- from sqlmesh.utils.concurrency import NodeExecutionFailedError
36
37
  from sqlmesh.utils.date import now
37
38
  from sqlmesh.utils.errors import (
38
39
  CICDBotError,
@@ -40,6 +41,7 @@ from sqlmesh.utils.errors import (
40
41
  PlanError,
41
42
  UncategorizedPlanError,
42
43
  LinterError,
44
+ SQLMeshError,
43
45
  )
44
46
  from sqlmesh.utils.pydantic import PydanticModel
45
47
 
@@ -283,7 +285,7 @@ class GithubController:
283
285
 
284
286
  def __init__(
285
287
  self,
286
- paths: t.Union[str, t.Iterable[str]],
288
+ paths: t.Union[Path, t.Iterable[Path]],
287
289
  token: str,
288
290
  config: t.Optional[t.Union[Config, str]] = None,
289
291
  event: t.Optional[GithubEvent] = None,
@@ -307,10 +309,13 @@ class GithubController:
307
309
  raise CICDBotError("Console must be a markdown console.")
308
310
  self._console = t.cast(MarkdownConsole, get_console())
309
311
 
312
+ from github.Consts import DEFAULT_BASE_URL
313
+ from github.Auth import Token
314
+
310
315
  self._client: Github = client or Github(
311
- base_url=os.environ["GITHUB_API_URL"],
312
- login_or_token=self._token,
316
+ base_url=os.environ.get("GITHUB_API_URL", DEFAULT_BASE_URL), auth=Token(self._token)
313
317
  )
318
+
314
319
  self._repo: Repository = self._client.get_repo(
315
320
  self._event.pull_request_info.full_repo_path, lazy=True
316
321
  )
@@ -328,6 +333,9 @@ class GithubController:
328
333
  logger.debug(f"Approvers: {', '.join(self._approvers)}")
329
334
  self._context: Context = Context(paths=self._paths, config=self.config)
330
335
 
336
+ # Bot config needs the context to be initialized
337
+ logger.debug(f"Bot config: {self.bot_config.json(indent=2)}")
338
+
331
339
  @property
332
340
  def deploy_command_enabled(self) -> bool:
333
341
  return self.bot_config.enable_deploy_command
@@ -433,7 +441,6 @@ class GithubController:
433
441
  bot_config = self._context.config.cicd_bot or GithubCICDBotConfig(
434
442
  auto_categorize_changes=self._context.auto_categorize_changes
435
443
  )
436
- logger.debug(f"Bot config: {bot_config.json(indent=2)}")
437
444
  return bot_config
438
445
 
439
446
  @property
@@ -454,8 +461,11 @@ class GithubController:
454
461
  Appends the given key/value to output so they can be read by following steps
455
462
  """
456
463
  logger.debug(f"Setting output. Key: {key}, Value: {value}")
457
- with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as fh:
458
- print(f"{key}={value}", file=fh)
464
+
465
+ # GitHub Actions sets this environment variable
466
+ if output_file := os.environ.get("GITHUB_OUTPUT"):
467
+ with open(output_file, "a", encoding="utf-8") as fh:
468
+ print(f"{key}={value}", file=fh)
459
469
 
460
470
  def get_plan_summary(self, plan: Plan) -> str:
461
471
  try:
@@ -637,15 +647,31 @@ class GithubController:
637
647
  if text:
638
648
  kwargs["output"]["text"] = text
639
649
  logger.debug(f"Updating check with kwargs: {kwargs}")
640
- if name in self._check_run_mapping:
641
- logger.debug(f"Found check run in mapping so updating it. Name: {name}")
642
- check_run = self._check_run_mapping[name]
643
- check_run.edit(
644
- **{k: v for k, v in kwargs.items() if k not in ("name", "head_sha", "started_at")}
645
- )
650
+
651
+ if self.running_in_github_actions:
652
+ # Only make the API call to update the checks if we are running within GitHub Actions
653
+ # One very annoying limitation of the Pull Request Checks API is that its only available to GitHub Apps
654
+ # and not personal access tokens, which makes it unable to be utilized during local development
655
+ if name in self._check_run_mapping:
656
+ logger.debug(f"Found check run in mapping so updating it. Name: {name}")
657
+ check_run = self._check_run_mapping[name]
658
+ check_run.edit(
659
+ **{
660
+ k: v
661
+ for k, v in kwargs.items()
662
+ if k not in ("name", "head_sha", "started_at")
663
+ }
664
+ )
665
+ else:
666
+ logger.debug(f"Did not find check run in mapping so creating it. Name: {name}")
667
+ self._check_run_mapping[name] = self._repo.create_check_run(**kwargs)
646
668
  else:
647
- logger.debug(f"Did not find check run in mapping so creating it. Name: {name}")
648
- self._check_run_mapping[name] = self._repo.create_check_run(**kwargs)
669
+ # Output the summary using print() so the newlines are resolved and the result can easily
670
+ # be disambiguated from the rest of the console output and copy+pasted into a Markdown renderer
671
+ print(
672
+ f"---CHECK OUTPUT START: {kwargs['output']['title']} ---\n{kwargs['output']['summary']}\n---CHECK OUTPUT END---\n"
673
+ )
674
+
649
675
  if conclusion:
650
676
  self._append_output(
651
677
  word_characters_only(name.replace("SQLMesh - ", "").lower()), conclusion.value
@@ -890,15 +916,21 @@ class GithubController:
890
916
  else:
891
917
  skip_reason = "A prior stage failed resulting in skipping PR creation."
892
918
 
919
+ if not skip_reason and exception:
920
+ logger.debug(
921
+ f"Got {type(exception).__name__}. Stack trace: " + traceback.format_exc()
922
+ )
923
+
893
924
  captured_errors = self._console.consume_captured_errors()
894
925
  if captured_errors:
895
926
  logger.debug(f"Captured errors: {captured_errors}")
896
927
  failure_msg = f"**Errors:**\n{captured_errors}\n"
897
- elif isinstance(exception, NodeExecutionFailedError):
898
- logger.debug(
899
- "Got Node Execution Failed Error. Stack trace: " + traceback.format_exc()
900
- )
901
- failure_msg = f"Node `{exception.node.name}` failed to apply.\n\n**Stack Trace:**\n```\n{traceback.format_exc()}\n```"
928
+ elif isinstance(exception, PlanError):
929
+ failure_msg = f"Plan application failed.\n\n{self._console.captured_output}"
930
+ elif isinstance(exception, (SQLMeshError, SqlglotError, ValueError)):
931
+ # this logic is taken from the global error handler attached to the CLI, which uses `click.echo()` to output the message
932
+ # so cant be re-used here because it bypasses the Console
933
+ failure_msg = f"**Error:** {str(exception)}"
902
934
  else:
903
935
  logger.debug(
904
936
  "Got unexpected error. Error Type: "
@@ -909,7 +941,7 @@ class GithubController:
909
941
  failure_msg = f"This is an unexpected error.\n\n**Exception:**\n```\n{traceback.format_exc()}\n```"
910
942
  conclusion_to_summary = {
911
943
  GithubCheckConclusion.SKIPPED: f":next_track_button: Skipped creating or updating PR Environment `{self.pr_environment_name}`. {skip_reason}",
912
- GithubCheckConclusion.FAILURE: f":x: Failed to create or update PR Environment `{self.pr_environment_name}`.\n{failure_msg}",
944
+ GithubCheckConclusion.FAILURE: f":x: Failed to create or update PR Environment `{self.pr_environment_name}`.\n\n{failure_msg}",
913
945
  GithubCheckConclusion.CANCELLED: f":stop_sign: Cancelled creating or updating PR Environment `{self.pr_environment_name}`",
914
946
  GithubCheckConclusion.ACTION_REQUIRED: f":warning: Action Required to create or update PR Environment `{self.pr_environment_name}`. There are likely uncateogrized changes. Run `plan` locally to apply these changes. If you want the bot to automatically categorize changes, then check documentation (https://sqlmesh.readthedocs.io/en/stable/integrations/github/) for more information.",
915
947
  }
@@ -1061,3 +1093,7 @@ class GithubController:
1061
1093
  message_encoded[i : i + self.MAX_BYTE_LENGTH].decode("utf-8", "ignore")
1062
1094
  for i in range(0, len(message_encoded), self.MAX_BYTE_LENGTH)
1063
1095
  ]
1096
+
1097
+ @property
1098
+ def running_in_github_actions(self) -> bool:
1099
+ return os.environ.get("GITHUB_ACTIONS", None) == "true"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.188.2.dev23
3
+ Version: 0.188.2.dev25
4
4
  Summary: Next-generation data transformation framework
5
5
  Author-email: "TobikoData Inc." <engineering@tobikodata.com>
6
6
  License: Apache License
@@ -233,7 +233,7 @@ Requires-Dist: pydantic>=2.0.0
233
233
  Requires-Dist: requests
234
234
  Requires-Dist: rich[jupyter]
235
235
  Requires-Dist: ruamel.yaml
236
- Requires-Dist: sqlglot[rs]~=26.24.0
236
+ Requires-Dist: sqlglot[rs]~=26.25.3
237
237
  Requires-Dist: tenacity
238
238
  Requires-Dist: time-machine
239
239
  Requires-Dist: json-stream
@@ -277,7 +277,7 @@ Requires-Dist: pre-commit; extra == "dev"
277
277
  Requires-Dist: psycopg2-binary; extra == "dev"
278
278
  Requires-Dist: pydantic; extra == "dev"
279
279
  Requires-Dist: PyAthena[Pandas]; extra == "dev"
280
- Requires-Dist: PyGithub~=2.5.0; extra == "dev"
280
+ Requires-Dist: PyGithub; extra == "dev"
281
281
  Requires-Dist: pyperf; extra == "dev"
282
282
  Requires-Dist: pyspark~=3.5.0; extra == "dev"
283
283
  Requires-Dist: pytest; extra == "dev"
@@ -1,5 +1,5 @@
1
- sqlmesh/__init__.py,sha256=69xw6bTmi4cW90M-sl3g6wLDgxVcLHcKg1q8GS3lqyA,7466
2
- sqlmesh/_version.py,sha256=1QD3HEdq_p-wg_mOYBMLE4yQPVoUKRRJ5ZEhaQj6ERg,530
1
+ sqlmesh/__init__.py,sha256=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
2
+ sqlmesh/_version.py,sha256=XC0bfEgnWVzhAmsRnAHFuB7gnKjq5oMqJ_wRERzz2XM,530
3
3
  sqlmesh/magics.py,sha256=fu7-OeT_0_TAkWZOLoiioE3-3iFpvTRxFCbQUlRnfuw,39944
4
4
  sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -11,7 +11,7 @@ sqlmesh/cli/main.py,sha256=dt92CJPuMzUZvBYqXMh-tkUCaLfj2Z5RC2COa98_9Co,32310
11
11
  sqlmesh/cli/options.py,sha256=aC_L5WnMScKzMU55BD1Y-8R-QzqCkPSYrlCI-payHRA,1333
12
12
  sqlmesh/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  sqlmesh/core/_typing.py,sha256=e1f7xO2aZCy38M_3VoDy-XI3shyd99-IFctgIFSgXWM,497
14
- sqlmesh/core/console.py,sha256=VfiiCZeraWIForLqJTkkyVsW0oRDfkctFuFHUpqUIBE,150948
14
+ sqlmesh/core/console.py,sha256=xgBoRG5TMIeCrp8pDNKyM5DYGM3dvoB71etrOXGlVbI,151139
15
15
  sqlmesh/core/constants.py,sha256=oqt6zjepUhQoWlgapKn_HpG7Pu9mrFwepdX5caNfJUI,2499
16
16
  sqlmesh/core/context.py,sha256=GyBO6rU_k0CAMsD1J6FdqwFDctTeDIVl-ZP6Z2zF_5U,116429
17
17
  sqlmesh/core/context_diff.py,sha256=I7luvY2za30E5ynVaFPaEQQEmNViJpWAmW48PGSyDCU,21135
@@ -152,9 +152,9 @@ sqlmesh/integrations/llm.py,sha256=URgp3JKr06HYv6hGlJ7DQ9m3QCc41xRWK23HzmGpbDI,1
152
152
  sqlmesh/integrations/slack.py,sha256=nxLxu5WztGbZH3JdqnzyPqmJUMfRdJ_49LQ7zR-u39Q,6801
153
153
  sqlmesh/integrations/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
154
  sqlmesh/integrations/github/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
155
- sqlmesh/integrations/github/cicd/command.py,sha256=KPnD08Jjt7L5_nPZ7OYrkZXO9u-2aG918YSVIULlITo,11559
155
+ sqlmesh/integrations/github/cicd/command.py,sha256=rNWb-aMOA9R23YumD5vPwR0PgPGGj8KwG6KG1ftdqV0,11586
156
156
  sqlmesh/integrations/github/cicd/config.py,sha256=tRhMZaLf1p6AWXvi67n85Q-lptJNGt1Wk_Jr61ytpiM,2104
157
- sqlmesh/integrations/github/cicd/controller.py,sha256=VM9zL1wsuhTTyDb-P27-RmZGQhTsLF5qeLmaZJ1l7_w,42100
157
+ sqlmesh/integrations/github/cicd/controller.py,sha256=IgUWK9orYSMiElO3GaL6Ja-osFgA7je3RDcLChWUi5s,43769
158
158
  sqlmesh/lsp/api.py,sha256=LJdECSaEZoPbu_Xl4KscVG-WLt7_g4dY-zKGO68dH14,2162
159
159
  sqlmesh/lsp/completions.py,sha256=Ufe5XyqmT8ttXqQDbhH2RtuGC0cVuVfSnGqDMl6KmB4,3601
160
160
  sqlmesh/lsp/context.py,sha256=ozkrw-897_Scbbn4AnKdeTQhrUb0CI0e34vcV-5U2DA,6158
@@ -270,7 +270,7 @@ sqlmesh/utils/pydantic.py,sha256=I898jAFqa3qU6lG2uPpRebVFncOUo8ZrLWM_R3K3DHU,116
270
270
  sqlmesh/utils/rich.py,sha256=xNZyPCqEc4TAlJlsEthg-5eYUWpaizz0QjBzO7a1Yv4,1509
271
271
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
272
272
  sqlmesh/utils/yaml.py,sha256=np-WVcwmwsKghCgAj1OBBMsK1SXSRn4wR-H37cGiFr8,2282
273
- sqlmesh-0.188.2.dev23.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
273
+ sqlmesh-0.188.2.dev25.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
274
274
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
275
275
  web/client/dist/index.html,sha256=LbR9XrOXE77otBPoDnaomssYz6h2TBwLANs6hUJ0p2M,5472
276
276
  web/client/dist/assets/Audits-DB1HcP9M.js,sha256=eGI_Soj69Jntsixw1NqQpdwG94N5jipQZv7T1Y7WUSs,1041
@@ -388,8 +388,8 @@ web/server/api/endpoints/models.py,sha256=ud-lRwriyI_OYg9tZchrBgeiXELiRTLNEodraf
388
388
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
389
389
  web/server/api/endpoints/plan.py,sha256=OYuQ_4dgbhG9ibTcX1a8mvYgH3ANxw9Fhbb4wg6QWqc,9222
390
390
  web/server/api/endpoints/table_diff.py,sha256=Wd5YxeKbZB7AkrDvqFgvV9ZQlnKYOF1n5W_w2EHE_Zw,2085
391
- sqlmesh-0.188.2.dev23.dist-info/METADATA,sha256=h0uAu684f0VZ6HugPgdvOFpsDUVagMOjGxPLXOlNApk,26532
392
- sqlmesh-0.188.2.dev23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
393
- sqlmesh-0.188.2.dev23.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
394
- sqlmesh-0.188.2.dev23.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
395
- sqlmesh-0.188.2.dev23.dist-info/RECORD,,
391
+ sqlmesh-0.188.2.dev25.dist-info/METADATA,sha256=faeOCzdk0WMq35XIalLvtOA0SvgZy0QGjKv9wV9KPko,26525
392
+ sqlmesh-0.188.2.dev25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
393
+ sqlmesh-0.188.2.dev25.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
394
+ sqlmesh-0.188.2.dev25.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
395
+ sqlmesh-0.188.2.dev25.dist-info/RECORD,,