Skip to content
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

chore: make full CDK codebase compliant with mypy #105

Merged
merged 37 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
55f6b4f
run mypy on all files, including unchanged
aaronsteers Dec 3, 2024
4d48d3f
fix mypy syntax
aaronsteers Dec 3, 2024
d3ea724
chore: `poetry add --dev types-requests`
aaronsteers Dec 3, 2024
3b9b389
chore: `poetry add --dev types-python-dateutil`
aaronsteers Dec 3, 2024
69fc701
chore: `poetry add --dev types-PyYaml`
aaronsteers Dec 3, 2024
f168266
chore: replace deprecated `deprecated` refs with PEP 702 `deprecated`
aaronsteers Dec 3, 2024
9c27d7e
chore: add missing cachetools stubs
aaronsteers Dec 3, 2024
9b08030
chore: remove unused `Deprecated` dependency
aaronsteers Dec 3, 2024
f54eb7c
chore: fix orjson imports
aaronsteers Dec 3, 2024
8202ce5
chore: misc mypy typing fixes
aaronsteers Dec 3, 2024
7e50af9
ci: remove stale if condition
aaronsteers Dec 3, 2024
5c65b46
fix deprecated syntax
aaronsteers Dec 3, 2024
e02629f
Merge branch 'main' into aj/chore/make-mypy-compliant
aaronsteers Dec 3, 2024
70bda72
chore: deprecated decorator readability and syntax fixes
aaronsteers Dec 3, 2024
22afbf6
allow unquoted class name via future annotations
aaronsteers Dec 3, 2024
df00054
fix test expecting ValueError
aaronsteers Dec 3, 2024
d7d1fda
add future annotations import
aaronsteers Dec 3, 2024
192e905
chore: pr review and cleanup
aaronsteers Dec 3, 2024
93e4534
more noqas
aaronsteers Dec 3, 2024
7f05353
fix inadvertent tuple
aaronsteers Dec 3, 2024
65dae78
add mypy target directory
aaronsteers Dec 3, 2024
92e6994
ci: remove non-interactive flag
aaronsteers Dec 3, 2024
3eff135
chore: fix or noqa remaining mypy issues (now 100% pass)
aaronsteers Dec 3, 2024
d68ac34
chore: fix mypy task in poe
aaronsteers Dec 3, 2024
59d585e
chore: fix type: `set[str]` instead of `Template`
aaronsteers Dec 3, 2024
40f9bca
revert: undo added guard statement
aaronsteers Dec 3, 2024
c8c0ef4
revert: undo added guard statement (2)
aaronsteers Dec 3, 2024
c29447c
add missing noqas
aaronsteers Dec 3, 2024
39d66af
remove unused type ignores
aaronsteers Dec 3, 2024
d3c2d10
ci: comment-out source-s3 and destination-pinecone
aaronsteers Dec 3, 2024
b77d957
ci: fix skip indicator
aaronsteers Dec 3, 2024
72d3e44
Merge branch 'main' into aj/chore/make-mypy-compliant
aaronsteers Dec 4, 2024
763ad95
Merge branch 'main' into aj/chore/make-mypy-compliant
aaronsteers Dec 4, 2024
eb2ea3c
comment-out deprecated decorator in "hot" codepath, with link to foll…
aaronsteers Dec 4, 2024
b62f634
comment-out flaky chargebee test
aaronsteers Dec 4, 2024
6873151
update from `main`
aaronsteers Dec 4, 2024
bd2e5af
add deprecated notice to docstring
aaronsteers Dec 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ updates:
interval: daily
labels:
- chore
open-pull-requests-limit: 8 # default is 5
open-pull-requests-limit: 8 # default is 5

- package-ecosystem: github-actions
open-pull-requests-limit: 5 # default is 5
open-pull-requests-limit: 5 # default is 5
directory: "/"
commit-message:
prefix: "ci(deps): "
Expand All @@ -29,5 +29,5 @@ updates:
minor-and-patch:
applies-to: version-updates
update-types:
- patch
- minor
- patch
- minor
13 changes: 5 additions & 8 deletions .github/workflows/publish_sdm_connector.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ on:
workflow_dispatch:
inputs:
version:
description:
The version to publish, ie 1.0.0 or 1.0.0-dev1.
If omitted, and if run from a release branch, the version will be
inferred from the git tag.
If omitted, and if run from a non-release branch, then only a SHA-based
Docker tag will be created.
description: The version to publish, ie 1.0.0 or 1.0.0-dev1.
If omitted, and if run from a release branch, the version will be
inferred from the git tag.
If omitted, and if run from a non-release branch, then only a SHA-based
Docker tag will be created.
required: false
dry_run:
description: If true, the workflow will not push to DockerHub.
Expand All @@ -24,7 +23,6 @@ jobs:
build:
runs-on: ubuntu-latest
steps:

- name: Detect Release Tag Version
if: startsWith(github.ref, 'refs/tags/v')
run: |
Expand Down Expand Up @@ -167,7 +165,6 @@ jobs:
tags: |
airbyte/source-declarative-manifest:${{ env.VERSION }}


- name: Build and push ('latest' tag)
# Only run if version is set and IS_PRERELEASE is false
if: env.VERSION != '' && env.IS_PRERELEASE == 'false' && github.event.inputs.dry_run == 'false'
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/pytest_matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ on:
branches:
- main
paths:
- 'airbyte_cdk/**'
- 'unit_tests/**'
- 'poetry.lock'
- 'pyproject.toml'
- "airbyte_cdk/**"
- "unit_tests/**"
- "poetry.lock"
- "pyproject.toml"
pull_request:

jobs:
Expand Down
13 changes: 3 additions & 10 deletions .github/workflows/python_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,7 @@ jobs:
- name: Install dependencies
run: poetry install --all-extras

# Job-specifc step(s):
# Job-specific step(s):

# For now, we run mypy only on modified files
- name: Get changed Python files
id: changed-py-files
uses: tj-actions/changed-files@v43
with:
files: "airbyte_cdk/**/*.py"
- name: Run mypy on changed files
if: steps.changed-py-files.outputs.any_changed == 'true'
run: poetry run mypy ${{ steps.changed-py-files.outputs.all_changed_files }} --config-file mypy.ini --install-types --non-interactive
- name: Run mypy
run: poetry run mypy --config-file mypy.ini --install-types --non-interactive
10 changes: 7 additions & 3 deletions airbyte_cdk/cli/source_declarative_manifest/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from pathlib import Path
from typing import Any, cast

from orjson import orjson
import orjson

