snowflake-cli-labs 3.0.0rc2__py3-none-any.whl → 3.0.0rc4__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.
- snowflake/cli/__about__.py +1 -1
- snowflake/cli/_app/commands_registration/builtin_plugins.py +2 -0
- snowflake/cli/_app/secret.py +9 -0
- snowflake/cli/_app/snow_connector.py +39 -27
- snowflake/cli/_app/telemetry.py +28 -0
- snowflake/cli/_plugins/connection/commands.py +9 -4
- snowflake/cli/_plugins/git/manager.py +53 -7
- snowflake/cli/_plugins/helpers/commands.py +61 -0
- snowflake/cli/{api/project/schemas/snowpark/__init__.py → _plugins/helpers/plugin_spec.py} +17 -0
- snowflake/cli/_plugins/nativeapp/artifacts.py +10 -9
- snowflake/cli/_plugins/nativeapp/bundle_context.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/compiler.py +6 -1
- snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/extension_function_utils.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/models.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +5 -1
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +4 -1
- snowflake/cli/_plugins/nativeapp/commands.py +87 -96
- snowflake/cli/_plugins/nativeapp/entities/__init__.py +0 -0
- snowflake/cli/{api/entities/application_entity.py → _plugins/nativeapp/entities/application.py} +264 -83
- snowflake/cli/_plugins/nativeapp/entities/application_package.py +1392 -0
- snowflake/cli/_plugins/nativeapp/exceptions.py +0 -9
- snowflake/cli/_plugins/nativeapp/manager.py +69 -185
- snowflake/cli/_plugins/nativeapp/policy.py +3 -0
- snowflake/cli/_plugins/nativeapp/project_model.py +2 -2
- snowflake/cli/_plugins/nativeapp/run_processor.py +17 -20
- snowflake/cli/_plugins/nativeapp/same_account_install_method.py +0 -4
- snowflake/cli/_plugins/nativeapp/teardown_processor.py +4 -6
- snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +122 -88
- snowflake/cli/_plugins/nativeapp/version/commands.py +7 -39
- snowflake/cli/_plugins/nativeapp/version/version_processor.py +46 -312
- snowflake/cli/_plugins/object/manager.py +36 -15
- snowflake/cli/_plugins/snowpark/commands.py +4 -4
- snowflake/cli/_plugins/snowpark/common.py +4 -4
- snowflake/cli/{api/entities → _plugins/snowpark}/snowpark_entity.py +2 -2
- snowflake/cli/{api/project/schemas/entities/snowpark_entity.py → _plugins/snowpark/snowpark_entity_model.py} +3 -6
- snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +1 -1
- snowflake/cli/_plugins/stage/manager.py +9 -4
- snowflake/cli/_plugins/streamlit/commands.py +15 -3
- snowflake/cli/_plugins/streamlit/manager.py +12 -4
- snowflake/cli/{api/entities → _plugins/streamlit}/streamlit_entity.py +2 -2
- snowflake/cli/{api/project/schemas/entities → _plugins/streamlit}/streamlit_entity_model.py +5 -12
- snowflake/cli/_plugins/workspace/commands.py +116 -36
- snowflake/cli/_plugins/workspace/plugin_spec.py +1 -1
- snowflake/cli/api/cli_global_context.py +7 -0
- snowflake/cli/api/commands/decorators.py +14 -0
- snowflake/cli/api/commands/flags.py +18 -0
- snowflake/cli/api/commands/snow_typer.py +1 -1
- snowflake/cli/api/config.py +25 -6
- snowflake/cli/api/connections.py +3 -1
- snowflake/cli/api/entities/common.py +4 -0
- snowflake/cli/api/entities/utils.py +3 -14
- snowflake/cli/api/errno.py +1 -0
- snowflake/cli/api/identifiers.py +4 -3
- snowflake/cli/api/metrics.py +92 -0
- snowflake/cli/api/project/definition_conversion.py +61 -18
- snowflake/cli/api/project/schemas/entities/common.py +17 -4
- snowflake/cli/api/project/schemas/entities/entities.py +11 -10
- snowflake/cli/api/project/schemas/project_definition.py +5 -7
- snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{identifier_model.py → v1/identifier_model.py} +0 -7
- snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/native_app.py +4 -4
- snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/callable.py +2 -2
- snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/snowpark.py +2 -2
- snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{streamlit → v1/streamlit}/streamlit.py +2 -1
- snowflake/cli/api/rendering/sql_templates.py +6 -0
- snowflake/cli/api/rest_api.py +11 -5
- snowflake/cli/api/sql_execution.py +6 -15
- snowflake/cli/api/utils/definition_rendering.py +24 -4
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/METADATA +9 -7
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/RECORD +83 -79
- snowflake/cli/_plugins/nativeapp/init.py +0 -345
- snowflake/cli/api/entities/application_package_entity.py +0 -658
- snowflake/cli/api/project/schemas/entities/application_entity_model.py +0 -56
- snowflake/cli/api/project/schemas/entities/application_package_entity_model.py +0 -94
- snowflake/cli/api/project/schemas/streamlit/__init__.py +0 -13
- /snowflake/cli/{api/project/schemas/native_app → _plugins/helpers}/__init__.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/application.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/package.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/path_mapping.py +0 -0
- /snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/argument.py +0 -0
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/entry_points.txt +0 -0
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/licenses/LICENSE +0 -0
|
@@ -22,14 +22,15 @@ from textwrap import dedent
|
|
|
22
22
|
from typing import Generator, Iterable, List, Optional, cast
|
|
23
23
|
|
|
24
24
|
import typer
|
|
25
|
+
from click.exceptions import ClickException
|
|
25
26
|
from snowflake.cli._plugins.nativeapp.common_flags import (
|
|
26
27
|
ForceOption,
|
|
27
28
|
InteractiveOption,
|
|
28
29
|
ValidateOption,
|
|
29
30
|
)
|
|
30
|
-
from snowflake.cli._plugins.nativeapp.
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
from snowflake.cli._plugins.nativeapp.entities.application import ApplicationEntityModel
|
|
32
|
+
from snowflake.cli._plugins.nativeapp.entities.application_package import (
|
|
33
|
+
ApplicationPackageEntityModel,
|
|
33
34
|
)
|
|
34
35
|
from snowflake.cli._plugins.nativeapp.manager import NativeAppManager
|
|
35
36
|
from snowflake.cli._plugins.nativeapp.policy import (
|
|
@@ -41,11 +42,8 @@ from snowflake.cli._plugins.nativeapp.run_processor import NativeAppRunProcessor
|
|
|
41
42
|
from snowflake.cli._plugins.nativeapp.teardown_processor import (
|
|
42
43
|
NativeAppTeardownProcessor,
|
|
43
44
|
)
|
|
44
|
-
from snowflake.cli._plugins.nativeapp.utils import (
|
|
45
|
-
get_first_paragraph_from_markdown_file,
|
|
46
|
-
shallow_git_clone,
|
|
47
|
-
)
|
|
48
45
|
from snowflake.cli._plugins.nativeapp.v2_conversions.v2_to_v1_decorator import (
|
|
46
|
+
find_entity,
|
|
49
47
|
nativeapp_definition_v2_to_v1,
|
|
50
48
|
)
|
|
51
49
|
from snowflake.cli._plugins.nativeapp.version.commands import app as versions_app
|
|
@@ -54,22 +52,23 @@ from snowflake.cli._plugins.stage.diff import (
|
|
|
54
52
|
compute_stage_diff,
|
|
55
53
|
)
|
|
56
54
|
from snowflake.cli._plugins.stage.utils import print_diff_to_console
|
|
55
|
+
from snowflake.cli._plugins.workspace.manager import WorkspaceManager
|
|
57
56
|
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
58
57
|
from snowflake.cli.api.commands.decorators import (
|
|
59
58
|
with_project_definition,
|
|
60
59
|
)
|
|
61
60
|
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
61
|
+
from snowflake.cli.api.entities.common import EntityActions
|
|
62
62
|
from snowflake.cli.api.exceptions import IncompatibleParametersError
|
|
63
63
|
from snowflake.cli.api.output.formats import OutputFormat
|
|
64
64
|
from snowflake.cli.api.output.types import (
|
|
65
|
-
CollectionResult,
|
|
66
65
|
CommandResult,
|
|
67
66
|
MessageResult,
|
|
68
67
|
ObjectResult,
|
|
69
68
|
StreamResult,
|
|
70
69
|
)
|
|
71
70
|
from snowflake.cli.api.project.project_verification import assert_project_type
|
|
72
|
-
from snowflake.cli.api.
|
|
71
|
+
from snowflake.cli.api.project.schemas.project_definition import ProjectDefinitionV1
|
|
73
72
|
from typing_extensions import Annotated
|
|
74
73
|
|
|
75
74
|
app = SnowTyperFactory(
|
|
@@ -81,86 +80,20 @@ app.add_typer(versions_app)
|
|
|
81
80
|
log = logging.getLogger(__name__)
|
|
82
81
|
|
|
83
82
|
|
|
84
|
-
@app.command("init")
|
|
85
|
-
def app_init(
|
|
86
|
-
path: str = typer.Argument(
|
|
87
|
-
...,
|
|
88
|
-
help=f"""Directory to be initialized with the Snowflake Native App project. This directory must not already exist.""",
|
|
89
|
-
show_default=False,
|
|
90
|
-
),
|
|
91
|
-
name: str = typer.Option(
|
|
92
|
-
None,
|
|
93
|
-
help=f"""The name of the Snowflake Native App project to include in snowflake.yml. When not specified, it is
|
|
94
|
-
generated from the name of the directory. Names are assumed to be unquoted identifiers whenever possible, but
|
|
95
|
-
can be forced to be quoted by including the surrounding quote characters in the provided value.""",
|
|
96
|
-
),
|
|
97
|
-
template_repo: str = typer.Option(
|
|
98
|
-
None,
|
|
99
|
-
help=f"""Specifies the git URL to a template repository, which can be a template itself or contain many templates inside it,
|
|
100
|
-
such as https://github.com/snowflakedb/native-apps-templates.git for all official Snowflake Native App with Snowflake CLI templates.
|
|
101
|
-
If using a private Github repo, you might be prompted to enter your Github username and password.
|
|
102
|
-
Please use your personal access token in the password prompt, and refer to
|
|
103
|
-
https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.""",
|
|
104
|
-
),
|
|
105
|
-
template: str = typer.Option(
|
|
106
|
-
None,
|
|
107
|
-
help="A specific template name within the template repo to use as template for the Snowflake Native App project. Example: Default is basic if `--template-repo` is https://github.com/snowflakedb/native-apps-templates.git, and None if any other --template-repo is specified.",
|
|
108
|
-
),
|
|
109
|
-
**options,
|
|
110
|
-
) -> CommandResult:
|
|
111
|
-
"""
|
|
112
|
-
Initializes a Snowflake Native App project.
|
|
83
|
+
@app.command("init", hidden=True)
|
|
84
|
+
def app_init(**options):
|
|
113
85
|
"""
|
|
114
|
-
|
|
115
|
-
path=path, name=name, git_url=template_repo, template=template
|
|
116
|
-
)
|
|
117
|
-
return MessageResult(
|
|
118
|
-
f"Snowflake Native App project {project.name} has been created at: {path}"
|
|
119
|
-
)
|
|
86
|
+
*** Deprecated. Use snow init instead ***
|
|
120
87
|
|
|
121
|
-
|
|
122
|
-
@app.command("list-templates", hidden=True)
|
|
123
|
-
def app_list_templates(**options) -> CommandResult:
|
|
124
|
-
"""
|
|
125
|
-
Prints information regarding the official templates that can be used with snow app init.
|
|
88
|
+
Initializes a Snowflake Native App project.
|
|
126
89
|
"""
|
|
127
|
-
with SecurePath.temporary_directory() as temp_path:
|
|
128
|
-
from git import rmtree as git_rmtree
|
|
129
|
-
|
|
130
|
-
repo = shallow_git_clone(OFFICIAL_TEMPLATES_GITHUB_URL, temp_path.path)
|
|
131
|
-
|
|
132
|
-
# Mark a directory as a template if a project definition jinja template is inside
|
|
133
|
-
template_directories = [
|
|
134
|
-
entry.name
|
|
135
|
-
for entry in repo.head.commit.tree
|
|
136
|
-
if (temp_path / entry.name / "snowflake.yml.jinja").exists()
|
|
137
|
-
]
|
|
138
|
-
|
|
139
|
-
# get the template descriptions from the README.md in its directory
|
|
140
|
-
template_descriptions = [
|
|
141
|
-
get_first_paragraph_from_markdown_file(
|
|
142
|
-
(temp_path / directory / "README.md").path
|
|
143
|
-
)
|
|
144
|
-
for directory in template_directories
|
|
145
|
-
]
|
|
146
|
-
|
|
147
|
-
result = (
|
|
148
|
-
{"template": directory, "description": description}
|
|
149
|
-
for directory, description in zip(
|
|
150
|
-
template_directories, template_descriptions
|
|
151
|
-
)
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
# proactively clean up here to avoid permission issues on Windows
|
|
155
|
-
repo.close()
|
|
156
|
-
git_rmtree(temp_path.path)
|
|
157
90
|
|
|
158
|
-
|
|
91
|
+
raise ClickException("This command has been removed. Use `snow init` instead.")
|
|
159
92
|
|
|
160
93
|
|
|
161
94
|
@app.command("bundle")
|
|
162
95
|
@with_project_definition()
|
|
163
|
-
@nativeapp_definition_v2_to_v1
|
|
96
|
+
@nativeapp_definition_v2_to_v1()
|
|
164
97
|
def app_bundle(
|
|
165
98
|
**options,
|
|
166
99
|
) -> CommandResult:
|
|
@@ -181,7 +114,7 @@ def app_bundle(
|
|
|
181
114
|
|
|
182
115
|
@app.command("diff", requires_connection=True, hidden=True)
|
|
183
116
|
@with_project_definition()
|
|
184
|
-
@nativeapp_definition_v2_to_v1
|
|
117
|
+
@nativeapp_definition_v2_to_v1()
|
|
185
118
|
def app_diff(
|
|
186
119
|
**options,
|
|
187
120
|
) -> CommandResult:
|
|
@@ -208,7 +141,7 @@ def app_diff(
|
|
|
208
141
|
|
|
209
142
|
@app.command("run", requires_connection=True)
|
|
210
143
|
@with_project_definition()
|
|
211
|
-
@nativeapp_definition_v2_to_v1
|
|
144
|
+
@nativeapp_definition_v2_to_v1(app_required=True)
|
|
212
145
|
def app_run(
|
|
213
146
|
version: Optional[str] = typer.Option(
|
|
214
147
|
None,
|
|
@@ -272,7 +205,7 @@ def app_run(
|
|
|
272
205
|
|
|
273
206
|
@app.command("open", requires_connection=True)
|
|
274
207
|
@with_project_definition()
|
|
275
|
-
@nativeapp_definition_v2_to_v1
|
|
208
|
+
@nativeapp_definition_v2_to_v1(app_required=True)
|
|
276
209
|
def app_open(
|
|
277
210
|
**options,
|
|
278
211
|
) -> CommandResult:
|
|
@@ -299,7 +232,9 @@ def app_open(
|
|
|
299
232
|
|
|
300
233
|
@app.command("teardown", requires_connection=True)
|
|
301
234
|
@with_project_definition()
|
|
302
|
-
@nativeapp_definition_v2_to_v1
|
|
235
|
+
# This command doesn't use @nativeapp_definition_v2_to_v1 because it needs to
|
|
236
|
+
# be aware of PDFv2 definitions that have multiple apps created from the same package,
|
|
237
|
+
# which all need to be torn down.
|
|
303
238
|
def app_teardown(
|
|
304
239
|
force: Optional[bool] = ForceOption,
|
|
305
240
|
cascade: Optional[bool] = typer.Option(
|
|
@@ -308,26 +243,70 @@ def app_teardown(
|
|
|
308
243
|
show_default=False,
|
|
309
244
|
),
|
|
310
245
|
interactive: bool = InteractiveOption,
|
|
246
|
+
# Same as the param auto-added by @nativeapp_definition_v2_to_v1
|
|
247
|
+
package_entity_id: Optional[str] = typer.Option(
|
|
248
|
+
default="",
|
|
249
|
+
help="The ID of the package entity on which to operate when definition_version is 2 or higher.",
|
|
250
|
+
),
|
|
311
251
|
**options,
|
|
312
252
|
) -> CommandResult:
|
|
313
253
|
"""
|
|
314
254
|
Attempts to drop both the application object and application package as defined in the project definition file.
|
|
315
255
|
"""
|
|
256
|
+
cli_context = get_cli_context()
|
|
257
|
+
project = cli_context.project_definition
|
|
258
|
+
if isinstance(project, ProjectDefinitionV1):
|
|
259
|
+
# Old behaviour, not multi-app aware so we can use the old processor
|
|
260
|
+
processor = NativeAppTeardownProcessor(
|
|
261
|
+
project_definition=cli_context.project_definition.native_app,
|
|
262
|
+
project_root=cli_context.project_root,
|
|
263
|
+
)
|
|
264
|
+
processor.process(interactive, force, cascade)
|
|
265
|
+
else:
|
|
266
|
+
# New behaviour, multi-app aware so teardown all the apps created from the package
|
|
267
|
+
|
|
268
|
+
# Determine the package entity to drop, there must be one
|
|
269
|
+
app_package_entity = find_entity(
|
|
270
|
+
project,
|
|
271
|
+
ApplicationPackageEntityModel,
|
|
272
|
+
package_entity_id,
|
|
273
|
+
disambiguation_option="--package-entity-id",
|
|
274
|
+
required=True,
|
|
275
|
+
)
|
|
276
|
+
assert app_package_entity is not None # satisfy mypy
|
|
316
277
|
|
|
317
|
-
|
|
278
|
+
# Same implementation as `snow ws drop`
|
|
279
|
+
ws = WorkspaceManager(
|
|
280
|
+
project_definition=cli_context.project_definition,
|
|
281
|
+
project_root=cli_context.project_root,
|
|
282
|
+
)
|
|
283
|
+
for app_entity in project.get_entities_by_type(
|
|
284
|
+
ApplicationEntityModel.get_type()
|
|
285
|
+
).values():
|
|
286
|
+
# Drop each app
|
|
287
|
+
if app_entity.from_.target == app_package_entity.entity_id:
|
|
288
|
+
ws.perform_action(
|
|
289
|
+
app_entity.entity_id,
|
|
290
|
+
EntityActions.DROP,
|
|
291
|
+
force_drop=force,
|
|
292
|
+
interactive=interactive,
|
|
293
|
+
cascade=cascade,
|
|
294
|
+
)
|
|
295
|
+
# Then drop the package
|
|
296
|
+
ws.perform_action(
|
|
297
|
+
app_package_entity.entity_id,
|
|
298
|
+
EntityActions.DROP,
|
|
299
|
+
force_drop=force,
|
|
300
|
+
interactive=interactive,
|
|
301
|
+
cascade=cascade,
|
|
302
|
+
)
|
|
318
303
|
|
|
319
|
-
cli_context = get_cli_context()
|
|
320
|
-
processor = NativeAppTeardownProcessor(
|
|
321
|
-
project_definition=cli_context.project_definition.native_app,
|
|
322
|
-
project_root=cli_context.project_root,
|
|
323
|
-
)
|
|
324
|
-
processor.process(interactive, force, cascade)
|
|
325
304
|
return MessageResult(f"Teardown is now complete.")
|
|
326
305
|
|
|
327
306
|
|
|
328
307
|
@app.command("deploy", requires_connection=True)
|
|
329
308
|
@with_project_definition()
|
|
330
|
-
@nativeapp_definition_v2_to_v1
|
|
309
|
+
@nativeapp_definition_v2_to_v1()
|
|
331
310
|
def app_deploy(
|
|
332
311
|
prune: Optional[bool] = typer.Option(
|
|
333
312
|
default=None,
|
|
@@ -350,6 +329,8 @@ def app_deploy(
|
|
|
350
329
|
unspecified, the command syncs all local changes to the stage."""
|
|
351
330
|
).strip(),
|
|
352
331
|
),
|
|
332
|
+
interactive: bool = InteractiveOption,
|
|
333
|
+
force: Optional[bool] = ForceOption,
|
|
353
334
|
validate: bool = ValidateOption,
|
|
354
335
|
**options,
|
|
355
336
|
) -> CommandResult:
|
|
@@ -360,6 +341,13 @@ def app_deploy(
|
|
|
360
341
|
|
|
361
342
|
assert_project_type("native_app")
|
|
362
343
|
|
|
344
|
+
if force:
|
|
345
|
+
policy = AllowAlwaysPolicy()
|
|
346
|
+
elif interactive:
|
|
347
|
+
policy = AskAlwaysPolicy()
|
|
348
|
+
else:
|
|
349
|
+
policy = DenyAlwaysPolicy()
|
|
350
|
+
|
|
363
351
|
has_paths = paths is not None and len(paths) > 0
|
|
364
352
|
if prune is None and recursive is None and not has_paths:
|
|
365
353
|
prune = True
|
|
@@ -386,6 +374,7 @@ def app_deploy(
|
|
|
386
374
|
recursive=recursive,
|
|
387
375
|
local_paths_to_sync=paths,
|
|
388
376
|
validate=validate,
|
|
377
|
+
policy=policy,
|
|
389
378
|
)
|
|
390
379
|
|
|
391
380
|
return MessageResult(
|
|
@@ -395,8 +384,10 @@ def app_deploy(
|
|
|
395
384
|
|
|
396
385
|
@app.command("validate", requires_connection=True)
|
|
397
386
|
@with_project_definition()
|
|
398
|
-
@nativeapp_definition_v2_to_v1
|
|
399
|
-
def app_validate(
|
|
387
|
+
@nativeapp_definition_v2_to_v1()
|
|
388
|
+
def app_validate(
|
|
389
|
+
**options,
|
|
390
|
+
):
|
|
400
391
|
"""
|
|
401
392
|
Validates a deployed Snowflake Native App's setup script.
|
|
402
393
|
"""
|
|
@@ -428,7 +419,7 @@ DEFAULT_EVENT_FOLLOW_LAST = 20
|
|
|
428
419
|
|
|
429
420
|
@app.command("events", requires_connection=True)
|
|
430
421
|
@with_project_definition()
|
|
431
|
-
@nativeapp_definition_v2_to_v1
|
|
422
|
+
@nativeapp_definition_v2_to_v1(app_required=True)
|
|
432
423
|
def app_events(
|
|
433
424
|
since: str = typer.Option(
|
|
434
425
|
default="",
|
|
File without changes
|