pydatarheo 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pydatarheo-0.1.0/.cache/01M2B83MDT7K3B30H4XHB75WZE/db_01M2B83MDT7K3B30H4XHB75WZE.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B83METTTKQA9DS10FSAW0M/db_01M2B83METTTKQA9DS10FSAW0M.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B83MF54V1WB2VYR36ZQRTD/db_01M2B83MF54V1WB2VYR36ZQRTD.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B83MFGRP7RXF53YB9KWMPF/db_01M2B83MFGRP7RXF53YB9KWMPF.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B85Z0SZTS8B3ZSSB1P88JH/db_01M2B85Z0SZTS8B3ZSSB1P88JH.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B85Z1HAD6FWHYKYVMFSPW3/db_01M2B85Z1HAD6FWHYKYVMFSPW3.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B85Z1W0KTNDXNN3MFKAEG1/db_01M2B85Z1W0KTNDXNN3MFKAEG1.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B85Z267F7XS3RFSGDMF81K/db_01M2B85Z267F7XS3RFSGDMF81K.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8871MV4504KDS6B4V4FN4/db_01M2B8871MV4504KDS6B4V4FN4.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8872AY9X701MJR9ZK9SCJ/db_01M2B8872AY9X701MJR9ZK9SCJ.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8872N8V4HQGZP6PYEWRRR/db_01M2B8872N8V4HQGZP6PYEWRRR.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B88730AAS1R2QSJAPQTTZC/db_01M2B88730AAS1R2QSJAPQTTZC.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8BW13HT58FK2NEFE66FQD/db_01M2B8BW13HT58FK2NEFE66FQD.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DFG10JX0V90XGVY3RDZJ/db_01M2B8DFG10JX0V90XGVY3RDZJ.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DFHFM0GJS5EMBT0ZJ0JH/db_01M2B8DFHFM0GJS5EMBT0ZJ0JH.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DFHVCZVC21FMP9S6HGEC/db_01M2B8DFHVCZVC21FMP9S6HGEC.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DFJ7H4GWV8PN2EXBX0TS/db_01M2B8DFJ7H4GWV8PN2EXBX0TS.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DFJHPPV36VHYCR1D1D8T/db_01M2B8DFJHPPV36VHYCR1D1D8T.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DTN91R517F2XS3APKYZJ/db_01M2B8DTN91R517F2XS3APKYZJ.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DTNYPRXY25VNWEYJTY8N/db_01M2B8DTNYPRXY25VNWEYJTY8N.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DTP9BJQS2EHYYAH4W3HD/db_01M2B8DTP9BJQS2EHYYAH4W3HD.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DTPNZJT1YEBHTG8S2KRD/db_01M2B8DTPNZJT1YEBHTG8S2KRD.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8DTQ08NXX4PC3G9RH549P/db_01M2B8DTQ08NXX4PC3G9RH549P.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8X84BR8VP5EV8F4J9PBVY/db_01M2B8X84BR8VP5EV8F4J9PBVY.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8X85KJYHRGRWF4HEM47RD/db_01M2B8X85KJYHRGRWF4HEM47RD.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8X85ZC0RZST8JF3MHK4CA/db_01M2B8X85ZC0RZST8JF3MHK4CA.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8X86BAG4QR8FXX748VV23/db_01M2B8X86BAG4QR8FXX748VV23.duckdb +0 -0
- pydatarheo-0.1.0/.cache/01M2B8X86NKYAHMZK940MB6RZT/db_01M2B8X86NKYAHMZK940MB6RZT.duckdb +0 -0
- pydatarheo-0.1.0/.cache/default_cache/default_cache.duckdb +0 -0
- pydatarheo-0.1.0/.cache/unit_tests/test_db.duckdb +0 -0
- pydatarheo-0.1.0/.github/workflows/docs.yml +70 -0
- pydatarheo-0.1.0/.github/workflows/publish.yml +74 -0
- pydatarheo-0.1.0/.gitignore +29 -0
- pydatarheo-0.1.0/AGENTS.md +28 -0
- pydatarheo-0.1.0/CONTRIBUTING.md +17 -0
- pydatarheo-0.1.0/Dockerfile.mcp +25 -0
- pydatarheo-0.1.0/LICENSE +22 -0
- pydatarheo-0.1.0/NOTICE +26 -0
- pydatarheo-0.1.0/PKG-INFO +238 -0
- pydatarheo-0.1.0/README.md +173 -0
- pydatarheo-0.1.0/datarheo/__init__.py +230 -0
- pydatarheo-0.1.0/datarheo/_batch_handles.py +85 -0
- pydatarheo-0.1.0/datarheo/_connector_base.py +513 -0
- pydatarheo-0.1.0/datarheo/_executors/__init__.py +2 -0
- pydatarheo-0.1.0/datarheo/_executors/base.py +261 -0
- pydatarheo-0.1.0/datarheo/_executors/declarative.py +182 -0
- pydatarheo-0.1.0/datarheo/_executors/docker.py +127 -0
- pydatarheo-0.1.0/datarheo/_executors/local.py +63 -0
- pydatarheo-0.1.0/datarheo/_executors/noop.py +136 -0
- pydatarheo-0.1.0/datarheo/_executors/python.py +344 -0
- pydatarheo-0.1.0/datarheo/_executors/util.py +397 -0
- pydatarheo-0.1.0/datarheo/_message_iterators.py +207 -0
- pydatarheo-0.1.0/datarheo/_processors/__init__.py +4 -0
- pydatarheo-0.1.0/datarheo/_processors/sql/__init__.py +2 -0
- pydatarheo-0.1.0/datarheo/_processors/sql/bigquery.py +306 -0
- pydatarheo-0.1.0/datarheo/_processors/sql/duckdb.py +184 -0
- pydatarheo-0.1.0/datarheo/_processors/sql/motherduck.py +44 -0
- pydatarheo-0.1.0/datarheo/_processors/sql/postgres.py +75 -0
- pydatarheo-0.1.0/datarheo/_processors/sql/snowflake.py +285 -0
- pydatarheo-0.1.0/datarheo/_registry_utils.py +121 -0
- pydatarheo-0.1.0/datarheo/_util/__init__.py +16 -0
- pydatarheo-0.1.0/datarheo/_util/api_duck_types.py +21 -0
- pydatarheo-0.1.0/datarheo/_util/api_imports.py +44 -0
- pydatarheo-0.1.0/datarheo/_util/api_util.py +2997 -0
- pydatarheo-0.1.0/datarheo/_util/connector_info.py +30 -0
- pydatarheo-0.1.0/datarheo/_util/destination_smoke_tests.py +609 -0
- pydatarheo-0.1.0/datarheo/_util/document_rendering.py +95 -0
- pydatarheo-0.1.0/datarheo/_util/hashing.py +35 -0
- pydatarheo-0.1.0/datarheo/_util/meta.py +195 -0
- pydatarheo-0.1.0/datarheo/_util/name_normalizers.py +93 -0
- pydatarheo-0.1.0/datarheo/_util/pip_util.py +57 -0
- pydatarheo-0.1.0/datarheo/_util/registry_spec.py +147 -0
- pydatarheo-0.1.0/datarheo/_util/telemetry.py +327 -0
- pydatarheo-0.1.0/datarheo/_util/temp_files.py +66 -0
- pydatarheo-0.1.0/datarheo/_util/text_util.py +22 -0
- pydatarheo-0.1.0/datarheo/_util/venv_util.py +20 -0
- pydatarheo-0.1.0/datarheo/_writers/__init__.py +14 -0
- pydatarheo-0.1.0/datarheo/_writers/base.py +88 -0
- pydatarheo-0.1.0/datarheo/_writers/file_writers.py +285 -0
- pydatarheo-0.1.0/datarheo/_writers/jsonl.py +59 -0
- pydatarheo-0.1.0/datarheo/agents/__init__.py +132 -0
- pydatarheo-0.1.0/datarheo/agents/_api_util.py +285 -0
- pydatarheo-0.1.0/datarheo/agents/connectors.py +370 -0
- pydatarheo-0.1.0/datarheo/agents/models.py +207 -0
- pydatarheo-0.1.0/datarheo/agents/organizations.py +245 -0
- pydatarheo-0.1.0/datarheo/agents/workspaces.py +248 -0
- pydatarheo-0.1.0/datarheo/caches/__init__.py +42 -0
- pydatarheo-0.1.0/datarheo/caches/_catalog_backend.py +278 -0
- pydatarheo-0.1.0/datarheo/caches/_state_backend.py +278 -0
- pydatarheo-0.1.0/datarheo/caches/_state_backend_base.py +69 -0
- pydatarheo-0.1.0/datarheo/caches/_utils/__init__.py +2 -0
- pydatarheo-0.1.0/datarheo/caches/_utils/_cache_to_dest.py +133 -0
- pydatarheo-0.1.0/datarheo/caches/_utils/_dest_to_cache.py +277 -0
- pydatarheo-0.1.0/datarheo/caches/base.py +477 -0
- pydatarheo-0.1.0/datarheo/caches/bigquery.py +72 -0
- pydatarheo-0.1.0/datarheo/caches/duckdb.py +61 -0
- pydatarheo-0.1.0/datarheo/caches/generic.py +20 -0
- pydatarheo-0.1.0/datarheo/caches/motherduck.py +89 -0
- pydatarheo-0.1.0/datarheo/caches/postgres.py +68 -0
- pydatarheo-0.1.0/datarheo/caches/snowflake.py +94 -0
- pydatarheo-0.1.0/datarheo/caches/util.py +166 -0
- pydatarheo-0.1.0/datarheo/callbacks.py +50 -0
- pydatarheo-0.1.0/datarheo/cli/__init__.py +7 -0
- pydatarheo-0.1.0/datarheo/cli/pydr.py +779 -0
- pydatarheo-0.1.0/datarheo/cli/smoke_test_source/__init__.py +18 -0
- pydatarheo-0.1.0/datarheo/cli/smoke_test_source/_scenarios.py +762 -0
- pydatarheo-0.1.0/datarheo/cli/smoke_test_source/run.py +17 -0
- pydatarheo-0.1.0/datarheo/cli/smoke_test_source/source.py +414 -0
- pydatarheo-0.1.0/datarheo/cloud/__init__.py +138 -0
- pydatarheo-0.1.0/datarheo/cloud/_case_conversion.py +55 -0
- pydatarheo-0.1.0/datarheo/cloud/_connection_catalog.py +98 -0
- pydatarheo-0.1.0/datarheo/cloud/_connection_state.py +274 -0
- pydatarheo-0.1.0/datarheo/cloud/_credentials.py +137 -0
- pydatarheo-0.1.0/datarheo/cloud/auth.py +84 -0
- pydatarheo-0.1.0/datarheo/cloud/client.py +1103 -0
- pydatarheo-0.1.0/datarheo/cloud/client_config.py +202 -0
- pydatarheo-0.1.0/datarheo/cloud/connections.py +1006 -0
- pydatarheo-0.1.0/datarheo/cloud/connectors.py +908 -0
- pydatarheo-0.1.0/datarheo/cloud/constants.py +26 -0
- pydatarheo-0.1.0/datarheo/cloud/models.py +343 -0
- pydatarheo-0.1.0/datarheo/cloud/organizations.py +116 -0
- pydatarheo-0.1.0/datarheo/cloud/sync_results.py +512 -0
- pydatarheo-0.1.0/datarheo/cloud/workspaces.py +951 -0
- pydatarheo-0.1.0/datarheo/constants.py +437 -0
- pydatarheo-0.1.0/datarheo/datasets/__init__.py +18 -0
- pydatarheo-0.1.0/datarheo/datasets/_base.py +84 -0
- pydatarheo-0.1.0/datarheo/datasets/_inmemory.py +45 -0
- pydatarheo-0.1.0/datarheo/datasets/_lazy.py +73 -0
- pydatarheo-0.1.0/datarheo/datasets/_map.py +32 -0
- pydatarheo-0.1.0/datarheo/datasets/_sql.py +231 -0
- pydatarheo-0.1.0/datarheo/destinations/__init__.py +101 -0
- pydatarheo-0.1.0/datarheo/destinations/base.py +367 -0
- pydatarheo-0.1.0/datarheo/destinations/util.py +122 -0
- pydatarheo-0.1.0/datarheo/documents.py +62 -0
- pydatarheo-0.1.0/datarheo/exceptions.py +707 -0
- pydatarheo-0.1.0/datarheo/experimental/__init__.py +27 -0
- pydatarheo-0.1.0/datarheo/logs.py +345 -0
- pydatarheo-0.1.0/datarheo/mcp/__init__.py +333 -0
- pydatarheo-0.1.0/datarheo/mcp/_arg_resolvers.py +205 -0
- pydatarheo-0.1.0/datarheo/mcp/_client_credentials.py +71 -0
- pydatarheo-0.1.0/datarheo/mcp/_config.py +91 -0
- pydatarheo-0.1.0/datarheo/mcp/_guards.py +49 -0
- pydatarheo-0.1.0/datarheo/mcp/_tool_utils.py +590 -0
- pydatarheo-0.1.0/datarheo/mcp/_transport_security.py +129 -0
- pydatarheo-0.1.0/datarheo/mcp/agents.py +759 -0
- pydatarheo-0.1.0/datarheo/mcp/cloud.py +2950 -0
- pydatarheo-0.1.0/datarheo/mcp/http_main.py +287 -0
- pydatarheo-0.1.0/datarheo/mcp/interactive/__init__.py +31 -0
- pydatarheo-0.1.0/datarheo/mcp/interactive/_registry_ui.py +550 -0
- pydatarheo-0.1.0/datarheo/mcp/interactive/_shared_models.py +127 -0
- pydatarheo-0.1.0/datarheo/mcp/interactive/_sync_history_ui.py +412 -0
- pydatarheo-0.1.0/datarheo/mcp/interactive/_workspace_sync_status_ui.py +764 -0
- pydatarheo-0.1.0/datarheo/mcp/local.py +1011 -0
- pydatarheo-0.1.0/datarheo/mcp/prompts.py +87 -0
- pydatarheo-0.1.0/datarheo/mcp/registry.py +297 -0
- pydatarheo-0.1.0/datarheo/mcp/server.py +412 -0
- pydatarheo-0.1.0/datarheo/progress.py +1039 -0
- pydatarheo-0.1.0/datarheo/py.typed +0 -0
- pydatarheo-0.1.0/datarheo/records.py +321 -0
- pydatarheo-0.1.0/datarheo/registry.py +620 -0
- pydatarheo-0.1.0/datarheo/results.py +144 -0
- pydatarheo-0.1.0/datarheo/secrets/__init__.py +146 -0
- pydatarheo-0.1.0/datarheo/secrets/base.py +267 -0
- pydatarheo-0.1.0/datarheo/secrets/config.py +75 -0
- pydatarheo-0.1.0/datarheo/secrets/custom.py +60 -0
- pydatarheo-0.1.0/datarheo/secrets/env_vars.py +71 -0
- pydatarheo-0.1.0/datarheo/secrets/google_colab.py +37 -0
- pydatarheo-0.1.0/datarheo/secrets/google_gsm.py +304 -0
- pydatarheo-0.1.0/datarheo/secrets/hydration.py +171 -0
- pydatarheo-0.1.0/datarheo/secrets/prompt.py +28 -0
- pydatarheo-0.1.0/datarheo/secrets/util.py +149 -0
- pydatarheo-0.1.0/datarheo/shared/__init__.py +16 -0
- pydatarheo-0.1.0/datarheo/shared/catalog_providers.py +226 -0
- pydatarheo-0.1.0/datarheo/shared/sql_processor.py +1393 -0
- pydatarheo-0.1.0/datarheo/shared/state_providers.py +169 -0
- pydatarheo-0.1.0/datarheo/shared/state_writers.py +96 -0
- pydatarheo-0.1.0/datarheo/sources/__init__.py +43 -0
- pydatarheo-0.1.0/datarheo/sources/base.py +1006 -0
- pydatarheo-0.1.0/datarheo/sources/registry.py +25 -0
- pydatarheo-0.1.0/datarheo/sources/util.py +195 -0
- pydatarheo-0.1.0/datarheo/strategies.py +92 -0
- pydatarheo-0.1.0/datarheo/types.py +163 -0
- pydatarheo-0.1.0/datarheo/validate.py +179 -0
- pydatarheo-0.1.0/datarheo/version.py +20 -0
- pydatarheo-0.1.0/docs/.gitignore +1 -0
- pydatarheo-0.1.0/docs/CONTRIBUTING.md +178 -0
- pydatarheo-0.1.0/docs/brand/datarheo-mark.svg +14 -0
- pydatarheo-0.1.0/docs/brand/pydatarheo-logo.svg +17 -0
- pydatarheo-0.1.0/docs/faq.md +47 -0
- pydatarheo-0.1.0/docs/generate.py +165 -0
- pydatarheo-0.1.0/docs/mcp-generated/agents.md +913 -0
- pydatarheo-0.1.0/docs/mcp-generated/cloud.md +4373 -0
- pydatarheo-0.1.0/docs/mcp-generated/index.md +59 -0
- pydatarheo-0.1.0/docs/mcp-generated/interactive.md +239 -0
- pydatarheo-0.1.0/docs/mcp-generated/local.md +1799 -0
- pydatarheo-0.1.0/docs/mcp-generated/misc.md +22 -0
- pydatarheo-0.1.0/docs/mcp-generated/prompts.md +18 -0
- pydatarheo-0.1.0/docs/mcp-generated/registry.md +683 -0
- pydatarheo-0.1.0/docs/templates/custom.css +276 -0
- pydatarheo-0.1.0/docs/templates/theme.css +46 -0
- pydatarheo-0.1.0/examples/pyproject.toml +13 -0
- pydatarheo-0.1.0/examples/run_bigquery_destination.py +59 -0
- pydatarheo-0.1.0/examples/run_bigquery_faker.py +67 -0
- pydatarheo-0.1.0/examples/run_declarative_manifest_source.py +181 -0
- pydatarheo-0.1.0/examples/run_downloadable_yaml_source.py +55 -0
- pydatarheo-0.1.0/examples/run_faker.py +35 -0
- pydatarheo-0.1.0/examples/run_faker_samples.py +18 -0
- pydatarheo-0.1.0/examples/run_faker_to_motherduck.py +41 -0
- pydatarheo-0.1.0/examples/run_file_source.py +23 -0
- pydatarheo-0.1.0/examples/run_get_documents_from_github.py +34 -0
- pydatarheo-0.1.0/examples/run_github.py +38 -0
- pydatarheo-0.1.0/examples/run_github_samples.py +39 -0
- pydatarheo-0.1.0/examples/run_gsm_connector_secret_fetch.py +63 -0
- pydatarheo-0.1.0/examples/run_integ_test_source.py +89 -0
- pydatarheo-0.1.0/examples/run_perf_test_reads.py +288 -0
- pydatarheo-0.1.0/examples/run_pokeapi.py +25 -0
- pydatarheo-0.1.0/examples/run_snowflake_faker.py +53 -0
- pydatarheo-0.1.0/examples/run_spacex.py +32 -0
- pydatarheo-0.1.0/examples/run_sync_to_destination_from_read_result.py +70 -0
- pydatarheo-0.1.0/examples/run_sync_to_destination_w_cache.py +62 -0
- pydatarheo-0.1.0/examples/run_sync_to_destination_wo_cache.py +77 -0
- pydatarheo-0.1.0/examples/run_test_source.py +32 -0
- pydatarheo-0.1.0/examples/run_test_source_single_stream.py +22 -0
- pydatarheo-0.1.0/pyproject.toml +234 -0
- pydatarheo-0.1.0/pyrefly.toml +16 -0
- pydatarheo-0.1.0/scripts/generate_mcp_markdown.py +759 -0
- pydatarheo-0.1.0/tests/conftest.py +323 -0
- pydatarheo-0.1.0/tests/docs_tests/__init__.py +0 -0
- pydatarheo-0.1.0/tests/docs_tests/test_docs_checked_in.py +27 -0
- pydatarheo-0.1.0/tests/integration_tests/__init__.py +0 -0
- pydatarheo-0.1.0/tests/integration_tests/cloud/__init__.py +0 -0
- pydatarheo-0.1.0/tests/integration_tests/cloud/conftest.py +210 -0
- pydatarheo-0.1.0/tests/integration_tests/cloud/test_cloud_api_util.py +413 -0
- pydatarheo-0.1.0/tests/integration_tests/cloud/test_cloud_sql_reads.py +210 -0
- pydatarheo-0.1.0/tests/integration_tests/cloud/test_cloud_sync.py +108 -0
- pydatarheo-0.1.0/tests/integration_tests/cloud/test_cloud_workspaces.py +100 -0
- pydatarheo-0.1.0/tests/integration_tests/cloud/test_custom_definitions.py +169 -0
- pydatarheo-0.1.0/tests/integration_tests/conftest.py +211 -0
- pydatarheo-0.1.0/tests/integration_tests/destinations/__init__.py +0 -0
- pydatarheo-0.1.0/tests/integration_tests/destinations/test_source_to_destination.py +158 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/invalid_config.json +1 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/registry.json +87 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/source-broken/metadata.yaml +17 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/source-broken/setup.py +20 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/source-broken/source_broken/run.py +6 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/source-test/metadata.yaml +17 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/source-test/setup.py +20 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/source-test/source_test/__init__.py +0 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/source-test/source_test/run.py +217 -0
- pydatarheo-0.1.0/tests/integration_tests/fixtures/valid_config.json +1 -0
- pydatarheo-0.1.0/tests/integration_tests/secrets/__init__.py +0 -0
- pydatarheo-0.1.0/tests/integration_tests/secrets/test_gsm_secrets.py +53 -0
- pydatarheo-0.1.0/tests/integration_tests/test_all_cache_types.py +318 -0
- pydatarheo-0.1.0/tests/integration_tests/test_bigquery_cache.py +26 -0
- pydatarheo-0.1.0/tests/integration_tests/test_config_change_callback.py +106 -0
- pydatarheo-0.1.0/tests/integration_tests/test_docker_executable.py +208 -0
- pydatarheo-0.1.0/tests/integration_tests/test_duckdb_cache.py +161 -0
- pydatarheo-0.1.0/tests/integration_tests/test_install.py +29 -0
- pydatarheo-0.1.0/tests/integration_tests/test_registry_spec.py +88 -0
- pydatarheo-0.1.0/tests/integration_tests/test_source_faker_integration.py +305 -0
- pydatarheo-0.1.0/tests/integration_tests/test_source_test_fixture.py +947 -0
- pydatarheo-0.1.0/tests/integration_tests/test_state_handling.py +222 -0
- pydatarheo-0.1.0/tests/integration_tests/test_validation.py +50 -0
- pydatarheo-0.1.0/tests/lint_tests/__init__.py +0 -0
- pydatarheo-0.1.0/tests/lint_tests/test_mypy.py +23 -0
- pydatarheo-0.1.0/tests/lint_tests/test_ruff.py +55 -0
- pydatarheo-0.1.0/tests/pyproject.toml +13 -0
- pydatarheo-0.1.0/tests/unit_tests/__init__.py +0 -0
- pydatarheo-0.1.0/tests/unit_tests/sources/test_source_key_overrides.py +261 -0
- pydatarheo-0.1.0/tests/unit_tests/test_agents.py +771 -0
- pydatarheo-0.1.0/tests/unit_tests/test_anonymous_usage_stats.py +197 -0
- pydatarheo-0.1.0/tests/unit_tests/test_caches.py +63 -0
- pydatarheo-0.1.0/tests/unit_tests/test_case_conversion.py +121 -0
- pydatarheo-0.1.0/tests/unit_tests/test_cli.py +98 -0
- pydatarheo-0.1.0/tests/unit_tests/test_cloud_api_roots.py +95 -0
- pydatarheo-0.1.0/tests/unit_tests/test_cloud_api_util.py +1132 -0
- pydatarheo-0.1.0/tests/unit_tests/test_cloud_client.py +729 -0
- pydatarheo-0.1.0/tests/unit_tests/test_cloud_connections.py +276 -0
- pydatarheo-0.1.0/tests/unit_tests/test_cloud_credentials.py +1750 -0
- pydatarheo-0.1.0/tests/unit_tests/test_cloud_models.py +107 -0
- pydatarheo-0.1.0/tests/unit_tests/test_connection_catalog.py +113 -0
- pydatarheo-0.1.0/tests/unit_tests/test_connection_state.py +456 -0
- pydatarheo-0.1.0/tests/unit_tests/test_constants.py +47 -0
- pydatarheo-0.1.0/tests/unit_tests/test_declarative_executor.py +114 -0
- pydatarheo-0.1.0/tests/unit_tests/test_docker_executor.py +75 -0
- pydatarheo-0.1.0/tests/unit_tests/test_exceptions.py +148 -0
- pydatarheo-0.1.0/tests/unit_tests/test_lowcode_connectors.py +42 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_agents.py +858 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_auth.py +427 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_cloud.py +529 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_connector_registry.py +603 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_docs_includes.py +76 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_http.py +267 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_http_main.py +191 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_telemetry.py +220 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_tool_filters.py +219 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_tool_utils.py +168 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_transport_security.py +124 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_trusted_execution.py +299 -0
- pydatarheo-0.1.0/tests/unit_tests/test_mcp_workspace_sync_status.py +279 -0
- pydatarheo-0.1.0/tests/unit_tests/test_pip_helpers.py +85 -0
- pydatarheo-0.1.0/tests/unit_tests/test_processors.py +75 -0
- pydatarheo-0.1.0/tests/unit_tests/test_progress.py +176 -0
- pydatarheo-0.1.0/tests/unit_tests/test_public_api_imports.py +182 -0
- pydatarheo-0.1.0/tests/unit_tests/test_snowflake_config.py +527 -0
- pydatarheo-0.1.0/tests/unit_tests/test_text_normalization.py +239 -0
- pydatarheo-0.1.0/tests/unit_tests/test_type_translation.py +172 -0
- pydatarheo-0.1.0/uv.lock +4739 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
name: Publish docs
|
|
2
|
+
|
|
3
|
+
# The API reference is generated from the source by pdoc, so it is rebuilt on
|
|
4
|
+
# every release and on every push to main rather than being checked in.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
tags: ["v*"]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
# Allow one docs deployment at a time. A queued run waits rather than cancelling,
|
|
12
|
+
# so a release build is never dropped in favour of a later push to main.
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: false
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
pages: write
|
|
20
|
+
id-token: write
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
build:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
outputs:
|
|
26
|
+
pages_ready: ${{ steps.configure_pages.outcome == 'success' }}
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0 # uv-dynamic-versioning needs full history and tags.
|
|
31
|
+
|
|
32
|
+
- uses: astral-sh/setup-uv@v5
|
|
33
|
+
with:
|
|
34
|
+
enable-cache: true
|
|
35
|
+
|
|
36
|
+
- name: Install dependencies
|
|
37
|
+
run: uv sync
|
|
38
|
+
|
|
39
|
+
- name: Generate API reference
|
|
40
|
+
run: uv run poe docs-generate
|
|
41
|
+
|
|
42
|
+
- name: Fail if the generated docs are empty
|
|
43
|
+
run: test -s docs/generated/datarheo.html
|
|
44
|
+
|
|
45
|
+
# GitHub's workflow token can deploy to an existing Pages site, but it may not
|
|
46
|
+
# be allowed to create one for the repository. Keep the docs build green and
|
|
47
|
+
# only deploy when Pages is already enabled.
|
|
48
|
+
- id: configure_pages
|
|
49
|
+
continue-on-error: true
|
|
50
|
+
uses: actions/configure-pages@v5
|
|
51
|
+
with:
|
|
52
|
+
enablement: true
|
|
53
|
+
- name: Skip deploy when Pages is unavailable
|
|
54
|
+
if: steps.configure_pages.outcome != 'success'
|
|
55
|
+
run: echo "::warning::Skipping GitHub Pages deployment because this workflow cannot enable Pages for the repository."
|
|
56
|
+
- uses: actions/upload-pages-artifact@v3
|
|
57
|
+
if: steps.configure_pages.outcome == 'success'
|
|
58
|
+
with:
|
|
59
|
+
path: docs/generated
|
|
60
|
+
|
|
61
|
+
deploy:
|
|
62
|
+
if: needs.build.outputs.pages_ready == 'true'
|
|
63
|
+
needs: build
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
environment:
|
|
66
|
+
name: github-pages
|
|
67
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
68
|
+
steps:
|
|
69
|
+
- id: deployment
|
|
70
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Publishing is triggered by pushing a version tag, so the released version is
|
|
4
|
+
# always the tag itself. `uv-dynamic-versioning` derives the package version
|
|
5
|
+
# from that tag, which is why no version is written in pyproject.toml.
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
tags:
|
|
9
|
+
- "v*"
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
inputs:
|
|
12
|
+
target:
|
|
13
|
+
description: "Where to publish"
|
|
14
|
+
required: true
|
|
15
|
+
default: testpypi
|
|
16
|
+
type: choice
|
|
17
|
+
options: [testpypi, pypi]
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
build:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0 # uv-dynamic-versioning needs full history and tags.
|
|
26
|
+
|
|
27
|
+
- uses: astral-sh/setup-uv@v5
|
|
28
|
+
with:
|
|
29
|
+
enable-cache: true
|
|
30
|
+
|
|
31
|
+
- name: Build sdist and wheel
|
|
32
|
+
run: uv build
|
|
33
|
+
|
|
34
|
+
- name: Verify the wheel imports from a clean environment
|
|
35
|
+
run: |
|
|
36
|
+
uv venv -p 3.11 /tmp/verify
|
|
37
|
+
VIRTUAL_ENV=/tmp/verify uv pip install dist/*.whl
|
|
38
|
+
/tmp/verify/bin/python -c "import datarheo; print(datarheo.__name__, 'ok')"
|
|
39
|
+
/tmp/verify/bin/pydr --help > /dev/null
|
|
40
|
+
|
|
41
|
+
- uses: actions/upload-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: dist
|
|
44
|
+
path: dist/
|
|
45
|
+
|
|
46
|
+
publish-testpypi:
|
|
47
|
+
needs: build
|
|
48
|
+
if: github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
environment: testpypi
|
|
51
|
+
permissions:
|
|
52
|
+
id-token: write # Required for Trusted Publishing; no API token is stored.
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/download-artifact@v4
|
|
55
|
+
with:
|
|
56
|
+
name: dist
|
|
57
|
+
path: dist/
|
|
58
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
59
|
+
with:
|
|
60
|
+
repository-url: https://test.pypi.org/legacy/
|
|
61
|
+
|
|
62
|
+
publish-pypi:
|
|
63
|
+
needs: build
|
|
64
|
+
if: github.event_name == 'push' || inputs.target == 'pypi'
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
environment: pypi
|
|
67
|
+
permissions:
|
|
68
|
+
id-token: write # Required for Trusted Publishing; no API token is stored.
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/download-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: dist
|
|
73
|
+
path: dist/
|
|
74
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.Python
|
|
6
|
+
|
|
7
|
+
# Build artifacts
|
|
8
|
+
/build/
|
|
9
|
+
/dist/
|
|
10
|
+
/htmlcov/
|
|
11
|
+
.coverage
|
|
12
|
+
coverage.xml
|
|
13
|
+
|
|
14
|
+
# Environments
|
|
15
|
+
.venv/
|
|
16
|
+
/venv/
|
|
17
|
+
.env
|
|
18
|
+
|
|
19
|
+
# Tooling caches
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
.pyre/
|
|
24
|
+
.viztracer/
|
|
25
|
+
|
|
26
|
+
# Local secrets
|
|
27
|
+
/secrets/
|
|
28
|
+
*.env
|
|
29
|
+
!*.env.example
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Agents
|
|
2
|
+
|
|
3
|
+
Notes for AI agents working in this repository.
|
|
4
|
+
|
|
5
|
+
## Naming
|
|
6
|
+
|
|
7
|
+
This project is **PyDataRheo**. The import package is `datarheo`, the PyPI distribution is
|
|
8
|
+
`pydatarheo`, and the CLI entry points are `pydatarheo` / `pydr` and `datarheo-mcp`.
|
|
9
|
+
|
|
10
|
+
References to **Airbyte** are deliberate and should not be renamed. They name external systems
|
|
11
|
+
that PyDataRheo integrates with: the Airbyte protocol and its message classes, the `airbyte-cdk`
|
|
12
|
+
/ `airbyte-api` / `airbyte-protocol-models-pdv2` packages, the public connector registry, and the
|
|
13
|
+
Airbyte Cloud API. Renaming those would either break imports or make the documentation wrong.
|
|
14
|
+
|
|
15
|
+
Everything that names *this* project uses the DataRheo name: exception classes (`DataRheoError`
|
|
16
|
+
and friends), environment variables (`DATARHEO_*`), cache metadata columns (`_datarheo_raw_id`,
|
|
17
|
+
`_datarheo_extracted_at`, `_datarheo_meta`), and the default cache schema (`datarheo_raw`).
|
|
18
|
+
|
|
19
|
+
## MCP UI Development
|
|
20
|
+
|
|
21
|
+
When adding or changing MCP tools that return UI elements:
|
|
22
|
+
|
|
23
|
+
- Name UI-first tools with a `show_` prefix.
|
|
24
|
+
- Return bounded agent-readable text plus structured UI content.
|
|
25
|
+
- Make any capped agent preview explicit, because the agent cannot see the user-facing UI.
|
|
26
|
+
- Verify the server-side payload contract.
|
|
27
|
+
- Capture human-reviewable evidence with MCPJam or Goose Desktop when retesting is requested,
|
|
28
|
+
including the rendered widget and any important UI interaction.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to PyDataRheo!
|
|
4
|
+
|
|
5
|
+
## Docstring Style
|
|
6
|
+
|
|
7
|
+
Use **Markdown** formatting in all docstrings — not reStructuredText (reST).
|
|
8
|
+
|
|
9
|
+
- Use single backticks for inline code: `` `MyClass` ``, not double backticks (` ``MyClass`` `).
|
|
10
|
+
- Reference methods as `` `get_column_info()` ``, not `:meth:\`get_column_info\``.
|
|
11
|
+
- Use standard Markdown for emphasis, lists, and links.
|
|
12
|
+
|
|
13
|
+
## 🚀 Releasing
|
|
14
|
+
|
|
15
|
+
This project uses [`semantic-pr-release-drafter`](https://github.com/aaronsteers/semantic-pr-release-drafter) for automated release management. To release, simply click "`Edit`" on the latest release draft from the [releases page](https://github.com/Vrahad-Analytics/pydatarheo/releases), and then click "`Publish release`". This publish operation will trigger all necessary downstream publish operations.
|
|
16
|
+
|
|
17
|
+
ℹ️ For more detailed instructions, please see the [Releasing Guide](https://github.com/aaronsteers/semantic-pr-release-drafter/blob/main/docs/releasing.md).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
|
|
3
|
+
COPY --from=ghcr.io/astral-sh/uv:0.8.17 /uv /uvx /bin/
|
|
4
|
+
|
|
5
|
+
RUN apt-get update \
|
|
6
|
+
&& apt-get install --no-install-recommends -y git \
|
|
7
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
8
|
+
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
|
|
11
|
+
COPY pyproject.toml uv.lock README.md /app/
|
|
12
|
+
COPY datarheo/ /app/datarheo/
|
|
13
|
+
|
|
14
|
+
RUN uv sync --frozen --no-dev
|
|
15
|
+
|
|
16
|
+
RUN useradd -m -u 10001 appuser \
|
|
17
|
+
&& chown -R appuser:appuser /app
|
|
18
|
+
|
|
19
|
+
ENV PATH="/app/.venv/bin:$PATH"
|
|
20
|
+
|
|
21
|
+
EXPOSE 8080
|
|
22
|
+
|
|
23
|
+
USER appuser
|
|
24
|
+
|
|
25
|
+
CMD ["datarheo-mcp-http"]
|
pydatarheo-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vrahad Analytics LLP
|
|
4
|
+
Copyright (c) 2023-2025 Airbyte, Inc.
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
pydatarheo-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
PyDataRheo
|
|
2
|
+
Copyright (c) 2026 Vrahad Analytics LLP
|
|
3
|
+
|
|
4
|
+
This product is a derivative work of PyAirbyte
|
|
5
|
+
(https://github.com/airbytehq/PyAirbyte), Copyright (c) 2023-2025 Airbyte, Inc.,
|
|
6
|
+
distributed under the MIT License. PyDataRheo is a rebranded and modified fork:
|
|
7
|
+
the package, public API names, CLI commands, environment variables, and
|
|
8
|
+
documentation have been renamed, and usage reporting has been changed to
|
|
9
|
+
opt-in with no default endpoint.
|
|
10
|
+
|
|
11
|
+
The MIT License requires that the original copyright notice be retained. Both
|
|
12
|
+
copyright lines appear in the LICENSE file at the root of this repository.
|
|
13
|
+
|
|
14
|
+
PyDataRheo executes connectors that implement the Airbyte protocol and can talk
|
|
15
|
+
to the Airbyte Cloud API. "Airbyte" is a trademark of Airbyte, Inc. References
|
|
16
|
+
to Airbyte in this project identify those external systems and do not imply
|
|
17
|
+
endorsement by, or affiliation with, Airbyte, Inc.
|
|
18
|
+
|
|
19
|
+
This product depends on the following third-party packages, which retain their
|
|
20
|
+
own licenses and copyright:
|
|
21
|
+
|
|
22
|
+
- airbyte-cdk (Airbyte, Inc.)
|
|
23
|
+
- airbyte-api (Airbyte, Inc.)
|
|
24
|
+
- airbyte-protocol-models-pdv2 (Airbyte, Inc.)
|
|
25
|
+
|
|
26
|
+
See the distribution metadata of each dependency for its full license text.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pydatarheo
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: PyDataRheo: run data-integration connectors from Python.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Vrahad-Analytics/pydatarheo
|
|
6
|
+
Project-URL: Documentation, https://vrahad-analytics.github.io/pydatarheo
|
|
7
|
+
Project-URL: Repository, https://github.com/Vrahad-Analytics/pydatarheo
|
|
8
|
+
Project-URL: Issues, https://github.com/Vrahad-Analytics/pydatarheo/issues
|
|
9
|
+
Author-email: Vrahad Analytics LLP <ardb40@gmail.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
License-File: NOTICE
|
|
13
|
+
Keywords: connectors,data-integration,datarheo,elt,etl,mcp
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Information Technology
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Database
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: <3.13,>=3.10
|
|
27
|
+
Requires-Dist: airbyte-api<1.0,>=0.53.0
|
|
28
|
+
Requires-Dist: airbyte-cdk<8.0.0,>=7.28.3
|
|
29
|
+
Requires-Dist: airbyte-protocol-models-pdv2<1.0,>=0.13.0
|
|
30
|
+
Requires-Dist: cryptography!=45.0.0,!=45.0.1,<47.0.0,>=44.0.0
|
|
31
|
+
Requires-Dist: cyclopts<5.0,>=4.0
|
|
32
|
+
Requires-Dist: duckdb-engine==0.17.0
|
|
33
|
+
Requires-Dist: duckdb==1.4.3
|
|
34
|
+
Requires-Dist: fastmcp-extensions<1.0.0,>=0.22.0
|
|
35
|
+
Requires-Dist: fastmcp<4.0,>=3.0
|
|
36
|
+
Requires-Dist: google-auth<3.0,>=2.27.0
|
|
37
|
+
Requires-Dist: google-cloud-bigquery-storage<3.0,>=2.25.0
|
|
38
|
+
Requires-Dist: google-cloud-bigquery<4.0,>=3.12.0
|
|
39
|
+
Requires-Dist: google-cloud-secret-manager<3.0,>=2.17.0
|
|
40
|
+
Requires-Dist: jsonschema<5.0,>=3.2.0
|
|
41
|
+
Requires-Dist: orjson<4.0,>=3.10
|
|
42
|
+
Requires-Dist: overrides<8.0,>=7.4.0
|
|
43
|
+
Requires-Dist: pandas<3.0,>=1.5.3
|
|
44
|
+
Requires-Dist: prefab-ui<0.21,>=0.20.1
|
|
45
|
+
Requires-Dist: psycopg2-binary<3.0,>=2.9.9
|
|
46
|
+
Requires-Dist: psycopg[binary,pool]<4.0,>=3.1.19
|
|
47
|
+
Requires-Dist: pyarrow<22.0,>=16.1
|
|
48
|
+
Requires-Dist: pydantic-core
|
|
49
|
+
Requires-Dist: pydantic<3.0,>=2.0
|
|
50
|
+
Requires-Dist: python-dotenv<2.0,>=1.0.1
|
|
51
|
+
Requires-Dist: python-ulid<4.0,>=3.0.0
|
|
52
|
+
Requires-Dist: pyyaml<7.0,>=6.0.2
|
|
53
|
+
Requires-Dist: requests!=3.32.0
|
|
54
|
+
Requires-Dist: rich<14.0,>=13.7.0
|
|
55
|
+
Requires-Dist: snowflake-connector-python<4.0,>=3.12.2
|
|
56
|
+
Requires-Dist: snowflake-sqlalchemy<2.0,>=1.6.1
|
|
57
|
+
Requires-Dist: sqlalchemy-bigquery==1.12.0
|
|
58
|
+
Requires-Dist: sqlalchemy==2.0.43
|
|
59
|
+
Requires-Dist: starlette
|
|
60
|
+
Requires-Dist: structlog<25.0,>=24.4.0
|
|
61
|
+
Requires-Dist: typing-extensions
|
|
62
|
+
Requires-Dist: uuid7<1.0,>=0.1.0
|
|
63
|
+
Requires-Dist: uv<0.9.0,>=0.5.0
|
|
64
|
+
Description-Content-Type: text/markdown
|
|
65
|
+
|
|
66
|
+
<p align="center">
|
|
67
|
+
<img src="https://raw.githubusercontent.com/Vrahad-Analytics/pydatarheo/main/docs/brand/pydatarheo-logo.svg" alt="PyDataRheo" width="260">
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
# PyDataRheo
|
|
71
|
+
|
|
72
|
+
**PyDataRheo moves data between hundreds of systems, from plain Python.**
|
|
73
|
+
|
|
74
|
+
Pick a source, read from it, and land the records in DuckDB, Postgres, Snowflake, BigQuery,
|
|
75
|
+
MotherDuck, or any destination connector. No orchestrator, no cluster, no YAML pipeline
|
|
76
|
+
definition. It is a library, so it runs wherever your Python runs: a script, a notebook, a
|
|
77
|
+
Lambda, an Airflow or Dagster task.
|
|
78
|
+
|
|
79
|
+
PyDataRheo runs [Airbyte-protocol connectors](https://docs.airbyte.com/integrations/), which is
|
|
80
|
+
what gives it several hundred sources and destinations on day one.
|
|
81
|
+
|
|
82
|
+
[](https://badge.fury.io/py/pydatarheo)
|
|
83
|
+
[](https://pypi.org/project/pydatarheo/)
|
|
84
|
+
[](https://pypi.org/project/pydatarheo/)
|
|
85
|
+
[](https://github.com/Vrahad-Analytics/pydatarheo)
|
|
86
|
+
|
|
87
|
+
## Install
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pip install pydatarheo
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The import package is `datarheo`; the distribution on PyPI is `pydatarheo`.
|
|
94
|
+
|
|
95
|
+
## Quick start
|
|
96
|
+
|
|
97
|
+
```py
|
|
98
|
+
import datarheo as dr
|
|
99
|
+
|
|
100
|
+
source = dr.get_source(
|
|
101
|
+
"source-faker",
|
|
102
|
+
config={"count": 5_000},
|
|
103
|
+
install_if_missing=True,
|
|
104
|
+
)
|
|
105
|
+
source.check()
|
|
106
|
+
source.select_all_streams()
|
|
107
|
+
|
|
108
|
+
result = source.read() # Lands in a local DuckDB cache by default.
|
|
109
|
+
|
|
110
|
+
for record in result["users"].records:
|
|
111
|
+
print(record)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Read into a dataframe:
|
|
115
|
+
|
|
116
|
+
```py
|
|
117
|
+
df = result["users"].to_pandas()
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Write to a real warehouse instead of the default local cache:
|
|
121
|
+
|
|
122
|
+
```py
|
|
123
|
+
from datarheo.caches import SnowflakeCache
|
|
124
|
+
|
|
125
|
+
cache = SnowflakeCache(
|
|
126
|
+
account="my-account",
|
|
127
|
+
username="my-user",
|
|
128
|
+
password=dr.get_secret("SNOWFLAKE_PASSWORD"),
|
|
129
|
+
database="my-db",
|
|
130
|
+
warehouse="my-wh",
|
|
131
|
+
role="my-role",
|
|
132
|
+
)
|
|
133
|
+
source.read(cache=cache)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Command line
|
|
137
|
+
|
|
138
|
+
These console scripts are installed:
|
|
139
|
+
|
|
140
|
+
| Command | What it does |
|
|
141
|
+
| --- | --- |
|
|
142
|
+
| `pydatarheo` / `pydr` | Benchmark, validate, and smoke-test connectors |
|
|
143
|
+
| `datarheo-mcp` | Run the DataRheo MCP server over stdio |
|
|
144
|
+
| `datarheo-mcp-http` | Run the DataRheo MCP server over HTTP |
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
pydr --help
|
|
148
|
+
pydr validate --connector=source-faker
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Connector installation
|
|
152
|
+
|
|
153
|
+
### Declarative (YAML) sources
|
|
154
|
+
|
|
155
|
+
Declarative sources are downloaded as a single YAML manifest and executed directly. These have
|
|
156
|
+
the fastest install times, because there is nothing to build.
|
|
157
|
+
|
|
158
|
+
### Python sources
|
|
159
|
+
|
|
160
|
+
When a connector publishes a Python package, PyDataRheo installs it automatically. Installation
|
|
161
|
+
uses [`uv`](https://docs.astral.sh/uv) rather than `pip`, which is both much faster and able to
|
|
162
|
+
install a connector under a different Python version than the one PyDataRheo itself is running
|
|
163
|
+
on. Set `DATARHEO_NO_UV=true` to fall back to `pip`.
|
|
164
|
+
|
|
165
|
+
To pin a connector to a specific Python version:
|
|
166
|
+
|
|
167
|
+
```py
|
|
168
|
+
source = dr.get_source("source-faker", use_python="3.10.17")
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Docker
|
|
172
|
+
|
|
173
|
+
Pass `docker_image=True` to `get_source()` or `get_destination()` to run the connector from its
|
|
174
|
+
published image instead, or `docker_image="my-org/my-image:tag"` to pick an exact image. Docker
|
|
175
|
+
is the most reproducible option, because every dependency is locked inside the image, and it is
|
|
176
|
+
required for Java-based destinations.
|
|
177
|
+
|
|
178
|
+
## Configuration
|
|
179
|
+
|
|
180
|
+
Every environment variable PyDataRheo reads is prefixed `DATARHEO_`. The most useful ones:
|
|
181
|
+
|
|
182
|
+
| Variable | Effect |
|
|
183
|
+
| --- | --- |
|
|
184
|
+
| `DATARHEO_CACHE_ROOT` | Where cache files are written (default `./.cache`) |
|
|
185
|
+
| `DATARHEO_PROJECT_DIR` | Parent directory for cache and connector installs |
|
|
186
|
+
| `DATARHEO_NO_UV` | Set to `1` to install connectors with `pip` instead of `uv` |
|
|
187
|
+
| `DATARHEO_OFFLINE_MODE` | Tolerate an unreachable connector registry; also disables telemetry |
|
|
188
|
+
| `DATARHEO_TEMP_DIR` | Directory for temporary files |
|
|
189
|
+
| `DATARHEO_CLOUD_CLIENT_ID` / `DATARHEO_CLOUD_CLIENT_SECRET` | Credentials for the hosted Cloud API |
|
|
190
|
+
|
|
191
|
+
An environment still carrying the older `AIRBYTE_`-prefixed names keeps working: each
|
|
192
|
+
`AIRBYTE_FOO` is read as `DATARHEO_FOO` unless the `DATARHEO_` name is also set, in which case
|
|
193
|
+
the explicit `DATARHEO_` value wins.
|
|
194
|
+
|
|
195
|
+
## Telemetry
|
|
196
|
+
|
|
197
|
+
**Off by default.** PyDataRheo sends nothing anywhere unless you set `DATARHEO_TRACKING_KEY` to
|
|
198
|
+
a Segment write key that you own. Setting `DO_NOT_TRACK`, or enabling offline mode, disables
|
|
199
|
+
reporting outright.
|
|
200
|
+
|
|
201
|
+
## Documentation
|
|
202
|
+
|
|
203
|
+
The full API reference is generated from the source with `poe docs-generate` and published at
|
|
204
|
+
[vrahad-analytics.github.io/pydatarheo](https://vrahad-analytics.github.io/pydatarheo).
|
|
205
|
+
|
|
206
|
+
## Contributing
|
|
207
|
+
|
|
208
|
+
See the [Contributors Guide](https://github.com/Vrahad-Analytics/pydatarheo/blob/main/docs/CONTRIBUTING.md).
|
|
209
|
+
|
|
210
|
+
## Frequently asked questions
|
|
211
|
+
|
|
212
|
+
**Is PyDataRheo a replacement for a data platform?**
|
|
213
|
+
No. It is a library. It has no orchestration, scheduling, alerting, or pipeline monitoring. Run
|
|
214
|
+
it inside whatever scheduler you already use.
|
|
215
|
+
|
|
216
|
+
**What is the cache? Is it a destination?**
|
|
217
|
+
Effectively yes: it is a built-in destination implementation backed by a SQL engine. We call it
|
|
218
|
+
a cache to keep it distinct from the destination connectors, which are separate executables.
|
|
219
|
+
|
|
220
|
+
**Does it work with Airflow, Dagster, Prefect, or Snowpark?**
|
|
221
|
+
Yes. It is an ordinary Python dependency with no background services.
|
|
222
|
+
|
|
223
|
+
**Can I build a normal ETL pipeline with it?**
|
|
224
|
+
Yes. Choose the cache type that matches where the data should land, such as `SnowflakeCache` for
|
|
225
|
+
Snowflake.
|
|
226
|
+
|
|
227
|
+
**Can it run a connector from a local directory?**
|
|
228
|
+
Yes. Any connector exposing a CLI works, and connectors already on `PATH` are found by name.
|
|
229
|
+
|
|
230
|
+
## License and provenance
|
|
231
|
+
|
|
232
|
+
PyDataRheo is released under the MIT license and is a rebranded derivative of
|
|
233
|
+
[PyAirbyte](https://github.com/airbytehq/PyAirbyte), which is also MIT licensed. See
|
|
234
|
+
[LICENSE](https://github.com/Vrahad-Analytics/pydatarheo/blob/main/LICENSE) and [NOTICE](https://github.com/Vrahad-Analytics/pydatarheo/blob/main/NOTICE).
|
|
235
|
+
|
|
236
|
+
## Changelog
|
|
237
|
+
|
|
238
|
+
See the [GitHub Releases](https://github.com/Vrahad-Analytics/pydatarheo/releases) page.
|