diff --git a/examples/chatgpt/gpt_actions_library/gpt_action_snowflake_direct.ipynb b/examples/chatgpt/gpt_actions_library/gpt_action_snowflake_direct.ipynb index 3171806e..5914f274 100644 --- a/examples/chatgpt/gpt_actions_library/gpt_action_snowflake_direct.ipynb +++ b/examples/chatgpt/gpt_actions_library/gpt_action_snowflake_direct.ipynb @@ -142,7 +142,7 @@ "\n", "### OpenAPI Schema\n", "\n", - "Once you've created a Custom GPT, copy the text below in the Actions panel. Have questions? Check out [Getting Started Example](https://platform.openai.com/docs/actions/getting-started) to see how this step works in more detail." + "Once you've created a Custom GPT, copy the text below in the Actions panel. Update the servers url to match your Snowflake Account Name url plus `/api/v2` as described [here](https://docs.snowflake.com/en/user-guide/organizations-connect#standard-account-urls). Have questions? Check out [Getting Started Example](https://platform.openai.com/docs/actions/getting-started) to see how this step works in more detail." ] }, { @@ -161,7 +161,7 @@ " version: 1.0.0\n", " description: API for executing statements in Snowflake with specific warehouse and role settings.\n", "servers:\n", - " - url: 'https://...snowflakecomputing.com/api/v2'\n", + " - url: 'https://-.snowflakecomputing.com/api/v2'\n", "\n", "\n", "paths:\n", @@ -238,16 +238,53 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Before you set up authentication in ChatGPT, please take the following steps in the application." + "Before you set up authentication in ChatGPT, please take the following steps in Snowflake.\n", + "\n", + "### 1. Optional: Configure IP Whitelisting for ChatGPT\n", + "Snowflake accounts with network policies that limit connections by IP, may require exceptions to be added for ChatGPT.\n", + "* Review the Snowflake documentation on [Network Policies](https://docs.snowflake.com/en/user-guide/network-policies)\n", + "* Go to the Snowflake Worksheets\n", + "* Create a network rule with the ChatGPT IP egress ranges listed [here](https://platform.openai.com/docs/actions/production/ip-egress-ranges)\n", + "* Create a corresponding Network Policy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "yaml" + } + }, + "outputs": [], + "source": [ + "## Example with ChatGPT IPs as of September 19, 2024\n", + "## Make sure to get the current IP ranges from https://platform.openai.com/docs/actions/production\n", + "CREATE NETWORK RULE chatgpt_network_rule\n", + " MODE = INGRESS\n", + " TYPE = IPV4\n", + " VALUE_LIST = ('23.102.140.112/28',\n", + " '13.66.11.96/28',\n", + " '104.210.133.240/28',\n", + " '20.97.188.144/28',\n", + " '20.161.76.48/28',\n", + " '52.234.32.208/28',\n", + " '52.156.132.32/28',\n", + " '40.84.220.192/28',\n", + " '23.98.178.64/28',\n", + " '40.84.180.128/28');\n", + "\n", + "CREATE NETWORK POLICY chatgpt_network_policy\n", + " ALLOWED_NETWORK_RULE_LIST = ('chatgpt_network_rule');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "### 2. Set up the Securit Integration\n", "* Review the Snowflake OAuth Overview: [https://docs.snowflake.com/en/user-guide/oauth-snowflake-overview](https://docs.snowflake.com/en/user-guide/oauth-snowflake-overview)\n", - "* Go to the Snowflake Worksheets\n", - "* Create new OAuth credentials through a [Security Integration](https://docs.snowflake.com/en/sql-reference/sql/create-security-integration-oauth-snowflake) - you will need a new one for each OAuth app/custom GPT since Snowflake Redirect URIs are 1-1 mapped to Security Integrations\n" + "* Create new OAuth credentials through a [Security Integration](https://docs.snowflake.com/en/sql-reference/sql/create-security-integration-oauth-snowflake) - you will need a new one for each OAuth app/custom GPT since Snowflake Redirect URIs are 1-1 mapped to Security Integrations" ] }, { @@ -267,7 +304,8 @@ " OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'\n", " OAUTH_REDIRECT_URI = 'https://oauth.pstmn.io/v1/callback' --- // this is a temporary value while testing your integration. You will replace this with the value your GPT provides\n", " OAUTH_ISSUE_REFRESH_TOKENS = TRUE\n", - " OAUTH_REFRESH_TOKEN_VALIDITY = 7776000;" + " OAUTH_REFRESH_TOKEN_VALIDITY = 7776000;\n", + " NETWORK_POLICY = chatgpt_network_policy --- // this line should only be included if you followed step 1 above" ] }, { @@ -312,11 +350,30 @@ "metadata": {}, "source": [ "\n", - "* Retrieve your OAuth Client Secret\n", + "* Retrieve your OAuth Client Secret" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "yaml" + } + }, + "outputs": [], + "source": [ + "select SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('CHATGPT_INTEGRATION');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "\n", - "You’ll find the Client Secret in OAUTH_CLIENT_SECRET.\n", + "You’ll find the Client Secret in OAUTH_CLIENT_SECRET. Do not include the double quotes when copying the value.\n", "\n", - "You’re now set to test your action in Postman. Once you get a successful API response there, you can proceed with your GPT Action." + "Now is a good time to [test your Snowflake integration in Postman](https://community.snowflake.com/s/article/How-to-configure-postman-for-testing-SQL-API-with-OAuth). If you copnfigured a network policy for your security integration, ensure that it includes the IP of the machine you're using to test." ] }, { @@ -332,12 +389,15 @@ "source": [ "In ChatGPT, click on \"Authentication\" and choose \"OAuth\". Enter in the information below.\n", "\n", - "* Client ID: use Client ID from steps above\n", - "* Client Secret: use Client Secret from steps above\n", - "* Authorization URL: use Authorization Endpoint from steps above\n", - "* Token URL: use Token Endpoint from steps above\n", - "* Scope: <empty>*\n", - "* Token: Default (POST)\n", + "| Form Field | Value |\n", + "| -------- | -------- |\n", + "| Authentication Type | OAuth |\n", + "| Client ID | OAUTH_CLIENT_ID from SHOW_OAUTH_CLIENT_SECRETS |\n", + "| Authorization URL | OAUTH_AUTHORIZATION_ENDPOINT from DESCRIBE SECURITY INTEGRATION |\n", + "| Token URL | OAUTH_TOKEN_ENDPOINT from DESCRIBE SECURITY INTEGRATION |\n", + "| Scope | <empty>* |\n", + "| Token Exchange Method | Default (POST Request) |\n", + "\n", "\n", "*Snowflake scopes pass the role, but you’ll notice the action itself also specifies the role as a parameter in runQuery, so the Scope is unnecessary. You may elect to pass roles in the scope instead of the action parameters if it makes more sense for your GPT." ] @@ -384,7 +444,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", + "* The callback url can change if you update the YAML, double check it is correct when making changes.\n", "* _Callback URL Error:_ If you get a callback URL error in ChatGPT, pay close attention to the Post-Action Steps above. You need to add the callback URL directly into your Security Integration for the action to authenticate correctly\n", "* _Schema calls the wrong warehouse or database:_ If ChatGPT calls the wrong warehouse or database, consider updating your instructions to make it more explicit either (a) which warehouse / database should be called or (b) to require the user provide those exact details before it runs the query\n" ]