Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Appify #13

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a0a248f
Add scaffolding
sfc-gh-cgorrie Dec 12, 2023
cdcf8e6
initial metadata scrape
sfc-gh-cgorrie Dec 12, 2023
bc774ef
fix parsing functions / procedures
sfc-gh-cgorrie Dec 12, 2023
efa2c00
skip callers rights
sfc-gh-cgorrie Dec 12, 2023
48ca3e2
dump stages; refactor paths
sfc-gh-cgorrie Dec 12, 2023
1b57bb3
include stages in snowflake.yml
sfc-gh-cgorrie Dec 12, 2023
55539af
quick refactor
sfc-gh-cgorrie Dec 12, 2023
20632bf
reference dump
sfc-gh-ssuresh Dec 12, 2023
6d4ef11
remove random files
sfc-gh-ssuresh Dec 12, 2023
16801b3
changes
sfc-gh-cgorrie Dec 12, 2023
b11882c
wip
sfc-gh-cgorrie Dec 12, 2023
0d71bd3
more scaffolding
sfc-gh-cgorrie Dec 12, 2023
9275389
require semicolons
sfc-gh-cgorrie Dec 12, 2023
76e7e87
rewrite stage imports
sfc-gh-cgorrie Dec 12, 2023
ca483d7
single ref file
sfc-gh-ssuresh Dec 12, 2023
262597d
remove single quotes around fqn
sfc-gh-ssuresh Dec 12, 2023
5c85687
cleanup function quotes in ref file
sfc-gh-ssuresh Dec 12, 2023
bc3e4b3
topo sort object ordering
sfc-gh-ssuresh Dec 12, 2023
9fc4731
file paths + fixes
sfc-gh-cgorrie Dec 12, 2023
81b0346
ordering dump
sfc-gh-ssuresh Dec 12, 2023
d95bb1d
fix bugs we could actually fix
sfc-gh-cgorrie Dec 12, 2023
1d7aea8
add schema to get_ddl statements
sfc-gh-cgorrie Dec 13, 2023
c749e44
ref_usage
sfc-gh-cgorrie Dec 13, 2023
6509f5d
fix package scripts
sfc-gh-cgorrie Dec 14, 2023
7a58719
dump stages only referenced by streamlits
sfc-gh-cgorrie Dec 14, 2023
71f8a76
fix semicolons and spaces at the end of a line
sfc-gh-cgorrie Dec 14, 2023
2bb7686
set default_streamlit
sfc-gh-cgorrie Dec 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ gen_docs/

^app.zip
^snowflake.yml

sid_db1/
2 changes: 2 additions & 0 deletions src/snowcli/app/commands_registration/builtin_plugins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from snowcli.cli.connection import plugin_spec as connection_plugin_spec
from snowcli.cli.containers import plugin_spec as containers_plugin_spec
from snowcli.cli.nativeapp import plugin_spec as nativeapp_plugin_spec
from snowcli.cli.appify import plugin_spec as appify_plugin_spec
from snowcli.cli.object import plugin_spec as object_plugin_spec
from snowcli.cli.registry import plugin_spec as registry_plugins_spec
from snowcli.cli.render import plugin_spec as render_plugin_spec
Expand All @@ -13,6 +14,7 @@
"connection": connection_plugin_spec,
"containers": containers_plugin_spec,
"nativeapp": nativeapp_plugin_spec,
"appify": appify_plugin_spec,
"object": object_plugin_spec,
"registry": registry_plugins_spec,
"render": render_plugin_spec,
Expand Down
Empty file.
108 changes: 108 additions & 0 deletions src/snowcli/cli/appify/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import logging
from typing import Optional

import json
import typer
from snowcli.cli.common.decorators import global_options_with_connection
from snowcli.cli.common.flags import DEFAULT_CONTEXT_SETTINGS
from snowcli.cli.nativeapp.init import nativeapp_init
from snowcli.output.decorators import with_output
from snowcli.output.types import CommandResult, MessageResult

from snowcli.cli.project.schemas.project_definition import project_schema

from snowcli.cli.appify.metadata import MetadataDumper
from snowcli.cli.appify.generate import (
modifications,
rewrite_ddl,
discover_external_tables,
generate_setup_statements,
generate_package_statements,
)

from strictyaml import as_document

app = typer.Typer(
context_settings=DEFAULT_CONTEXT_SETTINGS,
name="appify",
help="Generate a Native Application project from an existing database",
)

log = logging.getLogger(__name__)


@app.command()
@with_output
@global_options_with_connection
def appify(
db: str = typer.Argument(
...,
help="The database to extract metadata from and turn into an app.",
),
name: str = typer.Option(
None,
help=f"""The name of the native application project to include in snowflake.yml. When not specified, it is
generated from the name of the database. Names are assumed to be unquoted identifiers whenever possible, but
can be forced to be quoted by including the surrounding quote characters in the provided value.""",
),
**options,
) -> CommandResult:
"""
Initializes a Native Apps project from a database.
"""
project = nativeapp_init(path=db, name=name)

dumper = MetadataDumper(db, project.path)
dumper.execute()

catalog = json.loads(dumper.catalog_path.read_text())
ordering = json.loads(dumper.ordering_path.read_text())
rewrite_ddl(catalog, dumper.referenced_stage_ids, dumper.metadata_path)

# generate the setup script
setup_statements = list(generate_setup_statements(catalog, ordering))
with open(project.path / "app" / "setup_script.sql", "w") as setup_sql:
setup_sql.write("\n".join(setup_statements))
setup_sql.write("\n")

# generate the package script, if required
seen_external_tables = discover_external_tables(catalog)
if seen_external_tables:
package_statements = list(generate_package_statements(seen_external_tables))
with open(project.path / "package.sql", "w") as package_sql:
package_sql.write("\n".join(package_statements))
package_sql.write("\n")

# modify the project definition
with modifications(
project.path / "snowflake.yml", schema=project_schema
) as snowflake_yml:
# include referenced stages + metadata in our app stage
artifacts = snowflake_yml["native_app"]["artifacts"].data
artifacts.append(
dict(
src=str(dumper.metadata_path.relative_to(project.path)),
dest="./metadata",
)
)
if dumper.referenced_stage_ids:
artifacts.append(
dict(
src=str(dumper.stages_path.relative_to(project.path)),
dest="./stages",
)
)
snowflake_yml["native_app"]["artifacts"] = as_document(artifacts)

# add the package script, if we created one
if seen_external_tables:
# XXX: changing the template could cause us to lose other "package:" keys
snowflake_yml["native_app"]["package"] = {"scripts": ["package.sql"]}

# if we found any streamlits, just choose the first
if dumper.streamlits:
streamlit = dumper.streamlits[0]
with modifications(project.path / "app" / "manifest.yml") as manifest_yml:
manifest_yml["artifacts"]["default_streamlit"] = streamlit

return MessageResult(f"Created Native Application project from {db}.")
Loading
Loading