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

Setup Ruff linting/formatting #12

Merged
merged 3 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ repos:
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix, --show-fixes]
exclude: tests/
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
Expand All @@ -36,3 +37,4 @@ repos:
- id: mypy
additional_dependencies:
- types-requests
exclude: tests/
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.PHONY: help init lint test

help:
@echo AVAILABLE COMMANDS
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-23s\033[0m%s\n", $$1, $$2}'

init: ## Initialise repo for local development
@poetry install --sync --with dev
@poetry run pre-commit install --install-hooks

lint: ## Lint files
poetry run pre-commit run ruff

test: ## Run tests
@poetry run pytest
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ warn_unused_configs = true

[tool.ruff]
ignore = [
"ANN001", # missing-type-function-argument
"ANN101", # missing-type-self
"ANN102", # missing-type-cls
"ANN201", # missing-return-type-undocumented-public-function
"COM812", # missing-trailing-comma
"ISC001", # single-line-implicit-string-concatenation
]
select = ["ALL"]
src = ["tap_f1"]
Expand Down
3 changes: 3 additions & 0 deletions tap_f1/client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""REST client handling, including F1Stream base class."""

from singer_sdk.streams import RESTStream
from typing_extensions import override

from tap_f1.pagination import F1Paginator

Expand All @@ -11,9 +12,11 @@ class F1Stream(RESTStream):
url_base = "https://ergast.com/api/f1"
_limit = 1000

@override
def get_new_paginator(self):
return F1Paginator(0, self._limit)

@override
def get_url_params(self, context, next_page_token):
params = super().get_url_params(context, next_page_token)
params["limit"] = self._limit
Expand Down
7 changes: 7 additions & 0 deletions tap_f1/pagination.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
"""Pagination classes for tap-f1."""


from singer_sdk.pagination import BaseOffsetPaginator
from typing_extensions import override


class F1Paginator(BaseOffsetPaginator):
"""Base API paginator."""

@override
def has_more(self, response):
data = response.json()["MRData"]

Expand Down
37 changes: 23 additions & 14 deletions tap_f1/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
from datetime import date

from singer_sdk import typing as th
from typing_extensions import override

from tap_f1.client import F1Stream


class SpeedUnitType(th.StringType):
"""Speed unit type."""

@override
@th.DefaultInstanceProperty
def type_dict(self):
return {
Expand All @@ -24,7 +28,7 @@ class SeasonsStream(F1Stream):
"""Define seasons stream."""

name = "seasons"
primary_keys = ["season"]
primary_keys = ("season",)
replication_key = "season"
path = "/seasons.json"
records_jsonpath = "MRData.SeasonTable.Seasons[*]"
Expand All @@ -34,6 +38,7 @@ class SeasonsStream(F1Stream):
th.Property("url", th.URIType),
).to_dict()

@override
def get_child_context(self, record, context):
start_date = date.fromisoformat(self.config["start_date"])

Expand All @@ -48,7 +53,7 @@ class CircuitsStream(F1Stream):

parent_stream_type = SeasonsStream
name = "circuits"
primary_keys = ["circuitId"]
primary_keys = ("circuitId",)
path = "/{season}/circuits.json"
records_jsonpath = "MRData.CircuitTable.Circuits[*]"

Expand All @@ -74,7 +79,7 @@ class DriversStream(F1Stream):
parent_stream_type = SeasonsStream
context_key = "Driver"
name = "drivers"
primary_keys = ["driverId"]
primary_keys = ("driverId",)
path = "/{season}/drivers.json"
records_jsonpath = "MRData.DriverTable.Drivers[*]"

Expand All @@ -96,7 +101,7 @@ class ConstructorsStream(F1Stream):
parent_stream_type = SeasonsStream
context_key = "Constructor"
name = "constructors"
primary_keys = ["constructorId"]
primary_keys = ("constructorId",)
path = "/{season}/constructors.json"
records_jsonpath = "MRData.ConstructorTable.Constructors[*]"

Expand All @@ -113,7 +118,7 @@ class RacesStream(F1Stream):

parent_stream_type = SeasonsStream
name = "races"
primary_keys = ["season", "round"]
primary_keys = ("season", "round")
replication_key = "date"
path = "/{season}.json"
records_jsonpath = "MRData.RaceTable.Races[*]"
Expand Down Expand Up @@ -179,6 +184,7 @@ class RacesStream(F1Stream):
),
).to_dict()

@override
def get_child_context(self, record, context):
value = self.get_starting_replication_key_value(context)
start_date = date.fromisoformat(value)
Expand All @@ -197,7 +203,7 @@ class QualifyingResultsStream(F1Stream):

parent_stream_type = RacesStream
name = "qualifying_results"
primary_keys = ["season", "round", "number"]
primary_keys = ("season", "round", "number")
path = "/{season}/{round}/qualifying.json"
records_jsonpath = "MRData.RaceTable.Races[*].QualifyingResults[*]"

Expand Down Expand Up @@ -239,7 +245,7 @@ class SprintResultsStream(F1Stream):

parent_stream_type = RacesStream
name = "sprints_results"
primary_keys = ["season", "round", "number"]
primary_keys = ("season", "round", "number")
path = "/{season}/{round}/sprint.json"
records_jsonpath = "MRData.RaceTable.Races[*].SprintResults[*]"

Expand Down Expand Up @@ -310,7 +316,7 @@ class RaceResultsStream(F1Stream):

parent_stream_type = RacesStream
name = "race_results"
primary_keys = ["season", "round", "number"]
primary_keys = ("season", "round", "number")
path = "/{season}/{round}/results.json"
records_jsonpath = "MRData.RaceTable.Races[*].Results[*]"

Expand Down Expand Up @@ -375,6 +381,7 @@ class RaceResultsStream(F1Stream):
),
).to_dict()

@override
def get_child_context(self, record, context):
return {
**super().get_child_context(record, context),
Expand All @@ -387,7 +394,7 @@ class LapsStream(F1Stream):

parent_stream_type = RaceResultsStream
name = "laps"
primary_keys = ["season", "round", "driverId", "number"]
primary_keys = ("season", "round", "driverId", "number")
path = "/{season}/{round}/drivers/{driverId}/laps.json"
records_jsonpath = "MRData.RaceTable.Races[*].Laps[*]"

Expand All @@ -403,7 +410,7 @@ class LapsStream(F1Stream):
th.Property("driverId", th.StringType),
th.Property("position", th.StringType),
th.Property("time", th.StringType),
)
),
),
),
).to_dict()
Expand All @@ -414,7 +421,7 @@ class PitStopsStream(F1Stream):

parent_stream_type = RacesStream
name = "pit_stops"
primary_keys = ["season", "round", "driverId", "stop"]
primary_keys = ("season", "round", "driverId", "stop")
path = "/{season}/{round}/pitstops.json"
records_jsonpath = "MRData.RaceTable.Races[*].PitStops[*]"

Expand All @@ -434,7 +441,7 @@ class DriverStandingsStream(F1Stream):

parent_stream_type = RacesStream
name = "driver_standings"
primary_keys = ["season", "round", "driverId", "position"]
primary_keys = ("season", "round", "driverId", "position")
path = "/{season}/{round}/driverStandings.json"
records_jsonpath = "MRData.StandingsTable.StandingsLists[*].DriverStandings[*]"

Expand Down Expand Up @@ -467,11 +474,12 @@ class DriverStandingsStream(F1Stream):
th.Property("url", th.URIType),
th.Property("name", th.StringType),
th.Property("nationality", th.StringType),
)
),
),
),
).to_dict()

@override
def post_process(self, row, context):
# driverId forms part of primary key
row["driverId"] = row["Driver"]["driverId"]
Expand All @@ -484,7 +492,7 @@ class ConstructorStandingsStream(F1Stream):

parent_stream_type = RacesStream
name = "constructor_standings"
primary_keys = ["season", "round", "constructorId", "position"]
primary_keys = ("season", "round", "constructorId", "position")
path = "/{season}/{round}/constructorStandings.json"
records_jsonpath = "MRData.StandingsTable.StandingsLists[*].ConstructorStandings[*]"

Expand All @@ -507,6 +515,7 @@ class ConstructorStandingsStream(F1Stream):
),
).to_dict()

@override
def post_process(self, row, context):
# constructorId forms part of primary key
row["constructorId"] = row["Constructor"]["constructorId"]
Expand Down
6 changes: 4 additions & 2 deletions tap_f1/tap.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""F1 tap class."""

from datetime import date
from datetime import date, datetime, timezone

import singer_sdk.typing as th
from singer_sdk import Tap
from typing_extensions import override

from tap_f1 import streams

Expand Down Expand Up @@ -32,10 +33,11 @@ class TapF1(Tap):
th.Property(
"start_date",
th.DateType,
default=date(date.today().year, 1, 1).isoformat(),
default=date(datetime.now(tz=timezone.utc).year, 1, 1).isoformat(),
),
).to_dict()

@override
def discover_streams(self):
return [stream_type(self) for stream_type in STREAM_TYPES]

Expand Down
3 changes: 0 additions & 3 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,3 @@
tap_class=TapF1,
config=SAMPLE_CONFIG,
)


# TODO: Create additional tests as appropriate for your tap.