Tutorial 8: Access the public endpoint programmatically¶
Introduction¶
In Tutorial 1, you learned how to access a public endpoint by using a web browser. Using the browser, you sent a request to the public endpoint, which is the ingress endpoint. This required you to first authenticated with Snowflake, and then you interacted with the service by using the web UI that the service provides.
In this tutorial, you access the same public endpoint programmatically. The tutorial shows you three different options to authenticate when you log into Snowflake: by using a programmatic access token (PAT), by using a JSON Web Token (JWT), and using a Session Token from the Python Connector
Prerequisites¶
-
Start
echo_serviceservice as described in Tutorial 1. -
To verify that the service is running, execute the DESCRIBE SERVICE command.
-
In the
statuscolumn, verify that it shows that the service status as RUNNING.If the status is PENDING, it indicates that the service is still starting.
-
To investigate why the service isn’t RUNNING, execute the SHOW SERVICE CONTAINERS IN SERVICE command, and then review the
statusof individual containers:
Important
Don’t proceed with this tutorial until you have the echo_service running.
Option 1: Send requests to the service endpoint programmatically by using a PAT¶
This option shows you how to access a service endpoint programmatically by using curl and Python. In both cases you use a programmatic access token (PAT) for authentication. Snowflake recommends that you use PAT for programmatic access.
Set up a PAT¶
This procedure is a continuation of Tutorial 1. Use the same user (testuser), database (tutorial_db),
and schema (data_schema) as in Tutorial 1.
-
To create a PAT for the user, run the following command.
You should review the PAT-related prerequisites because if you don’t meet those prerequisites, you can generate a PAT but you can’t authenticate by using the PAT.
This command creates a PAT to sign in to Snowflake as a
testuserwith the rolepublic.Example output:
-
Save the
token_secretvalue for later use.You need this value later to authenticate when you send requests to the public endpoint.
-
To find the ingress URL for the public endpoint that the
echo_serviceexposes, run the following command:Example output:
-
Save the
ingress_urlvalue for later use.You need this value later to send requests to the public endpoint.
Now you are ready to sign in to Snowflake by using the PAT for authentication and send programmatic
requests to the ingress_url of the public endpoint of the echo_service.
Send requests to the service endpoint programmatically by using a PAT¶
In this section, you send programmatic requests to the public endpoint of the echo_service using curl and Python.
Send request using curl¶
Save the PAT to an environment variable.
For example, on a Mac or Linux operating system, you can use the following command:
Send a request to the public endpoint of the echo_service, as shown
in the following example:
The command sends a GET request to the public endpoint of the echo_service, providing the
following information:
- The URL (
https://<ingress-URL>/ui) of the endpoint. The string/uiappended to the ingress URL causes the service to execute theui()function. For more information, see theecho_service.pyfile. - The
Authorizationheader with PAT token for authentication.
In response, the echo_service in this example serves an HTML page, which curl prints to the console.
Without the PAT, the endpoint returns a redirect to the Snowflake sign-in page.
Send request using Python¶
To send a request to the public endpoint of the echo_service,
use a PAT for authentication by using Python, as shown in the following
example steps:
- In the
invokeUsingPat.pyfile, save the following code:
- Run the code that you saved by sending the following request:
When the request arrives, the service executes the
ui()function, which renders an HTML form as shown in the following example. For more information, see the “Reviewing the service code” step of Tutorial 1.
Option 2: Send requests to the service endpoint programmatically by using a JWT¶
In this option, the Python sample code that you are provided uses key pair authentication. By using the key pair that you provide, the sample code performs the following actions:
- Generates a JSON Web Token (JWT).
- Exchanges the JWT with Snowflake for an OAuth token.
- Uses the OAuth token for authentication when the sample code communicates
with the
echo_servicepublic endpoint.
Set up a JWT¶
To communicate with the echo_service programmatically,
complete the following steps. By using the Python code provided, you send
requests to the public endpoint that the echo_service exposes.
-
At the command prompt or in the terminal, create a directory, and then navigate to it.
-
Configure key pair authentication for the user:
-
Generate a key pair:
-
Generate a private key by running the following command.
To simplify the steps, you generate an unencrypted private key. You can also use an encrypted private key but it requires that you enter the password.
-
To generate a public key (
rsa_key.pub) by referencing the private key that you created, run the following command:
-
-
In the directory, verify that you generated the private key and public key.
-
Assign the public key to the user that you are using to test the programmatic access.
This action lets the user specify the key for authentication.
-
-
In Python files, save the provided sample code:
-
In the
generateJWT.pyfile, save the following code: -
In the
access-via-keypair.pyfile, save the following code:
-
Send requests to the service endpoint programmatically by using a JWT¶
- To make the ingress call to the
echo_servicepublic endpoint, execute theaccess-via-keypair.pyPython code:
Important
The name specified by the --role flag must exactly match the case of
the role name shown by SHOW ROLES.
For more information about account-identifier, see Account identifiers.
How authentication works when you use a JWT¶
The code first converts the provided key pair into a JWT token. It then sends the JWT token to Snowflake to obtain an OAuth token. Finally, the code uses the OAuth token to connect to Snowflake and access the public endpoint.
Specifically, the code performs the following actions:
-
The code calls the
_get_token(args)function to generate a JWT from the key pair that you provide.The function implementation is shown in the following example:
JWTGeneratoris a helper class that is provided to you. The following list includes information about the parameters that you provide when you create this object:args.accountand theargs.userparameters: A JWT has several fields. For more information, see token format.issis one of the JWT’s fields. This field value includes the Snowflake account name and a user name. Therefore, you provide these values as parameters.- Two
timedeltaparameters provide the following information:lifetimespecifies the number of minutes during which the key will be valid (60 minutes).renewal_delayspecifies the number of minutes from now after which the JWT generator should renew the JWT.
-
The code calls the
token_exchange()function to connect to Snowflake, and then exchange the JWT for an OAuth token:The preceding code constructs JSON text that sets the scope for the OAuth token, which is the public endpoint that can be accessed by using the specified role. This code then makes a POST request to Snowflake. Snowflake passes the JSON text to exchange the JWT for an OAuth token (see Token exchange), as shown in the following example:
-
To connect to the public endpoint of the
echo_service, the code then callsconnect_to_spcs()function.It provides the URL (
https://<ingress-URL>/ui) of the endpoint and the OAuth token for authentication.The
urlis thespcs_urlthat you provided to the program and thetokenis the OAuth token.The
echo_servicein this example serves an HTML page, as explained in the preceding section. This sample code simply prints the HTML in the response.
Option 3: Send requests to the service endpoint programmatically by using a session token¶
This option shows how to access a service endpoint programmatically by using a session token for authentication. You can obtain the session token by using the Python Connector, as shown in the following example.
This code provides an alternative to key-pair authentication; however, there is no guarantee that it will work with future versions of the Snowflake Connector for Python. The example first uses the connector to generate a session token that represents your identity, then uses that token to authenticate to the public endpoint.
-
Configure a connection named “test”.
For more instructions, see Connecting using the `connections.toml` file.
-
Save the following Python code to a
spcs-connect.pyfile. -
Update the Python code by supplying the connection name to
snowflake.connector.connect, similar to the following example: -
Use the following command to run the Python code that first generates a session token, and then sends a request to the public endpoint of the service programmatically by using the session token:
Alternatively, if you know the hostname of the public endpoint — SHOW ENDPOINTS — you can use the following script. For example, if the hostname of the public endpoint is
ewapx-testorg-testaccount.snowflakecomputing.app, you can use the following script:Example output:
Clean up¶
For instructions, see the Tutorial 1, Clean up step.