{"id":28550917,"url":"https://github.com/tekumara/fakesnow","last_synced_at":"2026-04-18T13:03:58.189Z","repository":{"id":142803647,"uuid":"601481058","full_name":"tekumara/fakesnow","owner":"tekumara","description":"Run, mock and test fake Snowflake databases locally.","archived":false,"fork":false,"pushed_at":"2026-04-11T23:52:28.000Z","size":1065,"stargazers_count":187,"open_issues_count":14,"forks_count":30,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-12T01:22:46.779Z","etag":null,"topics":["emulator","local","mock","snowflakedb","testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tekumara.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["tekumara"]}},"created_at":"2023-02-14T06:41:44.000Z","updated_at":"2026-04-11T23:52:26.000Z","dependencies_parsed_at":"2023-12-31T11:30:06.313Z","dependency_job_id":"c0b19e8c-7e55-4e6e-b400-9cf69e1c0327","html_url":"https://github.com/tekumara/fakesnow","commit_stats":null,"previous_names":[],"tags_count":75,"template":false,"template_full_name":null,"purl":"pkg:github/tekumara/fakesnow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekumara%2Ffakesnow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekumara%2Ffakesnow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekumara%2Ffakesnow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekumara%2Ffakesnow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tekumara","download_url":"https://codeload.github.com/tekumara/fakesnow/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tekumara%2Ffakesnow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31969773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["emulator","local","mock","snowflakedb","testing"],"created_at":"2025-06-10T03:10:34.098Z","updated_at":"2026-04-18T13:03:58.152Z","avatar_url":"https://github.com/tekumara.png","language":"Python","funding_links":["https://github.com/sponsors/tekumara"],"categories":[],"sub_categories":[],"readme":"# fakesnow ❄️\n\n[![ci](https://github.com/tekumara/fakesnow/actions/workflows/ci.yml/badge.svg)](https://github.com/tekumara/fakesnow/actions/workflows/ci.yml)\n[![release](https://github.com/tekumara/fakesnow/actions/workflows/release.yml/badge.svg)](https://github.com/tekumara/fakesnow/actions/workflows/release.yml)\n[![PyPI](https://img.shields.io/pypi/v/fakesnow?color=violet)](https://pypi.org/project/fakesnow/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/fakesnow?color=violet)](https://pypi.org/project/fakesnow/)\n\nRun, mock and test fake Snowflake databases locally.\n\n## Install\n\n```\npip install fakesnow\n```\n\nOr to install with the server:\n\n```\npip install fakesnow[server]\n```\n\n## Usage\n\nfakesnow offers two main approaches for faking Snowflake: [in-process patching](#in-process-patching) of the Snowflake Connector for Python or a [standalone HTTP server](#run-fakesnow-as-a-server).\n\nPatching 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.\n\n### In-process patching\n\nTo run script.py with patching:\n\n```shell\nfakesnow script.py\n```\n\nOr a module, eg: pytest\n\n```shell\nfakesnow -m pytest\n```\n\n`fakesnow` executes `fakesnow.patch` before running the script or module.\n\n#### Use fakesnow.patch in your code\n\nAlternatively, use fakesnow.patch in your code:\n\n```python\nimport fakesnow\nimport snowflake.connector\n\nwith fakesnow.patch():\n    conn = snowflake.connector.connect()\n\n    print(conn.cursor().execute(\"SELECT 'Hello fake world!'\").fetchone())\n```\n\n#### What gets patched\n\nThe following standard imports are automatically patched:\n\n- `import snowflake.connector.connect`\n- `import snowflake.connector.pandas_tools.write_pandas`\n\n#### Handling \"from ... import\" Statements\n\nTo patch modules that use the `from ... import` syntax, you need to manually specify them, eg: if _mymodule.py_ contains:\n\n```python\nfrom snowflake.connector.pandas_tools import write_pandas\n```\n\nThen patch it using:\n\n```python\nwith fakesnow.patch(\"mymodule.write_pandas\"):\n    ...\n```\n\n#### Database Persistence\n\nBy default, databases are in-memory and will be lost when the process ends. To persist databases between processes, specify a databases path:\n\n```python\nwith fakesnow.patch(db_path=\"databases/\"):\n    ...\n```\n\n### Run fakesnow as a server\n\nFor scenarios where patching won't work (like subprocesses or non-Python clients), you can run fakesnow as an HTTP server.\n\n#### From the command line\n\nUsing [uv](https://docs.astral.sh/uv/):\n\n```\nuvx 'fakesnow[server]' -s\n```\n\nOr from within a virtualenv that has `fakesnow[server]` installed:\n\n```\nfakesnow -s\n```\n\nBy default the server listens on a random available port. Use `-p` to specify a port.\n\n#### Within your python program\n\n```python\nimport fakesnow\nimport snowflake.connector\n\n# Start the fakesnow server in a context manager\n# This yields connection kwargs (host, port, etc.)\nwith fakesnow.server() as conn_kwargs:\n    # Connect to the fakesnow server using the yielded kwargs\n    with snowflake.connector.connect(**conn_kwargs) as conn:\n        print(conn.cursor().execute(\"SELECT 'Hello fake server!'\").fetchone())\n\n    # The server is automatically stopped when exiting the context manager\n```\n\nThis starts an HTTP server in its own thread listening for requests on a random available port.\n\n##### Server Configuration Options\n\nTo specify a port for the server:\n\n```python\nwith fakesnow.server(port=12345) as conn_kwargs:\n    ...\n```\n\nBy default, the server uses a single in-memory database for its lifetime. To configure database persistence or isolation:\n\n```python\n# Databases will be saved to the \"databases/\" directory\nwith fakesnow.server(session_parameters={\"FAKESNOW_DB_PATH\": \"databases/\"}):\n    ...\n\n# Each connection gets its own isolated in-memory database\nwith fakesnow.server(session_parameters={\"FAKESNOW_DB_PATH\": \":isolated:\"}):\n    ...\n```\n\n#### Connecting from non-Python clients\n\nThe server is available via HTTP and accepts any username/password/account combination, eg:\n\n```\nuser: fake\npassword: snow\naccount: fakesnow\nhost: 127.0.0.1\nport: \u003cport number from server startup\u003e\nprotocol: http\n```\n\nAdditional parameters that may be helpful:\n- Session parameter `CLIENT_OUT_OF_BAND_TELEMETRY_ENABLED` set to `false`\n- Network timeout set to 1 second (since retries aren't needed in testing)\n\n#### Connecting from the Snowflake CLI\n\nUpdate Snowflake's [config.toml](https://docs.snowflake.com/en/developer-guide/snowflake-cli/connecting/configure-cli):\n\n```toml\n[connections.fakesnow]\nhost = \"localhost\"\nport = \u003cport number from server startup\u003e\naccount = \"fakesnow\"\nuser = \"fake\"\npassword = \"snow\"\nprotocol = \"http\"\n```\n\n\u003e [!WARNING]\n\u003e Make sure to add the `protocol = http` for Fakesnow compatibility.\n\nUse the `-c` flag to specify the above connection: `snow sql -c fakesnow -q \"SELECT 'Hello World' as greeting\"`.\n\nOr set the default value using `set-default`:\n\n\n```sql\n$ snow connection set-default fakesnow\nDefault connection set to: fakesnow\n$ snow sql -q \"SELECT 'Hello World' as greeting\"\nSELECT 'Hello World' as greeting\n+-------------+\n| GREETING    |\n|-------------|\n| Hello World |\n+-------------+\n```\n\n### pytest fixtures\n\nfakesnow provides [fixtures](fakesnow/fixtures.py) for easier test integration. Add them in _conftest.py_:\n\n```python\npytest_plugins = \"fakesnow.fixtures\"\n```\n\nTo autouse the fixture you can wrap it like this in _conftest.py_:\n\n```python\nfrom typing import Iterator\n\nimport pytest\n\npytest_plugins = \"fakesnow.fixtures\"\n\n@pytest.fixture(scope=\"session\", autouse=True)\ndef setup(_fakesnow_session: None) -\u003e Iterator[None]:\n    # the standard imports are now patched\n    # Add any additional setup here\n    yield\n    # Add any teardown here\n```\n\nFor code that uses `from ... import` statements:\n\n```python\nfrom typing import Iterator\n\nimport fakesnow\nimport pytest\n\npytest_plugins = \"fakesnow.fixtures\"\n\n@pytest.fixture(scope=\"session\", autouse=True)\ndef _fakesnow_session() -\u003e Iterator[None]:\n    with fakesnow.patch(\"mymodule.write_pandas\"):\n        yield\n```\n\n#### server fixture\n\nTo start a fakesnow server instance, enable the plugin in _conftest.py_:\n\n```python\npytest_plugins = \"fakesnow.fixtures\"\n```\n\nAnd then use the `fakesnow_server` session fixture like this:\n\n```python\nimport snowflake.connector\n\ndef test_with_server(fakesnow_server: dict):\n    # fakesnow_server contains connection kwargs (host, port, etc.)\n    with snowflake.connector.connect(**fakesnow_server) as conn:\n        conn.cursor().execute(\"SELECT 1\")\n        assert conn.cursor().fetchone() == (1,)\n```\n\n## Implementation coverage\n\nFully supported:\n\n- Standard SQL operations and cursors\n- Information schema queries\n- Multiple databases\n- [Parameter binding](https://docs.snowflake.com/en/user-guide/python-connector-example#binding-data) in queries\n- Table comments\n- Pandas integration including [write_pandas(..)](https://docs.snowflake.com/en/user-guide/python-connector-api#write_pandas)\n- Result batch retrieval via [get_result_batches()](https://docs.snowflake.com/en/user-guide/python-connector-api#get_result_batches)\n- HTTP server for non-Python connectors\n\nPartially supported:\n\n- Date functions\n- Regular expression functions\n- Semi-structured data operations\n- Tags\n- User management\n- Stages and PUT\n- `COPY INTO` from S3 sources and stages, see [COPY INTO](#copy-into)\n\nNot yet implemented:\n\n- [Access control](https://docs.snowflake.com/en/user-guide/security-access-control-overview)\n- [Stored procedures](https://docs.snowflake.com/en/sql-reference/stored-procedures)\n\nFor more detail see the [test suite](tests/).\n\n## Caveats\n\n- Row ordering is non-deterministic and may differ from Snowflake unless you fully specify the ORDER BY clause.\n- fakesnow supports a more liberal SQL dialect than actual Snowflake. This means some queries that work with fakesnow might not work with a real Snowflake instance.\n\n## COPY INTO\n\n`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](https://duckdb.org/docs/stable/extensions/httpfs/s3api) statement. For an example of creating a secret to use a moto S3 endpoint see `s3_client` in [conftest.py](tests/conftest.py#L80)\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for instructions on getting started with development and contributing to this project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftekumara%2Ffakesnow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftekumara%2Ffakesnow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftekumara%2Ffakesnow/lists"}