diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 35ba54b..98cb4ad 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,14 +20,11 @@ jobs:
- name: Checkout repo
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- - name: Install poetry, isort, black
- run: pipx install poetry isort black
+ - name: Install poetry
+ run: pipx install poetry
- - name: View poetry, isort, black versions
- run: |
- poetry --version
- isort --version-number
- black --version
+ - name: View poetry
+ run: poetry --version
- name: 🐍 Set up Python
uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c
@@ -35,16 +32,23 @@ jobs:
python-version: 3.12
cache: "poetry"
+ - name: Add Poe the Poet plugin
+ run: poetry self add 'poethepoet[poetry_plugin]'
+
- name: Install dependencies
- run: poetry install --no-root
+ run: poetry install --no-root --with dev,lint,test
- - name: Python Lint (isort/black)
- run: |
- isort --check-only --quiet .
- black --check .
+ - name: Python Format (autoflake/isort/black)
+ run: poetry poe formatters
+
+ - name: Python Lint (pylint)
+ run: poetry poe pylint
+
+ - name: Python Typecheck (mypy)
+ run: poetry poe typings
- name: Run tests
- run: poetry run pytest -rpP
+ run: poetry poe tests
build:
name: 🐳 Build and publish docker images
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 1e3b1d8..dab9db5 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,18 +1,35 @@
+# Pre-commit hooks
repos:
+ # Execute external scripts
- repo: https://github.com/commitizen-tools/commitizen
rev: v3.13.0
hooks:
- id: commitizen
stages: [commit-msg]
- - repo: https://github.com/psf/black-pre-commit-mirror
- rev: 24.1.0
+ # Execute local scripts
+ - repo: local
hooks:
- - id: black
- language_version: python3.12
+ - id: run-formatter
+ name: Run formatter
+ entry: poetry poe formatters
+ language: system
+ pass_filenames: false
stages: [pre-commit, pre-push]
- - repo: https://github.com/pycqa/isort
- rev: 5.13.2
- hooks:
- - id: isort
- language_version: python3.12
+ - id: run-linter
+ name: Run linter
+ entry: poetry poe pylint
+ language: system
+ pass_filenames: false
+ stages: [pre-commit, pre-push]
+ - id: run-typings
+ name: Run typings
+ entry: poetry poe typings
+ language: system
+ pass_filenames: false
stages: [pre-commit, pre-push]
+ - id: run-tests
+ name: Run tests
+ entry: poetry poe tests
+ language: system
+ pass_filenames: false
+ stages: [pre-push]
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000..f2a5a9e
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,10 @@
+[MASTER]
+# A comma-separated list of package or module names from where C extensions may
+# be loaded. Extensions are loading into the active Python interpreter and may
+# run arbitrary code.
+extension-pkg-whitelist=
+
+[MESSAGES CONTROL]
+# https://pylint.readthedocs.io/en/latest/user_guide/checkers/features.html
+disable=all,E0401,E0611,E1101,E1102,E1123
+enable=F,E
diff --git a/.python-version b/.python-version
new file mode 100644
index 0000000..8531a3b
--- /dev/null
+++ b/.python-version
@@ -0,0 +1 @@
+3.12.2
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index a8d7ca9..bc4e127 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -10,6 +10,7 @@
"christian-kohler.path-intellisense",
"esbenp.prettier-vscode",
"ms-python.vscode-pylance",
+ "ms-python.pylint",
"ms-python.python",
"Gruntfuggly.todo-tree"
]
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 82758f8..e0a6210 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -6,5 +6,10 @@
}
},
"editor.formatOnSave": true,
- "isort.args": ["--profile", "black"]
+ "black-formatter.args": ["--line-length", "120", "--target-version", "py312"],
+ "isort.args": ["--settings-file", "${workspaceFolder}/pyproject.toml"],
+ "pylint.args": ["--rcfile", "${workspaceFolder}/.pylintrc"],
+ "python.testing.pytestArgs": ["tests"],
+ "python.testing.unittestEnabled": false,
+ "python.testing.pytestEnabled": true
}
diff --git a/Dockerfile.dev b/Dockerfile.dev
index 9fc62ce..8350c62 100644
--- a/Dockerfile.dev
+++ b/Dockerfile.dev
@@ -1,4 +1,4 @@
-FROM python:3.12.1-slim
+FROM python:3.12.2-slim
# Set the working directory to /code.
WORKDIR /code
@@ -16,7 +16,7 @@ RUN pip install --no-cache-dir poetry
# Use Poetry to install dependencies
RUN poetry config virtualenvs.create false \
- && poetry install --no-interaction --no-ansi --no-root
+ && poetry install --no-interaction --no-ansi --no-root --with dev,lint,test
# Make port 8081 available to the world outside this container
EXPOSE 8081
@@ -26,6 +26,6 @@ HEALTHCHECK --interval=5s --timeout=5s --retries=3 \
CMD curl -f http://localhost:8081/health || exit 1
# Run the uvicorn command, telling it to use the app object imported from app.main.
-CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8081", "--reload", "--reload-exclude", "app/test_main.py"]
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8081", "--reload", "--reload-exclude", "tests/*.py"]
-# CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "8081" "--reload", "--reload-exclude", "app/test_main.py"]
+# CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "8081" "--reload", "--reload-exclude", "tests/*.py"]
diff --git a/Dockerfile.prod b/Dockerfile.prod
index 00f23c8..05ccd47 100644
--- a/Dockerfile.prod
+++ b/Dockerfile.prod
@@ -1,7 +1,7 @@
# https://fastapi.tiangolo.com/deployment/docker/#docker-image-with-poetry
# First stage
-FROM python:3.12.1-slim as requirements-stage
+FROM python:3.12.2-slim as requirements-stage
# Set /tmp as the current working directory.
WORKDIR /tmp
@@ -16,7 +16,7 @@ COPY ./pyproject.toml ./poetry.lock* /tmp/
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
# This is the final stage, anything here will be preserved in the final container image.
-FROM python:3.12.1-slim
+FROM python:3.12.2-slim
# Install gcc and other dependencies
RUN apt-get update && apt-get install -y \
diff --git a/Dockerfile.staging b/Dockerfile.staging
index 00f23c8..05ccd47 100644
--- a/Dockerfile.staging
+++ b/Dockerfile.staging
@@ -1,7 +1,7 @@
# https://fastapi.tiangolo.com/deployment/docker/#docker-image-with-poetry
# First stage
-FROM python:3.12.1-slim as requirements-stage
+FROM python:3.12.2-slim as requirements-stage
# Set /tmp as the current working directory.
WORKDIR /tmp
@@ -16,7 +16,7 @@ COPY ./pyproject.toml ./poetry.lock* /tmp/
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
# This is the final stage, anything here will be preserved in the final container image.
-FROM python:3.12.1-slim
+FROM python:3.12.2-slim
# Install gcc and other dependencies
RUN apt-get update && apt-get install -y \
diff --git a/README.md b/README.md
index 9cbd45b..74eddac 100644
--- a/README.md
+++ b/README.md
@@ -13,13 +13,14 @@ Table of Contents:
- [Python virtual environment](#python-virtual-environment)
- [Installing dependencies](#installing-dependencies)
- [Virtual environment sanity check](#virtual-environment-sanity-check)
+ - [Poe the Poet poetry plugin](#poe-the-poet-poetry-plugin)
- [Installing git hooks](#installing-git-hooks)
- - [Running the project](#running-the-project)
+ - [Running the project](#running-the-project)
+ - [Running tests](#running-tests)
- [Docker](#docker)
- [App only](#app-only)
- [With Supabase](#with-supabase)
- [Interactive API docs](#interactive-api-docs)
- - [Running tests](#running-tests)
- [Contribution Guidelines](#contribution-guidelines)
- [Deployment](#deployment)
@@ -38,13 +39,14 @@ Table of Contents:
In `/docker`, create a copy of `.env.example` as `.env`.
+
### Python virtual environment
#### Installing dependencies
```sh
poetry config virtualenvs.in-project true # OPTIONAL
-poetry install --sync --no-root
+poetry install --sync --no-root --with dev,lint,test
```
**Note**: Ensure that the python interpreter in your IDE is set to the newly created virtual environment by poetry. If you have not modified poetry configuration, you can find the virtual environment location as stated [here](https://python-poetry.org/docs/configuration/#cache-directory).
@@ -58,19 +60,43 @@ poetry install --sync --no-root
- Run `poetry shell` ***OR***
- Execute the `/Scripts/Activate` script from the virtual environment located [here](https://python-poetry.org/docs/configuration/#cache-directory).
-#### Installing git hooks
-Run this command in the python environment.
+#### Poe the Poet poetry plugin
+
+```sh
+poetry self add 'poethepoet[poetry_plugin]'
+```
+
+1. Check available tasks:
+ ```sh
+ poetry poe
+ ```
+2. Execute a task:
+ ```sh
+ poetry poe
+ ```
+ For example, running the project formatters:
+ ```sh
+ poetry poe formatters
+ ```
+
+#### Installing git hooks
```sh
-pre-commit install --hook-type commit-msg --hook-type pre-push --hook-type pre-commit
+poetry poe git-hooks-setup
```
-#### Running the project
+### Running the project
- Open up a terminal in your IDE.
- Run `python run.py` to start the server.
-- Open your browser at `http://localhost:8081`.
+- Open your browser at [`http://localhost:8081`](http://localhost:8081).
+
+### Running tests
+
+```sh
+poetry poe tests
+```
### Docker
@@ -84,7 +110,7 @@ pre-commit install --hook-type commit-msg --hook-type pre-push --hook-type pre-c
```sh
docker run --name backend-dev --publish 8081:8081 backend-dev --detach
```
-- Open your browser at `http://localhost/8081`.
+- Open your browser at [`http://localhost:8081`](http://localhost:8081).
#### With Supabase
@@ -94,8 +120,8 @@ pre-commit install --hook-type commit-msg --hook-type pre-push --hook-type pre-c
docker compose --file compose.dev.yaml up --detach
```
- Open your browser at
- - `http://localhost/8081` for app
- - `http://localhost/8000` for supabase dashboard
+ - [`http://localhost:8081`](http://localhost:8081) for app
+ - [`http://localhost:8000`](http://localhost:8000) for supabase dashboard
- Username: `supabase`
- Password: `this_password_is_insecure_and_should_be_updated`
@@ -103,14 +129,8 @@ For other docker commands, see [useful_commands.md](./useful_commands.md)
### Interactive API docs
-- Once the server is running, open your browser at `http://localhost/docs`.
-- Alternate docs can be found at `http://localhost/redoc`, provided by [redoc](https://github.com/Redocly/redoc).
-
-### Running tests
-
-```sh
-poetry run pytest -rpP
-```
+- Once the server is running, open your browser at [`http://localhost/docs`](http://localhost/docs).
+- Alternate docs can be found at [`http://localhost/redoc`](http://localhost/redoc), provided by [redoc](https://github.com/Redocly/redoc).
### Contribution Guidelines
diff --git a/app/constants.py b/app/constants.py
index 78fa4e4..edd1573 100644
--- a/app/constants.py
+++ b/app/constants.py
@@ -1,5 +1,7 @@
+# Built-in
from datetime import datetime
+
METADATA_DESCRIPTION = """
Slick Telemetry backend written in python with fastf1. 🏎
@@ -31,4 +33,4 @@
MIN_SUPPORTED_SESSION = 1
MAX_SUPPORTED_SESSION = 5
-DEFAULT_SESSION_FOR_RESULTS = 5 # race
+DEFAULT_SESSION = 5 # race
diff --git a/app/main.py b/app/main.py
index 01f5333..c9fd8b9 100644
--- a/app/main.py
+++ b/app/main.py
@@ -1,18 +1,19 @@
+# Built-in
import json
-import logging
from datetime import datetime
-from typing import Annotated
+from typing import Annotated, List
+# External
import fastf1
from fastapi import FastAPI, HTTPException, Path, Query, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
-from fastapi_utils.timing import add_timing_middleware
from fastf1.ergast import Ergast
from pandas import Timestamp
+# App
from .constants import (
- DEFAULT_SESSION_FOR_RESULTS,
+ DEFAULT_SESSION,
EVENT_SCHEDULE_DATETIME_DTYPE_LIST,
MAX_SUPPORTED_ROUND,
MAX_SUPPORTED_SESSION,
@@ -22,21 +23,19 @@
MIN_SUPPORTED_SESSION,
MIN_SUPPORTED_YEAR,
)
-from .models import EventSchedule, HealthCheck, Results, Schedule, Standings
+from .models import EventSchedule, HealthCheck, Laps, Results, Root, Schedule, Standings
from .utils import get_default_year
-# fastf1.set_log_level("WARNING") # TODO use for production and staging
+
+fastf1.set_log_level("WARNING")
# Cors Middleware
origins = ["http://localhost:3000"]
# Ergast configuration
ergast = Ergast(result_type="raw", auto_cast=True)
+# Others
favicon_path = "favicon.ico"
-# Logging
-logging.basicConfig(level=logging.INFO)
-logger = logging.getLogger(__name__)
-
app = FastAPI(
title="Slick Telemetry API",
description=METADATA_DESCRIPTION,
@@ -61,7 +60,6 @@
allow_headers=["*"],
# HTTPSRedirectMiddleware # TODO use for production and staging
)
-add_timing_middleware(app, record=logger.info, prefix="app")
@app.get("/favicon.ico", include_in_schema=False)
@@ -75,6 +73,7 @@ async def favicon():
summary="Read root",
response_description="Return root info",
status_code=status.HTTP_200_OK,
+ response_model=Root,
)
def read_root():
return {"we_are": "SlickTelemetry"}
@@ -106,8 +105,8 @@ def get_health() -> HealthCheck:
@app.get(
"/schedule",
tags=["schedule"],
- summary="Get events schedule for a Formula 1 calendar year",
- response_description="Return list of events schedule for a Formula 1 calendar year",
+ summary="Get events schedule for a given year",
+ response_description="Return list of events schedule for a given year",
status_code=status.HTTP_200_OK,
response_model=Schedule,
)
@@ -120,16 +119,16 @@ def get_schedule(
ge=MIN_SUPPORTED_YEAR,
le=MAX_SUPPORTED_YEAR,
),
- ] = None
+ ] = None,
) -> Schedule:
"""
- ## Get events schedule for a Formula 1 calendar year
- Endpoint to get events schedule for Formula 1 calendar year.
+ ## Get events schedule for a given year
+ Endpoint to get events schedule for a given year.
**NOTE**: If `year` is not provided; we use the default year. Default year is defined as the year which has data for at least 1 race session.
**Returns**:
- list[Schedule]: Returns a JSON response with the list of event schedule
+ Schedule: Returns a JSON response with the list of event schedule
"""
if year is None:
@@ -146,11 +145,13 @@ def get_schedule(
event_schedule_as_json = event_schedule.to_json(orient="records")
# Parse the JSON string to a JSON object
- event_schedule_as_json_obj: list[EventSchedule] = json.loads(event_schedule_as_json)
- schedule_as_json_obj: Schedule = {
- "year": year,
- "EventSchedule": event_schedule_as_json_obj,
- }
+ event_schedule_as_json_obj: List[EventSchedule] = json.loads(event_schedule_as_json)
+ schedule_as_json_obj: Schedule = Schedule.model_validate(
+ {
+ "year": year,
+ "EventSchedule": event_schedule_as_json_obj,
+ }
+ )
return schedule_as_json_obj
@@ -172,16 +173,12 @@ def get_next_event() -> EventSchedule:
EventSchedule: Returns upcoming event
"""
- remaining_events = fastf1.get_events_remaining(
- dt=datetime.now(), include_testing=False
- )
+ remaining_events = fastf1.get_events_remaining(dt=datetime.now(), include_testing=False)
if len(remaining_events) == 0:
# EITHER current season has ended OR new season's schedule has not yet been released
- raise HTTPException(
- status_code=status.HTTP_404_NOT_FOUND, detail="Next event not found."
- )
+ raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Next event not found.")
else:
# Current season EITHER has not yet started OR is in progress
@@ -192,7 +189,7 @@ def get_next_event() -> EventSchedule:
lambda x: str(x) if isinstance(x, Timestamp) else x,
)
- # Convert the dataframe to a JSON string
+ # Convert the series to a JSON string
next_event_as_json = next_event.to_json()
# Parse the JSON string to a JSON object
@@ -204,8 +201,8 @@ def get_next_event() -> EventSchedule:
@app.get(
"/standings",
tags=["standings"],
- summary="Get drivers and constructors standings",
- response_description="Return a list of drivers and constructors standings at specific points of a season. If the season hasn't ended you will get the current standings.",
+ summary="Get drivers and constructors standing for a given year and round",
+ response_description="Return a list of drivers and constructors standings at specific points of a season for a given year and round. If the season hasn't ended you get the current standings.",
status_code=status.HTTP_200_OK,
response_model=Standings,
)
@@ -213,8 +210,8 @@ def get_standings(
year: Annotated[
int | None,
Query(
- title="The year for which to get the driver and constructors standing. If the season hasn't ended you will get the current standings.",
- description="The year for which to get the driver and constructors standing. If the season hasn't ended you will get the current standings.",
+ title="The year for which to get the driver and constructors standing. If the season hasn't ended you get the current standings.",
+ description="The year for which to get the driver and constructors standing. If the season hasn't ended you get the current standings.",
ge=MIN_SUPPORTED_YEAR,
le=MAX_SUPPORTED_YEAR,
),
@@ -230,8 +227,8 @@ def get_standings(
] = None,
) -> Standings:
"""
- ## Get driver and constructor standings
- Endpoint to get driver and constructor standings at specific points of a season. If the season hasn't ended you will get the current standings.
+ ## Get driver and constructor standings for a given year and round
+ Endpoint to get driver and constructor standings at specific points of a season for a given year and round. If the season hasn't ended you get the current standings.
**NOTE**: If `year` is not provided; we use the default year. Default year is defined as the year which has data for at least 1 race session.
@@ -261,12 +258,14 @@ def get_standings(
if driver_standings_available and constructor_standings_available:
# both driver and constructor standings are available
- data: Standings = {
- "season": driver_standings[0]["season"],
- "round": driver_standings[0]["round"],
- "DriverStandings": driver_standings[0]["DriverStandings"],
- "ConstructorStandings": constructor_standings[0]["ConstructorStandings"],
- }
+ data: Standings = Standings.model_validate(
+ {
+ "season": driver_standings[0]["season"],
+ "round": driver_standings[0]["round"],
+ "DriverStandings": driver_standings[0]["DriverStandings"],
+ "ConstructorStandings": constructor_standings[0]["ConstructorStandings"],
+ }
+ )
return data
elif not driver_standings_available and not constructor_standings_available:
# neither driver nor constructor standings are available
@@ -282,14 +281,10 @@ def get_standings(
)
elif constructor_standings_available:
# only constructor standings are available
- raise HTTPException(
- status_code=status.HTTP_404_NOT_FOUND, detail="Driver standings not found."
- )
+ raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Driver standings not found.")
else:
# something went wrong, investigate
- raise HTTPException(
- status_code=500, detail="Something went wrong. Investigate!"
- )
+ raise HTTPException(status_code=500, detail="Something went wrong. Investigate!")
@app.get(
@@ -298,7 +293,7 @@ def get_standings(
summary="Get session results for a given year, round and session",
response_description="Return session results for a given year, round and session.",
status_code=status.HTTP_200_OK,
- response_model=list[Results],
+ response_model=List[Results],
)
def get_results(
year: Annotated[
@@ -323,20 +318,20 @@ def get_results(
int,
Query(
title="The session in a round for which to get the results",
- description="The session in a round for which to get the results. (5 = race)",
+ description="The session in a round for which to get the results. (Default = 5; ie race)",
ge=MIN_SUPPORTED_SESSION,
le=MAX_SUPPORTED_SESSION,
),
- ] = DEFAULT_SESSION_FOR_RESULTS,
-) -> list[Results]:
+ ] = DEFAULT_SESSION,
+) -> List[Results]:
"""
## Get session results for a given year, round and session
Endpoint to get session results for a given year, round and session.
- **NOTE**: If `session` is not provided; we use the default session. Default session is the race session (5).
+ **NOTE**: If `session` is not provided; we use the default session. Default = 5; ie race.
**Returns**:
- list[Results]: Returns a JSON response with the list of session results
+ List[Results]: Returns a JSON response with the list of session results
"""
try:
@@ -353,15 +348,99 @@ def get_results(
session_results_as_json = session_results.to_json(orient="records")
# Parse the JSON string to a JSON object
- session_results_as_json_obj = json.loads(session_results_as_json)
+ session_results_as_json_obj: List[Results] = json.loads(session_results_as_json)
return session_results_as_json_obj
except ValueError as ve:
+ raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Bad Request. {str(ve)}")
+ except KeyError as ke:
raise HTTPException(
- status_code=status.HTTP_400_BAD_REQUEST, detail=f"Bad Request. {str(ve)}"
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Likely an error when fetching results data for a session that has yet to happen. {str(ke)}",
)
+
+
+@app.get(
+ "/laps/{year}/{round}",
+ tags=["laps"],
+ summary="Get laps of one or more drivers for a given year, round and session",
+ response_description="Return laps of one or more drivers for a given year, round and session.",
+ status_code=status.HTTP_200_OK,
+ response_model=List[Laps],
+)
+def get_laps(
+ year: Annotated[
+ int,
+ Path(
+ title="The year for which to get the laps",
+ description="The year for which to get the laps",
+ ge=MIN_SUPPORTED_YEAR,
+ le=MAX_SUPPORTED_YEAR,
+ ),
+ ],
+ round: Annotated[
+ int,
+ Path(
+ title="The round in a year for which to get the laps",
+ description="The round in a year for which to get the laps",
+ ge=MIN_SUPPORTED_ROUND,
+ le=MAX_SUPPORTED_ROUND,
+ ),
+ ],
+ session: Annotated[
+ int,
+ Query(
+ title="The session in a round for which to get the laps",
+ description="The session in a round for which to get the laps. (Default = 5; ie race)",
+ ge=MIN_SUPPORTED_SESSION,
+ le=MAX_SUPPORTED_SESSION,
+ ),
+ ] = DEFAULT_SESSION,
+ driver_number: Annotated[
+ List[int],
+ Query(
+ title="List of drivers for whom to get the laps",
+ description="List of drivers for whom to get the laps",
+ ),
+ ] = [],
+) -> List[Laps]:
+ """
+ ## Get laps of one or more drivers for a given year, round and session
+ Endpoint to get laps of one or more drivers for a given year, round and session.
+
+ **NOTE**:
+ - If `session` is not provided; we use the default session. Default = 5; ie race.
+ - If no `driver_numbers` are provided; you get laps for all drivers.
+
+ **Returns**:
+ List[Laps]: Returns a JSON response with the list of session results
+ """
+
+ session_obj = fastf1.get_session(year=year, gp=round, identifier=session)
+ session_obj.load(
+ laps=True,
+ telemetry=False,
+ weather=False,
+ messages=True, # required for `Deleted` and `DeletedReason`
+ )
+ session_laps = session_obj.laps
+
+ try:
+ if len(driver_number) > 0:
+ print(driver_number)
+ session_laps = session_laps.pick_drivers(driver_number)
+
+ # Convert the dataframe to a JSON string
+ session_laps_as_json = session_laps.to_json(orient="records")
+
+ # Parse the JSON string to a JSON object
+ session_laps_as_json_obj: List[Laps] = json.loads(session_laps_as_json)
+
+ return session_laps_as_json_obj
+ except ValueError as ve:
+ raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Bad Request. {str(ve)}")
except KeyError as ke:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
- detail=f"Likely an error when fetching results data for a session that has yet to happen. {str(ke)}",
+ detail=f"Likely an error when fetching laps data for a session that has yet to happen. {str(ke)}",
)
diff --git a/app/models.py b/app/models.py
index cf89834..d13a5ac 100644
--- a/app/models.py
+++ b/app/models.py
@@ -1,8 +1,12 @@
+# Built-in
+from typing import List
+
+# External
from pydantic import BaseModel
-class ReadRoot(BaseModel):
- """Response model to validate and return when performing a health check."""
+class Root(BaseModel):
+ """Response model for root."""
we_are: str = "SlickTelemetry"
@@ -39,7 +43,7 @@ class Schedule(BaseModel):
"""Response model for event schedule data with year"""
year: int
- EventSchedule: list[EventSchedule]
+ EventSchedule: List[EventSchedule]
class HealthCheck(BaseModel):
@@ -78,7 +82,7 @@ class DriverStandings(BaseModel):
points: str
wins: str
Driver: Driver
- Constructors: list[Constructor]
+ Constructors: List[Constructor]
class ConstructorStandings(BaseModel):
@@ -96,8 +100,8 @@ class Standings(BaseModel):
season: int
round: int
- DriverStandings: list[DriverStandings]
- ConstructorStandings: list[ConstructorStandings]
+ DriverStandings: List[DriverStandings]
+ ConstructorStandings: List[ConstructorStandings]
class Results(BaseModel):
@@ -124,3 +128,39 @@ class Results(BaseModel):
Time: int | None
Status: str
Points: float | None
+
+
+class Laps(BaseModel):
+ """Response model for session laps for a given year, round, session and drivers"""
+
+ Time: int
+ Driver: str
+ DriverNumber: str
+ LapTime: int | None
+ LapNumber: float
+ Stint: float
+ PitOutTime: int | None
+ PitInTime: int | None
+ Sector1Time: int | None
+ Sector2Time: int | None
+ Sector3Time: int | None
+ Sector1SessionTime: int | None
+ Sector2SessionTime: int | None
+ Sector3SessionTime: int | None
+ SpeedI1: float | None
+ SpeedI2: float | None
+ SpeedFL: float | None
+ SpeedST: float | None
+ IsPersonalBest: bool
+ Compound: str
+ TyreLife: float
+ FreshTyre: bool
+ Team: str
+ LapStartTime: int | None
+ LapStartDate: str | None
+ TrackStatus: str
+ Position: float | None
+ Deleted: bool | None
+ DeletedReason: str
+ FastF1Generated: bool
+ IsAccurate: bool
diff --git a/app/test_main.py b/app/test_main.py
deleted file mode 100644
index fc6db69..0000000
--- a/app/test_main.py
+++ /dev/null
@@ -1,4081 +0,0 @@
-from datetime import datetime
-
-from fastapi import status
-from fastapi.testclient import TestClient
-
-from .constants import (
- MAX_SUPPORTED_ROUND,
- MAX_SUPPORTED_YEAR,
- MIN_SUPPORTED_ROUND,
- MIN_SUPPORTED_YEAR,
-)
-from .main import app
-
-client = TestClient(app)
-
-
-# region root
-
-
-def test_read_root():
- response = client.get("/")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {"we_are": "SlickTelemetry"}
-
-
-# endregion root
-
-
-# region healthcheck
-
-
-def test_healthcheck():
- response = client.get("/health")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {"status": "OK"}
-
-
-# endregion healtcheck
-
-
-# region schedule
-
-# region schedule - good inputs
-
-
-def test_get_schedule():
- response = client.get("/schedule")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {
- "year": 2023,
- "EventSchedule": [
- {
- "RoundNumber": 1,
- "Country": "Bahrain",
- "Location": "Sakhir",
- "OfficialEventName": "FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2023",
- "EventDate": "2023-03-05",
- "EventName": "Bahrain Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-03-03 14:30:00+03:00",
- "Session1DateUtc": "2023-03-03 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-03-03 18:00:00+03:00",
- "Session2DateUtc": "2023-03-03 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-03-04 14:30:00+03:00",
- "Session3DateUtc": "2023-03-04 11:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-03-04 18:00:00+03:00",
- "Session4DateUtc": "2023-03-04 15:00:00",
- "Session5": "Race",
- "Session5Date": "2023-03-05 18:00:00+03:00",
- "Session5DateUtc": "2023-03-05 15:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 2,
- "Country": "Saudi Arabia",
- "Location": "Jeddah",
- "OfficialEventName": "FORMULA 1 STC SAUDI ARABIAN GRAND PRIX 2023",
- "EventDate": "2023-03-19",
- "EventName": "Saudi Arabian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-03-17 16:30:00+03:00",
- "Session1DateUtc": "2023-03-17 13:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-03-17 20:00:00+03:00",
- "Session2DateUtc": "2023-03-17 17:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-03-18 16:30:00+03:00",
- "Session3DateUtc": "2023-03-18 13:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-03-18 20:00:00+03:00",
- "Session4DateUtc": "2023-03-18 17:00:00",
- "Session5": "Race",
- "Session5Date": "2023-03-19 20:00:00+03:00",
- "Session5DateUtc": "2023-03-19 17:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 3,
- "Country": "Australia",
- "Location": "Melbourne",
- "OfficialEventName": "FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX 2023",
- "EventDate": "2023-04-02",
- "EventName": "Australian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-03-31 12:30:00+10:00",
- "Session1DateUtc": "2023-03-31 02:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-03-31 16:00:00+10:00",
- "Session2DateUtc": "2023-03-31 06:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-04-01 12:30:00+10:00",
- "Session3DateUtc": "2023-04-01 02:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-04-01 16:00:00+10:00",
- "Session4DateUtc": "2023-04-01 06:00:00",
- "Session5": "Race",
- "Session5Date": "2023-04-02 15:00:00+10:00",
- "Session5DateUtc": "2023-04-02 05:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 4,
- "Country": "Azerbaijan",
- "Location": "Baku",
- "OfficialEventName": "FORMULA 1 AZERBAIJAN GRAND PRIX 2023",
- "EventDate": "2023-04-30",
- "EventName": "Azerbaijan Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-04-28 13:30:00+04:00",
- "Session1DateUtc": "2023-04-28 09:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-04-28 17:00:00+04:00",
- "Session2DateUtc": "2023-04-28 13:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-04-29 12:30:00+04:00",
- "Session3DateUtc": "2023-04-29 08:30:00",
- "Session4": "Sprint",
- "Session4Date": "2023-04-29 17:30:00+04:00",
- "Session4DateUtc": "2023-04-29 13:30:00",
- "Session5": "Race",
- "Session5Date": "2023-04-30 15:00:00+04:00",
- "Session5DateUtc": "2023-04-30 11:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 5,
- "Country": "United States",
- "Location": "Miami",
- "OfficialEventName": "FORMULA 1 CRYPTO.COM MIAMI GRAND PRIX 2023",
- "EventDate": "2023-05-07",
- "EventName": "Miami Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-05-05 14:00:00-04:00",
- "Session1DateUtc": "2023-05-05 18:00:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-05-05 17:30:00-04:00",
- "Session2DateUtc": "2023-05-05 21:30:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-05-06 12:30:00-04:00",
- "Session3DateUtc": "2023-05-06 16:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-05-06 16:00:00-04:00",
- "Session4DateUtc": "2023-05-06 20:00:00",
- "Session5": "Race",
- "Session5Date": "2023-05-07 15:30:00-04:00",
- "Session5DateUtc": "2023-05-07 19:30:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 6,
- "Country": "Monaco",
- "Location": "Monaco",
- "OfficialEventName": "FORMULA 1 GRAND PRIX DE MONACO 2023",
- "EventDate": "2023-05-28",
- "EventName": "Monaco Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-05-26 13:30:00+02:00",
- "Session1DateUtc": "2023-05-26 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-05-26 17:00:00+02:00",
- "Session2DateUtc": "2023-05-26 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-05-27 12:30:00+02:00",
- "Session3DateUtc": "2023-05-27 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-05-27 16:00:00+02:00",
- "Session4DateUtc": "2023-05-27 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-05-28 15:00:00+02:00",
- "Session5DateUtc": "2023-05-28 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 7,
- "Country": "Spain",
- "Location": "Barcelona",
- "OfficialEventName": "FORMULA 1 AWS GRAN PREMIO DE ESPAÑA 2023",
- "EventDate": "2023-06-04",
- "EventName": "Spanish Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-06-02 13:30:00+02:00",
- "Session1DateUtc": "2023-06-02 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-06-02 17:00:00+02:00",
- "Session2DateUtc": "2023-06-02 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-06-03 12:30:00+02:00",
- "Session3DateUtc": "2023-06-03 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-06-03 16:00:00+02:00",
- "Session4DateUtc": "2023-06-03 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-06-04 15:00:00+02:00",
- "Session5DateUtc": "2023-06-04 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 8,
- "Country": "Canada",
- "Location": "Montréal",
- "OfficialEventName": "FORMULA 1 PIRELLI GRAND PRIX DU CANADA 2023",
- "EventDate": "2023-06-18",
- "EventName": "Canadian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-06-16 13:30:00-04:00",
- "Session1DateUtc": "2023-06-16 17:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-06-16 16:30:00-04:00",
- "Session2DateUtc": "2023-06-16 20:30:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-06-17 12:30:00-04:00",
- "Session3DateUtc": "2023-06-17 16:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-06-17 16:00:00-04:00",
- "Session4DateUtc": "2023-06-17 20:00:00",
- "Session5": "Race",
- "Session5Date": "2023-06-18 14:00:00-04:00",
- "Session5DateUtc": "2023-06-18 18:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 9,
- "Country": "Austria",
- "Location": "Spielberg",
- "OfficialEventName": "FORMULA 1 ROLEX GROSSER PREIS VON ÖSTERREICH 2023",
- "EventDate": "2023-07-02",
- "EventName": "Austrian Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-06-30 13:30:00+02:00",
- "Session1DateUtc": "2023-06-30 11:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-06-30 17:00:00+02:00",
- "Session2DateUtc": "2023-06-30 15:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-07-01 12:00:00+02:00",
- "Session3DateUtc": "2023-07-01 10:00:00",
- "Session4": "Sprint",
- "Session4Date": "2023-07-01 16:30:00+02:00",
- "Session4DateUtc": "2023-07-01 14:30:00",
- "Session5": "Race",
- "Session5Date": "2023-07-02 15:00:00+02:00",
- "Session5DateUtc": "2023-07-02 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 10,
- "Country": "Great Britain",
- "Location": "Silverstone",
- "OfficialEventName": "FORMULA 1 ARAMCO BRITISH GRAND PRIX 2023",
- "EventDate": "2023-07-09",
- "EventName": "British Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-07-07 12:30:00+01:00",
- "Session1DateUtc": "2023-07-07 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-07-07 16:00:00+01:00",
- "Session2DateUtc": "2023-07-07 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-07-08 11:30:00+01:00",
- "Session3DateUtc": "2023-07-08 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-07-08 15:00:00+01:00",
- "Session4DateUtc": "2023-07-08 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-07-09 15:00:00+01:00",
- "Session5DateUtc": "2023-07-09 14:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 11,
- "Country": "Hungary",
- "Location": "Budapest",
- "OfficialEventName": "FORMULA 1 QATAR AIRWAYS HUNGARIAN GRAND PRIX 2023",
- "EventDate": "2023-07-23",
- "EventName": "Hungarian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-07-21 13:30:00+02:00",
- "Session1DateUtc": "2023-07-21 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-07-21 17:00:00+02:00",
- "Session2DateUtc": "2023-07-21 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-07-22 12:30:00+02:00",
- "Session3DateUtc": "2023-07-22 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-07-22 16:00:00+02:00",
- "Session4DateUtc": "2023-07-22 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-07-23 15:00:00+02:00",
- "Session5DateUtc": "2023-07-23 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 12,
- "Country": "Belgium",
- "Location": "Spa-Francorchamps",
- "OfficialEventName": "FORMULA 1 MSC CRUISES BELGIAN GRAND PRIX 2023",
- "EventDate": "2023-07-30",
- "EventName": "Belgian Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-07-28 13:30:00+02:00",
- "Session1DateUtc": "2023-07-28 11:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-07-28 17:00:00+02:00",
- "Session2DateUtc": "2023-07-28 15:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-07-29 12:00:00+02:00",
- "Session3DateUtc": "2023-07-29 10:00:00",
- "Session4": "Sprint",
- "Session4Date": "2023-07-29 17:05:00+02:00",
- "Session4DateUtc": "2023-07-29 15:05:00",
- "Session5": "Race",
- "Session5Date": "2023-07-30 15:00:00+02:00",
- "Session5DateUtc": "2023-07-30 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 13,
- "Country": "Netherlands",
- "Location": "Zandvoort",
- "OfficialEventName": "FORMULA 1 HEINEKEN DUTCH GRAND PRIX 2023",
- "EventDate": "2023-08-27",
- "EventName": "Dutch Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-08-25 12:30:00+02:00",
- "Session1DateUtc": "2023-08-25 10:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-08-25 16:00:00+02:00",
- "Session2DateUtc": "2023-08-25 14:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-08-26 11:30:00+02:00",
- "Session3DateUtc": "2023-08-26 09:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-08-26 15:00:00+02:00",
- "Session4DateUtc": "2023-08-26 13:00:00",
- "Session5": "Race",
- "Session5Date": "2023-08-27 15:00:00+02:00",
- "Session5DateUtc": "2023-08-27 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 14,
- "Country": "Italy",
- "Location": "Monza",
- "OfficialEventName": "FORMULA 1 PIRELLI GRAN PREMIO D’ITALIA 2023 ",
- "EventDate": "2023-09-03",
- "EventName": "Italian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-09-01 13:30:00+02:00",
- "Session1DateUtc": "2023-09-01 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-09-01 17:00:00+02:00",
- "Session2DateUtc": "2023-09-01 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-09-02 12:30:00+02:00",
- "Session3DateUtc": "2023-09-02 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-09-02 16:00:00+02:00",
- "Session4DateUtc": "2023-09-02 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-09-03 15:00:00+02:00",
- "Session5DateUtc": "2023-09-03 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 15,
- "Country": "Singapore",
- "Location": "Marina Bay",
- "OfficialEventName": "FORMULA 1 SINGAPORE AIRLINES SINGAPORE GRAND PRIX 2023 ",
- "EventDate": "2023-09-17",
- "EventName": "Singapore Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-09-15 17:30:00+08:00",
- "Session1DateUtc": "2023-09-15 09:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-09-15 21:00:00+08:00",
- "Session2DateUtc": "2023-09-15 13:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-09-16 17:30:00+08:00",
- "Session3DateUtc": "2023-09-16 09:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-09-16 21:00:00+08:00",
- "Session4DateUtc": "2023-09-16 13:00:00",
- "Session5": "Race",
- "Session5Date": "2023-09-17 20:00:00+08:00",
- "Session5DateUtc": "2023-09-17 12:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 16,
- "Country": "Japan",
- "Location": "Suzuka",
- "OfficialEventName": "FORMULA 1 LENOVO JAPANESE GRAND PRIX 2023 ",
- "EventDate": "2023-09-24",
- "EventName": "Japanese Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-09-22 11:30:00+09:00",
- "Session1DateUtc": "2023-09-22 02:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-09-22 15:00:00+09:00",
- "Session2DateUtc": "2023-09-22 06:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-09-23 11:30:00+09:00",
- "Session3DateUtc": "2023-09-23 02:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-09-23 15:00:00+09:00",
- "Session4DateUtc": "2023-09-23 06:00:00",
- "Session5": "Race",
- "Session5Date": "2023-09-24 14:00:00+09:00",
- "Session5DateUtc": "2023-09-24 05:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 17,
- "Country": "Qatar",
- "Location": "Lusail",
- "OfficialEventName": "FORMULA 1 QATAR AIRWAYS QATAR GRAND PRIX 2023",
- "EventDate": "2023-10-08",
- "EventName": "Qatar Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-10-06 16:30:00+03:00",
- "Session1DateUtc": "2023-10-06 13:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-10-06 20:00:00+03:00",
- "Session2DateUtc": "2023-10-06 17:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-10-07 16:20:00+03:00",
- "Session3DateUtc": "2023-10-07 13:20:00",
- "Session4": "Sprint",
- "Session4Date": "2023-10-07 20:30:00+03:00",
- "Session4DateUtc": "2023-10-07 17:30:00",
- "Session5": "Race",
- "Session5Date": "2023-10-08 20:00:00+03:00",
- "Session5DateUtc": "2023-10-08 17:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 18,
- "Country": "United States",
- "Location": "Austin",
- "OfficialEventName": "FORMULA 1 LENOVO UNITED STATES GRAND PRIX 2023",
- "EventDate": "2023-10-22",
- "EventName": "United States Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-10-20 12:30:00-05:00",
- "Session1DateUtc": "2023-10-20 17:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-10-20 16:00:00-05:00",
- "Session2DateUtc": "2023-10-20 21:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-10-21 12:30:00-05:00",
- "Session3DateUtc": "2023-10-21 17:30:00",
- "Session4": "Sprint",
- "Session4Date": "2023-10-21 17:00:00-05:00",
- "Session4DateUtc": "2023-10-21 22:00:00",
- "Session5": "Race",
- "Session5Date": "2023-10-22 14:00:00-05:00",
- "Session5DateUtc": "2023-10-22 19:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 19,
- "Country": "Mexico",
- "Location": "Mexico City",
- "OfficialEventName": "FORMULA 1 GRAN PREMIO DE LA CIUDAD DE MÉXICO 2023",
- "EventDate": "2023-10-29",
- "EventName": "Mexico City Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-10-27 12:30:00-06:00",
- "Session1DateUtc": "2023-10-27 18:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-10-27 16:00:00-06:00",
- "Session2DateUtc": "2023-10-27 22:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-10-28 11:30:00-06:00",
- "Session3DateUtc": "2023-10-28 17:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-10-28 15:00:00-06:00",
- "Session4DateUtc": "2023-10-28 21:00:00",
- "Session5": "Race",
- "Session5Date": "2023-10-29 14:00:00-06:00",
- "Session5DateUtc": "2023-10-29 20:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 20,
- "Country": "Brazil",
- "Location": "São Paulo",
- "OfficialEventName": "FORMULA 1 ROLEX GRANDE PRÊMIO DE SÃO PAULO 2023",
- "EventDate": "2023-11-05",
- "EventName": "São Paulo Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-11-03 11:30:00-03:00",
- "Session1DateUtc": "2023-11-03 14:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-11-03 15:00:00-03:00",
- "Session2DateUtc": "2023-11-03 18:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-11-04 11:00:00-03:00",
- "Session3DateUtc": "2023-11-04 14:00:00",
- "Session4": "Sprint",
- "Session4Date": "2023-11-04 15:30:00-03:00",
- "Session4DateUtc": "2023-11-04 18:30:00",
- "Session5": "Race",
- "Session5Date": "2023-11-05 14:00:00-03:00",
- "Session5DateUtc": "2023-11-05 17:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 21,
- "Country": "United States",
- "Location": "Las Vegas",
- "OfficialEventName": "FORMULA 1 HEINEKEN SILVER LAS VEGAS GRAND PRIX 2023",
- "EventDate": "2023-11-18",
- "EventName": "Las Vegas Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-11-16 20:30:00-08:00",
- "Session1DateUtc": "2023-11-17 04:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-11-17 02:30:00-08:00",
- "Session2DateUtc": "2023-11-17 10:30:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-11-17 20:30:00-08:00",
- "Session3DateUtc": "2023-11-18 04:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-11-18 00:00:00-08:00",
- "Session4DateUtc": "2023-11-18 08:00:00",
- "Session5": "Race",
- "Session5Date": "2023-11-18 22:00:00-08:00",
- "Session5DateUtc": "2023-11-19 06:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 22,
- "Country": "Abu Dhabi",
- "Location": "Yas Island",
- "OfficialEventName": "FORMULA 1 ETIHAD AIRWAYS ABU DHABI GRAND PRIX 2023 ",
- "EventDate": "2023-11-26",
- "EventName": "Abu Dhabi Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-11-24 13:30:00+04:00",
- "Session1DateUtc": "2023-11-24 09:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-11-24 17:00:00+04:00",
- "Session2DateUtc": "2023-11-24 13:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-11-25 14:30:00+04:00",
- "Session3DateUtc": "2023-11-25 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-11-25 18:00:00+04:00",
- "Session4DateUtc": "2023-11-25 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-11-26 17:00:00+04:00",
- "Session5DateUtc": "2023-11-26 13:00:00",
- "F1ApiSupport": True,
- },
- ],
- }
-
-
-def test_get_schedule_good_year():
- response = client.get("/schedule?year=2023")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {
- "year": 2023,
- "EventSchedule": [
- {
- "RoundNumber": 1,
- "Country": "Bahrain",
- "Location": "Sakhir",
- "OfficialEventName": "FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2023",
- "EventDate": "2023-03-05",
- "EventName": "Bahrain Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-03-03 14:30:00+03:00",
- "Session1DateUtc": "2023-03-03 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-03-03 18:00:00+03:00",
- "Session2DateUtc": "2023-03-03 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-03-04 14:30:00+03:00",
- "Session3DateUtc": "2023-03-04 11:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-03-04 18:00:00+03:00",
- "Session4DateUtc": "2023-03-04 15:00:00",
- "Session5": "Race",
- "Session5Date": "2023-03-05 18:00:00+03:00",
- "Session5DateUtc": "2023-03-05 15:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 2,
- "Country": "Saudi Arabia",
- "Location": "Jeddah",
- "OfficialEventName": "FORMULA 1 STC SAUDI ARABIAN GRAND PRIX 2023",
- "EventDate": "2023-03-19",
- "EventName": "Saudi Arabian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-03-17 16:30:00+03:00",
- "Session1DateUtc": "2023-03-17 13:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-03-17 20:00:00+03:00",
- "Session2DateUtc": "2023-03-17 17:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-03-18 16:30:00+03:00",
- "Session3DateUtc": "2023-03-18 13:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-03-18 20:00:00+03:00",
- "Session4DateUtc": "2023-03-18 17:00:00",
- "Session5": "Race",
- "Session5Date": "2023-03-19 20:00:00+03:00",
- "Session5DateUtc": "2023-03-19 17:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 3,
- "Country": "Australia",
- "Location": "Melbourne",
- "OfficialEventName": "FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX 2023",
- "EventDate": "2023-04-02",
- "EventName": "Australian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-03-31 12:30:00+10:00",
- "Session1DateUtc": "2023-03-31 02:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-03-31 16:00:00+10:00",
- "Session2DateUtc": "2023-03-31 06:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-04-01 12:30:00+10:00",
- "Session3DateUtc": "2023-04-01 02:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-04-01 16:00:00+10:00",
- "Session4DateUtc": "2023-04-01 06:00:00",
- "Session5": "Race",
- "Session5Date": "2023-04-02 15:00:00+10:00",
- "Session5DateUtc": "2023-04-02 05:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 4,
- "Country": "Azerbaijan",
- "Location": "Baku",
- "OfficialEventName": "FORMULA 1 AZERBAIJAN GRAND PRIX 2023",
- "EventDate": "2023-04-30",
- "EventName": "Azerbaijan Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-04-28 13:30:00+04:00",
- "Session1DateUtc": "2023-04-28 09:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-04-28 17:00:00+04:00",
- "Session2DateUtc": "2023-04-28 13:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-04-29 12:30:00+04:00",
- "Session3DateUtc": "2023-04-29 08:30:00",
- "Session4": "Sprint",
- "Session4Date": "2023-04-29 17:30:00+04:00",
- "Session4DateUtc": "2023-04-29 13:30:00",
- "Session5": "Race",
- "Session5Date": "2023-04-30 15:00:00+04:00",
- "Session5DateUtc": "2023-04-30 11:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 5,
- "Country": "United States",
- "Location": "Miami",
- "OfficialEventName": "FORMULA 1 CRYPTO.COM MIAMI GRAND PRIX 2023",
- "EventDate": "2023-05-07",
- "EventName": "Miami Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-05-05 14:00:00-04:00",
- "Session1DateUtc": "2023-05-05 18:00:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-05-05 17:30:00-04:00",
- "Session2DateUtc": "2023-05-05 21:30:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-05-06 12:30:00-04:00",
- "Session3DateUtc": "2023-05-06 16:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-05-06 16:00:00-04:00",
- "Session4DateUtc": "2023-05-06 20:00:00",
- "Session5": "Race",
- "Session5Date": "2023-05-07 15:30:00-04:00",
- "Session5DateUtc": "2023-05-07 19:30:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 6,
- "Country": "Monaco",
- "Location": "Monaco",
- "OfficialEventName": "FORMULA 1 GRAND PRIX DE MONACO 2023",
- "EventDate": "2023-05-28",
- "EventName": "Monaco Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-05-26 13:30:00+02:00",
- "Session1DateUtc": "2023-05-26 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-05-26 17:00:00+02:00",
- "Session2DateUtc": "2023-05-26 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-05-27 12:30:00+02:00",
- "Session3DateUtc": "2023-05-27 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-05-27 16:00:00+02:00",
- "Session4DateUtc": "2023-05-27 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-05-28 15:00:00+02:00",
- "Session5DateUtc": "2023-05-28 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 7,
- "Country": "Spain",
- "Location": "Barcelona",
- "OfficialEventName": "FORMULA 1 AWS GRAN PREMIO DE ESPAÑA 2023",
- "EventDate": "2023-06-04",
- "EventName": "Spanish Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-06-02 13:30:00+02:00",
- "Session1DateUtc": "2023-06-02 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-06-02 17:00:00+02:00",
- "Session2DateUtc": "2023-06-02 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-06-03 12:30:00+02:00",
- "Session3DateUtc": "2023-06-03 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-06-03 16:00:00+02:00",
- "Session4DateUtc": "2023-06-03 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-06-04 15:00:00+02:00",
- "Session5DateUtc": "2023-06-04 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 8,
- "Country": "Canada",
- "Location": "Montréal",
- "OfficialEventName": "FORMULA 1 PIRELLI GRAND PRIX DU CANADA 2023",
- "EventDate": "2023-06-18",
- "EventName": "Canadian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-06-16 13:30:00-04:00",
- "Session1DateUtc": "2023-06-16 17:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-06-16 16:30:00-04:00",
- "Session2DateUtc": "2023-06-16 20:30:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-06-17 12:30:00-04:00",
- "Session3DateUtc": "2023-06-17 16:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-06-17 16:00:00-04:00",
- "Session4DateUtc": "2023-06-17 20:00:00",
- "Session5": "Race",
- "Session5Date": "2023-06-18 14:00:00-04:00",
- "Session5DateUtc": "2023-06-18 18:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 9,
- "Country": "Austria",
- "Location": "Spielberg",
- "OfficialEventName": "FORMULA 1 ROLEX GROSSER PREIS VON ÖSTERREICH 2023",
- "EventDate": "2023-07-02",
- "EventName": "Austrian Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-06-30 13:30:00+02:00",
- "Session1DateUtc": "2023-06-30 11:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-06-30 17:00:00+02:00",
- "Session2DateUtc": "2023-06-30 15:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-07-01 12:00:00+02:00",
- "Session3DateUtc": "2023-07-01 10:00:00",
- "Session4": "Sprint",
- "Session4Date": "2023-07-01 16:30:00+02:00",
- "Session4DateUtc": "2023-07-01 14:30:00",
- "Session5": "Race",
- "Session5Date": "2023-07-02 15:00:00+02:00",
- "Session5DateUtc": "2023-07-02 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 10,
- "Country": "Great Britain",
- "Location": "Silverstone",
- "OfficialEventName": "FORMULA 1 ARAMCO BRITISH GRAND PRIX 2023",
- "EventDate": "2023-07-09",
- "EventName": "British Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-07-07 12:30:00+01:00",
- "Session1DateUtc": "2023-07-07 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-07-07 16:00:00+01:00",
- "Session2DateUtc": "2023-07-07 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-07-08 11:30:00+01:00",
- "Session3DateUtc": "2023-07-08 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-07-08 15:00:00+01:00",
- "Session4DateUtc": "2023-07-08 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-07-09 15:00:00+01:00",
- "Session5DateUtc": "2023-07-09 14:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 11,
- "Country": "Hungary",
- "Location": "Budapest",
- "OfficialEventName": "FORMULA 1 QATAR AIRWAYS HUNGARIAN GRAND PRIX 2023",
- "EventDate": "2023-07-23",
- "EventName": "Hungarian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-07-21 13:30:00+02:00",
- "Session1DateUtc": "2023-07-21 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-07-21 17:00:00+02:00",
- "Session2DateUtc": "2023-07-21 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-07-22 12:30:00+02:00",
- "Session3DateUtc": "2023-07-22 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-07-22 16:00:00+02:00",
- "Session4DateUtc": "2023-07-22 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-07-23 15:00:00+02:00",
- "Session5DateUtc": "2023-07-23 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 12,
- "Country": "Belgium",
- "Location": "Spa-Francorchamps",
- "OfficialEventName": "FORMULA 1 MSC CRUISES BELGIAN GRAND PRIX 2023",
- "EventDate": "2023-07-30",
- "EventName": "Belgian Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-07-28 13:30:00+02:00",
- "Session1DateUtc": "2023-07-28 11:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-07-28 17:00:00+02:00",
- "Session2DateUtc": "2023-07-28 15:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-07-29 12:00:00+02:00",
- "Session3DateUtc": "2023-07-29 10:00:00",
- "Session4": "Sprint",
- "Session4Date": "2023-07-29 17:05:00+02:00",
- "Session4DateUtc": "2023-07-29 15:05:00",
- "Session5": "Race",
- "Session5Date": "2023-07-30 15:00:00+02:00",
- "Session5DateUtc": "2023-07-30 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 13,
- "Country": "Netherlands",
- "Location": "Zandvoort",
- "OfficialEventName": "FORMULA 1 HEINEKEN DUTCH GRAND PRIX 2023",
- "EventDate": "2023-08-27",
- "EventName": "Dutch Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-08-25 12:30:00+02:00",
- "Session1DateUtc": "2023-08-25 10:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-08-25 16:00:00+02:00",
- "Session2DateUtc": "2023-08-25 14:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-08-26 11:30:00+02:00",
- "Session3DateUtc": "2023-08-26 09:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-08-26 15:00:00+02:00",
- "Session4DateUtc": "2023-08-26 13:00:00",
- "Session5": "Race",
- "Session5Date": "2023-08-27 15:00:00+02:00",
- "Session5DateUtc": "2023-08-27 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 14,
- "Country": "Italy",
- "Location": "Monza",
- "OfficialEventName": "FORMULA 1 PIRELLI GRAN PREMIO D’ITALIA 2023 ",
- "EventDate": "2023-09-03",
- "EventName": "Italian Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-09-01 13:30:00+02:00",
- "Session1DateUtc": "2023-09-01 11:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-09-01 17:00:00+02:00",
- "Session2DateUtc": "2023-09-01 15:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-09-02 12:30:00+02:00",
- "Session3DateUtc": "2023-09-02 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-09-02 16:00:00+02:00",
- "Session4DateUtc": "2023-09-02 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-09-03 15:00:00+02:00",
- "Session5DateUtc": "2023-09-03 13:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 15,
- "Country": "Singapore",
- "Location": "Marina Bay",
- "OfficialEventName": "FORMULA 1 SINGAPORE AIRLINES SINGAPORE GRAND PRIX 2023 ",
- "EventDate": "2023-09-17",
- "EventName": "Singapore Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-09-15 17:30:00+08:00",
- "Session1DateUtc": "2023-09-15 09:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-09-15 21:00:00+08:00",
- "Session2DateUtc": "2023-09-15 13:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-09-16 17:30:00+08:00",
- "Session3DateUtc": "2023-09-16 09:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-09-16 21:00:00+08:00",
- "Session4DateUtc": "2023-09-16 13:00:00",
- "Session5": "Race",
- "Session5Date": "2023-09-17 20:00:00+08:00",
- "Session5DateUtc": "2023-09-17 12:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 16,
- "Country": "Japan",
- "Location": "Suzuka",
- "OfficialEventName": "FORMULA 1 LENOVO JAPANESE GRAND PRIX 2023 ",
- "EventDate": "2023-09-24",
- "EventName": "Japanese Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-09-22 11:30:00+09:00",
- "Session1DateUtc": "2023-09-22 02:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-09-22 15:00:00+09:00",
- "Session2DateUtc": "2023-09-22 06:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-09-23 11:30:00+09:00",
- "Session3DateUtc": "2023-09-23 02:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-09-23 15:00:00+09:00",
- "Session4DateUtc": "2023-09-23 06:00:00",
- "Session5": "Race",
- "Session5Date": "2023-09-24 14:00:00+09:00",
- "Session5DateUtc": "2023-09-24 05:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 17,
- "Country": "Qatar",
- "Location": "Lusail",
- "OfficialEventName": "FORMULA 1 QATAR AIRWAYS QATAR GRAND PRIX 2023",
- "EventDate": "2023-10-08",
- "EventName": "Qatar Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-10-06 16:30:00+03:00",
- "Session1DateUtc": "2023-10-06 13:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-10-06 20:00:00+03:00",
- "Session2DateUtc": "2023-10-06 17:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-10-07 16:20:00+03:00",
- "Session3DateUtc": "2023-10-07 13:20:00",
- "Session4": "Sprint",
- "Session4Date": "2023-10-07 20:30:00+03:00",
- "Session4DateUtc": "2023-10-07 17:30:00",
- "Session5": "Race",
- "Session5Date": "2023-10-08 20:00:00+03:00",
- "Session5DateUtc": "2023-10-08 17:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 18,
- "Country": "United States",
- "Location": "Austin",
- "OfficialEventName": "FORMULA 1 LENOVO UNITED STATES GRAND PRIX 2023",
- "EventDate": "2023-10-22",
- "EventName": "United States Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-10-20 12:30:00-05:00",
- "Session1DateUtc": "2023-10-20 17:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-10-20 16:00:00-05:00",
- "Session2DateUtc": "2023-10-20 21:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-10-21 12:30:00-05:00",
- "Session3DateUtc": "2023-10-21 17:30:00",
- "Session4": "Sprint",
- "Session4Date": "2023-10-21 17:00:00-05:00",
- "Session4DateUtc": "2023-10-21 22:00:00",
- "Session5": "Race",
- "Session5Date": "2023-10-22 14:00:00-05:00",
- "Session5DateUtc": "2023-10-22 19:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 19,
- "Country": "Mexico",
- "Location": "Mexico City",
- "OfficialEventName": "FORMULA 1 GRAN PREMIO DE LA CIUDAD DE MÉXICO 2023",
- "EventDate": "2023-10-29",
- "EventName": "Mexico City Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-10-27 12:30:00-06:00",
- "Session1DateUtc": "2023-10-27 18:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-10-27 16:00:00-06:00",
- "Session2DateUtc": "2023-10-27 22:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-10-28 11:30:00-06:00",
- "Session3DateUtc": "2023-10-28 17:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-10-28 15:00:00-06:00",
- "Session4DateUtc": "2023-10-28 21:00:00",
- "Session5": "Race",
- "Session5Date": "2023-10-29 14:00:00-06:00",
- "Session5DateUtc": "2023-10-29 20:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 20,
- "Country": "Brazil",
- "Location": "São Paulo",
- "OfficialEventName": "FORMULA 1 ROLEX GRANDE PRÊMIO DE SÃO PAULO 2023",
- "EventDate": "2023-11-05",
- "EventName": "São Paulo Grand Prix",
- "EventFormat": "sprint_shootout",
- "Session1": "Practice 1",
- "Session1Date": "2023-11-03 11:30:00-03:00",
- "Session1DateUtc": "2023-11-03 14:30:00",
- "Session2": "Qualifying",
- "Session2Date": "2023-11-03 15:00:00-03:00",
- "Session2DateUtc": "2023-11-03 18:00:00",
- "Session3": "Sprint Shootout",
- "Session3Date": "2023-11-04 11:00:00-03:00",
- "Session3DateUtc": "2023-11-04 14:00:00",
- "Session4": "Sprint",
- "Session4Date": "2023-11-04 15:30:00-03:00",
- "Session4DateUtc": "2023-11-04 18:30:00",
- "Session5": "Race",
- "Session5Date": "2023-11-05 14:00:00-03:00",
- "Session5DateUtc": "2023-11-05 17:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 21,
- "Country": "United States",
- "Location": "Las Vegas",
- "OfficialEventName": "FORMULA 1 HEINEKEN SILVER LAS VEGAS GRAND PRIX 2023",
- "EventDate": "2023-11-18",
- "EventName": "Las Vegas Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-11-16 20:30:00-08:00",
- "Session1DateUtc": "2023-11-17 04:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-11-17 02:30:00-08:00",
- "Session2DateUtc": "2023-11-17 10:30:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-11-17 20:30:00-08:00",
- "Session3DateUtc": "2023-11-18 04:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-11-18 00:00:00-08:00",
- "Session4DateUtc": "2023-11-18 08:00:00",
- "Session5": "Race",
- "Session5Date": "2023-11-18 22:00:00-08:00",
- "Session5DateUtc": "2023-11-19 06:00:00",
- "F1ApiSupport": True,
- },
- {
- "RoundNumber": 22,
- "Country": "Abu Dhabi",
- "Location": "Yas Island",
- "OfficialEventName": "FORMULA 1 ETIHAD AIRWAYS ABU DHABI GRAND PRIX 2023 ",
- "EventDate": "2023-11-26",
- "EventName": "Abu Dhabi Grand Prix",
- "EventFormat": "conventional",
- "Session1": "Practice 1",
- "Session1Date": "2023-11-24 13:30:00+04:00",
- "Session1DateUtc": "2023-11-24 09:30:00",
- "Session2": "Practice 2",
- "Session2Date": "2023-11-24 17:00:00+04:00",
- "Session2DateUtc": "2023-11-24 13:00:00",
- "Session3": "Practice 3",
- "Session3Date": "2023-11-25 14:30:00+04:00",
- "Session3DateUtc": "2023-11-25 10:30:00",
- "Session4": "Qualifying",
- "Session4Date": "2023-11-25 18:00:00+04:00",
- "Session4DateUtc": "2023-11-25 14:00:00",
- "Session5": "Race",
- "Session5Date": "2023-11-26 17:00:00+04:00",
- "Session5DateUtc": "2023-11-26 13:00:00",
- "F1ApiSupport": True,
- },
- ],
- }
-
-
-# endregion schedule - good inputs
-
-# endregion schedule
-
-
-# region standings
-
-# region standings - good inputs
-
-
-def test_get_standings():
- response = client.get("/standings")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {
- "season": 2023,
- "round": 22,
- "DriverStandings": [
- {
- "position": "1",
- "positionText": "1",
- "points": "575",
- "wins": "19",
- "Driver": {
- "driverId": "max_verstappen",
- "permanentNumber": "33",
- "code": "VER",
- "url": "http://en.wikipedia.org/wiki/Max_Verstappen",
- "givenName": "Max",
- "familyName": "Verstappen",
- "dateOfBirth": "1997-09-30",
- "nationality": "Dutch",
- },
- "Constructors": [
- {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- }
- ],
- },
- {
- "position": "2",
- "positionText": "2",
- "points": "285",
- "wins": "2",
- "Driver": {
- "driverId": "perez",
- "permanentNumber": "11",
- "code": "PER",
- "url": "http://en.wikipedia.org/wiki/Sergio_P%C3%A9rez",
- "givenName": "Sergio",
- "familyName": "Pérez",
- "dateOfBirth": "1990-01-26",
- "nationality": "Mexican",
- },
- "Constructors": [
- {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- }
- ],
- },
- {
- "position": "3",
- "positionText": "3",
- "points": "234",
- "wins": "0",
- "Driver": {
- "driverId": "hamilton",
- "permanentNumber": "44",
- "code": "HAM",
- "url": "http://en.wikipedia.org/wiki/Lewis_Hamilton",
- "givenName": "Lewis",
- "familyName": "Hamilton",
- "dateOfBirth": "1985-01-07",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- }
- ],
- },
- {
- "position": "4",
- "positionText": "4",
- "points": "206",
- "wins": "0",
- "Driver": {
- "driverId": "alonso",
- "permanentNumber": "14",
- "code": "ALO",
- "url": "http://en.wikipedia.org/wiki/Fernando_Alonso",
- "givenName": "Fernando",
- "familyName": "Alonso",
- "dateOfBirth": "1981-07-29",
- "nationality": "Spanish",
- },
- "Constructors": [
- {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "5",
- "positionText": "5",
- "points": "206",
- "wins": "0",
- "Driver": {
- "driverId": "leclerc",
- "permanentNumber": "16",
- "code": "LEC",
- "url": "http://en.wikipedia.org/wiki/Charles_Leclerc",
- "givenName": "Charles",
- "familyName": "Leclerc",
- "dateOfBirth": "1997-10-16",
- "nationality": "Monegasque",
- },
- "Constructors": [
- {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "6",
- "positionText": "6",
- "points": "205",
- "wins": "0",
- "Driver": {
- "driverId": "norris",
- "permanentNumber": "4",
- "code": "NOR",
- "url": "http://en.wikipedia.org/wiki/Lando_Norris",
- "givenName": "Lando",
- "familyName": "Norris",
- "dateOfBirth": "1999-11-13",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "7",
- "positionText": "7",
- "points": "200",
- "wins": "1",
- "Driver": {
- "driverId": "sainz",
- "permanentNumber": "55",
- "code": "SAI",
- "url": "http://en.wikipedia.org/wiki/Carlos_Sainz_Jr.",
- "givenName": "Carlos",
- "familyName": "Sainz",
- "dateOfBirth": "1994-09-01",
- "nationality": "Spanish",
- },
- "Constructors": [
- {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "8",
- "positionText": "8",
- "points": "175",
- "wins": "0",
- "Driver": {
- "driverId": "russell",
- "permanentNumber": "63",
- "code": "RUS",
- "url": "http://en.wikipedia.org/wiki/George_Russell_(racing_driver)",
- "givenName": "George",
- "familyName": "Russell",
- "dateOfBirth": "1998-02-15",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- }
- ],
- },
- {
- "position": "9",
- "positionText": "9",
- "points": "97",
- "wins": "0",
- "Driver": {
- "driverId": "piastri",
- "permanentNumber": "81",
- "code": "PIA",
- "url": "http://en.wikipedia.org/wiki/Oscar_Piastri",
- "givenName": "Oscar",
- "familyName": "Piastri",
- "dateOfBirth": "2001-04-06",
- "nationality": "Australian",
- },
- "Constructors": [
- {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "10",
- "positionText": "10",
- "points": "74",
- "wins": "0",
- "Driver": {
- "driverId": "stroll",
- "permanentNumber": "18",
- "code": "STR",
- "url": "http://en.wikipedia.org/wiki/Lance_Stroll",
- "givenName": "Lance",
- "familyName": "Stroll",
- "dateOfBirth": "1998-10-29",
- "nationality": "Canadian",
- },
- "Constructors": [
- {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "11",
- "positionText": "11",
- "points": "62",
- "wins": "0",
- "Driver": {
- "driverId": "gasly",
- "permanentNumber": "10",
- "code": "GAS",
- "url": "http://en.wikipedia.org/wiki/Pierre_Gasly",
- "givenName": "Pierre",
- "familyName": "Gasly",
- "dateOfBirth": "1996-02-07",
- "nationality": "French",
- },
- "Constructors": [
- {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- }
- ],
- },
- {
- "position": "12",
- "positionText": "12",
- "points": "58",
- "wins": "0",
- "Driver": {
- "driverId": "ocon",
- "permanentNumber": "31",
- "code": "OCO",
- "url": "http://en.wikipedia.org/wiki/Esteban_Ocon",
- "givenName": "Esteban",
- "familyName": "Ocon",
- "dateOfBirth": "1996-09-17",
- "nationality": "French",
- },
- "Constructors": [
- {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- }
- ],
- },
- {
- "position": "13",
- "positionText": "13",
- "points": "27",
- "wins": "0",
- "Driver": {
- "driverId": "albon",
- "permanentNumber": "23",
- "code": "ALB",
- "url": "http://en.wikipedia.org/wiki/Alexander_Albon",
- "givenName": "Alexander",
- "familyName": "Albon",
- "dateOfBirth": "1996-03-23",
- "nationality": "Thai",
- },
- "Constructors": [
- {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "14",
- "positionText": "14",
- "points": "17",
- "wins": "0",
- "Driver": {
- "driverId": "tsunoda",
- "permanentNumber": "22",
- "code": "TSU",
- "url": "http://en.wikipedia.org/wiki/Yuki_Tsunoda",
- "givenName": "Yuki",
- "familyName": "Tsunoda",
- "dateOfBirth": "2000-05-11",
- "nationality": "Japanese",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "15",
- "positionText": "15",
- "points": "10",
- "wins": "0",
- "Driver": {
- "driverId": "bottas",
- "permanentNumber": "77",
- "code": "BOT",
- "url": "http://en.wikipedia.org/wiki/Valtteri_Bottas",
- "givenName": "Valtteri",
- "familyName": "Bottas",
- "dateOfBirth": "1989-08-28",
- "nationality": "Finnish",
- },
- "Constructors": [
- {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- }
- ],
- },
- {
- "position": "16",
- "positionText": "16",
- "points": "9",
- "wins": "0",
- "Driver": {
- "driverId": "hulkenberg",
- "permanentNumber": "27",
- "code": "HUL",
- "url": "http://en.wikipedia.org/wiki/Nico_H%C3%BClkenberg",
- "givenName": "Nico",
- "familyName": "Hülkenberg",
- "dateOfBirth": "1987-08-19",
- "nationality": "German",
- },
- "Constructors": [
- {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- }
- ],
- },
- {
- "position": "17",
- "positionText": "17",
- "points": "6",
- "wins": "0",
- "Driver": {
- "driverId": "ricciardo",
- "permanentNumber": "3",
- "code": "RIC",
- "url": "http://en.wikipedia.org/wiki/Daniel_Ricciardo",
- "givenName": "Daniel",
- "familyName": "Ricciardo",
- "dateOfBirth": "1989-07-01",
- "nationality": "Australian",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "18",
- "positionText": "18",
- "points": "6",
- "wins": "0",
- "Driver": {
- "driverId": "zhou",
- "permanentNumber": "24",
- "code": "ZHO",
- "url": "http://en.wikipedia.org/wiki/Zhou_Guanyu",
- "givenName": "Guanyu",
- "familyName": "Zhou",
- "dateOfBirth": "1999-05-30",
- "nationality": "Chinese",
- },
- "Constructors": [
- {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- }
- ],
- },
- {
- "position": "19",
- "positionText": "19",
- "points": "3",
- "wins": "0",
- "Driver": {
- "driverId": "kevin_magnussen",
- "permanentNumber": "20",
- "code": "MAG",
- "url": "http://en.wikipedia.org/wiki/Kevin_Magnussen",
- "givenName": "Kevin",
- "familyName": "Magnussen",
- "dateOfBirth": "1992-10-05",
- "nationality": "Danish",
- },
- "Constructors": [
- {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- }
- ],
- },
- {
- "position": "20",
- "positionText": "20",
- "points": "2",
- "wins": "0",
- "Driver": {
- "driverId": "lawson",
- "permanentNumber": "40",
- "code": "LAW",
- "url": "http://en.wikipedia.org/wiki/Liam_Lawson",
- "givenName": "Liam",
- "familyName": "Lawson",
- "dateOfBirth": "2002-02-11",
- "nationality": "New Zealander",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "21",
- "positionText": "21",
- "points": "1",
- "wins": "0",
- "Driver": {
- "driverId": "sargeant",
- "permanentNumber": "2",
- "code": "SAR",
- "url": "http://en.wikipedia.org/wiki/Logan_Sargeant",
- "givenName": "Logan",
- "familyName": "Sargeant",
- "dateOfBirth": "2000-12-31",
- "nationality": "American",
- },
- "Constructors": [
- {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "22",
- "positionText": "22",
- "points": "0",
- "wins": "0",
- "Driver": {
- "driverId": "de_vries",
- "permanentNumber": "21",
- "code": "DEV",
- "url": "http://en.wikipedia.org/wiki/Nyck_de_Vries",
- "givenName": "Nyck",
- "familyName": "de Vries",
- "dateOfBirth": "1995-02-06",
- "nationality": "Dutch",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- ],
- "ConstructorStandings": [
- {
- "position": "1",
- "positionText": "1",
- "points": "860",
- "wins": "21",
- "Constructor": {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- },
- },
- {
- "position": "2",
- "positionText": "2",
- "points": "409",
- "wins": "0",
- "Constructor": {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- },
- },
- {
- "position": "3",
- "positionText": "3",
- "points": "406",
- "wins": "1",
- "Constructor": {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- },
- },
- {
- "position": "4",
- "positionText": "4",
- "points": "302",
- "wins": "0",
- "Constructor": {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- },
- },
- {
- "position": "5",
- "positionText": "5",
- "points": "280",
- "wins": "0",
- "Constructor": {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- },
- },
- {
- "position": "6",
- "positionText": "6",
- "points": "120",
- "wins": "0",
- "Constructor": {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- },
- },
- {
- "position": "7",
- "positionText": "7",
- "points": "28",
- "wins": "0",
- "Constructor": {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- },
- },
- {
- "position": "8",
- "positionText": "8",
- "points": "25",
- "wins": "0",
- "Constructor": {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- },
- },
- {
- "position": "9",
- "positionText": "9",
- "points": "16",
- "wins": "0",
- "Constructor": {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- },
- },
- {
- "position": "10",
- "positionText": "10",
- "points": "12",
- "wins": "0",
- "Constructor": {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- },
- },
- ],
- }
-
-
-def test_get_standings_good_year_only():
- response = client.get("/standings?year=2023")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {
- "season": 2023,
- "round": 22,
- "DriverStandings": [
- {
- "position": "1",
- "positionText": "1",
- "points": "575",
- "wins": "19",
- "Driver": {
- "driverId": "max_verstappen",
- "permanentNumber": "33",
- "code": "VER",
- "url": "http://en.wikipedia.org/wiki/Max_Verstappen",
- "givenName": "Max",
- "familyName": "Verstappen",
- "dateOfBirth": "1997-09-30",
- "nationality": "Dutch",
- },
- "Constructors": [
- {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- }
- ],
- },
- {
- "position": "2",
- "positionText": "2",
- "points": "285",
- "wins": "2",
- "Driver": {
- "driverId": "perez",
- "permanentNumber": "11",
- "code": "PER",
- "url": "http://en.wikipedia.org/wiki/Sergio_P%C3%A9rez",
- "givenName": "Sergio",
- "familyName": "Pérez",
- "dateOfBirth": "1990-01-26",
- "nationality": "Mexican",
- },
- "Constructors": [
- {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- }
- ],
- },
- {
- "position": "3",
- "positionText": "3",
- "points": "234",
- "wins": "0",
- "Driver": {
- "driverId": "hamilton",
- "permanentNumber": "44",
- "code": "HAM",
- "url": "http://en.wikipedia.org/wiki/Lewis_Hamilton",
- "givenName": "Lewis",
- "familyName": "Hamilton",
- "dateOfBirth": "1985-01-07",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- }
- ],
- },
- {
- "position": "4",
- "positionText": "4",
- "points": "206",
- "wins": "0",
- "Driver": {
- "driverId": "alonso",
- "permanentNumber": "14",
- "code": "ALO",
- "url": "http://en.wikipedia.org/wiki/Fernando_Alonso",
- "givenName": "Fernando",
- "familyName": "Alonso",
- "dateOfBirth": "1981-07-29",
- "nationality": "Spanish",
- },
- "Constructors": [
- {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "5",
- "positionText": "5",
- "points": "206",
- "wins": "0",
- "Driver": {
- "driverId": "leclerc",
- "permanentNumber": "16",
- "code": "LEC",
- "url": "http://en.wikipedia.org/wiki/Charles_Leclerc",
- "givenName": "Charles",
- "familyName": "Leclerc",
- "dateOfBirth": "1997-10-16",
- "nationality": "Monegasque",
- },
- "Constructors": [
- {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "6",
- "positionText": "6",
- "points": "205",
- "wins": "0",
- "Driver": {
- "driverId": "norris",
- "permanentNumber": "4",
- "code": "NOR",
- "url": "http://en.wikipedia.org/wiki/Lando_Norris",
- "givenName": "Lando",
- "familyName": "Norris",
- "dateOfBirth": "1999-11-13",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "7",
- "positionText": "7",
- "points": "200",
- "wins": "1",
- "Driver": {
- "driverId": "sainz",
- "permanentNumber": "55",
- "code": "SAI",
- "url": "http://en.wikipedia.org/wiki/Carlos_Sainz_Jr.",
- "givenName": "Carlos",
- "familyName": "Sainz",
- "dateOfBirth": "1994-09-01",
- "nationality": "Spanish",
- },
- "Constructors": [
- {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "8",
- "positionText": "8",
- "points": "175",
- "wins": "0",
- "Driver": {
- "driverId": "russell",
- "permanentNumber": "63",
- "code": "RUS",
- "url": "http://en.wikipedia.org/wiki/George_Russell_(racing_driver)",
- "givenName": "George",
- "familyName": "Russell",
- "dateOfBirth": "1998-02-15",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- }
- ],
- },
- {
- "position": "9",
- "positionText": "9",
- "points": "97",
- "wins": "0",
- "Driver": {
- "driverId": "piastri",
- "permanentNumber": "81",
- "code": "PIA",
- "url": "http://en.wikipedia.org/wiki/Oscar_Piastri",
- "givenName": "Oscar",
- "familyName": "Piastri",
- "dateOfBirth": "2001-04-06",
- "nationality": "Australian",
- },
- "Constructors": [
- {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "10",
- "positionText": "10",
- "points": "74",
- "wins": "0",
- "Driver": {
- "driverId": "stroll",
- "permanentNumber": "18",
- "code": "STR",
- "url": "http://en.wikipedia.org/wiki/Lance_Stroll",
- "givenName": "Lance",
- "familyName": "Stroll",
- "dateOfBirth": "1998-10-29",
- "nationality": "Canadian",
- },
- "Constructors": [
- {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "11",
- "positionText": "11",
- "points": "62",
- "wins": "0",
- "Driver": {
- "driverId": "gasly",
- "permanentNumber": "10",
- "code": "GAS",
- "url": "http://en.wikipedia.org/wiki/Pierre_Gasly",
- "givenName": "Pierre",
- "familyName": "Gasly",
- "dateOfBirth": "1996-02-07",
- "nationality": "French",
- },
- "Constructors": [
- {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- }
- ],
- },
- {
- "position": "12",
- "positionText": "12",
- "points": "58",
- "wins": "0",
- "Driver": {
- "driverId": "ocon",
- "permanentNumber": "31",
- "code": "OCO",
- "url": "http://en.wikipedia.org/wiki/Esteban_Ocon",
- "givenName": "Esteban",
- "familyName": "Ocon",
- "dateOfBirth": "1996-09-17",
- "nationality": "French",
- },
- "Constructors": [
- {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- }
- ],
- },
- {
- "position": "13",
- "positionText": "13",
- "points": "27",
- "wins": "0",
- "Driver": {
- "driverId": "albon",
- "permanentNumber": "23",
- "code": "ALB",
- "url": "http://en.wikipedia.org/wiki/Alexander_Albon",
- "givenName": "Alexander",
- "familyName": "Albon",
- "dateOfBirth": "1996-03-23",
- "nationality": "Thai",
- },
- "Constructors": [
- {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "14",
- "positionText": "14",
- "points": "17",
- "wins": "0",
- "Driver": {
- "driverId": "tsunoda",
- "permanentNumber": "22",
- "code": "TSU",
- "url": "http://en.wikipedia.org/wiki/Yuki_Tsunoda",
- "givenName": "Yuki",
- "familyName": "Tsunoda",
- "dateOfBirth": "2000-05-11",
- "nationality": "Japanese",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "15",
- "positionText": "15",
- "points": "10",
- "wins": "0",
- "Driver": {
- "driverId": "bottas",
- "permanentNumber": "77",
- "code": "BOT",
- "url": "http://en.wikipedia.org/wiki/Valtteri_Bottas",
- "givenName": "Valtteri",
- "familyName": "Bottas",
- "dateOfBirth": "1989-08-28",
- "nationality": "Finnish",
- },
- "Constructors": [
- {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- }
- ],
- },
- {
- "position": "16",
- "positionText": "16",
- "points": "9",
- "wins": "0",
- "Driver": {
- "driverId": "hulkenberg",
- "permanentNumber": "27",
- "code": "HUL",
- "url": "http://en.wikipedia.org/wiki/Nico_H%C3%BClkenberg",
- "givenName": "Nico",
- "familyName": "Hülkenberg",
- "dateOfBirth": "1987-08-19",
- "nationality": "German",
- },
- "Constructors": [
- {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- }
- ],
- },
- {
- "position": "17",
- "positionText": "17",
- "points": "6",
- "wins": "0",
- "Driver": {
- "driverId": "ricciardo",
- "permanentNumber": "3",
- "code": "RIC",
- "url": "http://en.wikipedia.org/wiki/Daniel_Ricciardo",
- "givenName": "Daniel",
- "familyName": "Ricciardo",
- "dateOfBirth": "1989-07-01",
- "nationality": "Australian",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "18",
- "positionText": "18",
- "points": "6",
- "wins": "0",
- "Driver": {
- "driverId": "zhou",
- "permanentNumber": "24",
- "code": "ZHO",
- "url": "http://en.wikipedia.org/wiki/Zhou_Guanyu",
- "givenName": "Guanyu",
- "familyName": "Zhou",
- "dateOfBirth": "1999-05-30",
- "nationality": "Chinese",
- },
- "Constructors": [
- {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- }
- ],
- },
- {
- "position": "19",
- "positionText": "19",
- "points": "3",
- "wins": "0",
- "Driver": {
- "driverId": "kevin_magnussen",
- "permanentNumber": "20",
- "code": "MAG",
- "url": "http://en.wikipedia.org/wiki/Kevin_Magnussen",
- "givenName": "Kevin",
- "familyName": "Magnussen",
- "dateOfBirth": "1992-10-05",
- "nationality": "Danish",
- },
- "Constructors": [
- {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- }
- ],
- },
- {
- "position": "20",
- "positionText": "20",
- "points": "2",
- "wins": "0",
- "Driver": {
- "driverId": "lawson",
- "permanentNumber": "40",
- "code": "LAW",
- "url": "http://en.wikipedia.org/wiki/Liam_Lawson",
- "givenName": "Liam",
- "familyName": "Lawson",
- "dateOfBirth": "2002-02-11",
- "nationality": "New Zealander",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "21",
- "positionText": "21",
- "points": "1",
- "wins": "0",
- "Driver": {
- "driverId": "sargeant",
- "permanentNumber": "2",
- "code": "SAR",
- "url": "http://en.wikipedia.org/wiki/Logan_Sargeant",
- "givenName": "Logan",
- "familyName": "Sargeant",
- "dateOfBirth": "2000-12-31",
- "nationality": "American",
- },
- "Constructors": [
- {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "22",
- "positionText": "22",
- "points": "0",
- "wins": "0",
- "Driver": {
- "driverId": "de_vries",
- "permanentNumber": "21",
- "code": "DEV",
- "url": "http://en.wikipedia.org/wiki/Nyck_de_Vries",
- "givenName": "Nyck",
- "familyName": "de Vries",
- "dateOfBirth": "1995-02-06",
- "nationality": "Dutch",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- ],
- "ConstructorStandings": [
- {
- "position": "1",
- "positionText": "1",
- "points": "860",
- "wins": "21",
- "Constructor": {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- },
- },
- {
- "position": "2",
- "positionText": "2",
- "points": "409",
- "wins": "0",
- "Constructor": {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- },
- },
- {
- "position": "3",
- "positionText": "3",
- "points": "406",
- "wins": "1",
- "Constructor": {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- },
- },
- {
- "position": "4",
- "positionText": "4",
- "points": "302",
- "wins": "0",
- "Constructor": {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- },
- },
- {
- "position": "5",
- "positionText": "5",
- "points": "280",
- "wins": "0",
- "Constructor": {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- },
- },
- {
- "position": "6",
- "positionText": "6",
- "points": "120",
- "wins": "0",
- "Constructor": {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- },
- },
- {
- "position": "7",
- "positionText": "7",
- "points": "28",
- "wins": "0",
- "Constructor": {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- },
- },
- {
- "position": "8",
- "positionText": "8",
- "points": "25",
- "wins": "0",
- "Constructor": {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- },
- },
- {
- "position": "9",
- "positionText": "9",
- "points": "16",
- "wins": "0",
- "Constructor": {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- },
- },
- {
- "position": "10",
- "positionText": "10",
- "points": "12",
- "wins": "0",
- "Constructor": {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- },
- },
- ],
- }
-
-
-def test_get_standings_good_year_and_round():
- response = client.get("/standings?year=2023&round=5")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == {
- "season": 2023,
- "round": 5,
- "DriverStandings": [
- {
- "position": "1",
- "positionText": "1",
- "points": "119",
- "wins": "3",
- "Driver": {
- "driverId": "max_verstappen",
- "permanentNumber": "33",
- "code": "VER",
- "url": "http://en.wikipedia.org/wiki/Max_Verstappen",
- "givenName": "Max",
- "familyName": "Verstappen",
- "dateOfBirth": "1997-09-30",
- "nationality": "Dutch",
- },
- "Constructors": [
- {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- }
- ],
- },
- {
- "position": "2",
- "positionText": "2",
- "points": "105",
- "wins": "2",
- "Driver": {
- "driverId": "perez",
- "permanentNumber": "11",
- "code": "PER",
- "url": "http://en.wikipedia.org/wiki/Sergio_P%C3%A9rez",
- "givenName": "Sergio",
- "familyName": "Pérez",
- "dateOfBirth": "1990-01-26",
- "nationality": "Mexican",
- },
- "Constructors": [
- {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- }
- ],
- },
- {
- "position": "3",
- "positionText": "3",
- "points": "75",
- "wins": "0",
- "Driver": {
- "driverId": "alonso",
- "permanentNumber": "14",
- "code": "ALO",
- "url": "http://en.wikipedia.org/wiki/Fernando_Alonso",
- "givenName": "Fernando",
- "familyName": "Alonso",
- "dateOfBirth": "1981-07-29",
- "nationality": "Spanish",
- },
- "Constructors": [
- {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "4",
- "positionText": "4",
- "points": "56",
- "wins": "0",
- "Driver": {
- "driverId": "hamilton",
- "permanentNumber": "44",
- "code": "HAM",
- "url": "http://en.wikipedia.org/wiki/Lewis_Hamilton",
- "givenName": "Lewis",
- "familyName": "Hamilton",
- "dateOfBirth": "1985-01-07",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- }
- ],
- },
- {
- "position": "5",
- "positionText": "5",
- "points": "44",
- "wins": "0",
- "Driver": {
- "driverId": "sainz",
- "permanentNumber": "55",
- "code": "SAI",
- "url": "http://en.wikipedia.org/wiki/Carlos_Sainz_Jr.",
- "givenName": "Carlos",
- "familyName": "Sainz",
- "dateOfBirth": "1994-09-01",
- "nationality": "Spanish",
- },
- "Constructors": [
- {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "6",
- "positionText": "6",
- "points": "40",
- "wins": "0",
- "Driver": {
- "driverId": "russell",
- "permanentNumber": "63",
- "code": "RUS",
- "url": "http://en.wikipedia.org/wiki/George_Russell_(racing_driver)",
- "givenName": "George",
- "familyName": "Russell",
- "dateOfBirth": "1998-02-15",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- }
- ],
- },
- {
- "position": "7",
- "positionText": "7",
- "points": "34",
- "wins": "0",
- "Driver": {
- "driverId": "leclerc",
- "permanentNumber": "16",
- "code": "LEC",
- "url": "http://en.wikipedia.org/wiki/Charles_Leclerc",
- "givenName": "Charles",
- "familyName": "Leclerc",
- "dateOfBirth": "1997-10-16",
- "nationality": "Monegasque",
- },
- "Constructors": [
- {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "8",
- "positionText": "8",
- "points": "27",
- "wins": "0",
- "Driver": {
- "driverId": "stroll",
- "permanentNumber": "18",
- "code": "STR",
- "url": "http://en.wikipedia.org/wiki/Lance_Stroll",
- "givenName": "Lance",
- "familyName": "Stroll",
- "dateOfBirth": "1998-10-29",
- "nationality": "Canadian",
- },
- "Constructors": [
- {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "9",
- "positionText": "9",
- "points": "10",
- "wins": "0",
- "Driver": {
- "driverId": "norris",
- "permanentNumber": "4",
- "code": "NOR",
- "url": "http://en.wikipedia.org/wiki/Lando_Norris",
- "givenName": "Lando",
- "familyName": "Norris",
- "dateOfBirth": "1999-11-13",
- "nationality": "British",
- },
- "Constructors": [
- {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "10",
- "positionText": "10",
- "points": "8",
- "wins": "0",
- "Driver": {
- "driverId": "gasly",
- "permanentNumber": "10",
- "code": "GAS",
- "url": "http://en.wikipedia.org/wiki/Pierre_Gasly",
- "givenName": "Pierre",
- "familyName": "Gasly",
- "dateOfBirth": "1996-02-07",
- "nationality": "French",
- },
- "Constructors": [
- {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- }
- ],
- },
- {
- "position": "11",
- "positionText": "11",
- "points": "6",
- "wins": "0",
- "Driver": {
- "driverId": "hulkenberg",
- "permanentNumber": "27",
- "code": "HUL",
- "url": "http://en.wikipedia.org/wiki/Nico_H%C3%BClkenberg",
- "givenName": "Nico",
- "familyName": "Hülkenberg",
- "dateOfBirth": "1987-08-19",
- "nationality": "German",
- },
- "Constructors": [
- {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- }
- ],
- },
- {
- "position": "12",
- "positionText": "12",
- "points": "6",
- "wins": "0",
- "Driver": {
- "driverId": "ocon",
- "permanentNumber": "31",
- "code": "OCO",
- "url": "http://en.wikipedia.org/wiki/Esteban_Ocon",
- "givenName": "Esteban",
- "familyName": "Ocon",
- "dateOfBirth": "1996-09-17",
- "nationality": "French",
- },
- "Constructors": [
- {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- }
- ],
- },
- {
- "position": "13",
- "positionText": "13",
- "points": "4",
- "wins": "0",
- "Driver": {
- "driverId": "bottas",
- "permanentNumber": "77",
- "code": "BOT",
- "url": "http://en.wikipedia.org/wiki/Valtteri_Bottas",
- "givenName": "Valtteri",
- "familyName": "Bottas",
- "dateOfBirth": "1989-08-28",
- "nationality": "Finnish",
- },
- "Constructors": [
- {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- }
- ],
- },
- {
- "position": "14",
- "positionText": "14",
- "points": "4",
- "wins": "0",
- "Driver": {
- "driverId": "piastri",
- "permanentNumber": "81",
- "code": "PIA",
- "url": "http://en.wikipedia.org/wiki/Oscar_Piastri",
- "givenName": "Oscar",
- "familyName": "Piastri",
- "dateOfBirth": "2001-04-06",
- "nationality": "Australian",
- },
- "Constructors": [
- {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "15",
- "positionText": "15",
- "points": "2",
- "wins": "0",
- "Driver": {
- "driverId": "zhou",
- "permanentNumber": "24",
- "code": "ZHO",
- "url": "http://en.wikipedia.org/wiki/Zhou_Guanyu",
- "givenName": "Guanyu",
- "familyName": "Zhou",
- "dateOfBirth": "1999-05-30",
- "nationality": "Chinese",
- },
- "Constructors": [
- {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- }
- ],
- },
- {
- "position": "16",
- "positionText": "16",
- "points": "2",
- "wins": "0",
- "Driver": {
- "driverId": "tsunoda",
- "permanentNumber": "22",
- "code": "TSU",
- "url": "http://en.wikipedia.org/wiki/Yuki_Tsunoda",
- "givenName": "Yuki",
- "familyName": "Tsunoda",
- "dateOfBirth": "2000-05-11",
- "nationality": "Japanese",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- {
- "position": "17",
- "positionText": "17",
- "points": "2",
- "wins": "0",
- "Driver": {
- "driverId": "kevin_magnussen",
- "permanentNumber": "20",
- "code": "MAG",
- "url": "http://en.wikipedia.org/wiki/Kevin_Magnussen",
- "givenName": "Kevin",
- "familyName": "Magnussen",
- "dateOfBirth": "1992-10-05",
- "nationality": "Danish",
- },
- "Constructors": [
- {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- }
- ],
- },
- {
- "position": "18",
- "positionText": "18",
- "points": "1",
- "wins": "0",
- "Driver": {
- "driverId": "albon",
- "permanentNumber": "23",
- "code": "ALB",
- "url": "http://en.wikipedia.org/wiki/Alexander_Albon",
- "givenName": "Alexander",
- "familyName": "Albon",
- "dateOfBirth": "1996-03-23",
- "nationality": "Thai",
- },
- "Constructors": [
- {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "19",
- "positionText": "19",
- "points": "0",
- "wins": "0",
- "Driver": {
- "driverId": "sargeant",
- "permanentNumber": "2",
- "code": "SAR",
- "url": "http://en.wikipedia.org/wiki/Logan_Sargeant",
- "givenName": "Logan",
- "familyName": "Sargeant",
- "dateOfBirth": "2000-12-31",
- "nationality": "American",
- },
- "Constructors": [
- {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- }
- ],
- },
- {
- "position": "20",
- "positionText": "20",
- "points": "0",
- "wins": "0",
- "Driver": {
- "driverId": "de_vries",
- "permanentNumber": "21",
- "code": "DEV",
- "url": "http://en.wikipedia.org/wiki/Nyck_de_Vries",
- "givenName": "Nyck",
- "familyName": "de Vries",
- "dateOfBirth": "1995-02-06",
- "nationality": "Dutch",
- },
- "Constructors": [
- {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- }
- ],
- },
- ],
- "ConstructorStandings": [
- {
- "position": "1",
- "positionText": "1",
- "points": "224",
- "wins": "5",
- "Constructor": {
- "constructorId": "red_bull",
- "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
- "name": "Red Bull",
- "nationality": "Austrian",
- },
- },
- {
- "position": "2",
- "positionText": "2",
- "points": "102",
- "wins": "0",
- "Constructor": {
- "constructorId": "aston_martin",
- "url": "http://en.wikipedia.org/wiki/Aston_Martin_in_Formula_One",
- "name": "Aston Martin",
- "nationality": "British",
- },
- },
- {
- "position": "3",
- "positionText": "3",
- "points": "96",
- "wins": "0",
- "Constructor": {
- "constructorId": "mercedes",
- "url": "http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One",
- "name": "Mercedes",
- "nationality": "German",
- },
- },
- {
- "position": "4",
- "positionText": "4",
- "points": "78",
- "wins": "0",
- "Constructor": {
- "constructorId": "ferrari",
- "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari",
- "name": "Ferrari",
- "nationality": "Italian",
- },
- },
- {
- "position": "5",
- "positionText": "5",
- "points": "14",
- "wins": "0",
- "Constructor": {
- "constructorId": "mclaren",
- "url": "http://en.wikipedia.org/wiki/McLaren",
- "name": "McLaren",
- "nationality": "British",
- },
- },
- {
- "position": "6",
- "positionText": "6",
- "points": "14",
- "wins": "0",
- "Constructor": {
- "constructorId": "alpine",
- "url": "http://en.wikipedia.org/wiki/Alpine_F1_Team",
- "name": "Alpine F1 Team",
- "nationality": "French",
- },
- },
- {
- "position": "7",
- "positionText": "7",
- "points": "8",
- "wins": "0",
- "Constructor": {
- "constructorId": "haas",
- "url": "http://en.wikipedia.org/wiki/Haas_F1_Team",
- "name": "Haas F1 Team",
- "nationality": "American",
- },
- },
- {
- "position": "8",
- "positionText": "8",
- "points": "6",
- "wins": "0",
- "Constructor": {
- "constructorId": "alfa",
- "url": "http://en.wikipedia.org/wiki/Alfa_Romeo_in_Formula_One",
- "name": "Alfa Romeo",
- "nationality": "Swiss",
- },
- },
- {
- "position": "9",
- "positionText": "9",
- "points": "2",
- "wins": "0",
- "Constructor": {
- "constructorId": "alphatauri",
- "url": "http://en.wikipedia.org/wiki/Scuderia_AlphaTauri",
- "name": "AlphaTauri",
- "nationality": "Italian",
- },
- },
- {
- "position": "10",
- "positionText": "10",
- "points": "1",
- "wins": "0",
- "Constructor": {
- "constructorId": "williams",
- "url": "http://en.wikipedia.org/wiki/Williams_Grand_Prix_Engineering",
- "name": "Williams",
- "nationality": "British",
- },
- },
- ],
- }
-
-
-# endregion standings - good inputs
-
-# region standings - no inputs
-
-
-def test_get_standings_good_round_bad_year_no_input():
- response = client.get("/standings?round=3")
- assert response.status_code == status.HTTP_400_BAD_REQUEST
- assert response.json() == {
- "detail": 'Bad request. Must provide the "year" parameter.'
- }
-
-
-# endregion standings - no inputs
-
-# endregion standings
-
-
-# region results
-
-# region results - good inputs
-
-
-def test_get_results():
- response = client.get("/results/2023/5")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == [
- {
- "DriverNumber": "1",
- "BroadcastName": "M VERSTAPPEN",
- "Abbreviation": "VER",
- "DriverId": "max_verstappen",
- "TeamName": "Red Bull Racing",
- "TeamColor": "3671C6",
- "TeamId": "red_bull",
- "FirstName": "Max",
- "LastName": "Verstappen",
- "FullName": "Max Verstappen",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/M/MAXVER01_Max_Verstappen/maxver01.png.transform/1col/image.png",
- "CountryCode": "NED",
- "Position": 1,
- "ClassifiedPosition": "1",
- "GridPosition": 9,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 5258241,
- "Status": "Finished",
- "Points": 26,
- },
- {
- "DriverNumber": "11",
- "BroadcastName": "S PEREZ",
- "Abbreviation": "PER",
- "DriverId": "perez",
- "TeamName": "Red Bull Racing",
- "TeamColor": "3671C6",
- "TeamId": "red_bull",
- "FirstName": "Sergio",
- "LastName": "Perez",
- "FullName": "Sergio Perez",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/S/SERPER01_Sergio_Perez/serper01.png.transform/1col/image.png",
- "CountryCode": "MEX",
- "Position": 2,
- "ClassifiedPosition": "2",
- "GridPosition": 1,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 5384,
- "Status": "Finished",
- "Points": 18,
- },
- {
- "DriverNumber": "14",
- "BroadcastName": "F ALONSO",
- "Abbreviation": "ALO",
- "DriverId": "alonso",
- "TeamName": "Aston Martin",
- "TeamColor": "358C75",
- "TeamId": "aston_martin",
- "FirstName": "Fernando",
- "LastName": "Alonso",
- "FullName": "Fernando Alonso",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/F/FERALO01_Fernando_Alonso/feralo01.png.transform/1col/image.png",
- "CountryCode": "ESP",
- "Position": 3,
- "ClassifiedPosition": "3",
- "GridPosition": 2,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 26305,
- "Status": "Finished",
- "Points": 15,
- },
- {
- "DriverNumber": "63",
- "BroadcastName": "G RUSSELL",
- "Abbreviation": "RUS",
- "DriverId": "russell",
- "TeamName": "Mercedes",
- "TeamColor": "6CD3BF",
- "TeamId": "mercedes",
- "FirstName": "George",
- "LastName": "Russell",
- "FullName": "George Russell",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/G/GEORUS01_George_Russell/georus01.png.transform/1col/image.png",
- "CountryCode": "GBR",
- "Position": 4,
- "ClassifiedPosition": "4",
- "GridPosition": 6,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 33229,
- "Status": "Finished",
- "Points": 12,
- },
- {
- "DriverNumber": "55",
- "BroadcastName": "C SAINZ",
- "Abbreviation": "SAI",
- "DriverId": "sainz",
- "TeamName": "Ferrari",
- "TeamColor": "F91536",
- "TeamId": "ferrari",
- "FirstName": "Carlos",
- "LastName": "Sainz",
- "FullName": "Carlos Sainz",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/C/CARSAI01_Carlos_Sainz/carsai01.png.transform/1col/image.png",
- "CountryCode": "ESP",
- "Position": 5,
- "ClassifiedPosition": "5",
- "GridPosition": 3,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 42511,
- "Status": "Finished",
- "Points": 10,
- },
- {
- "DriverNumber": "44",
- "BroadcastName": "L HAMILTON",
- "Abbreviation": "HAM",
- "DriverId": "hamilton",
- "TeamName": "Mercedes",
- "TeamColor": "6CD3BF",
- "TeamId": "mercedes",
- "FirstName": "Lewis",
- "LastName": "Hamilton",
- "FullName": "Lewis Hamilton",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/L/LEWHAM01_Lewis_Hamilton/lewham01.png.transform/1col/image.png",
- "CountryCode": "GBR",
- "Position": 6,
- "ClassifiedPosition": "6",
- "GridPosition": 13,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 51249,
- "Status": "Finished",
- "Points": 8,
- },
- {
- "DriverNumber": "16",
- "BroadcastName": "C LECLERC",
- "Abbreviation": "LEC",
- "DriverId": "leclerc",
- "TeamName": "Ferrari",
- "TeamColor": "F91536",
- "TeamId": "ferrari",
- "FirstName": "Charles",
- "LastName": "Leclerc",
- "FullName": "Charles Leclerc",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/C/CHALEC01_Charles_Leclerc/chalec01.png.transform/1col/image.png",
- "CountryCode": "MON",
- "Position": 7,
- "ClassifiedPosition": "7",
- "GridPosition": 7,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 52988,
- "Status": "Finished",
- "Points": 6,
- },
- {
- "DriverNumber": "10",
- "BroadcastName": "P GASLY",
- "Abbreviation": "GAS",
- "DriverId": "gasly",
- "TeamName": "Alpine",
- "TeamColor": "2293D1",
- "TeamId": "alpine",
- "FirstName": "Pierre",
- "LastName": "Gasly",
- "FullName": "Pierre Gasly",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/P/PIEGAS01_Pierre_Gasly/piegas01.png.transform/1col/image.png",
- "CountryCode": "FRA",
- "Position": 8,
- "ClassifiedPosition": "8",
- "GridPosition": 5,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 55670,
- "Status": "Finished",
- "Points": 4,
- },
- {
- "DriverNumber": "31",
- "BroadcastName": "E OCON",
- "Abbreviation": "OCO",
- "DriverId": "ocon",
- "TeamName": "Alpine",
- "TeamColor": "2293D1",
- "TeamId": "alpine",
- "FirstName": "Esteban",
- "LastName": "Ocon",
- "FullName": "Esteban Ocon",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/E/ESTOCO01_Esteban_Ocon/estoco01.png.transform/1col/image.png",
- "CountryCode": "FRA",
- "Position": 9,
- "ClassifiedPosition": "9",
- "GridPosition": 8,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 58123,
- "Status": "Finished",
- "Points": 2,
- },
- {
- "DriverNumber": "20",
- "BroadcastName": "K MAGNUSSEN",
- "Abbreviation": "MAG",
- "DriverId": "kevin_magnussen",
- "TeamName": "Haas F1 Team",
- "TeamColor": "B6BABD",
- "TeamId": "haas",
- "FirstName": "Kevin",
- "LastName": "Magnussen",
- "FullName": "Kevin Magnussen",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/K/KEVMAG01_Kevin_Magnussen/kevmag01.png.transform/1col/image.png",
- "CountryCode": "DEN",
- "Position": 10,
- "ClassifiedPosition": "10",
- "GridPosition": 4,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 62945,
- "Status": "Finished",
- "Points": 1,
- },
- {
- "DriverNumber": "22",
- "BroadcastName": "Y TSUNODA",
- "Abbreviation": "TSU",
- "DriverId": "tsunoda",
- "TeamName": "AlphaTauri",
- "TeamColor": "5E8FAA",
- "TeamId": "alphatauri",
- "FirstName": "Yuki",
- "LastName": "Tsunoda",
- "FullName": "Yuki Tsunoda",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/Y/YUKTSU01_Yuki_Tsunoda/yuktsu01.png.transform/1col/image.png",
- "CountryCode": "JPN",
- "Position": 11,
- "ClassifiedPosition": "11",
- "GridPosition": 17,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 64309,
- "Status": "Finished",
- "Points": 0,
- },
- {
- "DriverNumber": "18",
- "BroadcastName": "L STROLL",
- "Abbreviation": "STR",
- "DriverId": "stroll",
- "TeamName": "Aston Martin",
- "TeamColor": "358C75",
- "TeamId": "aston_martin",
- "FirstName": "Lance",
- "LastName": "Stroll",
- "FullName": "Lance Stroll",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/L/LANSTR01_Lance_Stroll/lanstr01.png.transform/1col/image.png",
- "CountryCode": "CAN",
- "Position": 12,
- "ClassifiedPosition": "12",
- "GridPosition": 18,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 64754,
- "Status": "Finished",
- "Points": 0,
- },
- {
- "DriverNumber": "77",
- "BroadcastName": "V BOTTAS",
- "Abbreviation": "BOT",
- "DriverId": "bottas",
- "TeamName": "Alfa Romeo",
- "TeamColor": "C92D4B",
- "TeamId": "alfa",
- "FirstName": "Valtteri",
- "LastName": "Bottas",
- "FullName": "Valtteri Bottas",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/V/VALBOT01_Valtteri_Bottas/valbot01.png.transform/1col/image.png",
- "CountryCode": "FIN",
- "Position": 13,
- "ClassifiedPosition": "13",
- "GridPosition": 10,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 71637,
- "Status": "Finished",
- "Points": 0,
- },
- {
- "DriverNumber": "23",
- "BroadcastName": "A ALBON",
- "Abbreviation": "ALB",
- "DriverId": "albon",
- "TeamName": "Williams",
- "TeamColor": "37BEDD",
- "TeamId": "williams",
- "FirstName": "Alexander",
- "LastName": "Albon",
- "FullName": "Alexander Albon",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/A/ALEALB01_Alexander_Albon/alealb01.png.transform/1col/image.png",
- "CountryCode": "THA",
- "Position": 14,
- "ClassifiedPosition": "14",
- "GridPosition": 11,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 72861,
- "Status": "Finished",
- "Points": 0,
- },
- {
- "DriverNumber": "27",
- "BroadcastName": "N HULKENBERG",
- "Abbreviation": "HUL",
- "DriverId": "hulkenberg",
- "TeamName": "Haas F1 Team",
- "TeamColor": "B6BABD",
- "TeamId": "haas",
- "FirstName": "Nico",
- "LastName": "Hulkenberg",
- "FullName": "Nico Hulkenberg",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/N/NICHUL01_Nico_Hulkenberg/nichul01.png.transform/1col/image.png",
- "CountryCode": "GER",
- "Position": 15,
- "ClassifiedPosition": "15",
- "GridPosition": 12,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 74950,
- "Status": "Finished",
- "Points": 0,
- },
- {
- "DriverNumber": "24",
- "BroadcastName": "G ZHOU",
- "Abbreviation": "ZHO",
- "DriverId": "zhou",
- "TeamName": "Alfa Romeo",
- "TeamColor": "C92D4B",
- "TeamId": "alfa",
- "FirstName": "Guanyu",
- "LastName": "Zhou",
- "FullName": "Guanyu Zhou",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/G/GUAZHO01_Guanyu_Zhou/guazho01.png.transform/1col/image.png",
- "CountryCode": "CHN",
- "Position": 16,
- "ClassifiedPosition": "16",
- "GridPosition": 14,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 78440,
- "Status": "Finished",
- "Points": 0,
- },
- {
- "DriverNumber": "4",
- "BroadcastName": "L NORRIS",
- "Abbreviation": "NOR",
- "DriverId": "norris",
- "TeamName": "McLaren",
- "TeamColor": "F58020",
- "TeamId": "mclaren",
- "FirstName": "Lando",
- "LastName": "Norris",
- "FullName": "Lando Norris",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/L/LANNOR01_Lando_Norris/lannor01.png.transform/1col/image.png",
- "CountryCode": "GBR",
- "Position": 17,
- "ClassifiedPosition": "17",
- "GridPosition": 16,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 87717,
- "Status": "Finished",
- "Points": 0,
- },
- {
- "DriverNumber": "21",
- "BroadcastName": "N DE VRIES",
- "Abbreviation": "DEV",
- "DriverId": "de_vries",
- "TeamName": "AlphaTauri",
- "TeamColor": "5E8FAA",
- "TeamId": "alphatauri",
- "FirstName": "Nyck",
- "LastName": "De Vries",
- "FullName": "Nyck De Vries",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/N/NYCDEV01_Nyck_De%20Vries/nycdev01.png.transform/1col/image.png",
- "CountryCode": "NED",
- "Position": 18,
- "ClassifiedPosition": "18",
- "GridPosition": 15,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": 88949,
- "Status": "Finished",
- "Points": 0,
- },
- {
- "DriverNumber": "81",
- "BroadcastName": "O PIASTRI",
- "Abbreviation": "PIA",
- "DriverId": "piastri",
- "TeamName": "McLaren",
- "TeamColor": "F58020",
- "TeamId": "mclaren",
- "FirstName": "Oscar",
- "LastName": "Piastri",
- "FullName": "Oscar Piastri",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/O/OSCPIA01_Oscar_Piastri/oscpia01.png.transform/1col/image.png",
- "CountryCode": "AUS",
- "Position": 19,
- "ClassifiedPosition": "19",
- "GridPosition": 19,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": None,
- "Status": "+1 Lap",
- "Points": 0,
- },
- {
- "DriverNumber": "2",
- "BroadcastName": "L SARGEANT",
- "Abbreviation": "SAR",
- "DriverId": "sargeant",
- "TeamName": "Williams",
- "TeamColor": "37BEDD",
- "TeamId": "williams",
- "FirstName": "Logan",
- "LastName": "Sargeant",
- "FullName": "Logan Sargeant",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/L/LOGSAR01_Logan_Sargeant/logsar01.png.transform/1col/image.png",
- "CountryCode": "USA",
- "Position": 20,
- "ClassifiedPosition": "20",
- "GridPosition": 20,
- "Q1": None,
- "Q2": None,
- "Q3": None,
- "Time": None,
- "Status": "+1 Lap",
- "Points": 0,
- },
- ]
-
-
-def test_get_results_with_session():
- response = client.get("/results/2023/5?session=4")
- assert response.status_code == status.HTTP_200_OK
- assert response.json() == [
- {
- "DriverNumber": "11",
- "BroadcastName": "S PEREZ",
- "Abbreviation": "PER",
- "DriverId": "perez",
- "TeamName": "Red Bull Racing",
- "TeamColor": "3671C6",
- "TeamId": "red_bull",
- "FirstName": "Sergio",
- "LastName": "Perez",
- "FullName": "Sergio Perez",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/S/SERPER01_Sergio_Perez/serper01.png.transform/1col/image.png",
- "CountryCode": "MEX",
- "Position": 1,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87713,
- "Q2": 87328,
- "Q3": 86841,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "14",
- "BroadcastName": "F ALONSO",
- "Abbreviation": "ALO",
- "DriverId": "alonso",
- "TeamName": "Aston Martin",
- "TeamColor": "358C75",
- "TeamId": "aston_martin",
- "FirstName": "Fernando",
- "LastName": "Alonso",
- "FullName": "Fernando Alonso",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/F/FERALO01_Fernando_Alonso/feralo01.png.transform/1col/image.png",
- "CountryCode": "ESP",
- "Position": 2,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88179,
- "Q2": 87097,
- "Q3": 87202,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "55",
- "BroadcastName": "C SAINZ",
- "Abbreviation": "SAI",
- "DriverId": "sainz",
- "TeamName": "Ferrari",
- "TeamColor": "F91536",
- "TeamId": "ferrari",
- "FirstName": "Carlos",
- "LastName": "Sainz",
- "FullName": "Carlos Sainz",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/C/CARSAI01_Carlos_Sainz/carsai01.png.transform/1col/image.png",
- "CountryCode": "ESP",
- "Position": 3,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87686,
- "Q2": 87148,
- "Q3": 87349,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "20",
- "BroadcastName": "K MAGNUSSEN",
- "Abbreviation": "MAG",
- "DriverId": "kevin_magnussen",
- "TeamName": "Haas F1 Team",
- "TeamColor": "B6BABD",
- "TeamId": "haas",
- "FirstName": "Kevin",
- "LastName": "Magnussen",
- "FullName": "Kevin Magnussen",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/K/KEVMAG01_Kevin_Magnussen/kevmag01.png.transform/1col/image.png",
- "CountryCode": "DEN",
- "Position": 4,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87809,
- "Q2": 87673,
- "Q3": 87767,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "10",
- "BroadcastName": "P GASLY",
- "Abbreviation": "GAS",
- "DriverId": "gasly",
- "TeamName": "Alpine",
- "TeamColor": "2293D1",
- "TeamId": "alpine",
- "FirstName": "Pierre",
- "LastName": "Gasly",
- "FullName": "Pierre Gasly",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/P/PIEGAS01_Pierre_Gasly/piegas01.png.transform/1col/image.png",
- "CountryCode": "FRA",
- "Position": 5,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88061,
- "Q2": 87612,
- "Q3": 87786,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "63",
- "BroadcastName": "G RUSSELL",
- "Abbreviation": "RUS",
- "DriverId": "russell",
- "TeamName": "Mercedes",
- "TeamColor": "6CD3BF",
- "TeamId": "mercedes",
- "FirstName": "George",
- "LastName": "Russell",
- "FullName": "George Russell",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/G/GEORUS01_George_Russell/georus01.png.transform/1col/image.png",
- "CountryCode": "GBR",
- "Position": 6,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88086,
- "Q2": 87743,
- "Q3": 87804,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "16",
- "BroadcastName": "C LECLERC",
- "Abbreviation": "LEC",
- "DriverId": "leclerc",
- "TeamName": "Ferrari",
- "TeamColor": "F91536",
- "TeamId": "ferrari",
- "FirstName": "Charles",
- "LastName": "Leclerc",
- "FullName": "Charles Leclerc",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/C/CHALEC01_Charles_Leclerc/chalec01.png.transform/1col/image.png",
- "CountryCode": "MON",
- "Position": 7,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87713,
- "Q2": 86964,
- "Q3": 87861,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "31",
- "BroadcastName": "E OCON",
- "Abbreviation": "OCO",
- "DriverId": "ocon",
- "TeamName": "Alpine",
- "TeamColor": "2293D1",
- "TeamId": "alpine",
- "FirstName": "Esteban",
- "LastName": "Ocon",
- "FullName": "Esteban Ocon",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/E/ESTOCO01_Esteban_Ocon/estoco01.png.transform/1col/image.png",
- "CountryCode": "FRA",
- "Position": 8,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87872,
- "Q2": 87444,
- "Q3": 87935,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "1",
- "BroadcastName": "M VERSTAPPEN",
- "Abbreviation": "VER",
- "DriverId": "max_verstappen",
- "TeamName": "Red Bull Racing",
- "TeamColor": "3671C6",
- "TeamId": "red_bull",
- "FirstName": "Max",
- "LastName": "Verstappen",
- "FullName": "Max Verstappen",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/M/MAXVER01_Max_Verstappen/maxver01.png.transform/1col/image.png",
- "CountryCode": "NED",
- "Position": 9,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87363,
- "Q2": 86814,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "77",
- "BroadcastName": "V BOTTAS",
- "Abbreviation": "BOT",
- "DriverId": "bottas",
- "TeamName": "Alfa Romeo",
- "TeamColor": "C92D4B",
- "TeamId": "alfa",
- "FirstName": "Valtteri",
- "LastName": "Bottas",
- "FullName": "Valtteri Bottas",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/V/VALBOT01_Valtteri_Bottas/valbot01.png.transform/1col/image.png",
- "CountryCode": "FIN",
- "Position": 10,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87864,
- "Q2": 87564,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "23",
- "BroadcastName": "A ALBON",
- "Abbreviation": "ALB",
- "DriverId": "albon",
- "TeamName": "Williams",
- "TeamColor": "37BEDD",
- "TeamId": "williams",
- "FirstName": "Alexander",
- "LastName": "Albon",
- "FullName": "Alexander Albon",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/A/ALEALB01_Alexander_Albon/alealb01.png.transform/1col/image.png",
- "CountryCode": "THA",
- "Position": 11,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88234,
- "Q2": 87795,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "27",
- "BroadcastName": "N HULKENBERG",
- "Abbreviation": "HUL",
- "DriverId": "hulkenberg",
- "TeamName": "Haas F1 Team",
- "TeamColor": "B6BABD",
- "TeamId": "haas",
- "FirstName": "Nico",
- "LastName": "Hulkenberg",
- "FullName": "Nico Hulkenberg",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/N/NICHUL01_Nico_Hulkenberg/nichul01.png.transform/1col/image.png",
- "CountryCode": "GER",
- "Position": 12,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87945,
- "Q2": 87903,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "44",
- "BroadcastName": "L HAMILTON",
- "Abbreviation": "HAM",
- "DriverId": "hamilton",
- "TeamName": "Mercedes",
- "TeamColor": "6CD3BF",
- "TeamId": "mercedes",
- "FirstName": "Lewis",
- "LastName": "Hamilton",
- "FullName": "Lewis Hamilton",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/L/LEWHAM01_Lewis_Hamilton/lewham01.png.transform/1col/image.png",
- "CountryCode": "GBR",
- "Position": 13,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 87846,
- "Q2": 87975,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "24",
- "BroadcastName": "G ZHOU",
- "Abbreviation": "ZHO",
- "DriverId": "zhou",
- "TeamName": "Alfa Romeo",
- "TeamColor": "C92D4B",
- "TeamId": "alfa",
- "FirstName": "Guanyu",
- "LastName": "Zhou",
- "FullName": "Guanyu Zhou",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/G/GUAZHO01_Guanyu_Zhou/guazho01.png.transform/1col/image.png",
- "CountryCode": "CHN",
- "Position": 14,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88180,
- "Q2": 88091,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "21",
- "BroadcastName": "N DE VRIES",
- "Abbreviation": "DEV",
- "DriverId": "de_vries",
- "TeamName": "AlphaTauri",
- "TeamColor": "5E8FAA",
- "TeamId": "alphatauri",
- "FirstName": "Nyck",
- "LastName": "De Vries",
- "FullName": "Nyck De Vries",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/N/NYCDEV01_Nyck_De%20Vries/nycdev01.png.transform/1col/image.png",
- "CountryCode": "NED",
- "Position": 15,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88325,
- "Q2": 88395,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "4",
- "BroadcastName": "L NORRIS",
- "Abbreviation": "NOR",
- "DriverId": "norris",
- "TeamName": "McLaren",
- "TeamColor": "F58020",
- "TeamId": "mclaren",
- "FirstName": "Lando",
- "LastName": "Norris",
- "FullName": "Lando Norris",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/L/LANNOR01_Lando_Norris/lannor01.png.transform/1col/image.png",
- "CountryCode": "GBR",
- "Position": 16,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88394,
- "Q2": None,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "22",
- "BroadcastName": "Y TSUNODA",
- "Abbreviation": "TSU",
- "DriverId": "tsunoda",
- "TeamName": "AlphaTauri",
- "TeamColor": "5E8FAA",
- "TeamId": "alphatauri",
- "FirstName": "Yuki",
- "LastName": "Tsunoda",
- "FullName": "Yuki Tsunoda",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/Y/YUKTSU01_Yuki_Tsunoda/yuktsu01.png.transform/1col/image.png",
- "CountryCode": "JPN",
- "Position": 17,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88429,
- "Q2": None,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "18",
- "BroadcastName": "L STROLL",
- "Abbreviation": "STR",
- "DriverId": "stroll",
- "TeamName": "Aston Martin",
- "TeamColor": "358C75",
- "TeamId": "aston_martin",
- "FirstName": "Lance",
- "LastName": "Stroll",
- "FullName": "Lance Stroll",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/L/LANSTR01_Lance_Stroll/lanstr01.png.transform/1col/image.png",
- "CountryCode": "CAN",
- "Position": 18,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88476,
- "Q2": None,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "81",
- "BroadcastName": "O PIASTRI",
- "Abbreviation": "PIA",
- "DriverId": "piastri",
- "TeamName": "McLaren",
- "TeamColor": "F58020",
- "TeamId": "mclaren",
- "FirstName": "Oscar",
- "LastName": "Piastri",
- "FullName": "Oscar Piastri",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/O/OSCPIA01_Oscar_Piastri/oscpia01.png.transform/1col/image.png",
- "CountryCode": "AUS",
- "Position": 19,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88484,
- "Q2": None,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- {
- "DriverNumber": "2",
- "BroadcastName": "L SARGEANT",
- "Abbreviation": "SAR",
- "DriverId": "sargeant",
- "TeamName": "Williams",
- "TeamColor": "37BEDD",
- "TeamId": "williams",
- "FirstName": "Logan",
- "LastName": "Sargeant",
- "FullName": "Logan Sargeant",
- "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/L/LOGSAR01_Logan_Sargeant/logsar01.png.transform/1col/image.png",
- "CountryCode": "USA",
- "Position": 20,
- "ClassifiedPosition": "",
- "GridPosition": None,
- "Q1": 88577,
- "Q2": None,
- "Q3": None,
- "Time": None,
- "Status": "",
- "Points": None,
- },
- ]
-
-
-# endregion results - good inputs
-
-# region results - bad inputs
-
-
-def test_get_results_bad_round_invalid():
- response = client.get("/results/2023/25?session=2")
- assert response.status_code == status.HTTP_400_BAD_REQUEST
- assert response.json() == {"detail": "Bad Request. Invalid round: 25"}
-
-
-# endregion results - bad inputs
-
-# endregion results
diff --git a/app/utils.py b/app/utils.py
index 744e56c..263e79c 100644
--- a/app/utils.py
+++ b/app/utils.py
@@ -1,5 +1,7 @@
+# Built-in
from datetime import datetime
+# External
import fastf1
@@ -18,9 +20,7 @@ def get_default_year() -> int:
# per current (2023-01-22) fastf1/ergast implementation, the value is 1.
race_event_round_number = event_schedule.iloc[0]["RoundNumber"]
# create a fastf1.core.Session object
- first_race_event_session_obj = fastf1.get_session(
- current_year, race_event_round_number, "Race"
- )
+ first_race_event_session_obj = fastf1.get_session(current_year, race_event_round_number, "Race")
# load session data
first_race_event_session_obj.load()
except (ValueError, KeyError):
diff --git a/poetry.lock b/poetry.lock
index c6fe831..a921e4a 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,14 +1,25 @@
-# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand.
+
+[[package]]
+name = "annotated-types"
+version = "0.6.0"
+description = "Reusable constraint types to use with typing.Annotated"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"},
+ {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"},
+]
[[package]]
name = "anyio"
-version = "4.2.0"
+version = "4.3.0"
description = "High level compatibility layer for multiple asynchronous event loop implementations"
optional = false
python-versions = ">=3.8"
files = [
- {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"},
- {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"},
+ {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"},
+ {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"},
]
[package.dependencies]
@@ -34,6 +45,17 @@ files = [
[package.extras]
test = ["coverage", "mypy", "pexpect", "ruff", "wheel"]
+[[package]]
+name = "astroid"
+version = "3.1.0"
+description = "An abstract syntax tree for Python with inference support."
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "astroid-3.1.0-py3-none-any.whl", hash = "sha256:951798f922990137ac090c53af473db7ab4e70c770e6d7fae0cec59f74411819"},
+ {file = "astroid-3.1.0.tar.gz", hash = "sha256:ac248253bfa4bd924a0de213707e7ebeeb3138abeb48d798784ead1e56d419d4"},
+]
+
[[package]]
name = "attrs"
version = "23.2.0"
@@ -53,35 +75,49 @@ tests = ["attrs[tests-no-zope]", "zope-interface"]
tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"]
tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"]
+[[package]]
+name = "autoflake"
+version = "2.3.0"
+description = "Removes unused imports and unused variables"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "autoflake-2.3.0-py3-none-any.whl", hash = "sha256:79a51eb8c0744759d2efe052455ab20aa6a314763510c3fd897499a402126327"},
+ {file = "autoflake-2.3.0.tar.gz", hash = "sha256:8c2011fa34701b9d7dcf05b9873bc4859d4fce4e62dfea90dffefd1576f5f01d"},
+]
+
+[package.dependencies]
+pyflakes = ">=3.0.0"
+
[[package]]
name = "black"
-version = "24.1.1"
+version = "24.2.0"
description = "The uncompromising code formatter."
optional = false
python-versions = ">=3.8"
files = [
- {file = "black-24.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2588021038bd5ada078de606f2a804cadd0a3cc6a79cb3e9bb3a8bf581325a4c"},
- {file = "black-24.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a95915c98d6e32ca43809d46d932e2abc5f1f7d582ffbe65a5b4d1588af7445"},
- {file = "black-24.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa6a0e965779c8f2afb286f9ef798df770ba2b6cee063c650b96adec22c056a"},
- {file = "black-24.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5242ecd9e990aeb995b6d03dc3b2d112d4a78f2083e5a8e86d566340ae80fec4"},
- {file = "black-24.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc1ec9aa6f4d98d022101e015261c056ddebe3da6a8ccfc2c792cbe0349d48b7"},
- {file = "black-24.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0269dfdea12442022e88043d2910429bed717b2d04523867a85dacce535916b8"},
- {file = "black-24.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d64db762eae4a5ce04b6e3dd745dcca0fb9560eb931a5be97472e38652a161"},
- {file = "black-24.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5d7b06ea8816cbd4becfe5f70accae953c53c0e53aa98730ceccb0395520ee5d"},
- {file = "black-24.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e2c8dfa14677f90d976f68e0c923947ae68fa3961d61ee30976c388adc0b02c8"},
- {file = "black-24.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a21725862d0e855ae05da1dd25e3825ed712eaaccef6b03017fe0853a01aa45e"},
- {file = "black-24.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07204d078e25327aad9ed2c64790d681238686bce254c910de640c7cc4fc3aa6"},
- {file = "black-24.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a83fe522d9698d8f9a101b860b1ee154c1d25f8a82ceb807d319f085b2627c5b"},
- {file = "black-24.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08b34e85170d368c37ca7bf81cf67ac863c9d1963b2c1780c39102187ec8dd62"},
- {file = "black-24.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7258c27115c1e3b5de9ac6c4f9957e3ee2c02c0b39222a24dc7aa03ba0e986f5"},
- {file = "black-24.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40657e1b78212d582a0edecafef133cf1dd02e6677f539b669db4746150d38f6"},
- {file = "black-24.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e298d588744efda02379521a19639ebcd314fba7a49be22136204d7ed1782717"},
- {file = "black-24.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34afe9da5056aa123b8bfda1664bfe6fb4e9c6f311d8e4a6eb089da9a9173bf9"},
- {file = "black-24.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:854c06fb86fd854140f37fb24dbf10621f5dab9e3b0c29a690ba595e3d543024"},
- {file = "black-24.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3897ae5a21ca132efa219c029cce5e6bfc9c3d34ed7e892113d199c0b1b444a2"},
- {file = "black-24.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:ecba2a15dfb2d97105be74bbfe5128bc5e9fa8477d8c46766505c1dda5883aac"},
- {file = "black-24.1.1-py3-none-any.whl", hash = "sha256:5cdc2e2195212208fbcae579b931407c1fa9997584f0a415421748aeafff1168"},
- {file = "black-24.1.1.tar.gz", hash = "sha256:48b5760dcbfe5cf97fd4fba23946681f3a81514c6ab8a45b50da67ac8fbc6c7b"},
+ {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"},
+ {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"},
+ {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"},
+ {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"},
+ {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"},
+ {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"},
+ {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"},
+ {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"},
+ {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"},
+ {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"},
+ {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"},
+ {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"},
+ {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"},
+ {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"},
+ {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"},
+ {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"},
+ {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"},
+ {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"},
+ {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"},
+ {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"},
+ {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"},
+ {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"},
]
[package.dependencies]
@@ -268,13 +304,13 @@ files = [
[[package]]
name = "commitizen"
-version = "3.14.1"
+version = "3.16.0"
description = "Python commitizen client tool"
optional = false
python-versions = ">=3.8"
files = [
- {file = "commitizen-3.14.1-py3-none-any.whl", hash = "sha256:e0f0bb2eb19a6bcc540902d32e5e3b53c2f7636e888bb1894f83efb416af8762"},
- {file = "commitizen-3.14.1.tar.gz", hash = "sha256:21e19143d209fd6b1feb6332430ad91cf5d37ba09990c74d1f941ef1e9087898"},
+ {file = "commitizen-3.16.0-py3-none-any.whl", hash = "sha256:a880005352fd35b908d9c3951e71e155b157f4a4ec61ca9c080a9637bf98e0a1"},
+ {file = "commitizen-3.16.0.tar.gz", hash = "sha256:1269619d383d12809f436ff196fb786a3d49fc50987562e6e566cd9c2908735c"},
]
[package.dependencies]
@@ -379,6 +415,21 @@ files = [
{file = "decli-0.6.1.tar.gz", hash = "sha256:ed88ccb947701e8e5509b7945fda56e150e2ac74a69f25d47ac85ef30ab0c0f0"},
]
+[[package]]
+name = "dill"
+version = "0.3.8"
+description = "serialize all of Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"},
+ {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"},
+]
+
+[package.extras]
+graph = ["objgraph (>=1.7.2)"]
+profile = ["gprof2dot (>=2022.7.29)"]
+
[[package]]
name = "distlib"
version = "0.3.8"
@@ -392,13 +443,13 @@ files = [
[[package]]
name = "fastapi"
-version = "0.109.2"
+version = "0.110.0"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
optional = false
python-versions = ">=3.8"
files = [
- {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"},
- {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"},
+ {file = "fastapi-0.110.0-py3-none-any.whl", hash = "sha256:87a1f6fb632a218222c5984be540055346a8f5d8a68e8f6fb647b1dc9934de4b"},
+ {file = "fastapi-0.110.0.tar.gz", hash = "sha256:266775f0dcc95af9d3ef39bad55cff525329a931d5fd51930aadd4f428bf7ff3"},
]
[package.dependencies]
@@ -409,22 +460,6 @@ typing-extensions = ">=4.8.0"
[package.extras]
all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
-[[package]]
-name = "fastapi-utils"
-version = "0.2.1"
-description = "Reusable utilities for FastAPI"
-optional = false
-python-versions = ">=3.6,<4.0"
-files = [
- {file = "fastapi-utils-0.2.1.tar.gz", hash = "sha256:0e6c7fc1870b80e681494957abf65d4f4f42f4c7f70005918e9181b22f1bd759"},
- {file = "fastapi_utils-0.2.1-py3-none-any.whl", hash = "sha256:dd0be7dc7f03fa681b25487a206651d99f2330d5a567fb8ab6cb5f8a06a29360"},
-]
-
-[package.dependencies]
-fastapi = "*"
-pydantic = ">=1.0,<2.0"
-sqlalchemy = ">=1.3.12,<2.0.0"
-
[[package]]
name = "fastf1"
version = "3.2.2"
@@ -466,53 +501,53 @@ typing = ["typing-extensions (>=4.8)"]
[[package]]
name = "fonttools"
-version = "4.48.1"
+version = "4.49.0"
description = "Tools to manipulate font files"
optional = false
python-versions = ">=3.8"
files = [
- {file = "fonttools-4.48.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:702ae93058c81f46461dc4b2c79f11d3c3d8fd7296eaf8f75b4ba5bbf813cd5f"},
- {file = "fonttools-4.48.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97f0a49fa6aa2d6205c6f72f4f98b74ef4b9bfdcb06fd78e6fe6c7af4989b63e"},
- {file = "fonttools-4.48.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3260db55f1843e57115256e91247ad9f68cb02a434b51262fe0019e95a98738"},
- {file = "fonttools-4.48.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e740a7602c2bb71e1091269b5dbe89549749a8817dc294b34628ffd8b2bf7124"},
- {file = "fonttools-4.48.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4108b1d247953dd7c90ec8f457a2dec5fceb373485973cc852b14200118a51ee"},
- {file = "fonttools-4.48.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56339ec557f0c342bddd7c175f5e41c45fc21282bee58a86bd9aa322bec715f2"},
- {file = "fonttools-4.48.1-cp310-cp310-win32.whl", hash = "sha256:bff5b38d0e76eb18e0b8abbf35d384e60b3371be92f7be36128ee3e67483b3ec"},
- {file = "fonttools-4.48.1-cp310-cp310-win_amd64.whl", hash = "sha256:f7449493886da6a17472004d3818cc050ba3f4a0aa03fb47972e4fa5578e6703"},
- {file = "fonttools-4.48.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:18b35fd1a850ed7233a99bbd6774485271756f717dac8b594958224b54118b61"},
- {file = "fonttools-4.48.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cad5cfd044ea2e306fda44482b3dd32ee47830fa82dfa4679374b41baa294f5f"},
- {file = "fonttools-4.48.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f30e605c7565d0da6f0aec75a30ec372072d016957cd8fc4469721a36ea59b7"},
- {file = "fonttools-4.48.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee76fd81a8571c68841d6ef0da750d5ff08ff2c5f025576473016f16ac3bcf7"},
- {file = "fonttools-4.48.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5057ade278e67923000041e2b195c9ea53e87f227690d499b6a4edd3702f7f01"},
- {file = "fonttools-4.48.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b10633aafc5932995a391ec07eba5e79f52af0003a1735b2306b3dab8a056d48"},
- {file = "fonttools-4.48.1-cp311-cp311-win32.whl", hash = "sha256:0d533f89819f9b3ee2dbedf0fed3825c425850e32bdda24c558563c71be0064e"},
- {file = "fonttools-4.48.1-cp311-cp311-win_amd64.whl", hash = "sha256:d20588466367f05025bb1efdf4e5d498ca6d14bde07b6928b79199c588800f0a"},
- {file = "fonttools-4.48.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0a2417547462e468edf35b32e3dd06a6215ac26aa6316b41e03b8eeaf9f079ea"},
- {file = "fonttools-4.48.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cf5a0cd974f85a80b74785db2d5c3c1fd6cc09a2ba3c837359b2b5da629ee1b0"},
- {file = "fonttools-4.48.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0452fcbfbce752ba596737a7c5ec5cf76bc5f83847ce1781f4f90eab14ece252"},
- {file = "fonttools-4.48.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578c00f93868f64a4102ecc5aa600a03b49162c654676c3fadc33de2ddb88a81"},
- {file = "fonttools-4.48.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:63dc592a16cd08388d8c4c7502b59ac74190b23e16dfc863c69fe1ea74605b68"},
- {file = "fonttools-4.48.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9b58638d8a85e3a1b32ec0a91d9f8171a877b4b81c408d4cb3257d0dee63e092"},
- {file = "fonttools-4.48.1-cp312-cp312-win32.whl", hash = "sha256:d10979ef14a8beaaa32f613bb698743f7241d92f437a3b5e32356dfb9769c65d"},
- {file = "fonttools-4.48.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdfd7557d1bd294a200bd211aa665ca3b02998dcc18f8211a5532da5b8fad5c5"},
- {file = "fonttools-4.48.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3cdb9a92521b81bf717ebccf592bd0292e853244d84115bfb4db0c426de58348"},
- {file = "fonttools-4.48.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b4ec6d42a7555f5ae35f3b805482f0aad0f1baeeef54859492ea3b782959d4a"},
- {file = "fonttools-4.48.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:902e9c4e9928301912f34a6638741b8ae0b64824112b42aaf240e06b735774b1"},
- {file = "fonttools-4.48.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8c8b54bd1420c184a995f980f1a8076f87363e2bb24239ef8c171a369d85a31"},
- {file = "fonttools-4.48.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:12ee86abca46193359ea69216b3a724e90c66ab05ab220d39e3fc068c1eb72ac"},
- {file = "fonttools-4.48.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6978bade7b6c0335095bdd0bd97f8f3d590d2877b370f17e03e0865241694eb5"},
- {file = "fonttools-4.48.1-cp38-cp38-win32.whl", hash = "sha256:bcd77f89fc1a6b18428e7a55dde8ef56dae95640293bfb8f4e929929eba5e2a2"},
- {file = "fonttools-4.48.1-cp38-cp38-win_amd64.whl", hash = "sha256:f40441437b039930428e04fb05ac3a132e77458fb57666c808d74a556779e784"},
- {file = "fonttools-4.48.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d2b01428f7da26f229a5656defc824427b741e454b4e210ad2b25ed6ea2aed4"},
- {file = "fonttools-4.48.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:df48798f9a4fc4c315ab46e17873436c8746f5df6eddd02fad91299b2af7af95"},
- {file = "fonttools-4.48.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2eb4167bde04e172a93cf22c875d8b0cff76a2491f67f5eb069566215302d45d"},
- {file = "fonttools-4.48.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c900508c46274d32d308ae8e82335117f11aaee1f7d369ac16502c9a78930b0a"},
- {file = "fonttools-4.48.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:594206b31c95fcfa65f484385171fabb4ec69f7d2d7f56d27f17db26b7a31814"},
- {file = "fonttools-4.48.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:292922dc356d7f11f5063b4111a8b719efb8faea92a2a88ed296408d449d8c2e"},
- {file = "fonttools-4.48.1-cp39-cp39-win32.whl", hash = "sha256:4709c5bf123ba10eac210d2d5c9027d3f472591d9f1a04262122710fa3d23199"},
- {file = "fonttools-4.48.1-cp39-cp39-win_amd64.whl", hash = "sha256:63c73b9dd56a94a3cbd2f90544b5fca83666948a9e03370888994143b8d7c070"},
- {file = "fonttools-4.48.1-py3-none-any.whl", hash = "sha256:e3e33862fc5261d46d9aae3544acb36203b1a337d00bdb5d3753aae50dac860e"},
- {file = "fonttools-4.48.1.tar.gz", hash = "sha256:8b8a45254218679c7f1127812761e7854ed5c8e34349aebf581e8c9204e7495a"},
+ {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d970ecca0aac90d399e458f0b7a8a597e08f95de021f17785fb68e2dc0b99717"},
+ {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac9a745b7609f489faa65e1dc842168c18530874a5f5b742ac3dd79e26bca8bc"},
+ {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ba0e00620ca28d4ca11fc700806fd69144b463aa3275e1b36e56c7c09915559"},
+ {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdee3ab220283057e7840d5fb768ad4c2ebe65bdba6f75d5d7bf47f4e0ed7d29"},
+ {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ce7033cb61f2bb65d8849658d3786188afd80f53dad8366a7232654804529532"},
+ {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:07bc5ea02bb7bc3aa40a1eb0481ce20e8d9b9642a9536cde0218290dd6085828"},
+ {file = "fonttools-4.49.0-cp310-cp310-win32.whl", hash = "sha256:86eef6aab7fd7c6c8545f3ebd00fd1d6729ca1f63b0cb4d621bccb7d1d1c852b"},
+ {file = "fonttools-4.49.0-cp310-cp310-win_amd64.whl", hash = "sha256:1fac1b7eebfce75ea663e860e7c5b4a8831b858c17acd68263bc156125201abf"},
+ {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:edc0cce355984bb3c1d1e89d6a661934d39586bb32191ebff98c600f8957c63e"},
+ {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:83a0d9336de2cba86d886507dd6e0153df333ac787377325a39a2797ec529814"},
+ {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36c8865bdb5cfeec88f5028e7e592370a0657b676c6f1d84a2108e0564f90e22"},
+ {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33037d9e56e2562c710c8954d0f20d25b8386b397250d65581e544edc9d6b942"},
+ {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8fb022d799b96df3eaa27263e9eea306bd3d437cc9aa981820850281a02b6c9a"},
+ {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33c584c0ef7dc54f5dd4f84082eabd8d09d1871a3d8ca2986b0c0c98165f8e86"},
+ {file = "fonttools-4.49.0-cp311-cp311-win32.whl", hash = "sha256:cbe61b158deb09cffdd8540dc4a948d6e8f4d5b4f3bf5cd7db09bd6a61fee64e"},
+ {file = "fonttools-4.49.0-cp311-cp311-win_amd64.whl", hash = "sha256:fc11e5114f3f978d0cea7e9853627935b30d451742eeb4239a81a677bdee6bf6"},
+ {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d647a0e697e5daa98c87993726da8281c7233d9d4ffe410812a4896c7c57c075"},
+ {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f3bbe672df03563d1f3a691ae531f2e31f84061724c319652039e5a70927167e"},
+ {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bebd91041dda0d511b0d303180ed36e31f4f54b106b1259b69fade68413aa7ff"},
+ {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4145f91531fd43c50f9eb893faa08399816bb0b13c425667c48475c9f3a2b9b5"},
+ {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ea329dafb9670ffbdf4dbc3b0e5c264104abcd8441d56de77f06967f032943cb"},
+ {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c076a9e548521ecc13d944b1d261ff3d7825048c338722a4bd126d22316087b7"},
+ {file = "fonttools-4.49.0-cp312-cp312-win32.whl", hash = "sha256:b607ea1e96768d13be26d2b400d10d3ebd1456343eb5eaddd2f47d1c4bd00880"},
+ {file = "fonttools-4.49.0-cp312-cp312-win_amd64.whl", hash = "sha256:a974c49a981e187381b9cc2c07c6b902d0079b88ff01aed34695ec5360767034"},
+ {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b85ec0bdd7bdaa5c1946398cbb541e90a6dfc51df76dfa88e0aaa41b335940cb"},
+ {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:af20acbe198a8a790618ee42db192eb128afcdcc4e96d99993aca0b60d1faeb4"},
+ {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d418b1fee41a1d14931f7ab4b92dc0bc323b490e41d7a333eec82c9f1780c75"},
+ {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b44a52b8e6244b6548851b03b2b377a9702b88ddc21dcaf56a15a0393d425cb9"},
+ {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7c7125068e04a70739dad11857a4d47626f2b0bd54de39e8622e89701836eabd"},
+ {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29e89d0e1a7f18bc30f197cfadcbef5a13d99806447c7e245f5667579a808036"},
+ {file = "fonttools-4.49.0-cp38-cp38-win32.whl", hash = "sha256:9d95fa0d22bf4f12d2fb7b07a46070cdfc19ef5a7b1c98bc172bfab5bf0d6844"},
+ {file = "fonttools-4.49.0-cp38-cp38-win_amd64.whl", hash = "sha256:768947008b4dc552d02772e5ebd49e71430a466e2373008ce905f953afea755a"},
+ {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:08877e355d3dde1c11973bb58d4acad1981e6d1140711230a4bfb40b2b937ccc"},
+ {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fdb54b076f25d6b0f0298dc706acee5052de20c83530fa165b60d1f2e9cbe3cb"},
+ {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0af65c720520710cc01c293f9c70bd69684365c6015cc3671db2b7d807fe51f2"},
+ {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f255ce8ed7556658f6d23f6afd22a6d9bbc3edb9b96c96682124dc487e1bf42"},
+ {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d00af0884c0e65f60dfaf9340e26658836b935052fdd0439952ae42e44fdd2be"},
+ {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:263832fae27481d48dfafcc43174644b6706639661e242902ceb30553557e16c"},
+ {file = "fonttools-4.49.0-cp39-cp39-win32.whl", hash = "sha256:0404faea044577a01bb82d47a8fa4bc7a54067fa7e324785dd65d200d6dd1133"},
+ {file = "fonttools-4.49.0-cp39-cp39-win_amd64.whl", hash = "sha256:b050d362df50fc6e38ae3954d8c29bf2da52be384649ee8245fdb5186b620836"},
+ {file = "fonttools-4.49.0-py3-none-any.whl", hash = "sha256:af281525e5dd7fa0b39fb1667b8d5ca0e2a9079967e14c4bfe90fd1cd13e0f18"},
+ {file = "fonttools-4.49.0.tar.gz", hash = "sha256:ebf46e7f01b7af7861310417d7c49591a85d99146fc23a5ba82fdb28af156321"},
]
[package.extras]
@@ -529,77 +564,6 @@ ufo = ["fs (>=2.2.0,<3)"]
unicode = ["unicodedata2 (>=15.1.0)"]
woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
-[[package]]
-name = "greenlet"
-version = "3.0.3"
-description = "Lightweight in-process concurrent programming"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"},
- {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"},
- {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"},
- {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"},
- {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"},
- {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"},
- {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"},
- {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"},
- {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"},
- {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"},
- {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"},
- {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"},
- {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"},
- {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"},
- {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"},
- {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"},
- {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"},
- {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"},
- {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"},
- {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"},
- {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"},
- {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"},
- {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"},
- {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"},
- {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"},
- {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"},
- {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"},
- {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"},
-]
-
-[package.extras]
-docs = ["Sphinx", "furo"]
-test = ["objgraph", "psutil"]
-
[[package]]
name = "h11"
version = "0.14.0"
@@ -613,13 +577,13 @@ files = [
[[package]]
name = "httpcore"
-version = "1.0.2"
+version = "1.0.4"
description = "A minimal low-level HTTP client."
optional = false
python-versions = ">=3.8"
files = [
- {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"},
- {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"},
+ {file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"},
+ {file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"},
]
[package.dependencies]
@@ -630,7 +594,7 @@ h11 = ">=0.13,<0.15"
asyncio = ["anyio (>=4.0,<5.0)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
-trio = ["trio (>=0.22.0,<0.23.0)"]
+trio = ["trio (>=0.22.0,<0.25.0)"]
[[package]]
name = "httptools"
@@ -682,13 +646,13 @@ test = ["Cython (>=0.29.24,<0.30.0)"]
[[package]]
name = "httpx"
-version = "0.26.0"
+version = "0.27.0"
description = "The next generation HTTP client."
optional = false
python-versions = ">=3.8"
files = [
- {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"},
- {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"},
+ {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"},
+ {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"},
]
[package.dependencies]
@@ -706,13 +670,13 @@ socks = ["socksio (==1.*)"]
[[package]]
name = "identify"
-version = "2.5.34"
+version = "2.5.35"
description = "File identification library for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "identify-2.5.34-py2.py3-none-any.whl", hash = "sha256:a4316013779e433d08b96e5eabb7f641e6c7942e4ab5d4c509ebd2e7a8994aed"},
- {file = "identify-2.5.34.tar.gz", hash = "sha256:ee17bc9d499899bc9eaec1ac7bf2dc9eedd480db9d88b96d123d3b64a9d34f5d"},
+ {file = "identify-2.5.35-py2.py3-none-any.whl", hash = "sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e"},
+ {file = "identify-2.5.35.tar.gz", hash = "sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791"},
]
[package.extras]
@@ -974,39 +938,39 @@ files = [
[[package]]
name = "matplotlib"
-version = "3.8.2"
+version = "3.8.3"
description = "Python plotting package"
optional = false
python-versions = ">=3.9"
files = [
- {file = "matplotlib-3.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:09796f89fb71a0c0e1e2f4bdaf63fb2cefc84446bb963ecdeb40dfee7dfa98c7"},
- {file = "matplotlib-3.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9c6976748a25e8b9be51ea028df49b8e561eed7809146da7a47dbecebab367"},
- {file = "matplotlib-3.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b78e4f2cedf303869b782071b55fdde5987fda3038e9d09e58c91cc261b5ad18"},
- {file = "matplotlib-3.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e208f46cf6576a7624195aa047cb344a7f802e113bb1a06cfd4bee431de5e31"},
- {file = "matplotlib-3.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46a569130ff53798ea5f50afce7406e91fdc471ca1e0e26ba976a8c734c9427a"},
- {file = "matplotlib-3.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:830f00640c965c5b7f6bc32f0d4ce0c36dfe0379f7dd65b07a00c801713ec40a"},
- {file = "matplotlib-3.8.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d86593ccf546223eb75a39b44c32788e6f6440d13cfc4750c1c15d0fcb850b63"},
- {file = "matplotlib-3.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a5430836811b7652991939012f43d2808a2db9b64ee240387e8c43e2e5578c8"},
- {file = "matplotlib-3.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9576723858a78751d5aacd2497b8aef29ffea6d1c95981505877f7ac28215c6"},
- {file = "matplotlib-3.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ba9cbd8ac6cf422f3102622b20f8552d601bf8837e49a3afed188d560152788"},
- {file = "matplotlib-3.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:03f9d160a29e0b65c0790bb07f4f45d6a181b1ac33eb1bb0dd225986450148f0"},
- {file = "matplotlib-3.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:3773002da767f0a9323ba1a9b9b5d00d6257dbd2a93107233167cfb581f64717"},
- {file = "matplotlib-3.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4c318c1e95e2f5926fba326f68177dee364aa791d6df022ceb91b8221bd0a627"},
- {file = "matplotlib-3.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:091275d18d942cf1ee9609c830a1bc36610607d8223b1b981c37d5c9fc3e46a4"},
- {file = "matplotlib-3.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b0f3b8ea0e99e233a4bcc44590f01604840d833c280ebb8fe5554fd3e6cfe8d"},
- {file = "matplotlib-3.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7b1704a530395aaf73912be741c04d181f82ca78084fbd80bc737be04848331"},
- {file = "matplotlib-3.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533b0e3b0c6768eef8cbe4b583731ce25a91ab54a22f830db2b031e83cca9213"},
- {file = "matplotlib-3.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:0f4fc5d72b75e2c18e55eb32292659cf731d9d5b312a6eb036506304f4675630"},
- {file = "matplotlib-3.8.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:deaed9ad4da0b1aea77fe0aa0cebb9ef611c70b3177be936a95e5d01fa05094f"},
- {file = "matplotlib-3.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:172f4d0fbac3383d39164c6caafd3255ce6fa58f08fc392513a0b1d3b89c4f89"},
- {file = "matplotlib-3.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7d36c2209d9136cd8e02fab1c0ddc185ce79bc914c45054a9f514e44c787917"},
- {file = "matplotlib-3.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5864bdd7da445e4e5e011b199bb67168cdad10b501750367c496420f2ad00843"},
- {file = "matplotlib-3.8.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ef8345b48e95cee45ff25192ed1f4857273117917a4dcd48e3905619bcd9c9b8"},
- {file = "matplotlib-3.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:7c48d9e221b637c017232e3760ed30b4e8d5dfd081daf327e829bf2a72c731b4"},
- {file = "matplotlib-3.8.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:aa11b3c6928a1e496c1a79917d51d4cd5d04f8a2e75f21df4949eeefdf697f4b"},
- {file = "matplotlib-3.8.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1095fecf99eeb7384dabad4bf44b965f929a5f6079654b681193edf7169ec20"},
- {file = "matplotlib-3.8.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:bddfb1db89bfaa855912261c805bd0e10218923cc262b9159a49c29a7a1c1afa"},
- {file = "matplotlib-3.8.2.tar.gz", hash = "sha256:01a978b871b881ee76017152f1f1a0cbf6bd5f7b8ff8c96df0df1bd57d8755a1"},
+ {file = "matplotlib-3.8.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cf60138ccc8004f117ab2a2bad513cc4d122e55864b4fe7adf4db20ca68a078f"},
+ {file = "matplotlib-3.8.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f557156f7116be3340cdeef7f128fa99b0d5d287d5f41a16e169819dcf22357"},
+ {file = "matplotlib-3.8.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f386cf162b059809ecfac3bcc491a9ea17da69fa35c8ded8ad154cd4b933d5ec"},
+ {file = "matplotlib-3.8.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3c5f96f57b0369c288bf6f9b5274ba45787f7e0589a34d24bdbaf6d3344632f"},
+ {file = "matplotlib-3.8.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:83e0f72e2c116ca7e571c57aa29b0fe697d4c6425c4e87c6e994159e0c008635"},
+ {file = "matplotlib-3.8.3-cp310-cp310-win_amd64.whl", hash = "sha256:1c5c8290074ba31a41db1dc332dc2b62def469ff33766cbe325d32a3ee291aea"},
+ {file = "matplotlib-3.8.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5184e07c7e1d6d1481862ee361905b7059f7fe065fc837f7c3dc11eeb3f2f900"},
+ {file = "matplotlib-3.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d7e7e0993d0758933b1a241a432b42c2db22dfa37d4108342ab4afb9557cbe3e"},
+ {file = "matplotlib-3.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04b36ad07eac9740fc76c2aa16edf94e50b297d6eb4c081e3add863de4bb19a7"},
+ {file = "matplotlib-3.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c42dae72a62f14982f1474f7e5c9959fc4bc70c9de11cc5244c6e766200ba65"},
+ {file = "matplotlib-3.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf5932eee0d428192c40b7eac1399d608f5d995f975cdb9d1e6b48539a5ad8d0"},
+ {file = "matplotlib-3.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:40321634e3a05ed02abf7c7b47a50be50b53ef3eaa3a573847431a545585b407"},
+ {file = "matplotlib-3.8.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:09074f8057917d17ab52c242fdf4916f30e99959c1908958b1fc6032e2d0f6d4"},
+ {file = "matplotlib-3.8.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5745f6d0fb5acfabbb2790318db03809a253096e98c91b9a31969df28ee604aa"},
+ {file = "matplotlib-3.8.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97653d869a71721b639714b42d87cda4cfee0ee74b47c569e4874c7590c55c5"},
+ {file = "matplotlib-3.8.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:242489efdb75b690c9c2e70bb5c6550727058c8a614e4c7716f363c27e10bba1"},
+ {file = "matplotlib-3.8.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:83c0653c64b73926730bd9ea14aa0f50f202ba187c307a881673bad4985967b7"},
+ {file = "matplotlib-3.8.3-cp312-cp312-win_amd64.whl", hash = "sha256:ef6c1025a570354297d6c15f7d0f296d95f88bd3850066b7f1e7b4f2f4c13a39"},
+ {file = "matplotlib-3.8.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c4af3f7317f8a1009bbb2d0bf23dfaba859eb7dd4ccbd604eba146dccaaaf0a4"},
+ {file = "matplotlib-3.8.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4c6e00a65d017d26009bac6808f637b75ceade3e1ff91a138576f6b3065eeeba"},
+ {file = "matplotlib-3.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7b49ab49a3bea17802df6872f8d44f664ba8f9be0632a60c99b20b6db2165b7"},
+ {file = "matplotlib-3.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6728dde0a3997396b053602dbd907a9bd64ec7d5cf99e728b404083698d3ca01"},
+ {file = "matplotlib-3.8.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:813925d08fb86aba139f2d31864928d67511f64e5945ca909ad5bc09a96189bb"},
+ {file = "matplotlib-3.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:cd3a0c2be76f4e7be03d34a14d49ded6acf22ef61f88da600a18a5cd8b3c5f3c"},
+ {file = "matplotlib-3.8.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fa93695d5c08544f4a0dfd0965f378e7afc410d8672816aff1e81be1f45dbf2e"},
+ {file = "matplotlib-3.8.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9764df0e8778f06414b9d281a75235c1e85071f64bb5d71564b97c1306a2afc"},
+ {file = "matplotlib-3.8.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5e431a09e6fab4012b01fc155db0ce6dccacdbabe8198197f523a4ef4805eb26"},
+ {file = "matplotlib-3.8.3.tar.gz", hash = "sha256:7b416239e9ae38be54b028abbf9048aff5054a9aba5416bef0bd17f9162ce161"},
]
[package.dependencies]
@@ -1020,6 +984,63 @@ pillow = ">=8"
pyparsing = ">=2.3.1"
python-dateutil = ">=2.7"
+[[package]]
+name = "mccabe"
+version = "0.7.0"
+description = "McCabe checker, plugin for flake8"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
+ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
+]
+
+[[package]]
+name = "mypy"
+version = "1.8.0"
+description = "Optional static typing for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"},
+ {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"},
+ {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"},
+ {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"},
+ {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"},
+ {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"},
+ {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"},
+ {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"},
+ {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"},
+ {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"},
+ {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"},
+ {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"},
+ {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"},
+ {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"},
+ {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"},
+ {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"},
+ {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"},
+ {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"},
+ {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"},
+ {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"},
+ {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"},
+ {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"},
+ {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"},
+ {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"},
+ {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"},
+ {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"},
+ {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"},
+]
+
+[package.dependencies]
+mypy-extensions = ">=1.0.0"
+typing-extensions = ">=4.1.0"
+
+[package.extras]
+dmypy = ["psutil (>=4.0)"]
+install-types = ["pip"]
+mypyc = ["setuptools (>=50)"]
+reports = ["lxml"]
+
[[package]]
name = "mypy-extensions"
version = "1.0.0"
@@ -1103,40 +1124,40 @@ files = [
[[package]]
name = "pandas"
-version = "2.2.0"
+version = "2.2.1"
description = "Powerful data structures for data analysis, time series, and statistics"
optional = false
python-versions = ">=3.9"
files = [
- {file = "pandas-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8108ee1712bb4fa2c16981fba7e68b3f6ea330277f5ca34fa8d557e986a11670"},
- {file = "pandas-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:736da9ad4033aeab51d067fc3bd69a0ba36f5a60f66a527b3d72e2030e63280a"},
- {file = "pandas-2.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38e0b4fc3ddceb56ec8a287313bc22abe17ab0eb184069f08fc6a9352a769b18"},
- {file = "pandas-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20404d2adefe92aed3b38da41d0847a143a09be982a31b85bc7dd565bdba0f4e"},
- {file = "pandas-2.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ea3ee3f125032bfcade3a4cf85131ed064b4f8dd23e5ce6fa16473e48ebcaf5"},
- {file = "pandas-2.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9670b3ac00a387620489dfc1bca66db47a787f4e55911f1293063a78b108df1"},
- {file = "pandas-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a946f210383c7e6d16312d30b238fd508d80d927014f3b33fb5b15c2f895430"},
- {file = "pandas-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a1b438fa26b208005c997e78672f1aa8138f67002e833312e6230f3e57fa87d5"},
- {file = "pandas-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8ce2fbc8d9bf303ce54a476116165220a1fedf15985b09656b4b4275300e920b"},
- {file = "pandas-2.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2707514a7bec41a4ab81f2ccce8b382961a29fbe9492eab1305bb075b2b1ff4f"},
- {file = "pandas-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85793cbdc2d5bc32620dc8ffa715423f0c680dacacf55056ba13454a5be5de88"},
- {file = "pandas-2.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cfd6c2491dc821b10c716ad6776e7ab311f7df5d16038d0b7458bc0b67dc10f3"},
- {file = "pandas-2.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a146b9dcacc3123aa2b399df1a284de5f46287a4ab4fbfc237eac98a92ebcb71"},
- {file = "pandas-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbc1b53c0e1fdf16388c33c3cca160f798d38aea2978004dd3f4d3dec56454c9"},
- {file = "pandas-2.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a41d06f308a024981dcaa6c41f2f2be46a6b186b902c94c2674e8cb5c42985bc"},
- {file = "pandas-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:159205c99d7a5ce89ecfc37cb08ed179de7783737cea403b295b5eda8e9c56d1"},
- {file = "pandas-2.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1e1f3861ea9132b32f2133788f3b14911b68102d562715d71bd0013bc45440"},
- {file = "pandas-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:761cb99b42a69005dec2b08854fb1d4888fdf7b05db23a8c5a099e4b886a2106"},
- {file = "pandas-2.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a20628faaf444da122b2a64b1e5360cde100ee6283ae8effa0d8745153809a2e"},
- {file = "pandas-2.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f5be5d03ea2073627e7111f61b9f1f0d9625dc3c4d8dda72cc827b0c58a1d042"},
- {file = "pandas-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:a626795722d893ed6aacb64d2401d017ddc8a2341b49e0384ab9bf7112bdec30"},
- {file = "pandas-2.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9f66419d4a41132eb7e9a73dcec9486cf5019f52d90dd35547af11bc58f8637d"},
- {file = "pandas-2.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:57abcaeda83fb80d447f28ab0cc7b32b13978f6f733875ebd1ed14f8fbc0f4ab"},
- {file = "pandas-2.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e60f1f7dba3c2d5ca159e18c46a34e7ca7247a73b5dd1a22b6d59707ed6b899a"},
- {file = "pandas-2.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb61dc8567b798b969bcc1fc964788f5a68214d333cade8319c7ab33e2b5d88a"},
- {file = "pandas-2.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:52826b5f4ed658fa2b729264d63f6732b8b29949c7fd234510d57c61dbeadfcd"},
- {file = "pandas-2.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bde2bc699dbd80d7bc7f9cab1e23a95c4375de615860ca089f34e7c64f4a8de7"},
- {file = "pandas-2.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:3de918a754bbf2da2381e8a3dcc45eede8cd7775b047b923f9006d5f876802ae"},
- {file = "pandas-2.2.0.tar.gz", hash = "sha256:30b83f7c3eb217fb4d1b494a57a2fda5444f17834f5df2de6b2ffff68dc3c8e2"},
+ {file = "pandas-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8df8612be9cd1c7797c93e1c5df861b2ddda0b48b08f2c3eaa0702cf88fb5f88"},
+ {file = "pandas-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0f573ab277252ed9aaf38240f3b54cfc90fff8e5cab70411ee1d03f5d51f3944"},
+ {file = "pandas-2.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f02a3a6c83df4026e55b63c1f06476c9aa3ed6af3d89b4f04ea656ccdaaaa359"},
+ {file = "pandas-2.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c38ce92cb22a4bea4e3929429aa1067a454dcc9c335799af93ba9be21b6beb51"},
+ {file = "pandas-2.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c2ce852e1cf2509a69e98358e8458775f89599566ac3775e70419b98615f4b06"},
+ {file = "pandas-2.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53680dc9b2519cbf609c62db3ed7c0b499077c7fefda564e330286e619ff0dd9"},
+ {file = "pandas-2.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:94e714a1cca63e4f5939cdce5f29ba8d415d85166be3441165edd427dc9f6bc0"},
+ {file = "pandas-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f821213d48f4ab353d20ebc24e4faf94ba40d76680642fb7ce2ea31a3ad94f9b"},
+ {file = "pandas-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c70e00c2d894cb230e5c15e4b1e1e6b2b478e09cf27cc593a11ef955b9ecc81a"},
+ {file = "pandas-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e97fbb5387c69209f134893abc788a6486dbf2f9e511070ca05eed4b930b1b02"},
+ {file = "pandas-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101d0eb9c5361aa0146f500773395a03839a5e6ecde4d4b6ced88b7e5a1a6403"},
+ {file = "pandas-2.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7d2ed41c319c9fb4fd454fe25372028dfa417aacb9790f68171b2e3f06eae8cd"},
+ {file = "pandas-2.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:af5d3c00557d657c8773ef9ee702c61dd13b9d7426794c9dfeb1dc4a0bf0ebc7"},
+ {file = "pandas-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:06cf591dbaefb6da9de8472535b185cba556d0ce2e6ed28e21d919704fef1a9e"},
+ {file = "pandas-2.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:88ecb5c01bb9ca927ebc4098136038519aa5d66b44671861ffab754cae75102c"},
+ {file = "pandas-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:04f6ec3baec203c13e3f8b139fb0f9f86cd8c0b94603ae3ae8ce9a422e9f5bee"},
+ {file = "pandas-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a935a90a76c44fe170d01e90a3594beef9e9a6220021acfb26053d01426f7dc2"},
+ {file = "pandas-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c391f594aae2fd9f679d419e9a4d5ba4bce5bb13f6a989195656e7dc4b95c8f0"},
+ {file = "pandas-2.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9d1265545f579edf3f8f0cb6f89f234f5e44ba725a34d86535b1a1d38decbccc"},
+ {file = "pandas-2.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11940e9e3056576ac3244baef2fedade891977bcc1cb7e5cc8f8cc7d603edc89"},
+ {file = "pandas-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:4acf681325ee1c7f950d058b05a820441075b0dd9a2adf5c4835b9bc056bf4fb"},
+ {file = "pandas-2.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9bd8a40f47080825af4317d0340c656744f2bfdb6819f818e6ba3cd24c0e1397"},
+ {file = "pandas-2.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:df0c37ebd19e11d089ceba66eba59a168242fc6b7155cba4ffffa6eccdfb8f16"},
+ {file = "pandas-2.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:739cc70eaf17d57608639e74d63387b0d8594ce02f69e7a0b046f117974b3019"},
+ {file = "pandas-2.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9d3558d263073ed95e46f4650becff0c5e1ffe0fc3a015de3c79283dfbdb3df"},
+ {file = "pandas-2.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4aa1d8707812a658debf03824016bf5ea0d516afdea29b7dc14cf687bc4d4ec6"},
+ {file = "pandas-2.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:76f27a809cda87e07f192f001d11adc2b930e93a2b0c4a236fde5429527423be"},
+ {file = "pandas-2.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:1ba21b1d5c0e43416218db63037dbe1a01fc101dc6e6024bcad08123e48004ab"},
+ {file = "pandas-2.2.1.tar.gz", hash = "sha256:0ab90f87093c13f3e8fa45b48ba9f39181046e8f3317d3aadb2fffbb1b978572"},
]
[package.dependencies]
@@ -1164,6 +1185,7 @@ parquet = ["pyarrow (>=10.0.1)"]
performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"]
plot = ["matplotlib (>=3.6.3)"]
postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"]
+pyarrow = ["pyarrow (>=10.0.1)"]
spss = ["pyreadstat (>=1.2.0)"]
sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"]
test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
@@ -1297,13 +1319,13 @@ testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pre-commit"
-version = "3.6.1"
+version = "3.6.2"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
optional = false
python-versions = ">=3.9"
files = [
- {file = "pre_commit-3.6.1-py2.py3-none-any.whl", hash = "sha256:9fe989afcf095d2c4796ce7c553cf28d4d4a9b9346de3cda079bcf40748454a4"},
- {file = "pre_commit-3.6.1.tar.gz", hash = "sha256:c90961d8aa706f75d60935aba09469a6b0bcb8345f127c3fbee4bdc5f114cf4b"},
+ {file = "pre_commit-3.6.2-py2.py3-none-any.whl", hash = "sha256:ba637c2d7a670c10daedc059f5c49b5bd0aadbccfcd7ec15592cf9665117532c"},
+ {file = "pre_commit-3.6.2.tar.gz", hash = "sha256:c3ef34f463045c88658c5b99f38c1e297abdcc0ff13f98d3370055fbbfabc67e"},
]
[package.dependencies]
@@ -1329,55 +1351,148 @@ wcwidth = "*"
[[package]]
name = "pydantic"
-version = "1.10.14"
-description = "Data validation and settings management using python type hints"
+version = "2.6.2"
+description = "Data validation using Python type hints"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"},
- {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"},
- {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"},
- {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"},
- {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"},
- {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"},
- {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"},
- {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"},
- {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"},
- {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"},
- {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"},
- {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"},
- {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"},
- {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"},
- {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"},
- {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"},
- {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"},
- {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"},
- {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"},
- {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"},
- {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"},
- {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"},
- {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"},
- {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"},
- {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"},
- {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"},
- {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"},
- {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"},
- {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"},
- {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"},
- {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"},
- {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"},
- {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"},
- {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"},
- {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"},
- {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"},
+ {file = "pydantic-2.6.2-py3-none-any.whl", hash = "sha256:37a5432e54b12fecaa1049c5195f3d860a10e01bdfd24f1840ef14bd0d3aeab3"},
+ {file = "pydantic-2.6.2.tar.gz", hash = "sha256:a09be1c3d28f3abe37f8a78af58284b236a92ce520105ddc91a6d29ea1176ba7"},
]
[package.dependencies]
-typing-extensions = ">=4.2.0"
+annotated-types = ">=0.4.0"
+pydantic-core = "2.16.3"
+typing-extensions = ">=4.6.1"
[package.extras]
-dotenv = ["python-dotenv (>=0.10.4)"]
-email = ["email-validator (>=1.0.3)"]
+email = ["email-validator (>=2.0.0)"]
+
+[[package]]
+name = "pydantic-core"
+version = "2.16.3"
+description = ""
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"},
+ {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"},
+ {file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"},
+ {file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"},
+ {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"},
+ {file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"},
+ {file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"},
+ {file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"},
+ {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"},
+ {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"},
+ {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"},
+ {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"},
+ {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"},
+ {file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"},
+ {file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"},
+ {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"},
+ {file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"},
+ {file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"},
+ {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"},
+ {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"},
+ {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"},
+ {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"},
+ {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"},
+ {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"},
+ {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"},
+ {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"},
+ {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"},
+ {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"},
+ {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"},
+ {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"},
+ {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"},
+ {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"},
+ {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"},
+ {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"},
+ {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"},
+]
+
+[package.dependencies]
+typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
+
+[[package]]
+name = "pyflakes"
+version = "3.2.0"
+description = "passive checker of Python programs"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"},
+ {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"},
+]
+
+[[package]]
+name = "pylint"
+version = "3.1.0"
+description = "python code static checker"
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "pylint-3.1.0-py3-none-any.whl", hash = "sha256:507a5b60953874766d8a366e8e8c7af63e058b26345cfcb5f91f89d987fd6b74"},
+ {file = "pylint-3.1.0.tar.gz", hash = "sha256:6a69beb4a6f63debebaab0a3477ecd0f559aa726af4954fc948c51f7a2549e23"},
+]
+
+[package.dependencies]
+astroid = ">=3.1.0,<=3.2.0-dev0"
+colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
+dill = {version = ">=0.3.7", markers = "python_version >= \"3.12\""}
+isort = ">=4.2.5,<5.13.0 || >5.13.0,<6"
+mccabe = ">=0.6,<0.8"
+platformdirs = ">=2.2.0"
+tomlkit = ">=0.10.1"
+
+[package.extras]
+spelling = ["pyenchant (>=3.2,<4.0)"]
+testutils = ["gitpython (>3)"]
[[package]]
name = "pyparsing"
@@ -1393,15 +1508,30 @@ files = [
[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]
+[[package]]
+name = "pyproject-autoflake"
+version = "1.0.2"
+description = "pyproject-autoflake (pautoflake), a monkey patching wrapper to connect autoflake with pyproject.toml configuration."
+optional = false
+python-versions = ">=3.6.2,<4.0.0"
+files = [
+ {file = "pyproject-autoflake-1.0.2.tar.gz", hash = "sha256:7ad1ab8c8e522bd04f05728f2656935853288b7b974a47850174c6cf6cc378ad"},
+ {file = "pyproject_autoflake-1.0.2-py3-none-any.whl", hash = "sha256:db7220bec762cbc8cfe93f1d23f3a564d0c076529bc1ebafc2dcb023c5ee265c"},
+]
+
+[package.dependencies]
+autoflake = "*"
+toml = ">=0.10.1"
+
[[package]]
name = "pytest"
-version = "8.0.0"
+version = "8.0.2"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pytest-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"},
- {file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"},
+ {file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"},
+ {file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"},
]
[package.dependencies]
@@ -1477,7 +1607,6 @@ files = [
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
@@ -1651,13 +1780,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "requests-cache"
-version = "1.1.1"
+version = "1.2.0"
description = "A persistent cache for python requests"
optional = false
-python-versions = ">=3.7,<4.0"
+python-versions = ">=3.8"
files = [
- {file = "requests_cache-1.1.1-py3-none-any.whl", hash = "sha256:c8420cf096f3aafde13c374979c21844752e2694ffd8710e6764685bb577ac90"},
- {file = "requests_cache-1.1.1.tar.gz", hash = "sha256:764f93d3fa860be72125a568c2cc8eafb151cf29b4dc2515433a56ee657e1c60"},
+ {file = "requests_cache-1.2.0-py3-none-any.whl", hash = "sha256:490324301bf0cb924ff4e6324bd2613453e7e1f847353928b08adb0fdfb7f722"},
+ {file = "requests_cache-1.2.0.tar.gz", hash = "sha256:db1c709ca343cc1cd5b6c8b1a5387298eceed02306a6040760db538c885e3838"},
]
[package.dependencies]
@@ -1669,15 +1798,15 @@ url-normalize = ">=1.4"
urllib3 = ">=1.25.5"
[package.extras]
-all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=5.4)", "redis (>=3)", "ujson (>=5.4)"]
+all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"]
bson = ["bson (>=0.5)"]
-docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.6)"]
+docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"]
dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"]
json = ["ujson (>=5.4)"]
mongodb = ["pymongo (>=3)"]
redis = ["redis (>=3)"]
security = ["itsdangerous (>=2.0)"]
-yaml = ["pyyaml (>=5.4)"]
+yaml = ["pyyaml (>=6.0.1)"]
[[package]]
name = "scipy"
@@ -1723,19 +1852,19 @@ test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov",
[[package]]
name = "setuptools"
-version = "69.0.3"
+version = "69.1.1"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
files = [
- {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"},
- {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"},
+ {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"},
+ {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
-testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
-testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "six"
@@ -1750,94 +1879,15 @@ files = [
[[package]]
name = "sniffio"
-version = "1.3.0"
+version = "1.3.1"
description = "Sniff out which async library your code is running under"
optional = false
python-versions = ">=3.7"
files = [
- {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
- {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
-]
-
-[[package]]
-name = "sqlalchemy"
-version = "1.4.51"
-description = "Database Abstraction Library"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
-files = [
- {file = "SQLAlchemy-1.4.51-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:1a09d5bd1a40d76ad90e5570530e082ddc000e1d92de495746f6257dc08f166b"},
- {file = "SQLAlchemy-1.4.51-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2be4e6294c53f2ec8ea36486b56390e3bcaa052bf3a9a47005687ccf376745d1"},
- {file = "SQLAlchemy-1.4.51-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca484ca11c65e05639ffe80f20d45e6be81fbec7683d6c9a15cd421e6e8b340"},
- {file = "SQLAlchemy-1.4.51-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0535d5b57d014d06ceeaeffd816bb3a6e2dddeb670222570b8c4953e2d2ea678"},
- {file = "SQLAlchemy-1.4.51-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af55cc207865d641a57f7044e98b08b09220da3d1b13a46f26487cc2f898a072"},
- {file = "SQLAlchemy-1.4.51-cp310-cp310-win32.whl", hash = "sha256:7af40425ac535cbda129d9915edcaa002afe35d84609fd3b9d6a8c46732e02ee"},
- {file = "SQLAlchemy-1.4.51-cp310-cp310-win_amd64.whl", hash = "sha256:8d1d7d63e5d2f4e92a39ae1e897a5d551720179bb8d1254883e7113d3826d43c"},
- {file = "SQLAlchemy-1.4.51-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eaeeb2464019765bc4340214fca1143081d49972864773f3f1e95dba5c7edc7d"},
- {file = "SQLAlchemy-1.4.51-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7deeae5071930abb3669b5185abb6c33ddfd2398f87660fafdb9e6a5fb0f3f2f"},
- {file = "SQLAlchemy-1.4.51-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0892e7ac8bc76da499ad3ee8de8da4d7905a3110b952e2a35a940dab1ffa550e"},
- {file = "SQLAlchemy-1.4.51-cp311-cp311-win32.whl", hash = "sha256:50e074aea505f4427151c286955ea025f51752fa42f9939749336672e0674c81"},
- {file = "SQLAlchemy-1.4.51-cp311-cp311-win_amd64.whl", hash = "sha256:3b0cd89a7bd03f57ae58263d0f828a072d1b440c8c2949f38f3b446148321171"},
- {file = "SQLAlchemy-1.4.51-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a33cb3f095e7d776ec76e79d92d83117438b6153510770fcd57b9c96f9ef623d"},
- {file = "SQLAlchemy-1.4.51-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cacc0b2dd7d22a918a9642fc89840a5d3cee18a0e1fe41080b1141b23b10916"},
- {file = "SQLAlchemy-1.4.51-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:245c67c88e63f1523e9216cad6ba3107dea2d3ee19adc359597a628afcabfbcb"},
- {file = "SQLAlchemy-1.4.51-cp312-cp312-win32.whl", hash = "sha256:8e702e7489f39375601c7ea5a0bef207256828a2bc5986c65cb15cd0cf097a87"},
- {file = "SQLAlchemy-1.4.51-cp312-cp312-win_amd64.whl", hash = "sha256:0525c4905b4b52d8ccc3c203c9d7ab2a80329ffa077d4bacf31aefda7604dc65"},
- {file = "SQLAlchemy-1.4.51-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:1980e6eb6c9be49ea8f89889989127daafc43f0b1b6843d71efab1514973cca0"},
- {file = "SQLAlchemy-1.4.51-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec7a0ed9b32afdf337172678a4a0e6419775ba4e649b66f49415615fa47efbd"},
- {file = "SQLAlchemy-1.4.51-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352df882088a55293f621328ec33b6ffca936ad7f23013b22520542e1ab6ad1b"},
- {file = "SQLAlchemy-1.4.51-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:86a22143a4001f53bf58027b044da1fb10d67b62a785fc1390b5c7f089d9838c"},
- {file = "SQLAlchemy-1.4.51-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c37bc677690fd33932182b85d37433845de612962ed080c3e4d92f758d1bd894"},
- {file = "SQLAlchemy-1.4.51-cp36-cp36m-win32.whl", hash = "sha256:d0a83afab5e062abffcdcbcc74f9d3ba37b2385294dd0927ad65fc6ebe04e054"},
- {file = "SQLAlchemy-1.4.51-cp36-cp36m-win_amd64.whl", hash = "sha256:a61184c7289146c8cff06b6b41807c6994c6d437278e72cf00ff7fe1c7a263d1"},
- {file = "SQLAlchemy-1.4.51-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:3f0ef620ecbab46e81035cf3dedfb412a7da35340500ba470f9ce43a1e6c423b"},
- {file = "SQLAlchemy-1.4.51-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c55040d8ea65414de7c47f1a23823cd9f3fad0dc93e6b6b728fee81230f817b"},
- {file = "SQLAlchemy-1.4.51-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ef80328e3fee2be0a1abe3fe9445d3a2e52a1282ba342d0dab6edf1fef4707"},
- {file = "SQLAlchemy-1.4.51-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f8cafa6f885a0ff5e39efa9325195217bb47d5929ab0051636610d24aef45ade"},
- {file = "SQLAlchemy-1.4.51-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8f2df79a46e130235bc5e1bbef4de0583fb19d481eaa0bffa76e8347ea45ec6"},
- {file = "SQLAlchemy-1.4.51-cp37-cp37m-win32.whl", hash = "sha256:f2e5b6f5cf7c18df66d082604a1d9c7a2d18f7d1dbe9514a2afaccbb51cc4fc3"},
- {file = "SQLAlchemy-1.4.51-cp37-cp37m-win_amd64.whl", hash = "sha256:5e180fff133d21a800c4f050733d59340f40d42364fcb9d14f6a67764bdc48d2"},
- {file = "SQLAlchemy-1.4.51-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7d8139ca0b9f93890ab899da678816518af74312bb8cd71fb721436a93a93298"},
- {file = "SQLAlchemy-1.4.51-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb18549b770351b54e1ab5da37d22bc530b8bfe2ee31e22b9ebe650640d2ef12"},
- {file = "SQLAlchemy-1.4.51-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55e699466106d09f028ab78d3c2e1f621b5ef2c8694598242259e4515715da7c"},
- {file = "SQLAlchemy-1.4.51-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2ad16880ccd971ac8e570550fbdef1385e094b022d6fc85ef3ce7df400dddad3"},
- {file = "SQLAlchemy-1.4.51-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b97fd5bb6b7c1a64b7ac0632f7ce389b8ab362e7bd5f60654c2a418496be5d7f"},
- {file = "SQLAlchemy-1.4.51-cp38-cp38-win32.whl", hash = "sha256:cecb66492440ae8592797dd705a0cbaa6abe0555f4fa6c5f40b078bd2740fc6b"},
- {file = "SQLAlchemy-1.4.51-cp38-cp38-win_amd64.whl", hash = "sha256:39b02b645632c5fe46b8dd30755682f629ffbb62ff317ecc14c998c21b2896ff"},
- {file = "SQLAlchemy-1.4.51-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:b03850c290c765b87102959ea53299dc9addf76ca08a06ea98383348ae205c99"},
- {file = "SQLAlchemy-1.4.51-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e646b19f47d655261b22df9976e572f588185279970efba3d45c377127d35349"},
- {file = "SQLAlchemy-1.4.51-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3cf56cc36d42908495760b223ca9c2c0f9f0002b4eddc994b24db5fcb86a9e4"},
- {file = "SQLAlchemy-1.4.51-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0d661cff58c91726c601cc0ee626bf167b20cc4d7941c93c5f3ac28dc34ddbea"},
- {file = "SQLAlchemy-1.4.51-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3823dda635988e6744d4417e13f2e2b5fe76c4bf29dd67e95f98717e1b094cad"},
- {file = "SQLAlchemy-1.4.51-cp39-cp39-win32.whl", hash = "sha256:b00cf0471888823b7a9f722c6c41eb6985cf34f077edcf62695ac4bed6ec01ee"},
- {file = "SQLAlchemy-1.4.51-cp39-cp39-win_amd64.whl", hash = "sha256:a055ba17f4675aadcda3005df2e28a86feb731fdcc865e1f6b4f209ed1225cba"},
- {file = "SQLAlchemy-1.4.51.tar.gz", hash = "sha256:e7908c2025eb18394e32d65dd02d2e37e17d733cdbe7d78231c2b6d7eb20cdb9"},
+ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
+ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
]
-[package.dependencies]
-greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"}
-
-[package.extras]
-aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"]
-aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"]
-asyncio = ["greenlet (!=0.4.17)"]
-asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"]
-mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"]
-mssql = ["pyodbc"]
-mssql-pymssql = ["pymssql"]
-mssql-pyodbc = ["pyodbc"]
-mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"]
-mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"]
-mysql-connector = ["mysql-connector-python"]
-oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"]
-postgresql = ["psycopg2 (>=2.7)"]
-postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"]
-postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"]
-postgresql-psycopg2binary = ["psycopg2-binary"]
-postgresql-psycopg2cffi = ["psycopg2cffi"]
-pymysql = ["pymysql", "pymysql (<1)"]
-sqlcipher = ["sqlcipher3_binary"]
-
[[package]]
name = "starlette"
version = "0.36.3"
@@ -1898,37 +1948,48 @@ files = [
matplotlib = "*"
numpy = "*"
+[[package]]
+name = "toml"
+version = "0.10.2"
+description = "Python Library for Tom's Obvious, Minimal Language"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
+ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
+]
+
[[package]]
name = "tomlkit"
-version = "0.12.3"
+version = "0.12.4"
description = "Style preserving TOML library"
optional = false
python-versions = ">=3.7"
files = [
- {file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"},
- {file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"},
+ {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"},
+ {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"},
]
[[package]]
name = "typing-extensions"
-version = "4.9.0"
+version = "4.10.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
- {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
- {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
+ {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
+ {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
]
[[package]]
name = "tzdata"
-version = "2023.4"
+version = "2024.1"
description = "Provider of IANA time zone data"
optional = false
python-versions = ">=2"
files = [
- {file = "tzdata-2023.4-py2.py3-none-any.whl", hash = "sha256:aa3ace4329eeacda5b7beb7ea08ece826c28d761cda36e747cfbf97996d39bf3"},
- {file = "tzdata-2023.4.tar.gz", hash = "sha256:dd54c94f294765522c77399649b4fefd95522479a664a0cec87f41bebc6148c9"},
+ {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"},
+ {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
]
[[package]]
@@ -1947,13 +2008,13 @@ six = "*"
[[package]]
name = "urllib3"
-version = "2.2.0"
+version = "2.2.1"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.8"
files = [
- {file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"},
- {file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"},
+ {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"},
+ {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"},
]
[package.extras]
@@ -2033,13 +2094,13 @@ test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)"
[[package]]
name = "virtualenv"
-version = "20.25.0"
+version = "20.25.1"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.7"
files = [
- {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"},
- {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"},
+ {file = "virtualenv-20.25.1-py3-none-any.whl", hash = "sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a"},
+ {file = "virtualenv-20.25.1.tar.gz", hash = "sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197"},
]
[package.dependencies]
@@ -2248,4 +2309,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = "^3.12"
-content-hash = "725d9324e4ab55620b0458bdcfd5e261b5009a7ecf4fd9a402df5e4842d46e46"
+content-hash = "d7f9e04a55712b57cbc832aa237e3bd09666056a6014f8c45fe4f8a3840881fc"
diff --git a/poetry.toml b/poetry.toml
new file mode 100644
index 0000000..e8effc6
--- /dev/null
+++ b/poetry.toml
@@ -0,0 +1,4 @@
+[virtualenvs]
+create = true
+in-project = true
+prompt = "{project_name}-py{python_version}"
diff --git a/pyproject.toml b/pyproject.toml
index 2b3ca0f..5f15ba0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,3 +1,9 @@
+#-->> System <<--------------------------------------------
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
+
+#-->> Metadata <<------------------------------------------
[tool.poetry]
name = "backend"
version = "0.2.0"
@@ -5,27 +11,68 @@ description = "Slick Telemetry backend written in python"
authors = ["Slick Telemetry "]
readme = "README.md"
+#-->> Dependencies <<--------------------------------------
+# Main dependencies (required by application)
[tool.poetry.dependencies]
python = "^3.12"
-fastapi = "^0.109.2"
-fastf1 = "^3.2.2"
-fastapi-utils = "^0.2.1"
+fastapi = "^0.110.0"
+fastf1 = "3.2.2"
uvicorn = { extras = ["standard"], version = "^0.27.1" }
+# Development (common)
[tool.poetry.group.dev.dependencies]
-black = "^24.1.1"
-commitizen = "^3.14.1"
-isort = "^5.13.2"
-pre-commit = "^3.6.0"
-pytest = "^8.0.0"
-httpx = "^0.26.0"
+commitizen = "*"
+pre-commit = "*"
-[build-system]
-requires = ["poetry-core"]
-build-backend = "poetry.core.masonry.api"
+# Formatting
+[tool.poetry.group.lint]
+optional = true
-[tool.isort]
-profile = "black"
+[tool.poetry.group.lint.dependencies]
+black = "*"
+isort = "*"
+mypy = "*"
+pylint = "*"
+pyproject-autoflake = "*"
+
+# Testing dependencies
+[tool.poetry.group.test]
+optional = true
+
+[tool.poetry.group.test.dependencies]
+httpx = "*"
+pytest = "*"
+
+#-->> Scripts <<-------------------------------------------
+[tool.poe.tasks]
+autoflake = "pautoflake run.py app"
+black = "black run.py app"
+isort = "isort run.py app"
+formatters = ["autoflake", "isort", "black"]
+git-hooks-setup = "pre-commit install --hook-type commit-msg --hook-type pre-push --hook-type pre-commit"
+git-hooks-upate = "pre-commit autoupdate"
+pylint = "pylint run.py app"
+tests = "pytest -rpP"
+typings = "mypy run.py app"
+
+#-->> Configuration <<-------------------------------------
+[tool.autoflake]
+# return error code if changes are needed
+check = false
+# make changes to files instead of printing diffs
+in-place = true
+# exclude __init__.py when removing unused imports
+ignore-init-module-imports = true
+# remove all unused imports (not just those from the standard library)
+remove-all-unused-imports = true
+# remove unused variables
+remove-unused-variables = true
+# drill down directories recursively
+recursive = true
+
+[tool.black]
+line-length = 120
+target-version = ["py312"]
[tool.commitizen]
version = "0.2.0"
@@ -36,3 +83,23 @@ version_files = [
]
update_changelog_on_bump = true
major_version_zero = true
+
+[tool.isort]
+profile = "black"
+lines_after_imports = 2
+line_length = 120
+multi_line_output = 3
+import_heading_stdlib = "Built-in"
+import_heading_thirdparty = "External"
+import_heading_firstparty = "Project"
+import_heading_localfolder = "App"
+
+[tool.mypy]
+enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
+files = ["app/*.py"]
+ignore_missing_imports = true
+pretty = true
+show_error_codes = true
+show_error_context = true
+warn_unreachable = true
+warn_return_any = true
diff --git a/run.py b/run.py
index f535f93..70491f5 100644
--- a/run.py
+++ b/run.py
@@ -1,14 +1,15 @@
+# External
import uvicorn
def start_server():
uvicorn.run(
"app.main:app",
- host="127.0.0.1",
+ host="localhost",
port=8081,
reload=True,
log_level="info",
- reload_excludes=["app/test_main.py"],
+ reload_excludes=["tests/*.py"],
)
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_healthcheck.py b/tests/test_healthcheck.py
new file mode 100644
index 0000000..629a68f
--- /dev/null
+++ b/tests/test_healthcheck.py
@@ -0,0 +1,15 @@
+# External
+from fastapi import status
+from fastapi.testclient import TestClient
+
+# Project
+from app.main import app
+
+
+client = TestClient(app)
+
+
+def test_healthcheck():
+ response = client.get("/health")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == {"status": "OK"}
diff --git a/tests/test_laps.py b/tests/test_laps.py
new file mode 100644
index 0000000..fa97fe9
--- /dev/null
+++ b/tests/test_laps.py
@@ -0,0 +1,220 @@
+# External
+from fastapi import status
+from fastapi.testclient import TestClient
+
+# Project
+from app.main import app
+
+
+client = TestClient(app)
+
+
+# region laps - good inputs
+
+
+def test_get_laps():
+ response = client.get("/laps/2023/5")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0] == {
+ "Time": 3868310,
+ "Driver": "VER",
+ "DriverNumber": "1",
+ "LapTime": 101724,
+ "LapNumber": 1.0,
+ "Stint": 1.0,
+ "PitOutTime": None,
+ "PitInTime": None,
+ "Sector1Time": None,
+ "Sector2Time": 36216,
+ "Sector3Time": 26263,
+ "Sector1SessionTime": None,
+ "Sector2SessionTime": 3842065,
+ "Sector3SessionTime": 3868409,
+ "SpeedI1": 212.0,
+ "SpeedI2": 186.0,
+ "SpeedFL": 274.0,
+ "SpeedST": 306.0,
+ "IsPersonalBest": False,
+ "Compound": "HARD",
+ "TyreLife": 1.0,
+ "FreshTyre": True,
+ "Team": "Red Bull Racing",
+ "LapStartTime": 3766300,
+ "LapStartDate": None,
+ "TrackStatus": "1",
+ "Position": 9.0,
+ "Deleted": False,
+ "DeletedReason": "",
+ "FastF1Generated": False,
+ "IsAccurate": False,
+ }
+
+
+def test_get_laps_with_session_only():
+ response = client.get("/laps/2023/5?session=4")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0] == {
+ "Time": 1098400,
+ "Driver": "PER",
+ "DriverNumber": "11",
+ "LapTime": None,
+ "LapNumber": 1.0,
+ "Stint": 1.0,
+ "PitOutTime": 979230,
+ "PitInTime": None,
+ "Sector1Time": None,
+ "Sector2Time": 46024,
+ "Sector3Time": 33583,
+ "Sector1SessionTime": None,
+ "Sector2SessionTime": 1064838,
+ "Sector3SessionTime": 1098400,
+ "SpeedI1": 205.0,
+ "SpeedI2": 110.0,
+ "SpeedFL": 284.0,
+ "SpeedST": 266.0,
+ "IsPersonalBest": False,
+ "Compound": "SOFT",
+ "TyreLife": 1.0,
+ "FreshTyre": True,
+ "Team": "Red Bull Racing",
+ "LapStartTime": 979230,
+ "LapStartDate": None,
+ "TrackStatus": "1",
+ "Position": None,
+ "Deleted": False,
+ "DeletedReason": "",
+ "FastF1Generated": False,
+ "IsAccurate": False,
+ }
+
+
+def test_get_laps_with_driver_numbers_only():
+ response = client.get("/laps/2023/5?driver_number=1&driver_number=44")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0] == {
+ "Time": 3868310,
+ "Driver": "VER",
+ "DriverNumber": "1",
+ "LapTime": 101724,
+ "LapNumber": 1.0,
+ "Stint": 1.0,
+ "PitOutTime": None,
+ "PitInTime": None,
+ "Sector1Time": None,
+ "Sector2Time": 36216,
+ "Sector3Time": 26263,
+ "Sector1SessionTime": None,
+ "Sector2SessionTime": 3842065,
+ "Sector3SessionTime": 3868409,
+ "SpeedI1": 212.0,
+ "SpeedI2": 186.0,
+ "SpeedFL": 274.0,
+ "SpeedST": 306.0,
+ "IsPersonalBest": False,
+ "Compound": "HARD",
+ "TyreLife": 1.0,
+ "FreshTyre": True,
+ "Team": "Red Bull Racing",
+ "LapStartTime": 3766300,
+ "LapStartDate": None,
+ "TrackStatus": "1",
+ "Position": 9.0,
+ "Deleted": False,
+ "DeletedReason": "",
+ "FastF1Generated": False,
+ "IsAccurate": False,
+ }
+
+
+def test_get_laps_with_session_and_driver_numbers():
+ response = client.get("/laps/2023/5?session=4&driver_number=1&driver_number=44")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0] == {
+ "Time": 1087970,
+ "Driver": "VER",
+ "DriverNumber": "1",
+ "LapTime": None,
+ "LapNumber": 1.0,
+ "Stint": 1.0,
+ "PitOutTime": 972293,
+ "PitInTime": None,
+ "Sector1Time": None,
+ "Sector2Time": 44852,
+ "Sector3Time": 31773,
+ "Sector1SessionTime": None,
+ "Sector2SessionTime": 1056197,
+ "Sector3SessionTime": 1088025,
+ "SpeedI1": 202.0,
+ "SpeedI2": 79.0,
+ "SpeedFL": 283.0,
+ "SpeedST": 257.0,
+ "IsPersonalBest": False,
+ "Compound": "SOFT",
+ "TyreLife": 1.0,
+ "FreshTyre": True,
+ "Team": "Red Bull Racing",
+ "LapStartTime": 972293,
+ "LapStartDate": None,
+ "TrackStatus": "1",
+ "Position": None,
+ "Deleted": False,
+ "DeletedReason": "",
+ "FastF1Generated": False,
+ "IsAccurate": False,
+ }
+
+
+# endregion laps - good inputs
+
+# region laps - bad inputs
+
+
+def test_get_laps_mixed_driver_numbers():
+ response = client.get(
+ "/laps/2023/5?driver_number=0&driver_number=1&driver_number=13&driver_number=44&driver_number=83"
+ )
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0] == {
+ "Time": 3868310,
+ "Driver": "VER",
+ "DriverNumber": "1",
+ "LapTime": 101724,
+ "LapNumber": 1.0,
+ "Stint": 1.0,
+ "PitOutTime": None,
+ "PitInTime": None,
+ "Sector1Time": None,
+ "Sector2Time": 36216,
+ "Sector3Time": 26263,
+ "Sector1SessionTime": None,
+ "Sector2SessionTime": 3842065,
+ "Sector3SessionTime": 3868409,
+ "SpeedI1": 212.0,
+ "SpeedI2": 186.0,
+ "SpeedFL": 274.0,
+ "SpeedST": 306.0,
+ "IsPersonalBest": False,
+ "Compound": "HARD",
+ "TyreLife": 1.0,
+ "FreshTyre": True,
+ "Team": "Red Bull Racing",
+ "LapStartTime": 3766300,
+ "LapStartDate": None,
+ "TrackStatus": "1",
+ "Position": 9.0,
+ "Deleted": False,
+ "DeletedReason": "",
+ "FastF1Generated": False,
+ "IsAccurate": False,
+ }
+
+
+def test_get_laps_bad_driver_numbers():
+ response = client.get(
+ "/laps/2023/5?driver_number=0&driver_number=99&driver_number=13&driver_number=45&driver_number=83"
+ )
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == []
+
+
+# endregion laps - bad inputs
diff --git a/tests/test_next_event.py b/tests/test_next_event.py
new file mode 100644
index 0000000..d56e48f
--- /dev/null
+++ b/tests/test_next_event.py
@@ -0,0 +1,39 @@
+# External
+from fastapi import status
+from fastapi.testclient import TestClient
+
+# Project
+from app.main import app
+
+
+client = TestClient(app)
+
+
+def test_get_next_event():
+ response = client.get("/next-event")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == {
+ "RoundNumber": 1,
+ "Country": "Bahrain",
+ "Location": "Sakhir",
+ "OfficialEventName": "FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2024",
+ "EventDate": "2024-03-02 00:00:00",
+ "EventName": "Bahrain Grand Prix",
+ "EventFormat": "conventional",
+ "Session1": "Practice 1",
+ "Session1Date": "2024-02-29 14:30:00+03:00",
+ "Session1DateUtc": "2024-02-29 11:30:00",
+ "Session2": "Practice 2",
+ "Session2Date": "2024-02-29 18:00:00+03:00",
+ "Session2DateUtc": "2024-02-29 15:00:00",
+ "Session3": "Practice 3",
+ "Session3Date": "2024-03-01 15:30:00+03:00",
+ "Session3DateUtc": "2024-03-01 12:30:00",
+ "Session4": "Qualifying",
+ "Session4Date": "2024-03-01 19:00:00+03:00",
+ "Session4DateUtc": "2024-03-01 16:00:00",
+ "Session5": "Race",
+ "Session5Date": "2024-03-02 18:00:00+03:00",
+ "Session5DateUtc": "2024-03-02 15:00:00",
+ "F1ApiSupport": True,
+ }
diff --git a/tests/test_results.py b/tests/test_results.py
new file mode 100644
index 0000000..ad990a1
--- /dev/null
+++ b/tests/test_results.py
@@ -0,0 +1,82 @@
+# External
+from fastapi import status
+from fastapi.testclient import TestClient
+
+# Project
+from app.main import app
+
+
+client = TestClient(app)
+
+
+# region results - good inputs
+
+
+def test_get_results():
+ response = client.get("/results/2023/5")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0] == {
+ "DriverNumber": "1",
+ "BroadcastName": "M VERSTAPPEN",
+ "Abbreviation": "VER",
+ "DriverId": "max_verstappen",
+ "TeamName": "Red Bull Racing",
+ "TeamColor": "3671C6",
+ "TeamId": "red_bull",
+ "FirstName": "Max",
+ "LastName": "Verstappen",
+ "FullName": "Max Verstappen",
+ "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/M/MAXVER01_Max_Verstappen/maxver01.png.transform/1col/image.png",
+ "CountryCode": "NED",
+ "Position": 1,
+ "ClassifiedPosition": "1",
+ "GridPosition": 9,
+ "Q1": None,
+ "Q2": None,
+ "Q3": None,
+ "Time": 5258241,
+ "Status": "Finished",
+ "Points": 26,
+ }
+
+
+def test_get_results_with_session():
+ response = client.get("/results/2023/5?session=4")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()[0] == {
+ "DriverNumber": "11",
+ "BroadcastName": "S PEREZ",
+ "Abbreviation": "PER",
+ "DriverId": "perez",
+ "TeamName": "Red Bull Racing",
+ "TeamColor": "3671C6",
+ "TeamId": "red_bull",
+ "FirstName": "Sergio",
+ "LastName": "Perez",
+ "FullName": "Sergio Perez",
+ "HeadshotUrl": "https://www.formula1.com/content/dam/fom-website/drivers/S/SERPER01_Sergio_Perez/serper01.png.transform/1col/image.png",
+ "CountryCode": "MEX",
+ "Position": 1,
+ "ClassifiedPosition": "",
+ "GridPosition": None,
+ "Q1": 87713,
+ "Q2": 87328,
+ "Q3": 86841,
+ "Time": None,
+ "Status": "",
+ "Points": None,
+ }
+
+
+# endregion results - good inputs
+
+# region results - bad inputs
+
+
+def test_get_results_bad_round_invalid():
+ response = client.get("/results/2023/25?session=2")
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+ assert response.json() == {"detail": "Bad Request. Invalid round: 25"}
+
+
+# endregion results - bad inputs
diff --git a/tests/test_root.py b/tests/test_root.py
new file mode 100644
index 0000000..e792da5
--- /dev/null
+++ b/tests/test_root.py
@@ -0,0 +1,15 @@
+# External
+from fastapi import status
+from fastapi.testclient import TestClient
+
+# Project
+from app.main import app
+
+
+client = TestClient(app)
+
+
+def test_read_root():
+ response = client.get("/")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json() == {"we_are": "SlickTelemetry"}
diff --git a/tests/test_schedule.py b/tests/test_schedule.py
new file mode 100644
index 0000000..298d907
--- /dev/null
+++ b/tests/test_schedule.py
@@ -0,0 +1,71 @@
+# External
+from fastapi import status
+from fastapi.testclient import TestClient
+
+# Project
+from app.main import app
+
+
+client = TestClient(app)
+
+
+def test_get_schedule():
+ response = client.get("/schedule")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["year"] == 2023
+ assert response.json()["EventSchedule"][0] == {
+ "RoundNumber": 1,
+ "Country": "Bahrain",
+ "Location": "Sakhir",
+ "OfficialEventName": "FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2023",
+ "EventDate": "2023-03-05",
+ "EventName": "Bahrain Grand Prix",
+ "EventFormat": "conventional",
+ "Session1": "Practice 1",
+ "Session1Date": "2023-03-03 14:30:00+03:00",
+ "Session1DateUtc": "2023-03-03 11:30:00",
+ "Session2": "Practice 2",
+ "Session2Date": "2023-03-03 18:00:00+03:00",
+ "Session2DateUtc": "2023-03-03 15:00:00",
+ "Session3": "Practice 3",
+ "Session3Date": "2023-03-04 14:30:00+03:00",
+ "Session3DateUtc": "2023-03-04 11:30:00",
+ "Session4": "Qualifying",
+ "Session4Date": "2023-03-04 18:00:00+03:00",
+ "Session4DateUtc": "2023-03-04 15:00:00",
+ "Session5": "Race",
+ "Session5Date": "2023-03-05 18:00:00+03:00",
+ "Session5DateUtc": "2023-03-05 15:00:00",
+ "F1ApiSupport": True,
+ }
+
+
+def test_get_schedule_good_year():
+ response = client.get("/schedule?year=2023")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["year"] == 2023
+ assert response.json()["EventSchedule"][0] == {
+ "RoundNumber": 1,
+ "Country": "Bahrain",
+ "Location": "Sakhir",
+ "OfficialEventName": "FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2023",
+ "EventDate": "2023-03-05",
+ "EventName": "Bahrain Grand Prix",
+ "EventFormat": "conventional",
+ "Session1": "Practice 1",
+ "Session1Date": "2023-03-03 14:30:00+03:00",
+ "Session1DateUtc": "2023-03-03 11:30:00",
+ "Session2": "Practice 2",
+ "Session2Date": "2023-03-03 18:00:00+03:00",
+ "Session2DateUtc": "2023-03-03 15:00:00",
+ "Session3": "Practice 3",
+ "Session3Date": "2023-03-04 14:30:00+03:00",
+ "Session3DateUtc": "2023-03-04 11:30:00",
+ "Session4": "Qualifying",
+ "Session4Date": "2023-03-04 18:00:00+03:00",
+ "Session4DateUtc": "2023-03-04 15:00:00",
+ "Session5": "Race",
+ "Session5Date": "2023-03-05 18:00:00+03:00",
+ "Session5DateUtc": "2023-03-05 15:00:00",
+ "F1ApiSupport": True,
+ }
diff --git a/tests/test_standings.py b/tests/test_standings.py
new file mode 100644
index 0000000..937791f
--- /dev/null
+++ b/tests/test_standings.py
@@ -0,0 +1,155 @@
+# External
+from fastapi import status
+from fastapi.testclient import TestClient
+
+# Project
+from app.main import app
+
+
+client = TestClient(app)
+
+
+# region standings - good inputs
+
+
+def test_get_standings():
+ response = client.get("/standings")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["season"] == 2023
+ assert response.json()["round"] == 22
+ assert response.json()["DriverStandings"][0] == {
+ "position": "1",
+ "positionText": "1",
+ "points": "575",
+ "wins": "19",
+ "Driver": {
+ "driverId": "max_verstappen",
+ "permanentNumber": "33",
+ "code": "VER",
+ "url": "http://en.wikipedia.org/wiki/Max_Verstappen",
+ "givenName": "Max",
+ "familyName": "Verstappen",
+ "dateOfBirth": "1997-09-30",
+ "nationality": "Dutch",
+ },
+ "Constructors": [
+ {
+ "constructorId": "red_bull",
+ "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
+ "name": "Red Bull",
+ "nationality": "Austrian",
+ }
+ ],
+ }
+ assert response.json()["ConstructorStandings"][0] == {
+ "position": "1",
+ "positionText": "1",
+ "points": "860",
+ "wins": "21",
+ "Constructor": {
+ "constructorId": "red_bull",
+ "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
+ "name": "Red Bull",
+ "nationality": "Austrian",
+ },
+ }
+
+
+def test_get_standings_good_year_only():
+ response = client.get("/standings?year=2023")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["season"] == 2023
+ assert response.json()["round"] == 22
+ assert response.json()["DriverStandings"][0] == {
+ "position": "1",
+ "positionText": "1",
+ "points": "575",
+ "wins": "19",
+ "Driver": {
+ "driverId": "max_verstappen",
+ "permanentNumber": "33",
+ "code": "VER",
+ "url": "http://en.wikipedia.org/wiki/Max_Verstappen",
+ "givenName": "Max",
+ "familyName": "Verstappen",
+ "dateOfBirth": "1997-09-30",
+ "nationality": "Dutch",
+ },
+ "Constructors": [
+ {
+ "constructorId": "red_bull",
+ "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
+ "name": "Red Bull",
+ "nationality": "Austrian",
+ }
+ ],
+ }
+ assert response.json()["ConstructorStandings"][0] == {
+ "position": "1",
+ "positionText": "1",
+ "points": "860",
+ "wins": "21",
+ "Constructor": {
+ "constructorId": "red_bull",
+ "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
+ "name": "Red Bull",
+ "nationality": "Austrian",
+ },
+ }
+
+
+def test_get_standings_good_year_and_round():
+ response = client.get("/standings?year=2023&round=5")
+ assert response.status_code == status.HTTP_200_OK
+ assert response.json()["season"] == 2023
+ assert response.json()["round"] == 5
+ assert response.json()["DriverStandings"][0] == {
+ "position": "1",
+ "positionText": "1",
+ "points": "119",
+ "wins": "3",
+ "Driver": {
+ "driverId": "max_verstappen",
+ "permanentNumber": "33",
+ "code": "VER",
+ "url": "http://en.wikipedia.org/wiki/Max_Verstappen",
+ "givenName": "Max",
+ "familyName": "Verstappen",
+ "dateOfBirth": "1997-09-30",
+ "nationality": "Dutch",
+ },
+ "Constructors": [
+ {
+ "constructorId": "red_bull",
+ "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
+ "name": "Red Bull",
+ "nationality": "Austrian",
+ }
+ ],
+ }
+ assert response.json()["ConstructorStandings"][0] == {
+ "position": "1",
+ "positionText": "1",
+ "points": "224",
+ "wins": "5",
+ "Constructor": {
+ "constructorId": "red_bull",
+ "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing",
+ "name": "Red Bull",
+ "nationality": "Austrian",
+ },
+ }
+
+
+# endregion standings - good inputs
+
+# region standings - no inputs
+
+
+def test_get_standings_good_round_bad_year_no_input():
+ response = client.get("/standings?round=3")
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+ assert response.json() == {"detail": 'Bad request. Must provide the "year" parameter.'}
+
+
+# endregion standings - no inputs
diff --git a/useful_commands.md b/useful_commands.md
index a9dccc3..03f3ae8 100644
--- a/useful_commands.md
+++ b/useful_commands.md
@@ -37,7 +37,8 @@ poetry show --outdated
### Run tests using pytest
```sh
-poetry run pytest -rpP
+ # pytest -rpP
+ poetry poe tests
```
## Git hooks
@@ -45,13 +46,15 @@ poetry run pytest -rpP
### Install git hooks
```sh
-pre-commit install --hook-type commit-msg --hook-type pre-push --hook-type pre-commit
+# pre-commit install --hook-type commit-msg --hook-type pre-push --hook-type pre-commit
+poetry poe git-hooks-setup
```
### Updating hooks automatically
```sh
-pre-commit autoupdate
+# pre-commit autoupdate
+poetry poe git-hooks-update
```
## Docker