Skip to content

Instantly share code, notes, and snippets.

@sfc-gh-vsekar
Last active October 28, 2024 13:59
Show Gist options
  • Select an option

  • Save sfc-gh-vsekar/4d61024cbd9ad8c7d746bc46d55a6090 to your computer and use it in GitHub Desktop.

Select an option

Save sfc-gh-vsekar/4d61024cbd9ad8c7d746bc46d55a6090 to your computer and use it in GitHub Desktop.
Connect to API end point hosted in Snowpark Containers (SPCS) using Snowpark
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Connect to API service endpoint, hosted in Snowpark Containers using Snowpark\n",
"\n",
"**Dated: Jan-2024**\n",
"\n",
"\n",
"This notebook demonstrates the gist of connecting to a REST API, hosted in Snowpark Container Services (SPCS). This demonstation\n",
"uses Snowpark (Python), but I am sure the approach would for Java / Scala implementations also."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Establish a Snowpark session\n",
"\n",
"from snowflake.snowpark.session import Session\n",
"\n",
"# Establish a Snowpark session\n",
"snowflake_connection_info = {\n",
" \"url\": \"https://<account locator>.snowflakecomputing.com\"\n",
" ,\"account\": \"<account locator>\"\n",
" ,\"account_name\": \"<account identifier>, do not include the organization name\"\n",
" ,\"organization\": \"<account org name>\"\n",
" ,\"user\": \"XXXX\"\n",
" ,\"password\": \"XXXX\"\n",
"}\n",
"\n",
"# I am establishing 2 snowpark sessions. \n",
"# One for DML processing with Snowflake and Another for interacting with the API.\n",
"sp_session = Session.builder.configs(snowflake_connection_info).create()\n",
"\n",
"# Another for interacting with the API.\n",
"api_sp_session = Session.builder.configs(snowflake_connection_info).create()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To access the API, the program would need to login into Snowflake. For this we need to get the JWT session token."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Get JWT Token\n",
"\n",
"api_sp_session.sql(f\"alter session set python_connector_query_result_format = json;\").collect()\n",
"\n",
"# Get the session token, which will be used for API calls for authentication\n",
"sptoken_data = api_sp_session.connection._rest._token_request('ISSUE')\n",
"api_session_token = sptoken_data['data']['sessionToken']\n",
"\n",
"# craft the request to ingress endpoint with authz\n",
"api_headers = {'Authorization': f'''Snowflake Token=\"{api_session_token}\"'''}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next we fetch the public URL, where the api endpoint is accessible for the service. We can retreive this using the command:\n",
"[SHOW ENDPOINTS](https://docs.snowflake.com/en/sql-reference/sql/show-endpoints)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Retreive the API end point for the SPCS \n",
"\n",
"spcs_service_name = '<your snowpark service name>'\n",
"spdf = sp_session.sql(f'''show endpoints in service {spcs_service_name} ''')\n",
"spdf.show()\n",
"\n",
"# Retreive the URL, mapped to the endpoint in the SPCS specifical file URL\n",
"# Ref: https://docs.snowflake.com/en/developer-guide/snowpark-container-services/specification-reference#spec-endpoints-field-optional\n",
"\n",
"# In this example, my endpoint is mapped to 'api'\n",
"spcs_endpoint = 'api'\n",
"df = spdf.filter(f''' \"name\" = '{spcs_endpoint}' ''').to_pandas()\n",
"api_base_url = df['ingress_url'].iloc[0]\n",
"api_base_url = f'http://{api_base_url}'\n",
"print(f'API Base url: {api_base_url}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next we are ready to make a call with the API.\n",
"\n",
"#### API using GET method"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Interact with the API end point\n",
"\n",
"import json\n",
"import requests\n",
"\n",
"print(f'Requesting to {api_base_url} ... \\n ')\n",
"response = requests.get(f'{api_base_url}/', headers = api_headers)\n",
"print(response.status_code)\n",
"print(response.text)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### API using POST method"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"params_data = {\n",
" 'first_name' : 'john'\n",
" ,'last_name' : 'doe'\n",
" ,'email' : '[email protected]'\n",
"}\n",
"\n",
"# Added content to existing api_header\n",
"api_headers['Content-Type'] = 'application/json'\n",
"r = requests.get(llm_codegen_url, params = params_data, headers = api_headers)\n",
"print(f'Status : {r.status_code}')\n",
"print(f'Body: \\n')\n",
"print(r.json())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venkat_env",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.18"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
@emanueol
Copy link

Hi, what is it and one setups that "ISSUE" in:

sptoken_data = api_sp_session.connection._rest._token_request('ISSUE') ?

Thanks~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment