tinybird 0.0.1.dev92__tar.gz → 0.0.1.dev94__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 (107) hide show
  1. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/PKG-INFO +1 -1
  2. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/__cli__.py +2 -2
  3. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/cli.py +1 -0
  4. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/cli.py +2 -2
  5. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/common.py +24 -0
  6. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/deployment.py +9 -0
  7. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/local_common.py +7 -2
  8. tinybird-0.0.1.dev94/tinybird/tb/modules/open.py +42 -0
  9. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird.egg-info/PKG-INFO +1 -1
  10. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird.egg-info/SOURCES.txt +1 -0
  11. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/setup.cfg +0 -0
  12. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/__cli__.py +0 -0
  13. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/ch_utils/constants.py +0 -0
  14. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/ch_utils/engine.py +0 -0
  15. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/check_pypi.py +0 -0
  16. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/client.py +0 -0
  17. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/config.py +0 -0
  18. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/connectors.py +0 -0
  19. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/context.py +0 -0
  20. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/datafile.py +0 -0
  21. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/datatypes.py +0 -0
  22. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/feedback_manager.py +0 -0
  23. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/git_settings.py +0 -0
  24. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/prompts.py +0 -0
  25. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/sql.py +0 -0
  26. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/sql_template.py +0 -0
  27. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/sql_template_fmt.py +0 -0
  28. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/sql_toolset.py +0 -0
  29. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/syncasync.py +0 -0
  30. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/auth.py +0 -0
  31. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/build.py +0 -0
  32. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/cicd.py +0 -0
  33. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/config.py +0 -0
  34. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/connection.py +0 -0
  35. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/copy.py +0 -0
  36. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/create.py +0 -0
  37. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/build.py +0 -0
  38. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/build_common.py +0 -0
  39. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  40. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  41. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/common.py +0 -0
  42. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/diff.py +0 -0
  43. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/exceptions.py +0 -0
  44. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/fixture.py +0 -0
  45. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/format_common.py +0 -0
  46. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  47. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  48. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/parse_datasource.py +0 -0
  49. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/parse_pipe.py +0 -0
  50. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  51. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/playground.py +0 -0
  52. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datafile/pull.py +0 -0
  53. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/datasource.py +0 -0
  54. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/endpoint.py +0 -0
  55. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/exceptions.py +0 -0
  56. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/feedback_manager.py +0 -0
  57. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/fmt.py +0 -0
  58. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/job.py +0 -0
  59. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/llm.py +0 -0
  60. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/llm_utils.py +0 -0
  61. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/local.py +0 -0
  62. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/login.py +0 -0
  63. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/logout.py +0 -0
  64. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/materialization.py +0 -0
  65. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/mock.py +0 -0
  66. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/pipe.py +0 -0
  67. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/playground.py +0 -0
  68. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/project.py +0 -0
  69. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/regions.py +0 -0
  70. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/secret.py +0 -0
  71. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/shell.py +0 -0
  72. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/table.py +0 -0
  73. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/tag.py +0 -0
  74. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/telemetry.py +0 -0
  75. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/test.py +0 -0
  76. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  77. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  78. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/token.py +0 -0
  79. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/watch.py +0 -0
  80. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/workspace.py +0 -0
  81. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb/modules/workspace_members.py +0 -0
  82. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli.py +0 -0
  83. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/auth.py +0 -0
  84. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/branch.py +0 -0
  85. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/cicd.py +0 -0
  86. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/cli.py +0 -0
  87. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/common.py +0 -0
  88. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/config.py +0 -0
  89. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/connection.py +0 -0
  90. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/datasource.py +0 -0
  91. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/exceptions.py +0 -0
  92. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/fmt.py +0 -0
  93. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/job.py +0 -0
  94. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/pipe.py +0 -0
  95. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/regions.py +0 -0
  96. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/tag.py +0 -0
  97. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/telemetry.py +0 -0
  98. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/test.py +0 -0
  99. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  100. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  101. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/workspace.py +0 -0
  102. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  103. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird/tornado_template.py +0 -0
  104. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird.egg-info/dependency_links.txt +0 -0
  105. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird.egg-info/entry_points.txt +0 -0
  106. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/tinybird.egg-info/requires.txt +0 -0
  107. {tinybird-0.0.1.dev92 → tinybird-0.0.1.dev94}/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.dev92
