Key metrics and engagement data
Repository has been active for 2 years, 5 months
⭐100
Want deeper insights? Explore GitObs.com
Run, mock and test fake Snowflake databases locally.
1pip install fakesnow
Or to install with the server:
1pip install fakesnow[server]
fakesnow offers two main approaches for faking Snowflake: in-process patching of the Snowflake Connector for Python or a standalone HTTP server.
Patching only applies to the current Python process. If a subprocess is spawned it won't be patched. For subprocesses, or for non-Python clients, use the server instead.
To run script.py with patching:
shell1fakesnow script.py
Or a module, eg: pytest
shell1fakesnow -m pytest
fakesnow
executes fakesnow.patch
before running the script or module.
Alternatively, use fakesnow.patch in your code:
python1import fakesnow2import snowflake.connector34with fakesnow.patch():5 conn = snowflake.connector.connect()67 print(conn.cursor().execute("SELECT 'Hello fake world!'").fetchone())
The following standard imports are automatically patched:
import snowflake.connector.connect
import snowflake.connector.pandas_tools.write_pandas
To patch modules that use the from ... import
syntax, you need to manually specify them, eg: if mymodule.py contains:
python1from snowflake.connector.pandas_tools import write_pandas
Then patch it using:
python1with fakesnow.patch("mymodule.write_pandas"):2 ...
By default, databases are in-memory and will be lost when the process ends. To persist databases between processes, specify a databases path:
python1with fakesnow.patch(db_path="databases/"):2 ...
For scenarios where patching won't work (like subprocesses or non-Python clients), you can run fakesnow as an HTTP server.
Using uv:
1uvx 'fakesnow[server]' -s
Or from within a virtualenv that has fakesnow[server]
installed:
1fakesnow -s
By default the server listens on a random available port. Use -p
to specify a port.
python1import fakesnow2import snowflake.connector34# Start the fakesnow server in a context manager5# This yields connection kwargs (host, port, etc.)6with fakesnow.server() as conn_kwargs:7 # Connect to the fakesnow server using the yielded kwargs8 with snowflake.connector.connect(**conn_kwargs) as conn:9 print(conn.cursor().execute("SELECT 'Hello fake server!'").fetchone())1011 # The server is automatically stopped when exiting the context manager
This starts an HTTP server in its own thread listening for requests on a random available port.
To specify a port for the server:
python1with fakesnow.server(port=12345) as conn_kwargs:2 ...
By default, the server uses a single in-memory database for its lifetime. To configure database persistence or isolation:
python1# Databases will be saved to the "databases/" directory2with fakesnow.server(session_parameters={"FAKESNOW_DB_PATH": "databases/"}):3 ...45# Each connection gets its own isolated in-memory database6with fakesnow.server(session_parameters={"FAKESNOW_DB_PATH": ":isolated:"}):7 ...
The server is available via HTTP and accepts any username/password/account combination, eg:
1user: fake2password: snow3account: fakesnow4host: localhost5port: <port number from server startup>6protocol: http
Additional parameters that may be helpful:
CLIENT_OUT_OF_BAND_TELEMETRY_ENABLED
set to false
For example, with the Snowflake CLI:
1snowsql -a fakesnow -u fake -p snow -h localhost -P <port> --protocol http
fakesnow provides fixtures for easier test integration. Add them in conftest.py:
python1pytest_plugins = "fakesnow.fixtures"
To autouse the fixture you can wrap it like this in conftest.py:
python1from typing import Iterator23import pytest45pytest_plugins = "fakesnow.fixtures"67@pytest.fixture(scope="session", autouse=True)8def setup(_fakesnow_session: None) -> Iterator[None]:9 # the standard imports are now patched10 # Add any additional setup here11 yield12 # Add any teardown here
For code that uses from ... import
statements:
python1from typing import Iterator23import fakesnow4import pytest56pytest_plugins = "fakesnow.fixtures"78@pytest.fixture(scope="session", autouse=True)9def _fakesnow_session() -> Iterator[None]:10 with fakesnow.patch("mymodule.write_pandas"):11 yield
To start a fakesnow server instance, enable the plugin in conftest.py:
python1pytest_plugins = "fakesnow.fixtures"
And then use the fakesnow_server
session fixture like this:
python1import snowflake.connector23def test_with_server(fakesnow_server: dict):4 # fakesnow_server contains connection kwargs (host, port, etc.)5 with snowflake.connector.connect(**fakesnow_server) as conn:6 conn.cursor().execute("SELECT 1")7 assert conn.cursor().fetchone() == (1,)
Fully supported:
Partially supported:
COPY INTO
from S3 sources and stages, see COPY INTONot yet implemented:
For more detail see the test suite.
COPY INTO
can be used from S3 sources and stages. By default the standard AWS credential chain will be used. If you are getting an HTTP 403 or need to provide alternative S3 credentials you can use the duckdb CREATE SECRET statement. For an example of creating a secret to use a moto S3 endpoint see s3_client
in conftest.py
See CONTRIBUTING.md for instructions on getting started with development and contributing to this project.