From e46b319282dab78c41d42b3e64daaf4ea2a4ce29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez-Mondrag=C3=B3n?= Date: Tue, 3 Sep 2024 22:49:59 -0600 Subject: [PATCH] refactor(templates): Drop support for Python 3.8 in templates --- .../.github/workflows/test.yml | 1 - .../{{cookiecutter.mapper_id}}/pyproject.toml | 5 ++-- .../{{cookiecutter.mapper_id}}/tox.ini | 4 +-- .../{{cookiecutter.library_name}}/mapper.py | 3 +-- .../.github/workflows/test.yml | 1 - .../{{cookiecutter.tap_id}}/pyproject.toml | 5 ++-- .../{{cookiecutter.tap_id}}/tox.ini | 4 +-- .../graphql-client.py | 6 ++--- .../other-client.py | 6 ++--- .../rest-client.py | 25 ++++++++----------- .../sql-client.py | 4 +-- .../{{cookiecutter.library_name}}/streams.py | 10 ++------ .../.github/workflows/test.yml | 1 - .../{{cookiecutter.target_id}}/pyproject.toml | 5 ++-- .../{{cookiecutter.target_id}}/tox.ini | 4 +-- noxfile.py | 2 +- samples/sample_tap_dummy_json/pyproject.toml | 9 +++---- 17 files changed, 38 insertions(+), 57 deletions(-) diff --git a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/.github/workflows/test.yml b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/.github/workflows/test.yml index 1399f9f8c..731c51a14 100644 --- a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/.github/workflows/test.yml +++ b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/.github/workflows/test.yml @@ -33,7 +33,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.8" - "3.9" - "3.10" - "3.11" diff --git a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/pyproject.toml b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/pyproject.toml index b397face4..40c8a9b17 100644 --- a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/pyproject.toml +++ b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/pyproject.toml @@ -16,7 +16,6 @@ keywords = [ classifiers = [ "Intended Audience :: Developers", "Operating System :: OS Independent", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -30,7 +29,7 @@ packages = [ {%- endif %} [tool.poetry.dependencies] -python = ">=3.8" +python = ">=3.9" singer-sdk = { version="~=0.40.0"{{ ', extras = ["faker"]' if cookiecutter.faker_extra }} } fs-s3fs = { version = "~=1.1.1", optional = true } @@ -50,7 +49,7 @@ warn_unused_configs = true [tool.ruff] src = ["{{cookiecutter.library_name}}"] -target-version = "py38" +target-version = "py39" [tool.ruff.lint] ignore = [ diff --git a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/tox.ini b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/tox.ini index 6be1c116a..59d5dd083 100644 --- a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/tox.ini +++ b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/tox.ini @@ -1,7 +1,7 @@ # This file can be used to customize tox tests as well as other test frameworks like flake8 and mypy [tox] -envlist = py{38,39,310,311,312} +envlist = py{39,310,311,312} isolated_build = true [testenv] @@ -13,7 +13,7 @@ commands = [testenv:pytest] # Run the python tests. # To execute, run `tox -e pytest` -envlist = py{38,39,310,311,312} +envlist = py{39,310,311,312} commands = poetry install -v poetry run pytest diff --git a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/{{cookiecutter.library_name}}/mapper.py b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/{{cookiecutter.library_name}}/mapper.py index c8c3d23ec..8e6ea991e 100644 --- a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/{{cookiecutter.library_name}}/mapper.py +++ b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/{{cookiecutter.library_name}}/mapper.py @@ -3,14 +3,13 @@ from __future__ import annotations import typing as t -from typing import TYPE_CHECKING import singer_sdk.typing as th from singer_sdk import _singerlib as singer from singer_sdk.mapper import PluginMapper from singer_sdk.mapper_base import InlineMapper -if TYPE_CHECKING: +if t.TYPE_CHECKING: from pathlib import PurePath diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/.github/workflows/test.yml b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/.github/workflows/test.yml index 85aba9d26..f6f11b0e7 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/.github/workflows/test.yml +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/.github/workflows/test.yml @@ -33,7 +33,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.8" - "3.9" - "3.10" - "3.11" diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml index 3037bcabf..4163251a1 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml @@ -15,7 +15,6 @@ keywords = [ classifiers = [ "Intended Audience :: Developers", "Operating System :: OS Independent", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -29,7 +28,7 @@ packages = [ {%- endif %} [tool.poetry.dependencies] -python = ">=3.8" +python = ">=3.9" importlib-resources = { version = "==6.4.*", python = "<3.9" } singer-sdk = { version="~=0.40.0", extras = [ {%- if cookiecutter.auth_method == "JWT" -%}"jwt", {% endif -%} @@ -65,7 +64,7 @@ plugins = "sqlmypy" [tool.ruff] src = ["{{cookiecutter.library_name}}"] -target-version = "py38" +target-version = "py39" [tool.ruff.lint] ignore = [ diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/tox.ini b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/tox.ini index 6be1c116a..59d5dd083 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/tox.ini +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/tox.ini @@ -1,7 +1,7 @@ # This file can be used to customize tox tests as well as other test frameworks like flake8 and mypy [tox] -envlist = py{38,39,310,311,312} +envlist = py{39,310,311,312} isolated_build = true [testenv] @@ -13,7 +13,7 @@ commands = [testenv:pytest] # Run the python tests. # To execute, run `tox -e pytest` -envlist = py{38,39,310,311,312} +envlist = py{39,310,311,312} commands = poetry install -v poetry run pytest diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/graphql-client.py b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/graphql-client.py index 4e878cb23..d1289efa4 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/graphql-client.py +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/graphql-client.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Iterable +import typing as t import requests # noqa: TCH002 from singer_sdk.streams import {{ cookiecutter.stream_type }}Stream @@ -12,7 +12,7 @@ from {{ cookiecutter.library_name }}.auth import {{ cookiecutter.source_name }}Authenticator {%- endif %} -if TYPE_CHECKING: +if t.TYPE_CHECKING: from singer_sdk.helpers.types import Context @@ -54,7 +54,7 @@ def http_headers(self) -> dict: {%- endif %} return headers - def parse_response(self, response: requests.Response) -> Iterable[dict]: + def parse_response(self, response: requests.Response) -> t.Iterable[dict]: """Parse the response and return an iterator of result records. Args: diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/other-client.py b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/other-client.py index 1952579d7..bf7e2536d 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/other-client.py +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/other-client.py @@ -2,11 +2,11 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Iterable +import typing as t from singer_sdk.streams import Stream -if TYPE_CHECKING: +if t.TYPE_CHECKING: from singer_sdk.helpers.types import Context @@ -16,7 +16,7 @@ class {{ cookiecutter.source_name }}Stream(Stream): def get_records( self, context: Context | None, # noqa: ARG002 - ) -> Iterable[dict]: + ) -> t.Iterable[dict]: """Return a generator of record-type dictionary objects. The optional `context` argument is used to identify a specific slice of the diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/rest-client.py b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/rest-client.py index fb805ad55..c1aa634a5 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/rest-client.py +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/rest-client.py @@ -2,11 +2,11 @@ from __future__ import annotations -import sys -{%- if cookiecutter.auth_method in ("OAuth2", "JWT") %} +import typing as t +{% if cookiecutter.auth_method in ("OAuth2", "JWT") -%} from functools import cached_property -{%- endif %} -from typing import TYPE_CHECKING, Any, Iterable +{% endif -%} +from importlib import resources {% if cookiecutter.auth_method == "API Key" -%} from singer_sdk.authenticators import APIKeyAuthenticator @@ -40,12 +40,7 @@ {% endif -%} -if sys.version_info >= (3, 9): - import importlib.resources as importlib_resources -else: - import importlib_resources - -if TYPE_CHECKING: +if t.TYPE_CHECKING: import requests {%- if cookiecutter.auth_method in ("OAuth2", "JWT") %} from singer_sdk.helpers.types import Auth, Context @@ -55,7 +50,7 @@ # TODO: Delete this is if not using json files for schema definition -SCHEMAS_DIR = importlib_resources.files(__package__) / "schemas" +SCHEMAS_DIR = resources.files(__package__) / "schemas" class {{ cookiecutter.source_name }}Stream({{ cookiecutter.stream_type }}Stream): @@ -164,8 +159,8 @@ def get_new_paginator(self) -> BaseAPIPaginator: def get_url_params( self, context: Context | None, # noqa: ARG002 - next_page_token: Any | None, # noqa: ANN401 - ) -> dict[str, Any]: + next_page_token: t.Any | None, # noqa: ANN401 + ) -> dict[str, t.Any]: """Return a dictionary of values to be used in URL parameterization. Args: @@ -186,7 +181,7 @@ def get_url_params( def prepare_request_payload( self, context: Context | None, # noqa: ARG002 - next_page_token: Any | None, # noqa: ARG002, ANN401 + next_page_token: t.Any | None, # noqa: ARG002, ANN401 ) -> dict | None: """Prepare the data payload for the REST API request. @@ -202,7 +197,7 @@ def prepare_request_payload( # TODO: Delete this method if no payload is required. (Most REST APIs.) return None - def parse_response(self, response: requests.Response) -> Iterable[dict]: + def parse_response(self, response: requests.Response) -> t.Iterable[dict]: """Parse the response and return an iterator of result records. Args: diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/sql-client.py b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/sql-client.py index a34cee4d0..886b0d8f7 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/sql-client.py +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/sql-client.py @@ -5,7 +5,7 @@ from __future__ import annotations -from typing import Any, Iterable +import typing as t import sqlalchemy # noqa: TCH002 from singer_sdk import SQLConnector, SQLStream @@ -77,7 +77,7 @@ class {{ cookiecutter.source_name }}Stream(SQLStream): connector_class = {{ cookiecutter.source_name }}Connector - def get_records(self, partition: dict | None) -> Iterable[dict[str, Any]]: + def get_records(self, partition: dict | None) -> t.Iterable[dict[str, t.Any]]: """Return a generator of record-type dictionary objects. Developers may optionally add custom logic before calling the default diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/streams.py b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/streams.py index 69c955e6f..6e296a259 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/streams.py +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/streams.py @@ -2,21 +2,15 @@ from __future__ import annotations -import sys import typing as t +from importlib import resources from singer_sdk import typing as th # JSON Schema typing helpers from {{ cookiecutter.library_name }}.client import {{ cookiecutter.source_name }}Stream -if sys.version_info >= (3, 9): - import importlib.resources as importlib_resources -else: - import importlib_resources - - # TODO: Delete this is if not using json files for schema definition -SCHEMAS_DIR = importlib_resources.files(__package__) / "schemas" +SCHEMAS_DIR = resources.files(__package__) / "schemas" {%- if cookiecutter.stream_type == "GraphQL" %} diff --git a/cookiecutter/target-template/{{cookiecutter.target_id}}/.github/workflows/test.yml b/cookiecutter/target-template/{{cookiecutter.target_id}}/.github/workflows/test.yml index 2ed7a8bc5..c5baeaa0f 100644 --- a/cookiecutter/target-template/{{cookiecutter.target_id}}/.github/workflows/test.yml +++ b/cookiecutter/target-template/{{cookiecutter.target_id}}/.github/workflows/test.yml @@ -33,7 +33,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.8" - "3.9" - "3.10" - "3.11" diff --git a/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml b/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml index 42d71ae99..0ede63ffb 100644 --- a/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml +++ b/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml @@ -15,7 +15,6 @@ keywords = [ classifiers = [ "Intended Audience :: Developers", "Operating System :: OS Independent", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -29,7 +28,7 @@ packages = [ {%- endif %} [tool.poetry.dependencies] -python = ">=3.8" +python = ">=3.9" singer-sdk = { version="~=0.40.0"{{ ', extras = ["faker"]' if cookiecutter.faker_extra }} } fs-s3fs = { version = "~=1.1.1", optional = true } {%- if cookiecutter.serialization_method != "SQL" %} @@ -52,7 +51,7 @@ warn_unused_configs = true [tool.ruff] src = ["{{cookiecutter.library_name}}"] -target-version = "py38" +target-version = "py39" [tool.ruff.lint] ignore = [ diff --git a/cookiecutter/target-template/{{cookiecutter.target_id}}/tox.ini b/cookiecutter/target-template/{{cookiecutter.target_id}}/tox.ini index 6be1c116a..59d5dd083 100644 --- a/cookiecutter/target-template/{{cookiecutter.target_id}}/tox.ini +++ b/cookiecutter/target-template/{{cookiecutter.target_id}}/tox.ini @@ -1,7 +1,7 @@ # This file can be used to customize tox tests as well as other test frameworks like flake8 and mypy [tox] -envlist = py{38,39,310,311,312} +envlist = py{39,310,311,312} isolated_build = true [testenv] @@ -13,7 +13,7 @@ commands = [testenv:pytest] # Run the python tests. # To execute, run `tox -e pytest` -envlist = py{38,39,310,311,312} +envlist = py{39,310,311,312} commands = poetry install -v poetry run pytest diff --git a/noxfile.py b/noxfile.py index a07c953ab..dd92622d0 100644 --- a/noxfile.py +++ b/noxfile.py @@ -198,7 +198,7 @@ def docs_serve(session: Session) -> None: @nox.parametrize("replay_file_path", COOKIECUTTER_REPLAY_FILES) -@session(python=main_python_version) +@session(python=main_python_version, tags=["cookiecutter"]) def test_cookiecutter(session: Session, replay_file_path: str) -> None: """Uses the tap template to build an empty cookiecutter. diff --git a/samples/sample_tap_dummy_json/pyproject.toml b/samples/sample_tap_dummy_json/pyproject.toml index 1263b3ca4..c72347748 100644 --- a/samples/sample_tap_dummy_json/pyproject.toml +++ b/samples/sample_tap_dummy_json/pyproject.toml @@ -11,7 +11,6 @@ keywords = [ classifiers = [ "Intended Audience :: Developers", "Operating System :: OS Independent", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -20,13 +19,13 @@ classifiers = [ license = "Apache-2.0" [tool.poetry.dependencies] -python = ">=3.8" +python = ">=3.9" requests = "~=2.32.3" -singer-sdk = { version="~=0.38.0", extras = [] } +singer-sdk = {path = "../..", develop = true} [tool.poetry.group.dev.dependencies] pytest = ">=8" -singer-sdk = { version="~=0.38.0", extras = ["testing"] } +singer-sdk = {path = "../..", develop = true, extras = ["testing"]} [tool.poetry.extras] s3 = ["fs-s3fs"] @@ -36,7 +35,7 @@ python_version = "3.12" warn_unused_configs = true [build-system] -requires = ["poetry-core==1.9.0"] +requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.poetry.scripts]