{"id":31482342,"url":"https://github.com/snowflake-labs/semantic-model-generator","last_synced_at":"2025-10-02T07:47:55.641Z","repository":{"id":232702900,"uuid":"781087075","full_name":"Snowflake-Labs/semantic-model-generator","owner":"Snowflake-Labs","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-30T20:51:04.000Z","size":3455,"stargazers_count":177,"open_issues_count":22,"forks_count":108,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-30T22:59:41.638Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Snowflake-Labs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-02T18:12:18.000Z","updated_at":"2025-07-30T21:56:28.000Z","dependencies_parsed_at":"2024-05-21T22:30:37.676Z","dependency_job_id":"8712e933-e858-42cd-8c30-a273591fd070","html_url":"https://github.com/Snowflake-Labs/semantic-model-generator","commit_stats":null,"previous_names":["snowflake-labs/semantic-model-generator"],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/Snowflake-Labs/semantic-model-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsemantic-model-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsemantic-model-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsemantic-model-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsemantic-model-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Snowflake-Labs","download_url":"https://codeload.github.com/Snowflake-Labs/semantic-model-generator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snowflake-Labs%2Fsemantic-model-generator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277974415,"owners_count":25908396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-02T02:00:08.890Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-02T07:47:53.885Z","updated_at":"2025-10-02T07:47:55.635Z","avatar_url":"https://github.com/Snowflake-Labs.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# semantic-model-generator\n\n\u003e [!NOTE]  \n\u003e The Semantic Model Generator in Streamlit has been replaced by the native [Cortex Analyst Semantic View Generator in Snowsight](https://docs.snowflake.com/en/user-guide/views-semantic/ui). Please use the native semantic generation moving forward. The team is actively working to support translating existing semantic layers from partner tools into consumable semantic models in Snowflake.\n\nThe `Semantic Model Generator` is an open-source tool used to generate and curate a semantic model for Snowflake [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst).\n\nThe tool is rendered as a Streamlit application, which can be started in [Streamlit in Snowflake](https://docs.snowflake.com/en/developer-guide/streamlit/about-streamlit) or locally with open-source Streamlit.\nSetup instructions are separated below for the two methods - Please proceed to your preferred deployment method: [SiS deployment](#streamlit-in-snowflake-deployment) or [local deployment](#local-deployment).\n\nIf you want to see what a semantic model looks like, skip to [Examples](#examples).\n\n## Table of Contents\n\n* [Table of Contents](#table-of-contents)\n* [Streamlit in Snowflake Deployment](#streamlit-in-snowflake-deployment)\n* [Local Deployment](#local-deployment)\n* [Partner Tool Translation](#partner-tool-translation)\n* [Callable Semantic Generation](#callable-semantic-generation)\n* [Usage](#usage)\n    + [Semantic Model Context Length Constraints](#semantic-model-context-length-constraints)\n    + [Auto-Generated Descriptions](#auto-generated-descriptions)\n    + [Additional Fields to Fill Out](#additional-fields-to-fill-out)\n* [Examples](#examples)\n* [Release](#release)\n\n## Streamlit in Snowflake Deployment\n\n\u003e **Note**: Deploying this app in Streamlit in Snowflake requires support for python 3.9+ in Streamlit in Snowflake.  This feature is part of the 2024-08 BCR (Behavior Change Bundle) which is currently **disabled by default**.  A user with ACCOUNTADMIN privileges can enable this feature in your account by running the following code in Snowsight:\n\u003e \n```sql\nSELECT SYSTEM$ENABLE_BEHAVIOR_CHANGE_BUNDLE('2024_08');\n```\n\u003e You can check to see if this BCR is already enabled by running:\n```sql\nSELECT SYSTEM$BEHAVIOR_CHANGE_BUNDLE_STATUS('2024_08');\n```\n\u003e A typical error you might see if you do not have this feature enabled looks like this:\n\u003cimg src = \"images/error39.png\" width=30% height=30%\u003e\n\n\u003e For more information on this bundle please see our [BCR Documentation](https://docs.snowflake.com/en/release-notes/behavior-changes).\n\n\n[Snowflake CLI](https://docs.snowflake.com/en/developer-guide/snowflake-cli-v2/index) is recommended for deploying the app in Streamlit in Snowflake. Please see Snowflake CLI [installation instructions](https://docs.snowflake.com/en/developer-guide/snowflake-cli-v2/installation/installation) to install. **Snowflake CLI version 3.0+ is recommended**. Follow the below instructions to install the Semantic Model Generator in Streamlit in Snowflake.\n\nIf you do not have Snowflake CLI installed, the setup can be replicated manually with the [VS Code Snowflake extension](https://docs.snowflake.com/en/user-guide/vscode-ext), Snowsight or [Snowflake Native Git Integration](https://docs.snowflake.com/en/developer-guide/git/git-overview):\n - If using Snowsight, you may use the files upload wizard to upload files. Please pay close attention to maintain the directory structure referenced in `setup_sis/app_setup.sql`.\n - If using the Native Git Integration, copy and paste the code from this [setup file](https://github.com/Snowflake-Labs/semantic-model-generator/blob/main/sis_setup/sissetup_snowsightgit.sql) and run in Snowsight. \n\n### Snowflake CLI Installation\n\n1. Configure Snowflake CLI\n\nFollow [instructions](https://docs.snowflake.com/en/developer-guide/snowflake-cli-v2/connecting/specify-credentials) for your preferred connection method to connect Snowflake CLI to your Snowflake account. Please [test](https://docs.snowflake.com/en/developer-guide/snowflake-cli-v2/connecting/manage-connections#label-snowcli-connection-test) your connection. Depending on your connection configuration, you may need to continue passing credentials for subsequent Snowflake CLI commands.\n\n2. Deploy app in Streamlit in Snowflake\n\nRun the below command from the project root directory to create all necessary objects in Snowflake. \n\n**Hint**: The owner of the app will be the role specified in your Snowflake CLI connection. To use a different role, append `--role \u003cDESIRED_ROLE\u003e` to the end of the command, replacing `\u003cDESIRED_ROLE\u003e`.\n\n```bash\nsnow sql -f sis_setup/app_setup.sql\n```\n\nThe app, titled Semantic Model Generator can be opened directly in Snowsight. Alternatively, you may run the below command in your terminal to open it.\n\n```bash\nsnow streamlit get-url SEMANTIC_MODEL_GENERATOR --open --database cortex_analyst_semantics --schema semantic_model_generator\n```\n\n### **OPTIONAL**: Setup Looker Integration\n\nThe Semantic Model Generator supports translating metadata from a Looker Explore. To add this functionality to the Streamlit in Snowflake app, we need to create an external access integration to allow Snowflake to reach your Looker instance. \n\nHave the following information available:\n- `\u003cLOOKER_URL\u003e`: [Looker Base URL](https://cloud.google.com/looker/docs/admin-panel-platform-api#api_host_url). Pass the domain excluding https:// such as snowflakedemo.looker.com.\n- `\u003cCLIENT_SECRET\u003e`: [Looker Client Secret](https://cloud.google.com/looker/docs/api-auth#authentication_with_an_sdk)\n- `\u003cAPP_ROLE\u003e`: the owning role used in step #2 above\n\nIf using the CLI method, run the below command to create the external access integration. Before running, replace the parameters.\n\n**Hint**: Creating external access integrations may require increased privileges. To use a different role from what is specified in your Snowflake CLI connection, append `--role \u003cDESIRED_ROLE\u003e` to the end of the command, replacing `\u003cDESIRED_ROLE\u003e`.\n\n```bash\nsnow sql -f sis_setup/looker_integration.sql -D \"looker_url=\u003cLOOKER_URL\u003e\" -D \"client_secret=\u003cCLIENT_SECRET\u003e\" -D \"streamlit_role=\u003cAPP_ROLE\u003e\"\n```\nIf using any other method (e.g., Git Integration), you will need to update and run [looker_integration.sql](https://github.com/Snowflake-Labs/semantic-model-generator/blob/main/sis_setup/looker_integration.sql) in Snowsight with these variables replaced.\n\n## Local Deployment\n\nLocal usage of the Streamlit app offers Snowflake connections via [Snowflake connections.toml](https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-connect#connecting-using-the-connections-toml-file) OR environment variables. The app will first check for a connections.toml before using environment variables. Please follow the setup for your desired method and continue to [Start Local Streamlit App](#start-local-streamlit-app) once completed.\n\n### Setup connections.toml (Option 1)\nThe Snowflake Python connector lets you add connection definitions to a connections.toml configuration file. A connection definition refers to a collection of connection-related parameters. Snowflake Python libraries currently support TOML version 1.0.0.\n\nPlease follow these [instructions](https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-connect#connecting-using-the-connections-toml-file) to create the appropriate connections.toml file. For convenience, we recommend setting the desired connection as your default.\n\n### Environment Variables (Option 2)\nAt minimum, the below environment variables are required if using this method to connect to Snowflake.\n\n```bash\nSNOWFLAKE_ROLE\nSNOWFLAKE_WAREHOUSE\nSNOWFLAKE_USER\nSNOWFLAKE_ACCOUNT_LOCATOR\nSNOWFLAKE_HOST\n```\n\nFor your convenience, we have created examples of setting these environment variables in [`.env.example`](.env.example). If using environment variables, we recommend creating a `.env` file in the root directory of this repo. Please feel free to set your environment variables directly in terminal if preferred.\n\nTo find your Account locator, please execute the following sql command in your account.\n\n```sql\nSELECT CURRENT_ACCOUNT_LOCATOR();\n```\n\nB. To find the `SNOWFLAKE_HOST` for your\naccount, [follow these instructions](https://docs.snowflake.com/en/user-guide/organizations-connect#connecting-with-a-url). The easiest way to find your account URL is to click the `Copy account URL` button from the Account panel in Snowsight: \n\n![CleanShot 2024-10-09 at 14 25 13](https://github.com/user-attachments/assets/b1715c57-9571-4c65-92fb-e5d43afa871b)\n\nHowever, if you have trouble authenticating with this URL, you can try building the URL manually:\n* Currently we recommend you to look under the `Account locator (legacy)` method of connection for better compatibility on API.\n* It typically follows format of: `\u003caccountlocator\u003e.\u003cregion\u003e.\u003ccloud\u003e.snowflakecomputing.com`. Ensure that you omit\n  the `https://` prefix.\n\nOur semantic model generator currently support three types of authentication. \nIf no `SNOWFLAKE_AUTHENTICATOR` environment variable is set, the default is `snowflake`, which uses standard username/password support (#1 below).\n\n1. Username and Password\n\nSet the below environment variables:\n```bash\nSNOWFLAKE_USER=\"\u003cyour-snowflake-username\u003e\" \nSNOWFLAKE_PASSWORD=\"\u003cyour-snowflake-password\u003e\" \n```\nIf you have MFA enabled, using this default authenticator should send a push notification to your device.\n\n2. Username/Password with MFA passcode\n\nUsing a passcode from your authenticator app:\n\n```bash\nSNOWFLAKE_AUTHENTICATOR=\"username_password_mfa\"\nSNOWFLAKE_PASSWORD=\"\u003cyour-snowflake-password\u003e\"\nSNOWFLAKE_MFA_PASSCODE=\"\u003cyour-snowflake-mfa-passcode\u003e\" # if your authenticator app reads \"123 456\", fill in \"123456\" (No spaces)\n```\n\nUsing a passcode embedded in the password:\n\n```bash\nSNOWFLAKE_AUTHENTICATOR=\"username_password_mfa\"\nSNOWFLAKE_PASSWORD=\"\u003cyour-snowflake-password\u003e\"\nSNOWFLAKE_MFA_PASSCODE_IN_PASSWORD=\"true\"\n```\n\n3. Single Sign-On (SSO) with Okta\n\n```bash\n# no SNOWFLAKE_PASSWORD needed\nSNOWFLAKE_AUTHENTICATOR=\"externalbrowser\"\n```\n\n### Start Local Streamlit App\n\nOnce you have completed 1 of the 2 setup options above, you're ready to start the local Streamlit app.\n\n1) If you have Make on your machine, run the below command to install dependencies for the Streamlit app.\n\n```bash\nmake setup_admin_app\n```\n\nThis uses `pip` to install dependencies from the root `pyproject.toml`. Feel free to use `conda` or any package manager\nyou prefer. Below is an alternative to the Make command.\n```bash\npip install .\n```\n\nThe generator supports merging data from your existing semantic models built with partners such as dbt and Looker. To\nuse the Looker-specific features, please use the below command to install the extras. This is only required for looker translation.\n\n```bash\npip install -e \".[looker]\"\n```\n\n2) You can run the app using the provided Makefile target if you have Make on your machine.\n\n```bash\nmake run_admin_app\n```\n\nAlternatively, you can use your current version of Python to start the app manually. Please use Python 3.8-3.11.\n\n```bash\npython3 -m streamlit run app.py\n```\n\n## Partner Semantic Translation\n\nWe continue to add support for partner semantic and metric layers. Our aim is to expedite the creation of Cortex Analyst\nsemantic files using logic and metadata from partner tools.\nPlease see below for details about current partner support.\n\n**IMPORTANT**: Instructions for each of the below sources are provided in the Streamlit application.\n\n| Source   | Method                                                                                                                                                                                                                                       | Requirements                                                                                                                                                                                                                                                                                                                                                                                                             |\n|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| DBT Semantic Model   | We extract and translate metadata from [semantic_models](https://docs.getdbt.com/docs/build/semantic-models#semantic-models-components) in uploaded DBT yaml file(s) and merge with a generated Cortex Analyst semantic file table-by-table. | DBT models and sources leading up to the semantic model layer(s) must be tables/views in Snowflake. |\n| DBT SQL Model | DBT SQL Models should be materialized in Snowflake with persist docs to capture comments. A new semantic file can be generated for these newly materialized tables/views in Snowflake directly.| |\n| Looker Explore | We materialize your Explore dataset in Looker as Snowflake table(s) and generate a Cortex Analyst semantic file. Metadata from your Explore fields can be merged with the generated Cortex Analyst semantic file.                            | Looker Views referenced in the Looker Explores must be tables/views in Snowflake. Looker SDK credentials are required. Visit [Looker Authentication SDK Docs](https://cloud.google.com/looker/docs/api-auth#authentication_with_an_sdk) for more information. Install Looker's [API Explorer extension](https://cloud.google.com/looker/docs/api-explorer) from the Looker Marketplace to view API credentials directly. |\n\n## Callable Semantic Generation\n\nA semantic model for table(s) can be generated in a callable fashion using the below stored procedure:\n\n```sql\nCORTEX_ANALYST_SEMANTICS.SEMANTIC_MODEL_GENERATOR.GENERATE_SEMANTIC_FILE(\n    STAGE_NAME STRING,\n    MODEL_NAME STRING,\n    SAMPLE_VALUE INT,\n    ALLOW_JOINS BOOLEAN,\n    TABLE_LIST ARRAY\n)\n```\n\nCalling the stored procedure will generate and upload a **minimal** semantic model YAML file to the specified Snowflake stage. Below is an example of calling the stored procedure for a single table. \n\n```sql\nCALL CORTEX_ANALYST_SEMANTICS.SEMANTIC_MODEL_GENERATOR.GENERATE_SEMANTIC_FILE(\n'CATRANSLATOR.ANALYTICS.DATA',\n'MY_SEMANTIC_MODEL',\n5,\nFalse,\n['CATRANSLATOR.ANALYTICS.CUSTOMERS']\n);\n```\nPlease note that high accuracy generally requires hands-on curation beyond that of a minimal semantic model.\n\n## Usage\n\n### Semantic Model Context Length Constraints\n\nDue to context window as well as quality constraints, we currently limit the size of the generated semantic model to \u003c\n30,980 tokens (~123,920 characters).\n\nPlease note sample values and verified queries is not counted into this token length constraints. You can include as\nmany sample values or verified queries as you'd like with limiting the overall file to \u003c1MB.\n\n### Auto-Generated Descriptions\n\nIf your snowflake tables and comments do not have comments, we currently\nleverages [cortex LLM function](https://docs.snowflake.com/en/user-guide/snowflake-cortex/llm-functions) to\nauto-generate description suggestions. Those generation are suffixed with '__' and additional comment to remind you to\nconfirm/modity the descriptions.\n\n### Additional Fields to Fill Out\n\n**IMPORTANT**: After generation, your YAML files will have a series of lines with `# \u003cFILL-OUT\u003e`. Please take the time\nto fill these out with your business context, or else subsequent validation of your model will fail.\n\nBy default, the generated semantic model will contain all columns from the provided tables/views. However, it's highly\nencouraged to only keep relevant columns and drop any unwanted columns from the generated semantic model.\n\nIn addition, consider adding the following elements to your semantic model:\n\n1. Logical columns for a given table/view that are expressions over physical columns.\n    * Example: `col1 - col2` could be the `expr` for a logical column.\n2. Synonyms. Any additional synonyms for column names.\n3. Filters. Additional filters with their relevant `expr`.\n\n## Examples\n\nIf you have an example table in your account with the following DDL statements.\n\n```sql\nCREATE TABLE sales.public.sd_data\n(\n    id    SERIAL PRIMARY KEY,\n    dt    DATETIME,\n    cat   VARCHAR(255),\n    loc   VARCHAR(255),\n    cntry VARCHAR(255),\n    chn   VARCHAR(50),\n    amt   DECIMAL(10, 2),\n    unts  INT,\n    cst   DECIMAL(10, 2)\n);\n```\n\nHere is an example semantic model, with data elements automatically generated from this repo and filled out by a user.\n\n```yaml\n# Name and description of the semantic model.\nname: Sales Data\ndescription: This semantic model can be used for asking questions over the sales data.\n\n# A semantic model can contain one or more tables.\ntables:\n\n  # A logical table on top of the 'sd_data' base table.\n  - name: sales_data\n    description: A logical table capturing daily sales information across different store locations and product categories.\n\n    # The fully qualified name of the base table.\n    base_table:\n      database: sales\n      schema: public\n      table: sd_data\n\n    # Dimension columns in the logical table.\n    dimensions:\n      - name: product_category\n        synonyms:\n          - \"item_category\"\n          - \"product_type\"\n        description: The category of the product sold.\n        expr: cat\n        data_type: NUMBER\n        unique: false\n        sample_values:\n          - \"501\"\n          - \"544\"\n\n      - name: store_country\n        description: The country where the sale took place.\n        expr: cntry\n        data_type: TEXT\n        unique: false\n        sample_values:\n          - \"USA\"\n          - \"GBR\"\n\n      - name: sales_channel\n        synonyms:\n          - \"channel\"\n          - \"distribution_channel\"\n        description: The channel through which the sale was made.\n        expr: chn\n        data_type: TEXT\n        unique: false\n        sample_values:\n          - \"FB\"\n          - \"GOOGLE\"\n\n    # Time dimension columns in the logical table.\n    time_dimensions:\n      - name: sale_timestamp\n        synonyms:\n          - \"time_of_sale\"\n          - \"transaction_time\"\n        description: The time when the sale occurred. In UTC.\n        expr: dt\n        data_type: TIMESTAMP\n        unique: false\n\n    # Measure columns in the logical table.\n    measures:\n      - name: sales_amount\n        synonyms:\n          - \"revenue\"\n          - \"total_sales\"\n        description: The total amount of money generated from the sale.\n        expr: amt\n        data_type: NUMBER\n        default_aggregation: sum\n\n      - name: sales_tax\n        description: The sales tax paid for this sale.\n        expr: amt * 0.0975\n        data_type: NUMBER\n        default_aggregation: sum\n\n      - name: units_sold\n        synonyms:\n          - \"quantity_sold\"\n          - \"number_of_units\"\n        description: The number of units sold in the transaction.\n        expr: unts\n        data_type: NUMBER\n        default_aggregation: sum\n\n      - name: cost\n        description: The cost of the product sold.\n        expr: cst\n        data_type: NUMBER\n        default_aggregation: sum\n\n      - name: profit\n        synonyms:\n          - \"earnings\"\n          - \"net income\"\n        description: The profit generated from a sale.\n        expr: amt - cst\n        data_type: NUMBER\n        default_aggregation: sum\n\n    # A table can define commonly used filters over it. These filters can then be referenced in user questions directly.\n    filters:\n      - name: north_america\n        synonyms:\n          - \"North America\"\n          - \"N.A.\"\n          - \"NA\"\n        description: \"A filter to restrict only to north american countries\"\n        expr: cntry IN ('canada', 'mexico', 'usa')\n```\n\n## Release\n\nIn order to push a new build and release, follow the steps below. Note, only admins are allowed to push `release/v`\ntags.\n\nYou should follow the setup commands from usage-cli to install poetry and create your environment.\n\n1. Checkout a new branch from main. You should name this branch `release/vYYYY-MM-DD`.\n2. Bump the poetry:\n    * `poetry version patch` - increments `0.1.x` to `0.1.(x+1)`\n    * `poetry version minor` - increments `0.x.0` to `0.(x+1).0`\n    * `poetry version major` - increments `x.0.0` to `(x+1).0.0`\n3. Update the `CHANGELOG.md` adding a relevant header for your version number along with a description of the changes\n   made.\n4. Run `make build` to create a new .whl file.\n5. Push your files for approval.\n6. After approval, run `make release` which will cut a new release and attach the .whl file.\n7. Merge in your pr.\n\n- Note: If you `make release` does not trigger the GH action. Please delete the tag and push again.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowflake-labs%2Fsemantic-model-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnowflake-labs%2Fsemantic-model-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowflake-labs%2Fsemantic-model-generator/lists"}