From 88dda32f5cfba70d3e8a008d6cee247f8dacef69 Mon Sep 17 00:00:00 2001 From: Pratik Borole Date: Thu, 4 Jan 2024 10:18:52 +0530 Subject: [PATCH 1/6] updated docs related to docker --- .vscode/extensions.json | 1 - README.md | 41 ++++++++++++++++++++++++++++++++--------- useful_commands.md | 25 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e139cc1..a8d7ca9 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,7 +2,6 @@ "recommendations": [ "aaron-bond.better-comments", "ms-python.black-formatter", - "ms-vscode-remote.remote-containers", "ms-azuretools.vscode-docker", "tamasfe.even-better-toml", "kisstkondoros.vscode-gutter-preview", diff --git a/README.md b/README.md index d255650..1be6fcf 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,11 @@ Table of Contents: - [Setting up the project](#setting-up-the-project) - [What you'll need](#what-youll-need) - - [Installing dependencies](#installing-dependencies) - [Development](#development) - - [Running the project](#running-the-project) + - [Python virtual environment](#python-virtual-environment) + - [Installing dependencies](#installing-dependencies) + - [Running the project](#running-the-project) + - [Docker](#docker) - [Interactive API docs](#interactive-api-docs) - [Interactive Jupyter notebook](#interactive-jupyter-notebook) - [Using Jupyter Lab](#using-jupyter-lab) @@ -23,10 +25,15 @@ Table of Contents: ### What you'll need - [VSCode](https://code.visualstudio.com/) / [Intellij Pycharm](https://www.jetbrains.com/pycharm/) -- [Python 3.11](https://www.python.org/) (Please check `pyproject.toml` for the latest supported python version) +- [Python 3.12](https://www.python.org/) (Please check [`pyproject.toml`](./pyproject.toml) for the latest supported python version) - [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer) for dependency management +- [Docker Desktop](https://docs.docker.com/desktop/) [OPTIONAL] -### Installing dependencies +## Development + +### Python virtual environment + +#### Installing dependencies ```sh poetry install --no-root @@ -34,16 +41,32 @@ poetry install --no-root **Note**: Ensure that the python intepreter 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). -## Development - -### Running the project +#### Running the project - Open up a terminal in your IDE. - Your IDE should activate the virtual environment for you automatically. - - If it doesnt, you can execute the `/Scripts/Activate` script from the virtual environment. + - If it doesnt, you can follow either of these steps: + - Set poetry [python interpreter path in VS Code](https://code.visualstudio.com/docs/python/environments#_working-with-python-interpreters) ***OR*** + - Run `poetry shell` ***OR*** + - Execute the `/Scripts/Activate` script from the virtual environment located [here](https://python-poetry.org/docs/configuration/#cache-directory) + - Run `python run.py` to start the server. - Open your browser at `http://0.0.0.0/80`. +### Docker + +- Build image + ```sh + docker build --file Dockerfile.dev --tag backend-dev . + ``` + **Note**: The first build will take about 10 minutes. Please be patient. Subsequent builds should be quicker (given that the image has not been prunes). +- Run container + ```sh + docker run --detach --name backend-dev-container --publish 80:80 backend-dev + ``` +- Open your browser at http://0.0.0.0/80. +- For other docker commands, see [useful_commands.md](./useful_commands.md) + ### Interactive API docs - Once the server is running, open your browser at `http://0.0.0.0:80/docs`. @@ -58,7 +81,7 @@ poetry install --no-root #### Running the notebook in VS Code -- Alternatively, you can install `https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter` and run the notebook in VS Code. +- Alternatively, you can install the [Jupyer extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) and run the notebook in VS Code. - Ensure to use the poetry python environment as the kernel. ### Contribution Guidelines diff --git a/useful_commands.md b/useful_commands.md index b749f15..f4b5cb6 100644 --- a/useful_commands.md +++ b/useful_commands.md @@ -6,8 +6,11 @@ - [Jupyter Lab](#jupyter-lab) - [Opening jupyter lab](#opening-jupyter-lab) - [Docker](#docker) + - [List all docker processes](#list-all-docker-processes) - [Building the images](#building-the-images) - [Starting the containers](#starting-the-containers) + - [Stopping the containers](#stopping-the-containers) + - [Restarting the containers](#restarting-the-containers) ## Poetry @@ -33,6 +36,12 @@ jupyter lab ## Docker +### List all docker processes + +```sh +docker ps +``` + ### Building the images ```sh @@ -48,3 +57,19 @@ docker run --detach --name backend-dev-container --publish 80:80 backend-dev docker run --detach --name backend-staging-container --publish 80:80 backend-staging docker run --detach --name backend-prod-container --publish 80:80 backend-prod ``` + +### Stopping the containers + +```sh +docker stop backend-dev-container +docker stop backend-staging-container +docker stop backend-prod-container +``` + +### Restarting the containers + +```sh +docker restart backend-dev-container +docker restart backend-staging-container +docker restart backend-prod-container +``` \ No newline at end of file From 04ede8f39a197d9187df8409d3b286ab9fed81e8 Mon Sep 17 00:00:00 2001 From: Pratik Borole Date: Tue, 9 Jan 2024 16:34:44 +0530 Subject: [PATCH 2/6] made year optional for /schedule --- app/main.py | 16 ++++++++-------- app/utils.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 app/utils.py diff --git a/app/main.py b/app/main.py index 8bb7d2b..756d17f 100644 --- a/app/main.py +++ b/app/main.py @@ -2,12 +2,13 @@ from typing import Annotated import fastf1 -from fastapi import FastAPI, Path, status +from fastapi import FastAPI, Query, status from app.constants import EVENT_SCHEDULE_DATETIME_DTYPE_LIST, METADATA_DESCRIPTION from app.models import HealthCheck, Schedule +from app.utils import get_default_year_for_schedule -# fastf1.set_log_level("WARNING") # TODO use for production +# fastf1.set_log_level("WARNING") # TODO use for production and staging app = FastAPI( title="Slick Telemetry API", @@ -58,23 +59,22 @@ def get_health() -> HealthCheck: return HealthCheck(status="OK") -# TODO make {year} optional @app.get( - "/schedule/{year}", + "/schedule", tags=["schedule"], summary="Get events schedule for a Formula 1 calendar year", - response_description="Return list of events schedule", + response_description="Return list of events schedule for a Formula 1 calendar year", status_code=status.HTTP_200_OK, response_model=list[Schedule], ) def get_schedule( year: Annotated[ - int, - Path( + int | None, + Query( title="The year for which to get the schedule", gt=1949, # Supported years are 1950 to current ), - ] + ] = get_default_year_for_schedule() ) -> list[Schedule]: """ ## Get events schedule for a Formula 1 calendar year diff --git a/app/utils.py b/app/utils.py new file mode 100644 index 0000000..8c33bdd --- /dev/null +++ b/app/utils.py @@ -0,0 +1,30 @@ +import datetime + +import fastf1 + + +def get_default_year_for_schedule() -> int: + # TODO default year is defined as the year which has data for atleast 1 session + # get current year + # get first race event from that year + # get relevant race session from that event + # get race data + # if available default is current year, else last year + + current_year = datetime.datetime.now().current_year + default_year = current_year + event_schedule = fastf1.get_event_schedule(default_year, include_testing=False) + + if len(event_schedule) == 0: + return default_year - 1 + + try: + first_event_round_number = event_schedule.iloc[0]["RoundNumber"] + first_event_session = fastf1.get_session( + default_year, first_event_round_number, "Race" + ) + first_event_session.load() + except ValueError: + return default_year - 1 + + return default_year - 1 From 854bd7b81a6f9ca395391f8b8df408a0549426cc Mon Sep 17 00:00:00 2001 From: Pratik Borole Date: Tue, 9 Jan 2024 17:48:40 +0530 Subject: [PATCH 3/6] updated uvicorn parameters to support windows os --- Dockerfile.dev | 8 ++++---- README.md | 10 +++++----- run.py | 4 +++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index e275fc5..d94fcef 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -18,14 +18,14 @@ RUN pip install --no-cache-dir poetry RUN poetry config virtualenvs.create false \ && poetry install --no-interaction --no-ansi -# Make port 80 available to the world outside this container -EXPOSE 80 +# Make port 8080 available to the world outside this container +EXPOSE 8080 # Healthcheck HEALTHCHECK --interval=5m --timeout=3s \ CMD curl -f http://localhost/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", "80", "--reload"] +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080", "--reload"] -# CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80" "--reload"] \ No newline at end of file +# CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "8080" "--reload"] \ No newline at end of file diff --git a/README.md b/README.md index 1be6fcf..a86fc35 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ poetry install --no-root - Execute the `/Scripts/Activate` script from the virtual environment located [here](https://python-poetry.org/docs/configuration/#cache-directory) - Run `python run.py` to start the server. -- Open your browser at `http://0.0.0.0/80`. +- Open your browser at `http://127.0.0.1/8080`. ### Docker @@ -62,15 +62,15 @@ poetry install --no-root **Note**: The first build will take about 10 minutes. Please be patient. Subsequent builds should be quicker (given that the image has not been prunes). - Run container ```sh - docker run --detach --name backend-dev-container --publish 80:80 backend-dev + docker run --detach --name backend-dev-container --publish 8080:8080 backend-dev ``` -- Open your browser at http://0.0.0.0/80. +- Open your browser at http://127.0.0.1/8080. - For other docker commands, see [useful_commands.md](./useful_commands.md) ### Interactive API docs -- Once the server is running, open your browser at `http://0.0.0.0:80/docs`. -- Alternate docs can be found at `http://0.0.0.0:80/redoc`, provided by [redoc](https://github.com/Redocly/redoc). +- Once the server is running, open your browser at `http://127.0.0.1:8080/docs`. +- Alternate docs can be found at `http://127.0.0.1:8080/redoc`, provided by [redoc](https://github.com/Redocly/redoc). ### Interactive Jupyter notebook diff --git a/run.py b/run.py index 4f55c96..34ebf5f 100644 --- a/run.py +++ b/run.py @@ -2,7 +2,9 @@ def start_server(): - uvicorn.run("app.main:app", host="0.0.0.0", port=80, reload=True, log_level="info") + uvicorn.run( + "app.main:app", host="127.0.0.1", port=8080, reload=True, log_level="info" + ) if __name__ == "__main__": From 36a18873ea8b86a109c01b95933d726b7fb02d45 Mon Sep 17 00:00:00 2001 From: Pratik Borole Date: Tue, 9 Jan 2024 19:11:51 +0530 Subject: [PATCH 4/6] updated tests --- app/main.py | 7 ++++++- app/test_main.py | 43 ++++++++++++++++++++++++++++++++++++++++--- app/utils.py | 24 +++++++++--------------- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/app/main.py b/app/main.py index 756d17f..96203de 100644 --- a/app/main.py +++ b/app/main.py @@ -1,4 +1,5 @@ import json +from datetime import datetime from typing import Annotated import fastf1 @@ -73,8 +74,9 @@ def get_schedule( Query( title="The year for which to get the schedule", gt=1949, # Supported years are 1950 to current + le=datetime.today().year, ), - ] = get_default_year_for_schedule() + ] = None ) -> list[Schedule]: """ ## Get events schedule for a Formula 1 calendar year @@ -82,6 +84,9 @@ def get_schedule( Returns: list[Schedule]: Returns a JSON response with the list of event schedule """ + if year is None: + year = get_default_year_for_schedule() + event_schedule = fastf1.get_event_schedule(year) # Convert timestamp(z) related columns' data into a string type diff --git a/app/test_main.py b/app/test_main.py index 32ed830..d5fa1c2 100644 --- a/app/test_main.py +++ b/app/test_main.py @@ -1,3 +1,5 @@ +from datetime import datetime + from fastapi.testclient import TestClient from app.main import app @@ -18,7 +20,7 @@ def test_healthcheck(): def test_get_schedule(): - response = client.get("/schedule/2023") + response = client.get("/schedule") assert response.status_code == 200 assert response.json()[0] == { "RoundNumber": 0, @@ -47,14 +49,30 @@ def test_get_schedule(): } +def test_get_schedule_bad_year_no_input(): + response = client.get("/schedule/?year=") + assert response.status_code == 422 + assert response.json() == { + "detail": [ + { + "type": "int_parsing", + "loc": ["query", "year"], + "msg": "Input should be a valid integer, unable to parse string as an integer", + "input": "", + "url": "https://errors.pydantic.dev/2.5/v/int_parsing", + } + ] + } + + def test_get_schedule_bad_year_lower_limit(): - response = client.get("/schedule/1949") + response = client.get("/schedule/?year=1949") assert response.status_code == 422 assert response.json() == { "detail": [ { "type": "greater_than", - "loc": ["path", "year"], + "loc": ["query", "year"], "msg": "Input should be greater than 1949", "input": "1949", "ctx": {"gt": 1949}, @@ -62,3 +80,22 @@ def test_get_schedule_bad_year_lower_limit(): } ] } + + +def test_get_schedule_bad_year_upper_limit(): + current_year = datetime.today().year + bad_year = current_year + 1 + response = client.get(f"/schedule/?year={bad_year}") + assert response.status_code == 422 + assert response.json() == { + "detail": [ + { + "type": "less_than_equal", + "loc": ["query", "year"], + "msg": "Input should be less than or equal to 2024", + "input": "2025", + "ctx": {"le": 2024}, + "url": "https://errors.pydantic.dev/2.5/v/less_than_equal", + } + ] + } diff --git a/app/utils.py b/app/utils.py index 8c33bdd..282994d 100644 --- a/app/utils.py +++ b/app/utils.py @@ -1,30 +1,24 @@ -import datetime +from datetime import datetime import fastf1 def get_default_year_for_schedule() -> int: - # TODO default year is defined as the year which has data for atleast 1 session - # get current year - # get first race event from that year - # get relevant race session from that event - # get race data - # if available default is current year, else last year + # default year is defined as the year which has data for atleast 1 race session - current_year = datetime.datetime.now().current_year - default_year = current_year - event_schedule = fastf1.get_event_schedule(default_year, include_testing=False) + current_year = datetime.today().year + event_schedule = fastf1.get_event_schedule(current_year, include_testing=False) if len(event_schedule) == 0: - return default_year - 1 + return current_year - 1 try: first_event_round_number = event_schedule.iloc[0]["RoundNumber"] first_event_session = fastf1.get_session( - default_year, first_event_round_number, "Race" + current_year, first_event_round_number, "Race" ) first_event_session.load() - except ValueError: - return default_year - 1 + except (ValueError, KeyError): + return current_year - 1 - return default_year - 1 + return current_year - 1 From 11ea0d168711360b458167c4bc89aa39bcf12cd7 Mon Sep 17 00:00:00 2001 From: Pratik Borole Date: Tue, 9 Jan 2024 19:34:45 +0530 Subject: [PATCH 5/6] updated dependencies --- poetry.lock | 229 +++++++++++++++++++++++++------------------------ pyproject.toml | 2 +- 2 files changed, 116 insertions(+), 115 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5a325a4..5d2121a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -661,26 +661,26 @@ all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)" [[package]] name = "fastf1" -version = "3.1.6" -description = "Wrapper library for F1 data and telemetry API with additional data processing capabilities." +version = "3.2.0" +description = "Python package for accessing and analyzing Formula 1 results, schedules, timing data and telemetry." optional = false python-versions = ">=3.8" files = [ - {file = "fastf1-3.1.6-py3-none-any.whl", hash = "sha256:bc54a4f8c0bbb82a878d1ff9682595a0f026e36d2904e001fa299d9ffad6426f"}, - {file = "fastf1-3.1.6.tar.gz", hash = "sha256:1ffa50807f8da1165ddb920e0da0d31fa173f67d84f705167c9d1cdfe0dba9e1"}, + {file = "fastf1-3.2.0-py3-none-any.whl", hash = "sha256:c651709881b08604c8df7bc0c95d3c6e2e184967ddb05a6d7ae8adac1f2df559"}, + {file = "fastf1-3.2.0.tar.gz", hash = "sha256:45b8e6bc3faa48f476d0e6c96fcf97c097029ec4efcaddf9d583cabd8cd753ca"}, ] [package.dependencies] -matplotlib = ">=3.4.2,<4.0.0" -numpy = ">=1.20.3,<2.0.0" -pandas = ">=1.2.4,<2.1.0" +matplotlib = ">=3.5.1,<4.0.0" +numpy = ">=1.21.5,<2.0.0" +pandas = ">=1.3.5,<3.0.0" python-dateutil = "*" -requests = ">=2.28.0" -requests-cache = ">=0.8.0" -scipy = ">=1.6.3,<2.0.0" +requests = ">=2.28.1" +requests-cache = ">=1.0.0" +scipy = ">=1.7.3,<2.0.0" thefuzz = "*" timple = ">=0.1.6" -websockets = ">=8.1" +websockets = ">=10.3" [[package]] name = "fastjsonschema" @@ -933,13 +933,13 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.19.0" +version = "8.20.0" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.10" files = [ - {file = "ipython-8.19.0-py3-none-any.whl", hash = "sha256:2f55d59370f59d0d2b2212109fe0e6035cfea436b1c0e6150ad2244746272ec5"}, - {file = "ipython-8.19.0.tar.gz", hash = "sha256:ac4da4ecf0042fb4e0ce57c60430c2db3c719fa8bdf92f8631d6bd8a5785d1f0"}, + {file = "ipython-8.20.0-py3-none-any.whl", hash = "sha256:bc9716aad6f29f36c449e30821c9dd0c1c1a7b59ddcc26931685b87b4c569619"}, + {file = "ipython-8.20.0.tar.gz", hash = "sha256:2f21bd3fc1d51550c89ee3944ae04bbc7bc79e129ea0937da6e6c68bfdbf117a"}, ] [package.dependencies] @@ -1122,13 +1122,13 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt [[package]] name = "jupyter-core" -version = "5.6.1" +version = "5.7.1" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.6.1-py3-none-any.whl", hash = "sha256:3d16aec2e1ec84b69f7794e49c32830c1d950ad149526aec954c100047c5f3a7"}, - {file = "jupyter_core-5.6.1.tar.gz", hash = "sha256:5139be639404f7f80f3db6f687f47b8a8ec97286b4fa063c984024720e7224dc"}, + {file = "jupyter_core-5.7.1-py3-none-any.whl", hash = "sha256:c65c82126453a723a2804aa52409930434598fd9d35091d63dfb919d2b765bb7"}, + {file = "jupyter_core-5.7.1.tar.gz", hash = "sha256:de61a9d7fc71240f688b2fb5ab659fbb56979458dc66a71decd098e03c79e218"}, ] [package.dependencies] @@ -1181,13 +1181,13 @@ jupyter-server = ">=1.1.2" [[package]] name = "jupyter-server" -version = "2.12.1" +version = "2.12.2" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_server-2.12.1-py3-none-any.whl", hash = "sha256:fd030dd7be1ca572e4598203f718df6630c12bd28a599d7f1791c4d7938e1010"}, - {file = "jupyter_server-2.12.1.tar.gz", hash = "sha256:dc77b7dcc5fc0547acba2b2844f01798008667201eea27c6319ff9257d700a6d"}, + {file = "jupyter_server-2.12.2-py3-none-any.whl", hash = "sha256:abcfa33f98a959f908c8733aa2d9fa0101d26941cbd49b148f4cef4d3046fc61"}, + {file = "jupyter_server-2.12.2.tar.gz", hash = "sha256:5eae86be15224b5375cdec0c3542ce72ff20f7a25297a2a8166a250bb455a519"}, ] [package.dependencies] @@ -1695,47 +1695,47 @@ test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync" [[package]] name = "numpy" -version = "1.26.2" +version = "1.26.3" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.9" files = [ - {file = "numpy-1.26.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3703fc9258a4a122d17043e57b35e5ef1c5a5837c3db8be396c82e04c1cf9b0f"}, - {file = "numpy-1.26.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc392fdcbd21d4be6ae1bb4475a03ce3b025cd49a9be5345d76d7585aea69440"}, - {file = "numpy-1.26.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36340109af8da8805d8851ef1d74761b3b88e81a9bd80b290bbfed61bd2b4f75"}, - {file = "numpy-1.26.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcc008217145b3d77abd3e4d5ef586e3bdfba8fe17940769f8aa09b99e856c00"}, - {file = "numpy-1.26.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ced40d4e9e18242f70dd02d739e44698df3dcb010d31f495ff00a31ef6014fe"}, - {file = "numpy-1.26.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b272d4cecc32c9e19911891446b72e986157e6a1809b7b56518b4f3755267523"}, - {file = "numpy-1.26.2-cp310-cp310-win32.whl", hash = "sha256:22f8fc02fdbc829e7a8c578dd8d2e15a9074b630d4da29cda483337e300e3ee9"}, - {file = "numpy-1.26.2-cp310-cp310-win_amd64.whl", hash = "sha256:26c9d33f8e8b846d5a65dd068c14e04018d05533b348d9eaeef6c1bd787f9919"}, - {file = "numpy-1.26.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b96e7b9c624ef3ae2ae0e04fa9b460f6b9f17ad8b4bec6d7756510f1f6c0c841"}, - {file = "numpy-1.26.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa18428111fb9a591d7a9cc1b48150097ba6a7e8299fb56bdf574df650e7d1f1"}, - {file = "numpy-1.26.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06fa1ed84aa60ea6ef9f91ba57b5ed963c3729534e6e54055fc151fad0423f0a"}, - {file = "numpy-1.26.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96ca5482c3dbdd051bcd1fce8034603d6ebfc125a7bd59f55b40d8f5d246832b"}, - {file = "numpy-1.26.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:854ab91a2906ef29dc3925a064fcd365c7b4da743f84b123002f6139bcb3f8a7"}, - {file = "numpy-1.26.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f43740ab089277d403aa07567be138fc2a89d4d9892d113b76153e0e412409f8"}, - {file = "numpy-1.26.2-cp311-cp311-win32.whl", hash = "sha256:a2bbc29fcb1771cd7b7425f98b05307776a6baf43035d3b80c4b0f29e9545186"}, - {file = "numpy-1.26.2-cp311-cp311-win_amd64.whl", hash = "sha256:2b3fca8a5b00184828d12b073af4d0fc5fdd94b1632c2477526f6bd7842d700d"}, - {file = "numpy-1.26.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a4cd6ed4a339c21f1d1b0fdf13426cb3b284555c27ac2f156dfdaaa7e16bfab0"}, - {file = "numpy-1.26.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d5244aabd6ed7f312268b9247be47343a654ebea52a60f002dc70c769048e75"}, - {file = "numpy-1.26.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a3cdb4d9c70e6b8c0814239ead47da00934666f668426fc6e94cce869e13fd7"}, - {file = "numpy-1.26.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa317b2325f7aa0a9471663e6093c210cb2ae9c0ad824732b307d2c51983d5b6"}, - {file = "numpy-1.26.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:174a8880739c16c925799c018f3f55b8130c1f7c8e75ab0a6fa9d41cab092fd6"}, - {file = "numpy-1.26.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f79b231bf5c16b1f39c7f4875e1ded36abee1591e98742b05d8a0fb55d8a3eec"}, - {file = "numpy-1.26.2-cp312-cp312-win32.whl", hash = "sha256:4a06263321dfd3598cacb252f51e521a8cb4b6df471bb12a7ee5cbab20ea9167"}, - {file = "numpy-1.26.2-cp312-cp312-win_amd64.whl", hash = "sha256:b04f5dc6b3efdaab541f7857351aac359e6ae3c126e2edb376929bd3b7f92d7e"}, - {file = "numpy-1.26.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4eb8df4bf8d3d90d091e0146f6c28492b0be84da3e409ebef54349f71ed271ef"}, - {file = "numpy-1.26.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1a13860fdcd95de7cf58bd6f8bc5a5ef81c0b0625eb2c9a783948847abbef2c2"}, - {file = "numpy-1.26.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64308ebc366a8ed63fd0bf426b6a9468060962f1a4339ab1074c228fa6ade8e3"}, - {file = "numpy-1.26.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baf8aab04a2c0e859da118f0b38617e5ee65d75b83795055fb66c0d5e9e9b818"}, - {file = "numpy-1.26.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d73a3abcac238250091b11caef9ad12413dab01669511779bc9b29261dd50210"}, - {file = "numpy-1.26.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b361d369fc7e5e1714cf827b731ca32bff8d411212fccd29ad98ad622449cc36"}, - {file = "numpy-1.26.2-cp39-cp39-win32.whl", hash = "sha256:bd3f0091e845164a20bd5a326860c840fe2af79fa12e0469a12768a3ec578d80"}, - {file = "numpy-1.26.2-cp39-cp39-win_amd64.whl", hash = "sha256:2beef57fb031dcc0dc8fa4fe297a742027b954949cabb52a2a376c144e5e6060"}, - {file = "numpy-1.26.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1cc3d5029a30fb5f06704ad6b23b35e11309491c999838c31f124fee32107c79"}, - {file = "numpy-1.26.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94cc3c222bb9fb5a12e334d0479b97bb2df446fbe622b470928f5284ffca3f8d"}, - {file = "numpy-1.26.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe6b44fb8fcdf7eda4ef4461b97b3f63c466b27ab151bec2366db8b197387841"}, - {file = "numpy-1.26.2.tar.gz", hash = "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea"}, + {file = "numpy-1.26.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:806dd64230dbbfaca8a27faa64e2f414bf1c6622ab78cc4264f7f5f028fee3bf"}, + {file = "numpy-1.26.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f98011ba4ab17f46f80f7f8f1c291ee7d855fcef0a5a98db80767a468c85cd"}, + {file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d45b3ec2faed4baca41c76617fcdcfa4f684ff7a151ce6fc78ad3b6e85af0a6"}, + {file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd2b45bf079d9ad90377048e2747a0c82351989a2165821f0c96831b4a2a54b"}, + {file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:211ddd1e94817ed2d175b60b6374120244a4dd2287f4ece45d49228b4d529178"}, + {file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1240f767f69d7c4c8a29adde2310b871153df9b26b5cb2b54a561ac85146485"}, + {file = "numpy-1.26.3-cp310-cp310-win32.whl", hash = "sha256:21a9484e75ad018974a2fdaa216524d64ed4212e418e0a551a2d83403b0531d3"}, + {file = "numpy-1.26.3-cp310-cp310-win_amd64.whl", hash = "sha256:9e1591f6ae98bcfac2a4bbf9221c0b92ab49762228f38287f6eeb5f3f55905ce"}, + {file = "numpy-1.26.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b831295e5472954104ecb46cd98c08b98b49c69fdb7040483aff799a755a7374"}, + {file = "numpy-1.26.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e87562b91f68dd8b1c39149d0323b42e0082db7ddb8e934ab4c292094d575d6"}, + {file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c66d6fec467e8c0f975818c1796d25c53521124b7cfb760114be0abad53a0a2"}, + {file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f25e2811a9c932e43943a2615e65fc487a0b6b49218899e62e426e7f0a57eeda"}, + {file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af36e0aa45e25c9f57bf684b1175e59ea05d9a7d3e8e87b7ae1a1da246f2767e"}, + {file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:51c7f1b344f302067b02e0f5b5d2daa9ed4a721cf49f070280ac202738ea7f00"}, + {file = "numpy-1.26.3-cp311-cp311-win32.whl", hash = "sha256:7ca4f24341df071877849eb2034948459ce3a07915c2734f1abb4018d9c49d7b"}, + {file = "numpy-1.26.3-cp311-cp311-win_amd64.whl", hash = "sha256:39763aee6dfdd4878032361b30b2b12593fb445ddb66bbac802e2113eb8a6ac4"}, + {file = "numpy-1.26.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a7081fd19a6d573e1a05e600c82a1c421011db7935ed0d5c483e9dd96b99cf13"}, + {file = "numpy-1.26.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12c70ac274b32bc00c7f61b515126c9205323703abb99cd41836e8125ea0043e"}, + {file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f784e13e598e9594750b2ef6729bcd5a47f6cfe4a12cca13def35e06d8163e3"}, + {file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f24750ef94d56ce6e33e4019a8a4d68cfdb1ef661a52cdaee628a56d2437419"}, + {file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:77810ef29e0fb1d289d225cabb9ee6cf4d11978a00bb99f7f8ec2132a84e0166"}, + {file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8ed07a90f5450d99dad60d3799f9c03c6566709bd53b497eb9ccad9a55867f36"}, + {file = "numpy-1.26.3-cp312-cp312-win32.whl", hash = "sha256:f73497e8c38295aaa4741bdfa4fda1a5aedda5473074369eca10626835445511"}, + {file = "numpy-1.26.3-cp312-cp312-win_amd64.whl", hash = "sha256:da4b0c6c699a0ad73c810736303f7fbae483bcb012e38d7eb06a5e3b432c981b"}, + {file = "numpy-1.26.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1666f634cb3c80ccbd77ec97bc17337718f56d6658acf5d3b906ca03e90ce87f"}, + {file = "numpy-1.26.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18c3319a7d39b2c6a9e3bb75aab2304ab79a811ac0168a671a62e6346c29b03f"}, + {file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b7e807d6888da0db6e7e75838444d62495e2b588b99e90dd80c3459594e857b"}, + {file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4d362e17bcb0011738c2d83e0a65ea8ce627057b2fdda37678f4374a382a137"}, + {file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b8c275f0ae90069496068c714387b4a0eba5d531aace269559ff2b43655edd58"}, + {file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cc0743f0302b94f397a4a65a660d4cd24267439eb16493fb3caad2e4389bccbb"}, + {file = "numpy-1.26.3-cp39-cp39-win32.whl", hash = "sha256:9bc6d1a7f8cedd519c4b7b1156d98e051b726bf160715b769106661d567b3f03"}, + {file = "numpy-1.26.3-cp39-cp39-win_amd64.whl", hash = "sha256:867e3644e208c8922a3be26fc6bbf112a035f50f0a86497f98f228c50c607bb2"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3c67423b3703f8fbd90f5adaa37f85b5794d3366948efe9a5190a5f3a83fc34e"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46f47ee566d98849323f01b349d58f2557f02167ee301e5e28809a8c0e27a2d0"}, + {file = "numpy-1.26.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a8474703bffc65ca15853d5fd4d06b18138ae90c17c8d12169968e998e448bb5"}, + {file = "numpy-1.26.3.tar.gz", hash = "sha256:697df43e2b6310ecc9d95f05d5ef20eacc09c7c4ecc9da3f235d39e71b7da1e4"}, ] [[package]] @@ -1762,66 +1762,67 @@ files = [ [[package]] name = "pandas" -version = "2.0.3" +version = "2.1.4" description = "Powerful data structures for data analysis, time series, and statistics" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pandas-2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c7c9f27a4185304c7caf96dc7d91bc60bc162221152de697c98eb0b2648dd8"}, - {file = "pandas-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f167beed68918d62bffb6ec64f2e1d8a7d297a038f86d4aed056b9493fca407f"}, - {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce0c6f76a0f1ba361551f3e6dceaff06bde7514a374aa43e33b588ec10420183"}, - {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba619e410a21d8c387a1ea6e8a0e49bb42216474436245718d7f2e88a2f8d7c0"}, - {file = "pandas-2.0.3-cp310-cp310-win32.whl", hash = "sha256:3ef285093b4fe5058eefd756100a367f27029913760773c8bf1d2d8bebe5d210"}, - {file = "pandas-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:9ee1a69328d5c36c98d8e74db06f4ad518a1840e8ccb94a4ba86920986bb617e"}, - {file = "pandas-2.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b084b91d8d66ab19f5bb3256cbd5ea661848338301940e17f4492b2ce0801fe8"}, - {file = "pandas-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37673e3bdf1551b95bf5d4ce372b37770f9529743d2498032439371fc7b7eb26"}, - {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9cb1e14fdb546396b7e1b923ffaeeac24e4cedd14266c3497216dd4448e4f2d"}, - {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9cd88488cceb7635aebb84809d087468eb33551097d600c6dad13602029c2df"}, - {file = "pandas-2.0.3-cp311-cp311-win32.whl", hash = "sha256:694888a81198786f0e164ee3a581df7d505024fbb1f15202fc7db88a71d84ebd"}, - {file = "pandas-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6a21ab5c89dcbd57f78d0ae16630b090eec626360085a4148693def5452d8a6b"}, - {file = "pandas-2.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4da0d45e7f34c069fe4d522359df7d23badf83abc1d1cef398895822d11061"}, - {file = "pandas-2.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:32fca2ee1b0d93dd71d979726b12b61faa06aeb93cf77468776287f41ff8fdc5"}, - {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d3624b3ae734490e4d63c430256e716f488c4fcb7c8e9bde2d3aa46c29089"}, - {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eae3dc34fa1aa7772dd3fc60270d13ced7346fcbcfee017d3132ec625e23bb0"}, - {file = "pandas-2.0.3-cp38-cp38-win32.whl", hash = "sha256:f3421a7afb1a43f7e38e82e844e2bca9a6d793d66c1a7f9f0ff39a795bbc5e02"}, - {file = "pandas-2.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:69d7f3884c95da3a31ef82b7618af5710dba95bb885ffab339aad925c3e8ce78"}, - {file = "pandas-2.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5247fb1ba347c1261cbbf0fcfba4a3121fbb4029d95d9ef4dc45406620b25c8b"}, - {file = "pandas-2.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81af086f4543c9d8bb128328b5d32e9986e0c84d3ee673a2ac6fb57fd14f755e"}, - {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1994c789bf12a7c5098277fb43836ce090f1073858c10f9220998ac74f37c69b"}, - {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ec591c48e29226bcbb316e0c1e9423622bc7a4eaf1ef7c3c9fa1a3981f89641"}, - {file = "pandas-2.0.3-cp39-cp39-win32.whl", hash = "sha256:04dbdbaf2e4d46ca8da896e1805bc04eb85caa9a82e259e8eed00254d5e0c682"}, - {file = "pandas-2.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:1168574b036cd8b93abc746171c9b4f1b83467438a5e45909fed645cf8692dbc"}, - {file = "pandas-2.0.3.tar.gz", hash = "sha256:c02f372a88e0d17f36d3093a644c73cfc1788e876a7c4bcb4020a77512e2043c"}, + {file = "pandas-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bdec823dc6ec53f7a6339a0e34c68b144a7a1fd28d80c260534c39c62c5bf8c9"}, + {file = "pandas-2.1.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:294d96cfaf28d688f30c918a765ea2ae2e0e71d3536754f4b6de0ea4a496d034"}, + {file = "pandas-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b728fb8deba8905b319f96447a27033969f3ea1fea09d07d296c9030ab2ed1d"}, + {file = "pandas-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00028e6737c594feac3c2df15636d73ace46b8314d236100b57ed7e4b9ebe8d9"}, + {file = "pandas-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:426dc0f1b187523c4db06f96fb5c8d1a845e259c99bda74f7de97bd8a3bb3139"}, + {file = "pandas-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:f237e6ca6421265643608813ce9793610ad09b40154a3344a088159590469e46"}, + {file = "pandas-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b7d852d16c270e4331f6f59b3e9aa23f935f5c4b0ed2d0bc77637a8890a5d092"}, + {file = "pandas-2.1.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bd7d5f2f54f78164b3d7a40f33bf79a74cdee72c31affec86bfcabe7e0789821"}, + {file = "pandas-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0aa6e92e639da0d6e2017d9ccff563222f4eb31e4b2c3cf32a2a392fc3103c0d"}, + {file = "pandas-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d797591b6846b9db79e65dc2d0d48e61f7db8d10b2a9480b4e3faaddc421a171"}, + {file = "pandas-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2d3e7b00f703aea3945995ee63375c61b2e6aa5aa7871c5d622870e5e137623"}, + {file = "pandas-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:dc9bf7ade01143cddc0074aa6995edd05323974e6e40d9dbde081021ded8510e"}, + {file = "pandas-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:482d5076e1791777e1571f2e2d789e940dedd927325cc3cb6d0800c6304082f6"}, + {file = "pandas-2.1.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8a706cfe7955c4ca59af8c7a0517370eafbd98593155b48f10f9811da440248b"}, + {file = "pandas-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0513a132a15977b4a5b89aabd304647919bc2169eac4c8536afb29c07c23540"}, + {file = "pandas-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9f17f2b6fc076b2a0078862547595d66244db0f41bf79fc5f64a5c4d635bead"}, + {file = "pandas-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:45d63d2a9b1b37fa6c84a68ba2422dc9ed018bdaa668c7f47566a01188ceeec1"}, + {file = "pandas-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:f69b0c9bb174a2342818d3e2778584e18c740d56857fc5cdb944ec8bbe4082cf"}, + {file = "pandas-2.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3f06bda01a143020bad20f7a85dd5f4a1600112145f126bc9e3e42077c24ef34"}, + {file = "pandas-2.1.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab5796839eb1fd62a39eec2916d3e979ec3130509930fea17fe6f81e18108f6a"}, + {file = "pandas-2.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edbaf9e8d3a63a9276d707b4d25930a262341bca9874fcb22eff5e3da5394732"}, + {file = "pandas-2.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ebfd771110b50055712b3b711b51bee5d50135429364d0498e1213a7adc2be8"}, + {file = "pandas-2.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8ea107e0be2aba1da619cc6ba3f999b2bfc9669a83554b1904ce3dd9507f0860"}, + {file = "pandas-2.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:d65148b14788b3758daf57bf42725caa536575da2b64df9964c563b015230984"}, + {file = "pandas-2.1.4.tar.gz", hash = "sha256:fcb68203c833cc735321512e13861358079a96c174a61f5116a1de89c58c0ef7"}, ] [package.dependencies] -numpy = {version = ">=1.23.2", markers = "python_version >= \"3.11\""} +numpy = {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""} python-dateutil = ">=2.8.2" pytz = ">=2020.1" tzdata = ">=2022.1" [package.extras] -all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"] -aws = ["s3fs (>=2021.08.0)"] -clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"] -compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"] -computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"] +all = ["PyQt5 (>=5.15.6)", "SQLAlchemy (>=1.4.36)", "beautifulsoup4 (>=4.11.1)", "bottleneck (>=1.3.4)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=0.8.1)", "fsspec (>=2022.05.0)", "gcsfs (>=2022.05.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.8.0)", "matplotlib (>=3.6.1)", "numba (>=0.55.2)", "numexpr (>=2.8.0)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pandas-gbq (>=0.17.5)", "psycopg2 (>=2.9.3)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.5)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "pyxlsb (>=1.0.9)", "qtpy (>=2.2.0)", "s3fs (>=2022.05.0)", "scipy (>=1.8.1)", "tables (>=3.7.0)", "tabulate (>=0.8.10)", "xarray (>=2022.03.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)", "zstandard (>=0.17.0)"] +aws = ["s3fs (>=2022.05.0)"] +clipboard = ["PyQt5 (>=5.15.6)", "qtpy (>=2.2.0)"] +compression = ["zstandard (>=0.17.0)"] +computation = ["scipy (>=1.8.1)", "xarray (>=2022.03.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pyxlsb (>=1.0.9)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)"] feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2021.07.0)"] -gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"] -hdf5 = ["tables (>=3.6.1)"] -html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"] -mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"] +fss = ["fsspec (>=2022.05.0)"] +gcp = ["gcsfs (>=2022.05.0)", "pandas-gbq (>=0.17.5)"] +hdf5 = ["tables (>=3.7.0)"] +html = ["beautifulsoup4 (>=4.11.1)", "html5lib (>=1.1)", "lxml (>=4.8.0)"] +mysql = ["SQLAlchemy (>=1.4.36)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.8.10)"] parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"] +performance = ["bottleneck (>=1.3.4)", "numba (>=0.55.2)", "numexpr (>=2.8.0)"] plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"] -spss = ["pyreadstat (>=1.1.2)"] -sql-other = ["SQLAlchemy (>=1.4.16)"] -test = ["hypothesis (>=6.34.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.6.3)"] +postgresql = ["SQLAlchemy (>=1.4.36)", "psycopg2 (>=2.9.3)"] +spss = ["pyreadstat (>=1.1.5)"] +sql-other = ["SQLAlchemy (>=1.4.36)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.8.0)"] [[package]] name = "pandocfilters" @@ -2622,13 +2623,13 @@ full = ["numpy"] [[package]] name = "referencing" -version = "0.32.0" +version = "0.32.1" description = "JSON Referencing + Python" optional = false python-versions = ">=3.8" files = [ - {file = "referencing-0.32.0-py3-none-any.whl", hash = "sha256:bdcd3efb936f82ff86f993093f6da7435c7de69a3b3a5a06678a6050184bee99"}, - {file = "referencing-0.32.0.tar.gz", hash = "sha256:689e64fe121843dcfd57b71933318ef1f91188ffb45367332700a86ac8fd6161"}, + {file = "referencing-0.32.1-py3-none-any.whl", hash = "sha256:7e4dc12271d8e15612bfe35792f5ea1c40970dadf8624602e33db2758f7ee554"}, + {file = "referencing-0.32.1.tar.gz", hash = "sha256:3c57da0513e9563eb7e203ebe9bb3a1b509b042016433bd1e45a2853466c3dd3"}, ] [package.dependencies] @@ -3051,13 +3052,13 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "types-python-dateutil" -version = "2.8.19.14" +version = "2.8.19.20240106" description = "Typing stubs for python-dateutil" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.14.tar.gz", hash = "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b"}, - {file = "types_python_dateutil-2.8.19.14-py3-none-any.whl", hash = "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9"}, + {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, + {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, ] [[package]] @@ -3284,13 +3285,13 @@ anyio = ">=3.0.0" [[package]] name = "wcwidth" -version = "0.2.12" +version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.12-py2.py3-none-any.whl", hash = "sha256:f26ec43d96c8cbfed76a5075dac87680124fa84e0855195a6184da9c187f133c"}, - {file = "wcwidth-0.2.12.tar.gz", hash = "sha256:f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02"}, + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, ] [[package]] @@ -3419,4 +3420,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "b837cc5a63c25fda22017cb3feefea42f064727e2d8a8781284e99ca718c44d7" +content-hash = "9d42ac368a17a1fa0a1530bbe84edbe06b71e5cb7d7de22fc5921a3d44296c8a" diff --git a/pyproject.toml b/pyproject.toml index 9de6796..1e035f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,6 @@ readme = "README.md" python = "^3.12" fastapi = "^0.108.0" fastf1 = "^3.1.6" -httpx = "^0.26.0" uvicorn = { extras = ["standard"], version = "^0.25.0" } [tool.poetry.group.dev.dependencies] @@ -18,6 +17,7 @@ isort = "^5.13.2" jupyterlab = "^4.0.9" jupyterlab-code-formatter = "^2.2.1" pytest = "^7.4.3" +httpx = "^0.26.0" [build-system] requires = ["poetry-core"] From eb46c72123f673b5efad21ea4c3b98a7c7f6ac02 Mon Sep 17 00:00:00 2001 From: Pratik Borole Date: Tue, 9 Jan 2024 19:40:33 +0530 Subject: [PATCH 6/6] added --no-root to poetry install in dockerfile.dev --- Dockerfile.dev | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.dev b/Dockerfile.dev index d94fcef..f6f827a 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -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 + && poetry install --no-interaction --no-ansi --no-root # Make port 8080 available to the world outside this container EXPOSE 8080