Skip to main content

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"

Metadata

Release files for async-snowflake 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for async-snowflake 0.2.1
File Size Uploaded
async_snowflake-0.2.1.tar.gz 82.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for async-snowflake 0.2.1
File Interpreter ABI Platform
async_snowflake-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 127.4 kB

Release files / async_snowflake-0.2.1.tar.gz

Download URL async_snowflake-0.2.1.tar.gz
Size 82.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4c4f15560947062bdcc86e1787aafecaae453e322b3ed273ac0b5d4ddced9bbf
BLAKE2b-256 checksum
How to use checksums
5c469924b3bccd6a881321063f8642181256c409a8cec2c5599c926e7da863ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Release files / async_snowflake-0.2.1-py3-none-any.whl

Download URL async_snowflake-0.2.1-py3-none-any.whl
Size 45.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c0a41099b472ca63ba0acebba5661739813bb74f4a2c2af4c100a2d8aabebc54
BLAKE2b-256 checksum
How to use checksums
6132070ce49155a4ba9c698050639a927565b073d8cb4c0a14dd80728e63a0ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page