tinybird 0.0.1.dev249__tar.gz → 0.0.1.dev251__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.

Potentially problematic release.


This version of tinybird might be problematic. Click here for more details.

Files changed (140) hide show
  1. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/config.py +4 -0
  3. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/prompts.py +1 -1
  4. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/sql_template.py +5 -1
  5. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/__cli__.py +2 -2
  6. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/agent.py +68 -27
  7. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/animations.py +26 -7
  8. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/prompts.py +4 -2
  9. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/tools/append.py +13 -22
  10. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/tools/create_datafile.py +29 -25
  11. tinybird-0.0.1.dev251/tinybird/tb/modules/agent/tools/deploy.py +36 -0
  12. tinybird-0.0.1.dev251/tinybird/tb/modules/agent/tools/get_endpoint_stats.py +51 -0
  13. tinybird-0.0.1.dev251/tinybird/tb/modules/agent/tools/get_openapi_definition.py +39 -0
  14. tinybird-0.0.1.dev251/tinybird/tb/modules/agent/tools/mock.py +73 -0
  15. tinybird-0.0.1.dev251/tinybird/tb/modules/agent/tools/plan.py +37 -0
  16. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/tools/read_fixture_data.py +8 -0
  17. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/utils.py +48 -1
  18. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird.egg-info/PKG-INFO +1 -1
  19. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird.egg-info/SOURCES.txt +2 -0
  20. tinybird-0.0.1.dev249/tinybird/tb/modules/agent/tools/deploy.py +0 -45
  21. tinybird-0.0.1.dev249/tinybird/tb/modules/agent/tools/mock.py +0 -59
  22. tinybird-0.0.1.dev249/tinybird/tb/modules/agent/tools/plan.py +0 -47
  23. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/setup.cfg +0 -0
  24. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/__cli__.py +0 -0
  25. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/ch_utils/constants.py +0 -0
  26. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/ch_utils/engine.py +0 -0
  27. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/check_pypi.py +0 -0
  28. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/client.py +0 -0
  29. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/connectors.py +0 -0
  30. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/context.py +0 -0
  31. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/datafile/common.py +0 -0
  32. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/datafile/exceptions.py +0 -0
  33. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/datafile/parse_connection.py +0 -0
  34. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/datafile/parse_datasource.py +0 -0
  35. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/datafile/parse_pipe.py +0 -0
  36. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/datatypes.py +0 -0
  37. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/feedback_manager.py +0 -0
  38. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/git_settings.py +0 -0
  39. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/sql.py +0 -0
  40. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/sql_template_fmt.py +0 -0
  41. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/sql_toolset.py +0 -0
  42. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/syncasync.py +0 -0
  43. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/check_pypi.py +0 -0
  44. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/cli.py +0 -0
  45. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/client.py +0 -0
  46. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/config.py +0 -0
  47. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/__init__.py +0 -0
  48. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/banner.py +0 -0
  49. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/memory.py +0 -0
  50. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/models.py +0 -0
  51. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/tools/__init__.py +0 -0
  52. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/tools/build.py +0 -0
  53. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/tools/deploy_check.py +0 -0
  54. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/tools/explore.py +0 -0
  55. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/agent/tools/preview_datafile.py +0 -0
  56. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/build.py +0 -0
  57. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/build_common.py +0 -0
  58. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/cicd.py +0 -0
  59. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/cli.py +0 -0
  60. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/common.py +0 -0
  61. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/config.py +0 -0
  62. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/connection.py +0 -0
  63. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/copy.py +0 -0
  64. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/create.py +0 -0
  65. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/build.py +0 -0
  66. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/build_common.py +0 -0
  67. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  68. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  69. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/diff.py +0 -0
  70. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/fixture.py +0 -0
  71. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/format_common.py +0 -0
  72. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  73. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  74. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  75. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/playground.py +0 -0
  76. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datafile/pull.py +0 -0
  77. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/datasource.py +0 -0
  78. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/deployment.py +0 -0
  79. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/deployment_common.py +0 -0
  80. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/deprecations.py +0 -0
  81. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/dev_server.py +0 -0
  82. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/endpoint.py +0 -0
  83. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/exceptions.py +0 -0
  84. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/feedback_manager.py +0 -0
  85. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/info.py +0 -0
  86. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/infra.py +0 -0
  87. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/job.py +0 -0
  88. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/llm.py +0 -0
  89. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/llm_utils.py +0 -0
  90. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/local.py +0 -0
  91. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/local_common.py +0 -0
  92. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/login.py +0 -0
  93. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/login_common.py +0 -0
  94. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/logout.py +0 -0
  95. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/materialization.py +0 -0
  96. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/mock.py +0 -0
  97. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/mock_common.py +0 -0
  98. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/open.py +0 -0
  99. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/pipe.py +0 -0
  100. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/project.py +0 -0
  101. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/regions.py +0 -0
  102. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/secret.py +0 -0
  103. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/secret_common.py +0 -0
  104. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/shell.py +0 -0
  105. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/sink.py +0 -0
  106. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/table.py +0 -0
  107. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/telemetry.py +0 -0
  108. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/test.py +0 -0
  109. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  110. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  111. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/token.py +0 -0
  112. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/watch.py +0 -0
  113. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/workspace.py +0 -0
  114. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb/modules/workspace_members.py +0 -0
  115. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli.py +0 -0
  116. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/auth.py +0 -0
  117. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/branch.py +0 -0
  118. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/cicd.py +0 -0
  119. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/cli.py +0 -0
  120. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/common.py +0 -0
  121. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/config.py +0 -0
  122. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/connection.py +0 -0
  123. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/datasource.py +0 -0
  124. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/exceptions.py +0 -0
  125. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/fmt.py +0 -0
  126. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/job.py +0 -0
  127. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/pipe.py +0 -0
  128. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/regions.py +0 -0
  129. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/tag.py +0 -0
  130. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/telemetry.py +0 -0
  131. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/test.py +0 -0
  132. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  133. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  134. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/workspace.py +0 -0
  135. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  136. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird/tornado_template.py +0 -0
  137. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird.egg-info/dependency_links.txt +0 -0
  138. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird.egg-info/entry_points.txt +0 -0
  139. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird.egg-info/requires.txt +0 -0
  140. {tinybird-0.0.1.dev249 → tinybird-0.0.1.dev251}/tinybird.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev249
