-
Notifications
You must be signed in to change notification settings - Fork 74
build: prepare PyAirbyte slim package boundaries #1035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
8c12be3
957093a
4081609
ba6dca9
3352d81
52bd2a8
9cbc54d
bb99bc2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -123,21 +123,40 @@ | |
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import TYPE_CHECKING | ||
| # ruff: noqa: F822 # Lazy exports are resolved by __getattr__ at runtime. | ||
| from importlib import import_module | ||
| from typing import TYPE_CHECKING, Any, cast | ||
|
|
||
| from airbyte import registry | ||
| from airbyte.caches.bigquery import BigQueryCache | ||
| from airbyte.caches.duckdb import DuckDBCache | ||
| from airbyte.caches.util import get_colab_cache, get_default_cache, new_local_cache | ||
| from airbyte.datasets import CachedDataset | ||
| from airbyte.destinations.base import Destination | ||
| from airbyte.destinations.util import get_destination | ||
| from airbyte.records import StreamRecord | ||
| from airbyte.registry import get_available_connectors | ||
| from airbyte.results import ReadResult, WriteResult | ||
| from airbyte.secrets import SecretSourceEnum, get_secret | ||
| from airbyte.sources.base import Source | ||
| from airbyte.sources.util import get_source | ||
|
|
||
|
|
||
| _LAZY_EXPORTS = { | ||
| "BigQueryCache": "airbyte.caches.bigquery", | ||
| "CachedDataset": "airbyte.datasets", | ||
| "Destination": "airbyte.destinations.base", | ||
| "DuckDBCache": "airbyte.caches.duckdb", | ||
| "ReadResult": "airbyte.results", | ||
| "Source": "airbyte.sources.base", | ||
| "WriteResult": "airbyte.results", | ||
| "get_colab_cache": "airbyte.caches.util", | ||
| "get_default_cache": "airbyte.caches.util", | ||
| "get_destination": "airbyte.destinations.util", | ||
| "get_source": "airbyte.sources.util", | ||
| "new_local_cache": "airbyte.caches.util", | ||
| } | ||
|
Comment on lines
+136
to
+149
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't follow what 'lazy exports' is supposed to mean. If obvious/easy, answer here. If shameful/controversial, answer in slack.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not shameful. Here "lazy exports" means the top-level Example: |
||
|
|
||
|
|
||
| def __getattr__(name: str) -> Any: # noqa: ANN401 | ||
| if name not in _LAZY_EXPORTS: | ||
| raise AttributeError(f"module 'airbyte' has no attribute {name!r}") | ||
|
|
||
| module = import_module(_LAZY_EXPORTS[name]) | ||
| value = cast("Any", getattr(module, name)) | ||
| globals()[name] = value | ||
| return value | ||
|
|
||
|
|
||
| # Submodules imported here for documentation reasons: https://github.com/mitmproxy/pdoc/issues/757 | ||
|
|
@@ -161,6 +180,15 @@ | |
| secrets, | ||
| sources, | ||
| ) | ||
| from airbyte.caches.bigquery import BigQueryCache | ||
| from airbyte.caches.duckdb import DuckDBCache | ||
| from airbyte.caches.util import get_colab_cache, get_default_cache, new_local_cache | ||
| from airbyte.datasets import CachedDataset | ||
| from airbyte.destinations.base import Destination | ||
| from airbyte.destinations.util import get_destination | ||
| from airbyte.results import ReadResult, WriteResult | ||
| from airbyte.sources.base import Source | ||
| from airbyte.sources.util import get_source | ||
|
|
||
|
|
||
| __all__ = [ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # Copyright (c) 2026 Airbyte, Inc., all rights reserved. | ||
| """Datetime parsing helpers.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from datetime import datetime, timezone | ||
|
|
||
|
|
||
| def parse_datetime(value: str | int) -> datetime: | ||
| """Parse an ISO datetime string or Unix timestamp as a timezone-aware datetime.""" | ||
| if isinstance(value, int) or ( | ||
| isinstance(value, str) | ||
| and (value.isdigit() or (value.startswith("-") and value[1:].isdigit())) | ||
| ): | ||
| return datetime.fromtimestamp(int(value), tz=timezone.utc) | ||
|
|
||
| if not isinstance(value, str): | ||
| raise TypeError(f"Could not parse datetime string: {value}") | ||
|
|
||
| normalized = value.replace("Z", "+00:00") | ||
| parsed = datetime.fromisoformat(normalized) | ||
| if parsed.tzinfo is None: | ||
| return parsed.replace(tzinfo=timezone.utc) | ||
|
|
||
| return parsed |
Uh oh!
There was an error while loading. Please reload this page.