Async Snowflake connector for Python with JWT authentication
Project description
Async Snowflake Connector for Python
An async Python connector for Snowflake using JWT authentication.
Installation
pip install async-snowflake
Quick Usage
import asyncio
from async_snowflake import SnowflakeClient, SnowflakeJWTAuthClient
async def main():
auth = SnowflakeJWTAuthClient(
account="YOUR_ACCOUNT",
user="YOUR_USER",
private_key_path="/path/to/private_key.pem",
)
async with SnowflakeClient.create(
base_url="https://your-account.snowflakecomputing.com",
auth_client=auth,
) as client:
# Execute queries
result = await client.query.execute("SELECT * FROM users LIMIT 10")
print(f"Rows: {result.rows}")
print(f"Columns: {result.columns}")
# List databases
databases = await client.database.list()
for db in databases:
print(db.name)
asyncio.run(main())
Async Queries
For long-running queries, submit the statement asynchronously and poll for completion instead of blocking on a single request:
import asyncio
# Submit the query; returns a statement handle immediately
handle = await client.query.execute_async("SELECT * FROM big_table")
# Poll until the statement finishes
status = await client.query.get_status(handle)
while status.state == "running":
await asyncio.sleep(1)
status = await client.query.get_status(handle)
# Fetch the full result set (all partitions are reassembled for you)
result = await client.query.get_results(handle)
print(f"Rows: {result.row_count}")
print(f"Columns: {result.columns}")
Streaming large result sets
get_results() loads every partition into memory. For large results, stream
them one partition (a batch of rows) at a time with generate_results(), which
keeps memory bounded:
async for partition in client.query.generate_results(handle):
for row in partition:
process(row)
Each partition fetch is retried automatically on transient connection drops.
Account names with underscores: if your account name contains underscores, the client normalizes the URL host (
_→-) so TLS verification against Snowflake's wildcard certificate succeeds. Pass your account/base URL as-is — the JWT issuer keeps the real account name intact.
Fluent Interface
# Account operations
await client.account.get_current_account()
await client.account.list_accounts()
# Database operations
await client.database.list()
await client.database.describe("my_db")
# Schema operations
await client.schema.list(database="my_db")
await client.schema.describe("my_db", "my_schema")
# Table operations
await client.table.list(database="my_db", schema="my_schema")
# Warehouse operations
await client.warehouse.list()
await client.warehouse.resume("warehouse_name")
# Query execution
result = await client.query.execute("SELECT * FROM table")
Using with FastAPI
from contextlib import asynccontextmanager
from fastapi import FastAPI
from async_snowflake import SnowflakeClient, SnowflakeJWTAuthClient
# Global client instance
snowflake_client: SnowflakeClient = None
@asynccontextmanager
async def lifespan(app: FastAPI):
global snowflake_client
auth = SnowflakeJWTAuthClient(
account="YOUR_ACCOUNT",
user="YOUR_USER",
private_key_path="/path/to/private_key.pem",
)
snowflake_client = await SnowflakeClient.create(
base_url="https://your-account.snowflakecomputing.com",
auth_client=auth,
)
yield
await snowflake_client.close()
app = FastAPI(lifespan=lifespan)
@app.get("/users")
async def get_users():
result = await snowflake_client.query.execute(
"SELECT * FROM users LIMIT 100"
)
return {"columns": result.columns, "rows": result.rows}
@app.get("/databases")
async def get_databases():
databases = await snowflake_client.database.list()
return {"databases": [db.model_dump() for db in databases]}
Configuration with Credentials File
Create a credentials.toml file:
[default]
account = "YOUR_ACCOUNT"
user = "YOUR_USER"
private_key_path = "/path/to/private_key.pem"
region = "us-east-1"
[production]
account = "PROD_ACCOUNT"
user = "admin"
private_key_path = "/path/to/prod_key.pem"
Then load with CredentialsManager:
from async_snowflake import CredentialsManager
creds = CredentialsManager(profile="default").credentials
# Use creds.account, creds.user, etc.
Or use environment variables:
export SNOWFLAKE_ACCOUNT="your_account"
export SNOWFLAKE_USER="your_user"
export SNOWFLAKE_PRIVATE_KEY_PATH="/path/to/key.pem"
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file async_snowflake-0.2.1.tar.gz.
File metadata
- Download URL: async_snowflake-0.2.1.tar.gz
- Upload date:
- Size: 82.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c4f15560947062bdcc86e1787aafecaae453e322b3ed273ac0b5d4ddced9bbf
|
|
| MD5 |
451f4f46d6564a72886534954b091347
|
|
| BLAKE2b-256 |
5c469924b3bccd6a881321063f8642181256c409a8cec2c5599c926e7da863ea
|
File details
Details for the file async_snowflake-0.2.1-py3-none-any.whl.
File metadata
- Download URL: async_snowflake-0.2.1-py3-none-any.whl
- Upload date:
- Size: 45.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0a41099b472ca63ba0acebba5661739813bb74f4a2c2af4c100a2d8aabebc54
|
|
| MD5 |
c9e4ddbe9891dc5a1d7385fe2b59d2a4
|
|
| BLAKE2b-256 |
6132070ce49155a4ba9c698050639a927565b073d8cb4c0a14dd80728e63a0ea
|