3
+ Version: 0.0.1.dev251
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -33,6 +33,7 @@ LEGACY_HOSTS = {
33
33
  "https://api.europe-west2.gcp.tinybird.co": "https://cloud.tinybird.co/gcp/europe-west2",
34
34
  "https://api.ap-east.aws.tinybird.co": "https://app.tinybird.co/aws/ap-east",
35
35
  "https://api.northamerica-northeast2.gcp.tinybird.co": "https://app.tinybird.co/gcp/northamerica-northeast2",
36
+ "https://api.us-west1.gcp.tinybird.co": "https://app.tinybird.co/gcp/us-west1",
36
37
  "https://api.wadus1.gcp.tinybird.co": "https://app.wadus.tinybird.co/gcp/wadus1",
37
38
  "https://api.wadus2.gcp.tinybird.co": "https://app.wadus.tinybird.co/gcp/wadus2",
38
39
  "https://api.wadus3.gcp.tinybird.co": "https://app.wadus.tinybird.co/gcp/wadus3",
@@ -55,6 +56,7 @@ LEGACY_HOSTS = {
55
56
  "https://ui.split.tinybird.co": "https://app.tinybird.co/aws/split-us-east",
56
57
  "https://ui.split.us-west-2.aws.tinybird.co": "https://app.tinybird.co/aws/split-us-west-2",
57
58
  "https://ui.northamerica-northeast2.gcp.tinybird.co": "https://app.tinybird.co/gcp/northamerica-northeast2",
59
+ "https://ui.us-west1.gcp.tinybird.co": "https://app.tinybird.co/gcp/us-west1",
58
60
  "https://api.split.tinybird.co": "https://app.tinybird.co/aws/split-us-east",
59
61
  "https://api.split.us-west-2.aws.tinybird.co": "https://app.tinybird.co/aws/split-us-west-2",
60
62
  "https://ui.wadus1.gcp.tinybird.co": "https://app.wadus.tinybird.co/gcp/wadus1",
@@ -81,6 +83,7 @@ CLOUD_HOSTS = {
81
83
  "https://api.eu-west-1.aws.tinybird.co": "https://cloud.tinybird.co/aws/eu-west-1",
82
84
  "https://api.europe-west2.gcp.tinybird.co": "https://cloud.tinybird.co/gcp/europe-west2",
83
85
  "https://api.northamerica-northeast2.gcp.tinybird.co": "https://cloud.tinybird.co/gcp/northamerica-northeast2",
86
+ "https://api.us-west1.gcp.tinybird.co": "https://cloud.tinybird.co/gcp/us-west1",
84
87
  "https://api.ap-east.aws.tinybird.co": "https://cloud.tinybird.co/aws/ap-east",
85
88
  "https://ui.tinybird.co": "https://cloud.tinybird.co/gcp/europe-west3",
86
89
  "https://ui.us-east.tinybird.co": "https://cloud.tinybird.co/gcp/us-east4",
@@ -89,6 +92,7 @@ CLOUD_HOSTS = {
89
92
  "https://ui.eu-central-1.aws.tinybird.co": "https://cloud.tinybird.co/aws/eu-central-1",
90
93
  "https://ui.europe-west2.gcp.tinybird.co": "https://cloud.tinybird.co/gcp/europe-west2",
91
94
  "https://ui.northamerica-northeast2.gcp.tinybird.co": "https://cloud.tinybird.co/gcp/northamerica-northeast2",
95
+ "https://ui.us-west1.gcp.tinybird.co": "https://cloud.tinybird.co/gcp/us-west1",
92
96
  }
93
97
 
94
98
 
@@ -815,7 +815,7 @@ pipe_instructions = """
815
815
  <pipe_file_instructions>
816
816
  - The pipe names must be unique.
817
817
  - Nodes do NOT use the same name as the Pipe they belong to. So if the pipe name is "my_pipe", the nodes must be named different like "my_pipe_node_1", "my_pipe_node_2", etc.
818
- - Nodes can't have the same exact name as the Pipe they belong to.
818
+ - Node names MUST be different from the resource names in the project.
819
819
  - Avoid more than one node per pipe unless it is really necessary or requested by the user.
820
820
  - No indentation is allowed for property names: DESCRIPTION, NODE, SQL, TYPE, etc.
821
821
  - Allowed TYPE values are: endpoint, copy, materialized, sink.
@@ -1388,13 +1388,14 @@ _namespace = {
1388
1388
  "close": None,
1389
1389
  "print": None,
1390
1390
  "input": None,
1391
- "id": None,
1392
1391
  }
1393
1392
 
1394
1393
 
1395
1394
  reserved_vars = set(["_tt_tmp", "_tt_append", "isinstance", "str", "error", "custom_error", *list(vars(builtins))])
1396
1395
  for p in DEFAULT_PARAM_NAMES: # we handle these in an specific manner
1397
1396
  reserved_vars.discard(p) # `format` is part of builtins
1397
+ # Allow 'id' to be used as a template parameter - https://gitlab.com/tinybird/analytics/-/issues/19119
1398
+ reserved_vars.discard("id")
1398
1399
  error_vars = ["error", "custom_error"]
1399
1400
 
1400
1401
 
@@ -1463,6 +1464,9 @@ def generate(self, **kwargs) -> Tuple[str, TemplateExecutionResults]:
1463
1464
  return Expression(f"-- disable {feature}\n")
1464
1465
 
1465
1466
  namespace.update(_namespace)
1467
+ # This is to fix the issue https://gitlab.com/tinybird/analytics/-/issues/19119
1468
+ # We need to do the override here because if we modify the _namespace, we would filter out parameters from the users
1469
+ namespace.update({"id": None})
1466
1470
  namespace.update(kwargs)
1467
1471
  namespace.update(
1468
1472
  {
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/forward/commands'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '0.0.1.dev249'
8
- __revision__ = 'ef4e98c'
7
+ __version__ = '0.0.1.dev251'
8
+ __revision__ = 'c11760c'
@@ -4,12 +4,9 @@ import sys
4
4
  from datetime import datetime
5
5
  from functools import partial
6
6
  from pathlib import Path
7
- from typing import Any
7
+ from typing import Any, Optional
8
8
 
9
9
  import click
10
- from prompt_toolkit import prompt
11
- from prompt_toolkit.cursor_shapes import CursorShape
12
- from prompt_toolkit.styles import Style
13
10
  from pydantic_ai import Agent, Tool
14
11
  from pydantic_ai.messages import ModelMessage
15
12
 
@@ -29,7 +26,7 @@ from tinybird.prompts import (
29
26
  from tinybird.tb.client import TinyB
30
27
  from tinybird.tb.modules.agent.animations import ThinkingAnimation
31
28
  from tinybird.tb.modules.agent.banner import display_banner
32
- from tinybird.tb.modules.agent.memory import clear_history, load_history
29
+ from tinybird.tb.modules.agent.memory import clear_history
33
30
  from tinybird.tb.modules.agent.models import create_model, model_costs
34
31
  from tinybird.tb.modules.agent.prompts import (
35
32
  datafile_instructions,
@@ -43,11 +40,13 @@ from tinybird.tb.modules.agent.tools.create_datafile import create_datafile
43
40
  from tinybird.tb.modules.agent.tools.deploy import deploy
44
41
  from tinybird.tb.modules.agent.tools.deploy_check import deploy_check
45
42
  from tinybird.tb.modules.agent.tools.explore import explore_data
43
+ from tinybird.tb.modules.agent.tools.get_endpoint_stats import get_endpoint_stats
44
+ from tinybird.tb.modules.agent.tools.get_openapi_definition import get_openapi_definition
46
45
  from tinybird.tb.modules.agent.tools.mock import mock
47
46
  from tinybird.tb.modules.agent.tools.plan import plan
48
47
  from tinybird.tb.modules.agent.tools.preview_datafile import preview_datafile
49
48
  from tinybird.tb.modules.agent.tools.read_fixture_data import read_fixture_data
50
- from tinybird.tb.modules.agent.utils import TinybirdAgentContext
49
+ from tinybird.tb.modules.agent.utils import TinybirdAgentContext, show_input
51
50
  from tinybird.tb.modules.build_common import process as build_process
52
51
  from tinybird.tb.modules.common import _analyze, _get_tb_client
53
52
  from tinybird.tb.modules.config import CLIConfig
@@ -115,6 +114,8 @@ You have access to the following tools:
115
114
  8. `mock` - Create mock data for a landing datasource.
116
115
  9. `read_fixture_data` - Read a fixture data file present in the project folder.
117
116
  10. `append` - Append existing fixture to a datasource.
117
+ 11. `get_endpoint_stats` - Get metrics of the requests to an endpoint.
118
+ 12. `get_openapi_definition` - Get the OpenAPI definition for all endpoints that are built/deployed to Tinybird Cloud or Local.
118
119
 
119
120
  # When creating or updating datafiles:
120
121
  1. Use `plan` tool to plan the creation or update of resources.
@@ -126,6 +127,24 @@ You have access to the following tools:
126
127
  7. If the datafile was not created, finish the process and just wait for a new user prompt.
127
128
  8. If the datafile was created successfully, but the built failed, try to fix the error and repeat the process.
128
129
 
130
+ # When creating a landing datasource given a .ndjson file:
131
+ - If the user does not specify anything about the desired schema, create a schema like this:
132
+ SCHEMA >
133
+ `data` String `json:$`
134
+ - Use always json paths with .ndjson files.
135
+
136
+ # When user wants to optimize an endpoint:
137
+ First check if the query is optimized. E.g is filtering by a column present in the sorting key.
138
+ Avoid when possible to not update the landing datasource.
139
+ Check endpoint stats to analyze how the endpoint is performing. Use `get_endpoint_stats` tool to get the stats.
140
+ When your data is in Tinybird, you can create intermediate data sources to preprocess data and make the endpoints faster. This can be done by using materialized views or copy pipes.
141
+ - Copy pipes capture the result of a pipe at a specific point in time and write it to a target data source. They can run on a schedule or run on demand, making them ideal for event-sourced snapshots, data experimentation, and deduplication with snapshots.
142
+ - Materialized views continuously re-evaluate a query as new events are inserted, maintaining an always up-to-date derived dataset. Unlike copy pipes which create point-in-time snapshots, materialized views provide real-time transformations of your data.
143
+ Each approach has its own strengths and use cases:
144
+ - Use copy pipes when you need scheduled or on-demand snapshots of your data.
145
+ - Use materialized views when you need continuous, real-time transformations.
146
+ Finally, update the existing endpoint itself, do not add a new one.
147
+
129
148
  IMPORTANT: If the user cancels some of the steps or there is an error in file creation, DO NOT continue with the plan. Stop the process and wait for the user before using any other tool.
130
149
  IMPORTANT: Every time you finish a plan and start a new resource creation or update process, create a new plan before starting with the changes.
131
150
 
@@ -175,6 +194,15 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
175
194
  Tool(mock, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
176
195
  Tool(read_fixture_data, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
177
196
  Tool(append, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
197
+ Tool(
198
+ get_endpoint_stats, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True
199
+ ),
200
+ Tool(
201
+ get_openapi_definition,
202
+ docstring_format="google",
203
+ require_parameter_descriptions=True,
204
+ takes_ctx=True,
205
+ ),
178
206
  ],
179
207
  )
180
208
 
@@ -186,7 +214,7 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
186
214
  user_prompt = f"{user_prompt}\n\n{resources_prompt(project)}"
187
215
  client = TinyB(token=self.token, host=self.host)
188
216
  folder = self.project.folder
189
-
217
+ click.echo()
190
218
  thinking_animation = ThinkingAnimation(message="Chirping", delay=0.15)
191
219
  thinking_animation.start()
192
220
  result = self.agent.run_sync(
@@ -200,11 +228,16 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
200
228
  mock_data=partial(mock_data, project=project, config=config),
201
229
  append_data=partial(append_data, config=config),
202
230
  analyze_fixture=partial(analyze_fixture, config=config),
231
+ execute_cloud_query=partial(execute_cloud_query, config=config),
232
+ execute_local_query=partial(execute_local_query, config=config),
203
233
  get_project_files=project.get_project_files,
204
234
  folder=folder,
205
235
  thinking_animation=thinking_animation,
206
236
  workspace_name=self.project.workspace_name,
207
237
  dangerously_skip_permissions=self.dangerously_skip_permissions,
238
+ token=self.token,
239
+ user_token=self.user_token,
240
+ host=self.host,
208
241
  ),
209
242
  message_history=self.messages,
210
243
  )
@@ -219,13 +252,15 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
219
252
  request_tokens * model_costs["input_cost_per_token"]
220
253
  + response_tokens * model_costs["output_cost_per_token"]
221
254
  )
222
- click.echo()
223
255
  click.echo(result.output)
224
256
  click.echo("\n")
225
- click.echo(f"Input tokens: {request_tokens}")
226
- click.echo(f"Output tokens: {response_tokens}")
227
- click.echo(f"Total tokens: {total_tokens}")
228
- click.echo(f"Cost: ${cost:.6f}")
257
+
258
+ if "@tinybird.co" in config.get("user_email", ""):
259
+ click.echo(f"Input tokens: {request_tokens}")
260
+ click.echo(f"Output tokens: {response_tokens}")
261
+ click.echo(f"Total tokens: {total_tokens}")
262
+ click.echo(f"Cost: ${cost:.6f}")
263
+ click.echo("\n")
229
264
 
230
265
 
231
266
  def run_agent(config: dict[str, Any], project: Project, dangerously_skip_permissions: bool):
@@ -233,6 +268,7 @@ def run_agent(config: dict[str, Any], project: Project, dangerously_skip_permiss
233
268
  host = config.get("host", None)
234
269
  user_token = config.get("user_token", None)
235
270
  workspace_id = config.get("id", None)
271
+ workspace_name = config.get("name", None)
236
272
  try:
237
273
  if not token or not host or not workspace_id or not user_token:
238
274
  yes = click.confirm(
@@ -274,20 +310,11 @@ def run_agent(config: dict[str, Any], project: Project, dangerously_skip_permiss
274
310
  try:
275
311
  while True:
276
312
  try:
277
- user_input = prompt(
278
- [("class:prompt", f"tb ({project.workspace_name}) » ")],
279
- history=load_history(),
280
- cursor=CursorShape.BLOCK,
281
- style=Style.from_dict(
282
- {
283
- "prompt": "#40a8a8 bold",
284
- "": "", # Normal color for user input
285
- }
286
- ),
287
- )
313
+ user_input = show_input(workspace_name)
288
314
  if user_input.startswith("tb "):
289
315
  cmd_parts = shlex.split(user_input)
290
- subprocess.run(cmd_parts, check=True)
316
+ subprocess.run(cmd_parts)
317
+ click.echo()
291
318
  continue
292
319
  if user_input.lower() in ["/exit", "/quit"]:
293
320
  click.echo(FeedbackManager.info(message="Goodbye!"))
@@ -364,7 +391,12 @@ def append_data(config: dict[str, Any], datasource_name: str, path: str) -> None
364
391
 
365
392
 
366
393
  def mock_data(
367
- config: dict[str, Any], project: Project, datasource_name: str, data_format: str, rows: int
394
+ config: dict[str, Any],
395
+ project: Project,
396
+ datasource_name: str,
397
+ data_format: str,
398
+ rows: int,
399
+ context: Optional[str] = None,
368
400
  ) -> list[dict[str, Any]]:
369
401
  client = get_tinybird_local_client(config, test=False, silent=False)
370
402
  cli_config = CLIConfig.get_project_config()
@@ -374,12 +406,11 @@ def mock_data(
374
406
  raise CLIMockException(f"Datasource {datasource_name} not found")
375
407
 
376
408
  datasource_content = Path(datasource_path).read_text()
377
- prompt = ""
378
409
  return create_mock_data(
379
410
  datasource_name,
380
411
  datasource_content,
381
412
  rows,
382
- prompt,
413
+ context or "",
383
414
  cli_config,
384
415
  config,
385
416
  cli_config.get_user_token() or "",
@@ -393,3 +424,13 @@ def analyze_fixture(config: dict[str, Any], fixture_path: str) -> dict[str, Any]
393
424
  local_client = get_tinybird_local_client(config, test=False, silent=True)
394
425
  meta, _data = _analyze(fixture_path, local_client, Path(fixture_path).suffix.lstrip("."))
395
426
  return meta
427
+
428
+
429
+ def execute_cloud_query(config: dict[str, Any], query: str, pipe_name: Optional[str] = None) -> str:
430
+ client = _get_tb_client(config["token"], config["host"])
431
+ return client.query(sql=query, pipeline=pipe_name)
432
+
433
+
434
+ def execute_local_query(config: dict[str, Any], query: str, pipe_name: Optional[str] = None) -> str:
435
+ local_client = get_tinybird_local_client(config, test=False, silent=True)
436
+ return local_client.query(sql=query, pipeline=pipe_name)
@@ -4,15 +4,13 @@ import threading
4
4
  from time import sleep
5
5
  from typing import Optional
6
6
 
7
- import click
8
-
9
7
 
10
8
  class ThinkingAnimation:
11
9
  """Thinking animation that shows changing sparkles as a prefix."""
12
10
 
13
11
  def __init__(
14
12
  self,
15
- message: str = "Thinking",
13
+ message: str = "Chirping",
16
14
  delay: float = 0.15,
17
15
  colors: bool = True,
18
16
  dots: bool = True,
@@ -37,17 +35,35 @@ class ThinkingAnimation:
37
35
  ]
38
36
  self.reset_color = "\033[0m"
39
37
 
40
- def start(self):
38
+ def start(self, message: Optional[str] = None):
41
39
  """Start the animation in a separate thread."""
40
+ # Stop any existing animation first
41
+ if self.running:
42
+ self._stop_without_reset()
43
+
44
+ if message:
45
+ self.message = message
42
46
  self.running = True
43
47
  self.thread = threading.Thread(target=self._run_animation)
44
48
  self.thread.daemon = True
45
49
 
46
- click.echo("\n")
50
+ # Clear the current line before starting new animation
51
+ sys.stdout.write("\r" + " " * (len(self.message) + 10) + "\r")
52
+ sys.stdout.flush()
47
53
  self.thread.start()
48
54
 
49
55
  def stop(self):
50
56
  """Stop the animation."""
57
+ self.message = "Chirping"
58
+ self.running = False
59
+ if self.thread:
60
+ self.thread.join()
61
+ # Clear the line and reset cursor position
62
+ sys.stdout.write("\r" + " " * (len(self.message) + 10) + "\r")
63
+ sys.stdout.flush()
64
+
65
+ def _stop_without_reset(self):
66
+ """Stop the animation without resetting the message."""
51
67
  self.running = False
52
68
  if self.thread:
53
69
  self.thread.join()
@@ -78,8 +94,11 @@ class ThinkingAnimation:
78
94
  else:
79
95
  display_message = self.message
80
96
 
81
- # Print the message with the prefix sparkle
82
- sys.stdout.write(f"\r{colored_sparkle} {display_message}")
97
+ # Print the message with the prefix sparkle, padding to clear any leftover characters
98
+ line_content = f"{colored_sparkle} {display_message}"
99
+ # Pad with spaces to clear any leftover characters from longer previous messages
100
+ padded_line = line_content.ljust(len(self.message) + 10)
101
+ sys.stdout.write(f"\r{padded_line}")
83
102
  sys.stdout.flush()
84
103
 
85
104
  sleep(self.delay)
@@ -22,8 +22,10 @@ Steps:
22
22
  <dev_notes>
23
23
  You can skip steps where resources will not be created or updated.
24
24
  Always add 'Build project' step after generating resources.
25
- Always add 'Generate mock data' step after building project if a landing datasource was created.
26
- Always add 'Append existing fixture' step after building project if a fixture file was provided at the beginning of the plan.
25
+ Always add 'Generate mock data' step after building project if a landing datasource was created without providing a fixture file.
26
+ Always add 'Append existing fixture' step after building project if a landing datasource was created after providing a fixture file.
27
+ Solve the specific user request, do not add extra steps that are not related to the user request.
28
+ Reuse the existing resources if possible.
27
29
  </dev_notes>
28
30
 
29
31
  Resource dependencies:
@@ -1,29 +1,10 @@
1
1
  import click
2
2
  from pydantic_ai import RunContext
3
3
 
4
- from tinybird.tb.modules.agent.utils import TinybirdAgentContext, show_options
4
+ from tinybird.tb.modules.agent.utils import TinybirdAgentContext, show_confirmation, show_input
5
5
  from tinybird.tb.modules.feedback_manager import FeedbackManager
6
6
 
7
7
 
8
- def get_append_confirmation(datasource_name: str) -> bool:
9
- """Get user confirmation for appending existing fixture"""
10
- while True:
11
- result = show_options(
12
- options=["Yes, append existing fixture", "No, and tell Tinybird Code what to do"],
13
- title=f"Do you want to append existing fixture for datasource {datasource_name}?",
14
- )
15
-
16
- if result is None: # Cancelled
17
- return False
18
-
19
- if result.startswith("Yes"):
20
- return True
21
- elif result.startswith("No"):
22
- return False
23
-
24
- return False
25
-
26
-
27
8
  def append(ctx: RunContext[TinybirdAgentContext], datasource_name: str, fixture_pathname: str) -> str:
28
9
  """Append existing fixture to a datasource
29
10
 
@@ -36,10 +17,20 @@ def append(ctx: RunContext[TinybirdAgentContext], datasource_name: str, fixture_
36
17
  """
37
18
  try:
38
19
  ctx.deps.thinking_animation.stop()
39
- confirmation = ctx.deps.dangerously_skip_permissions or get_append_confirmation(datasource_name)
20
+ confirmation = show_confirmation(
21
+ title=f"Append existing fixture for datasource {datasource_name}?",
22
+ skip_confirmation=ctx.deps.dangerously_skip_permissions,
23
+ )
24
+
40
25
  ctx.deps.thinking_animation.start()
41
26
 
42
- if not confirmation:
27
+ if confirmation == "review":
28
+ click.echo()
29
+ feedback = show_input(ctx.deps.workspace_name)
30
+ ctx.deps.thinking_animation.start()
31
+ return f"User did not confirm the proposed plan and gave the following feedback: {feedback}"
32
+
33
+ if confirmation == "cancel":
43
34
  return "User rejected appending existing fixture. Skipping..."
44
35
 
45
36
  ctx.deps.thinking_animation.stop()
@@ -3,31 +3,17 @@ from pathlib import Path
3
3
  import click
4
4
  from pydantic_ai import RunContext
5
5
 
6
- from tinybird.tb.modules.agent.utils import Datafile, TinybirdAgentContext, create_terminal_box, show_options
6
+ from tinybird.tb.modules.agent.utils import (
7
+ Datafile,
8
+ TinybirdAgentContext,
9
+ create_terminal_box,
10
+ show_confirmation,
11
+ show_input,
12
+ )
7
13
  from tinybird.tb.modules.exceptions import CLIBuildException
8
14
  from tinybird.tb.modules.feedback_manager import FeedbackManager
9
15
 
10
16
 
11
- def get_resource_confirmation(resource: Datafile, exists: bool) -> bool:
12
- """Get user confirmation for creating a resource"""
13
- while True:
14
- action = "create" if not exists else "update"
15
- result = show_options(
16
- options=[f"Yes, {action} {resource.type} '{resource.name}'", "No, and tell Tinybird Code what to do"],
17
- title=f"What would you like to do with {resource.type} '{resource.name}'?",
18
- )
19
-
20
- if result is None: # Cancelled
21
- return False
22
-
23
- if result.startswith("Yes"):
24
- return True
25
- elif result.startswith("No"):
26
- return False
27
-
28
- return False
29
-
30
-
31
17
  def create_datafile(ctx: RunContext[TinybirdAgentContext], resource: Datafile) -> str:
32
18
  """Given a resource representation, create a file in the project folder
33
19
 
@@ -48,19 +34,34 @@ def create_datafile(ctx: RunContext[TinybirdAgentContext], resource: Datafile) -
48
34
  else:
49
35
  content = create_terminal_box(resource.content, title=resource.pathname)
50
36
  click.echo(content)
51
- confirmation = ctx.deps.dangerously_skip_permissions or get_resource_confirmation(resource, exists)
52
37
 
53
- if not confirmation:
38
+ action = "Create" if not exists else "Update"
39
+ confirmation = show_confirmation(
40
+ title=f"{action} '{resource.pathname}'?",
41
+ skip_confirmation=ctx.deps.dangerously_skip_permissions,
42
+ )
43
+
44
+ if confirmation == "review":
45
+ click.echo()
46
+ feedback = show_input(ctx.deps.workspace_name)
47
+ ctx.deps.thinking_animation.start()
48
+ return f"User did not confirm the proposed changes and gave the following feedback: {feedback}"
49
+
50
+ if confirmation == "cancel":
54
51
  ctx.deps.thinking_animation.start()
55
- return f"Resource {resource.pathname} was not created. User cancelled creation."
52
+ return f"User cancelled {action} of {resource.pathname}. Stop resource creation."
56
53
 
54
+ action_text = "Creating" if not exists else "Updating"
55
+ click.echo(FeedbackManager.highlight(message=f"\n» {action_text} {resource.pathname}..."))
57
56
  folder_path = path.parent
58
57
  folder_path.mkdir(parents=True, exist_ok=True)
59
58
  path.touch(exist_ok=True)
60
59
  path.write_text(resource.content)
61
60
  ctx.deps.build_project(test=True, silent=True)
61
+ action_text = "created" if not exists else "updated"
62
+ click.echo(FeedbackManager.success(message=f"✓ {resource.pathname} {action_text} successfully"))
62
63
  ctx.deps.thinking_animation.start()
63
- return f"Created {resource.pathname}"
64
+ return f"{action_text} {resource.pathname}"
64
65
 
65
66
  except CLIBuildException as e:
66
67
  ctx.deps.thinking_animation.stop()
@@ -68,4 +69,7 @@ def create_datafile(ctx: RunContext[TinybirdAgentContext], resource: Datafile) -
68
69
  ctx.deps.thinking_animation.start()
69
70
  return f"Error building project: {e}"
70
71
  except Exception as e:
72
+ ctx.deps.thinking_animation.stop()
73
+ click.echo(FeedbackManager.error(message=e))
74
+ ctx.deps.thinking_animation.start()
71
75
  return f"Error creating {resource.pathname}: {e}"
@@ -0,0 +1,36 @@
1
+ import click
2
+ from pydantic_ai import RunContext
3
+
4
+ from tinybird.tb.modules.agent.utils import TinybirdAgentContext, show_confirmation, show_input
5
+ from tinybird.tb.modules.feedback_manager import FeedbackManager
6
+
7
+
8
+ def deploy(ctx: RunContext[TinybirdAgentContext]) -> str:
9
+ """Deploy the project"""
10
+ try:
11
+ ctx.deps.thinking_animation.stop()
12
+ confirmation = show_confirmation(
13
+ title="Deploy the project?",
14
+ skip_confirmation=ctx.deps.dangerously_skip_permissions,
15
+ )
16
+
17
+ if confirmation == "review":
18
+ click.echo()
19
+ feedback = show_input(ctx.deps.workspace_name)
20
+ ctx.deps.thinking_animation.start()
21
+ return f"User did not confirm deployment and gave the following feedback: {feedback}"
22
+
23
+ if confirmation == "cancel":
24
+ ctx.deps.thinking_animation.start()
25
+ return "User cancelled deployment. Stop deployment."
26
+
27
+ click.echo(FeedbackManager.highlight(message="\n» Deploying project..."))
28
+ ctx.deps.deploy_project()
29
+ click.echo(FeedbackManager.success(message="✓ Project deployed successfully"))
30
+ ctx.deps.thinking_animation.start()
31
+ return "Project deployed successfully"
32
+ except Exception as e:
33
+ ctx.deps.thinking_animation.stop()
34
+ click.echo(FeedbackManager.error(message=e))
35
+ ctx.deps.thinking_animation.start()
36
+ return f"Error depoying project: {e}"
@@ -0,0 +1,51 @@
1
+ import click
2
+ from pydantic_ai import RunContext
3
+
4
+ from tinybird.tb.modules.agent.utils import TinybirdAgentContext
5
+ from tinybird.tb.modules.feedback_manager import FeedbackManager
6
+
7
+
8
+ def get_endpoint_stats(
9
+ ctx: RunContext[TinybirdAgentContext], endpoint_name: str, interval_days: int = 1, cloud: bool = True
10
+ ):
11
+ """Get stats for an endpoint:
12
+
13
+ Args:
14
+ endpoint_name (str): The name of the endpoint to get stats for. Required.
15
+ interval_days (int): The number of days to get stats for. Optional.
16
+ cloud (bool): Whether to get stats from cloud or local. Optional.
17
+
18
+ Returns:
19
+ str: The result of the stats.
20
+ """
21
+ if interval_days == 1:
22
+ pipe_stats = "tinybird.pipe_stats_rt"
23
+ date_column = "start_datetime"
24
+ else:
25
+ pipe_stats = "tinybird.pipe_stats"
26
+ date_column = "date"
27
+
28
+ days = "day" if interval_days == 1 else "days"
29
+ cloud_or_local = "cloud" if cloud else "local"
30
+ ctx.deps.thinking_animation.stop()
31
+
32
+ click.echo(
33
+ FeedbackManager.highlight(
34
+ message=f"» Analyzing {cloud_or_local} requests in the last {interval_days} {days} for '{endpoint_name}' endpoint"
35
+ )
36
+ )
37
+
38
+ query = f"""SELECT * FROM {pipe_stats}
39
+ WHERE {date_column} > NOW() - INTERVAL {interval_days} DAY
40
+ AND pipe_name = '{endpoint_name}'
41
+ LIMIT 100
42
+ FORMAT JSON
43
+ """
44
+
45
+ execute_query = ctx.deps.execute_cloud_query if cloud else ctx.deps.execute_local_query
46
+
47
+ result = execute_query(query=query)
48
+ click.echo(FeedbackManager.success(message="✓ Done!"))
49
+ click.echo()
50
+ ctx.deps.thinking_animation.start()
51
+ return f"Result for {endpoint_name} in the last {interval_days} {days}: {result}"
@@ -0,0 +1,39 @@
1
+ import click
2
+ import requests
3
+ from pydantic_ai import RunContext
4
+
5
+ from tinybird.tb.modules.agent.utils import TinybirdAgentContext
6
+ from tinybird.tb.modules.feedback_manager import FeedbackManager
7
+
8
+
9
+ def get_openapi_definition(ctx: RunContext[TinybirdAgentContext], cloud: bool = True):
10
+ """Get the OpenAPI definition for all endpoints in the project:
11
+
12
+ Args:
13
+ cloud (bool): Whether to get the OpenAPI spec from cloud or local. Optional.
14
+
15
+ Returns:
16
+ str: The OpenAPI spec for all endpoints in the project.
17
+ """
18
+
19
+ cloud_or_local = "Cloud" if cloud else "Local"
20
+ ctx.deps.thinking_animation.stop()
21
+
22
+ click.echo(FeedbackManager.highlight(message=f"» Accessing Tinybird {cloud_or_local} endpoints"))
23
+ try:
24
+ url = f"{ctx.deps.host}/v0/pipes/openapi.json"
25
+
26
+ result = requests.get(url, headers={"Authorization": f"Bearer {ctx.deps.token}"})
27
+ if result.status_code != 200:
28
+ raise Exception(f"Failed to get OpenAPI spec: {result.status_code} {result.text}")
29
+
30
+ openapi_spec = result.text
31
+
32
+ click.echo(FeedbackManager.success(message="✓ Done!"))
33
+ click.echo()
34
+ ctx.deps.thinking_animation.start()
35
+ return f"OpenAPI spec for {cloud_or_local} endpoints: {openapi_spec}. <dev_note>Add the base url to each path so the user can copy paste if needed: {ctx.deps.host}</dev_note>"
36
+ except Exception as e:
37
+ click.echo(FeedbackManager.error(message=f"Error getting OpenAPI spec: {e}"))
38
+ ctx.deps.thinking_animation.start()
39
+ return f"Error getting OpenAPI spec: {e}"