3
+ Version: 0.0.1.dev94
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/cli/introduction.html'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '0.0.1.dev92'
8
- __revision__ = 'd99cccc'
7
+ __version__ = '0.0.1.dev94'
8
+ __revision__ = '97387e2'
@@ -21,6 +21,7 @@ import tinybird.tb.modules.login
21
21
  import tinybird.tb.modules.logout
22
22
  import tinybird.tb.modules.materialization
23
23
  import tinybird.tb.modules.mock
24
+ import tinybird.tb.modules.open
24
25
  import tinybird.tb.modules.pipe
25
26
  import tinybird.tb.modules.playground
26
27
  import tinybird.tb.modules.secret
@@ -110,7 +110,7 @@ async def cli(
110
110
  folder = os.path.join(config_temp._path.replace(".tinyb", ""), config.get("cwd", os.getcwd()))
111
111
  project = Project(folder=folder)
112
112
  config["path"] = str(project.path)
113
- # If they have passed a token or host as paramter and it's different that record in .tinyb, refresh the workspace id
113
+ # If they have passed a token or host as parameter and it's different that record in .tinyb, refresh the workspace id
114
114
  if token or host:
115
115
  try:
116
116
  workspace = await client.workspace_info()
@@ -393,7 +393,7 @@ def __unpatch_click_output():
393
393
 
394
394
 
395
395
  async def create_ctx_client(ctx: Context, config: Dict[str, Any], cloud: bool, build: bool, staging: bool):
396
- commands_without_ctx_client = ["auth", "check", "login", "local", "update", "upgrade", "logout"]
396
+ commands_without_ctx_client = ["auth", "check", "local", "login", "logout", "update", "upgrade"]
397
397
  command = ctx.invoked_subcommand
398
398
  if command in commands_without_ctx_client:
399
399
  return None
@@ -2138,3 +2138,27 @@ async def get_user_token(config: CLIConfig, user_token: Optional[str] = None) ->
2138
2138
  await check_user_token_with_client(client, user_token)
2139
2139
 
2140
2140
  return user_token
2141
+
2142
+
2143
+ def get_ui_url(api_host: str) -> str:
2144
+ """Transforms API URLs into their corresponding UI URLs.
2145
+ Examples:
2146
+ >>> get_ui_url("http://localhost:8000")
2147
+ 'https://cloud.tinybird.co/local/8000'
2148
+ >>> get_ui_url("https://api.europe-west2.gcp.tinybird.co")
2149
+ 'https://cloud.tinybird.co/gcp/europe-west2'
2150
+ >>> get_ui_url("https://other-domain.com")
2151
+ 'https://other-domain.com'
2152
+ """
2153
+ if "//localhost" in api_host:
2154
+ port = api_host.split(":")[-1] or "80"
2155
+ return f"https://cloud.tinybird.co/local/{port}"
2156
+
2157
+ if api_host.endswith("tinybird.co") and "api." in api_host:
2158
+ parts = api_host.split(".")
2159
+ if len(parts) >= 4:
2160
+ region = parts[1] or "europe-west2"
2161
+ cloud = parts[2] or "gcp"
2162
+ return f"https://cloud.tinybird.co/{cloud}/{region}"
2163
+
2164
+ return api_host
@@ -460,18 +460,27 @@ def print_changes(result: dict, project: Project) -> None:
460
460
  for p in deployment.get("new_pipe_names", []):
461
461
  resources.append(["new", p, project.get_resource_path(p, "pipe")])
462
462
 
463
+ for dc in deployment.get("new_data_connector_names", []):
464
+ resources.append(["new", dc, project.get_resource_path(dc, "data_connector")])
465
+
463
466
  for ds in deployment.get("changed_datasource_names", []):
464
467
  resources.append(["modified", ds, project.get_resource_path(ds, "datasource")])
465
468
 
466
469
  for p in deployment.get("changed_pipe_names", []):
467
470
  resources.append(["modified", p, project.get_resource_path(p, "pipe")])
468
471
 
472
+ for dc in deployment.get("changed_data_connector_names", []):
473
+ resources.append(["modified", dc, project.get_resource_path(dc, "data_connector")])
474
+
469
475
  for ds in deployment.get("deleted_datasource_names", []):
470
476
  resources.append(["deleted", ds, project.get_resource_path(ds, "datasource")])
471
477
 
472
478
  for p in deployment.get("deleted_pipe_names", []):
473
479
  resources.append(["deleted", p, project.get_resource_path(p, "pipe")])
474
480
 
481
+ for dc in deployment.get("deleted_data_connector_names", []):
482
+ resources.append(["deleted", dc, project.get_resource_path(dc, "data_connector")])
483
+
475
484
  if resources:
476
485
  click.echo(FeedbackManager.highlight(message="\n» Changes to be deployed...\n"))
477
486
  echo_safe_humanfriendly_tables_format_smart_table(resources, column_names=columns)
@@ -17,6 +17,7 @@ TB_LOCAL_HOST = f"http://localhost:{TB_LOCAL_PORT}"
17
17
 
18
18
  async def get_tinybird_local_client(config_obj: Dict[str, Any], build: bool = False, staging: bool = False) -> TinyB:
19
19
  """Get a Tinybird client connected to the local environment."""
20
+
20
21
  config = await get_tinybird_local_config(config_obj, build=build)
21
22
  return config.get_client(host=TB_LOCAL_HOST, staging=staging)
22
23
 
@@ -40,9 +41,8 @@ async def get_tinybird_local_config(config_obj: Dict[str, Any], build: bool = Fa
40
41
  default_token = tokens["workspace_admin_token"]
41
42
  # Create a new workspace if path is provided. This is used to isolate the build in a different workspace.
42
43
  if path:
43
- folder_hash = hashlib.sha256(path.encode()).hexdigest()
44
44
  user_client = config.get_client(host=TB_LOCAL_HOST, token=user_token)
45
- ws_name = f"Tinybird_Local_Build_{folder_hash}" if build else config.get("name") or config_obj.get("name")
45
+ ws_name = get_build_workspace_name(path) if build else config.get("name") or config_obj.get("name")
46
46
  if not ws_name:
47
47
  raise AuthNoTokenException()
48
48
 
@@ -74,3 +74,8 @@ async def get_tinybird_local_config(config_obj: Dict[str, Any], build: bool = Fa
74
74
 
75
75
  config.set_user_token(user_token)
76
76
  return config
77
+
78
+
79
+ def get_build_workspace_name(path: str) -> str:
80
+ folder_hash = hashlib.sha256(path.encode()).hexdigest()
81
+ return f"Tinybird_Local_Build_{folder_hash}"
@@ -0,0 +1,42 @@
1
+ import webbrowser
2
+
3
+ import click
4
+ from click import Context
5
+
6
+ from tinybird.tb.modules.cli import cli
7
+ from tinybird.tb.modules.common import coro, get_ui_url
8
+ from tinybird.tb.modules.exceptions import CLIException
9
+ from tinybird.tb.modules.feedback_manager import FeedbackManager
10
+ from tinybird.tb.modules.local_common import get_build_workspace_name
11
+
12
+
13
+ @cli.command()
14
+ @click.option(
15
+ "--workspace",
16
+ help="Set the workspace you want to open. If unset, your current workspace will be used.",
17
+ )
18
+ @click.pass_context
19
+ @coro
20
+ async def open(ctx: Context, workspace: str):
21
+ """Open workspace in the browser."""
22
+
23
+ config = ctx.ensure_object(dict)["config"]
24
+ client = ctx.ensure_object(dict)["client"]
25
+ env = ctx.ensure_object(dict)["env"]
26
+
27
+ url_host = get_ui_url(client.host)
28
+
29
+ if not workspace:
30
+ workspace = get_build_workspace_name(config.get("path")) if env == "build" else config.get("name")
31
+
32
+ if not workspace:
33
+ raise CLIException(
34
+ FeedbackManager.error(
35
+ message="No workspace found. Run 'tb login' first or pass a workspace using the --workspace parameter"
36
+ )
37
+ )
38
+
39
+ click.echo(FeedbackManager.highlight(message=f"» Opening workspace {workspace} in the browser"))
40
+
41
+ auth_url = f"{url_host}/{workspace}"
42
+ webbrowser.open(auth_url)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev92
3
+ Version: 0.0.1.dev94
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -50,6 +50,7 @@ tinybird/tb/modules/login.py
50
50
  tinybird/tb/modules/logout.py
51
51
  tinybird/tb/modules/materialization.py
52
52
  tinybird/tb/modules/mock.py
53
+ tinybird/tb/modules/open.py
53
54
  tinybird/tb/modules/pipe.py
54
55
  tinybird/tb/modules/playground.py
55
56
  tinybird/tb/modules/project.py
File without changes