from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch
from airbyte_cdk.models import (
Expand Down Expand Up @@ -160,10 +160,14 @@ def create_declarative_source(args: list[str]) -> ConcurrentDeclarativeSource:
connector builder.
"""
try:
config: Mapping[str, Any] | None
catalog: ConfiguredAirbyteCatalog | None
state: list[AirbyteStateMessage]
config, catalog, state = _parse_inputs_into_config_catalog_state(args)
if "__injected_declarative_manifest" not in config:
if config is None or "__injected_declarative_manifest" not in config:
raise ValueError(
f"Invalid config: `__injected_declarative_manifest` should be provided at the root of the config but config only has keys {list(config.keys())}"
"Invalid config: `__injected_declarative_manifest` should be provided at the root "
f"of the config but config only has keys: {list(config.keys() if config else [])}"
)
return ConcurrentDeclarativeSource(
config=config,
Expand Down
2 changes: 1 addition & 1 deletion airbyte_cdk/config_observation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from copy import copy
from typing import Any, List, MutableMapping

from orjson import orjson
import orjson

from airbyte_cdk.models import (
AirbyteControlConnectorConfigMessage,
Expand Down
2 changes: 1 addition & 1 deletion airbyte_cdk/connector_builder/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sys
from typing import Any, List, Mapping, Optional, Tuple

from orjson import orjson
import orjson

from airbyte_cdk.connector import BaseConnector
from airbyte_cdk.connector_builder.connector_builder_handler import (
Expand Down
2 changes: 1 addition & 1 deletion airbyte_cdk/destinations/destination.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from abc import ABC, abstractmethod
from typing import Any, Iterable, List, Mapping

from orjson import orjson
import orjson

from airbyte_cdk.connector import Connector
from airbyte_cdk.exception_handler import init_uncaught_exception_handler
Expand Down
3 changes: 3 additions & 0 deletions airbyte_cdk/destinations/vector_db_based/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ def write(
record_chunks, record_id_to_delete = self.processor.process(message.record)
self.chunks[(message.record.namespace, message.record.stream)].extend(record_chunks)
if record_id_to_delete is not None:
if message.record is None:
raise ValueError("Record messages cannot have null `record` property.")

self.ids_to_delete[(message.record.namespace, message.record.stream)].append(
record_id_to_delete
)
Expand Down
2 changes: 1 addition & 1 deletion airbyte_cdk/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from typing import Any, DefaultDict, Iterable, List, Mapping, Optional
from urllib.parse import urlparse

import orjson
import requests
from orjson import orjson
from requests import PreparedRequest, Response, Session

from airbyte_cdk.connector import TConfig
Expand Down
2 changes: 1 addition & 1 deletion airbyte_cdk/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import logging.config
from typing import Any, Callable, Mapping, Optional, Tuple

from orjson import orjson
import orjson

from airbyte_cdk.models import (
AirbyteLogMessage,
Expand Down
2 changes: 1 addition & 1 deletion airbyte_cdk/sources/connector_state_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def _extract_from_state_message(
else:
streams = {
HashableStreamDescriptor(
name=per_stream_state.stream.stream_descriptor.name,
name=per_stream_state.stream.stream_descriptor.name, # type: ignore[union-attr] # stream has stream_descriptor
namespace=per_stream_state.stream.stream_descriptor.namespace, # type: ignore[union-attr] # stream has stream_descriptor
): per_stream_state.stream.stream_state # type: ignore[union-attr] # stream has stream_state
for per_stream_state in state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ def __new__( # type: ignore[misc]
**kwargs: Any,
) -> DeclarativeAuthenticator:
try:
selected_key = str(dpath.get(config, authenticator_selection_path))
selected_key = str(
dpath.get(
config, # type: ignore [arg-type] # Dpath wants mutable mapping but doesn't need it.
authenticator_selection_path,
)
)
except KeyError as err:
raise ValueError(
"The path from `authenticator_selection_path` is not found in the config."
Expand Down
33 changes: 16 additions & 17 deletions airbyte_cdk/sources/declarative/declarative_component_schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2057,17 +2057,18 @@ definitions:
The DeclarativeOAuth Specific URL templated string to obtain the `access_token`, `refresh_token` etc.
The placeholders are replaced during the processing to provide neccessary values.
examples:
- access_token_url: https://auth.host.com/oauth2/token?{client_id_key}={{client_id_key}}&{client_secret_key}={{client_secret_key}}&{auth_code_key}={{auth_code_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}
- access_token_url: https://auth.host.com/oauth2/token?{client_id_key}={{client_id_key}}&{client_secret_key}={{client_secret_key}}&{auth_code_key}={{auth_code_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}
access_token_headers:
title: (Optional) DeclarativeOAuth Access Token Headers
type: object
additionalProperties: true
description: |-
The DeclarativeOAuth Specific optional headers to inject while exchanging the `auth_code` to `access_token` during `completeOAuthFlow` step.
examples:
- access_token_headers: {
"Authorization": "Basic {base64Encoder:{client_id}:{client_secret}}"
}
- access_token_headers:
{
"Authorization": "Basic {base64Encoder:{client_id}:{client_secret}}",
}
access_token_params:
title: (Optional) DeclarativeOAuth Access Token Query Params (Json Encoded)
type: object
Expand All @@ -2076,18 +2077,19 @@ definitions:
The DeclarativeOAuth Specific optional query parameters to inject while exchanging the `auth_code` to `access_token` during `completeOAuthFlow` step.
When this property is provided, the query params will be encoded as `Json` and included in the outgoing API request.
examples:
- access_token_params: {
"{auth_code_key}": "{{auth_code_key}}",
"{client_id_key}": "{{client_id_key}}",
"{client_secret_key}": "{{client_secret_key}}"
}
- access_token_params:
{
"{auth_code_key}": "{{auth_code_key}}",
"{client_id_key}": "{{client_id_key}}",
"{client_secret_key}": "{{client_secret_key}}",
}
extract_output:
title: DeclarativeOAuth Extract Output
type: array
items:
type: string
description: |-
The DeclarativeOAuth Specific list of strings to indicate which keys should be extracted and returned back to the input config.
The DeclarativeOAuth Specific list of strings to indicate which keys should be extracted and returned back to the input config.
examples:
- extract_output: ["access_token", "refresh_token", "other_field"]
state:
Expand All @@ -2099,17 +2101,14 @@ definitions:
- max
description: |-
The DeclarativeOAuth Specific object to provide the criteria of how the `state` query param should be constructed,
including length and complexity.
including length and complexity.
properties:
min:
type: integer
max:
type: integer
examples:
- state: {
"min": 7,
"max": 128,
}
- state: { "min": 7, "max": 128 }
client_id_key:
title: (Optional) DeclarativeOAuth Client ID Key Override
type: string
Expand All @@ -2135,14 +2134,14 @@ definitions:
title: (Optional) DeclarativeOAuth State Key Override
type: string
description: |-
The DeclarativeOAuth Specific optional override to provide the custom `state` key name, if required by data-provider.
The DeclarativeOAuth Specific optional override to provide the custom `state` key name, if required by data-provider.
examples:
- state_key: "my_custom_state_key_key_name"
auth_code_key:
title: (Optional) DeclarativeOAuth Auth Code Key Override
type: string
description: |-
The DeclarativeOAuth Specific optional override to provide the custom `code` key name to something like `auth_code` or `custom_auth_code`, if required by data-provider.
The DeclarativeOAuth Specific optional override to provide the custom `code` key name to something like `auth_code` or `custom_auth_code`, if required by data-provider.
examples:
- auth_code_key: "my_custom_auth_code_key_name"
redirect_uri_key:
Expand Down
5 changes: 4 additions & 1 deletion airbyte_cdk/sources/declarative/decoders/noop_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ class NoopDecoder(Decoder):
def is_stream_response(self) -> bool:
return False

def decode(self, response: requests.Response) -> Generator[Mapping[str, Any], None, None]:
def decode( # type: ignore[override] # Signature doesn't match base class
self,
response: requests.Response,
) -> Generator[Mapping[str, Any], None, None]:
yield from [{}]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dataclasses import InitVar, dataclass, field
from typing import Any, Mapping, MutableMapping, Optional, Union

from deprecated import deprecated
from typing_extensions import deprecated

from airbyte_cdk.sources.declarative.interpolation.interpolated_nested_mapping import NestedMapping
from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_nested_request_input_provider import (
Expand Down
7 changes: 5 additions & 2 deletions airbyte_cdk/sources/declarative/retrievers/async_retriever.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from dataclasses import InitVar, dataclass, field
from typing import Any, Callable, Iterable, Mapping, Optional

from deprecated.classic import deprecated
from typing_extensions import deprecated

from airbyte_cdk.models import FailureType
from airbyte_cdk.sources.declarative.async_job.job_orchestrator import (
Expand All @@ -21,7 +21,10 @@
from airbyte_cdk.utils.traced_exception import AirbyteTracedException


@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning)
@deprecated(
"This class is experimental. Use at your own risk.",
category=ExperimentalClassWarning,
)
@dataclass
class AsyncRetriever(Retriever):
config: Config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
#

from __future__ import annotations

import logging
from abc import abstractmethod
from typing import TYPE_CHECKING, Optional, Tuple
Expand All @@ -22,8 +24,11 @@

class AbstractFileBasedAvailabilityStrategy(AvailabilityStrategy):
@abstractmethod
def check_availability(
self, stream: Stream, logger: logging.Logger, _: Optional[Source]
def check_availability( # type: ignore[override] # Signature doesn't match base class
self,
stream: Stream,
logger: logging.Logger,
_: Optional[Source],
) -> Tuple[bool, Optional[str]]:
"""
Perform a connection check for the stream.
Expand All @@ -34,7 +39,10 @@ def check_availability(

@abstractmethod
def check_availability_and_parsability(
self, stream: "AbstractFileBasedStream", logger: logging.Logger, _: Optional[Source]
self,
stream: AbstractFileBasedStream,
logger: logging.Logger,
_: Optional[Source],
) -> Tuple[bool, Optional[str]]:
"""
Performs a connection check for the stream, as well as additional checks that
Expand All @@ -46,7 +54,7 @@ def check_availability_and_parsability(


class AbstractFileBasedAvailabilityStrategyWrapper(AbstractAvailabilityStrategy):
def __init__(self, stream: "AbstractFileBasedStream"):
def __init__(self, stream: AbstractFileBasedStream) -> None:
self.stream = stream

def check_availability(self, logger: logging.Logger) -> StreamAvailability:
Expand Down
Loading
Loading