├── .gimlet
└── electric-paper-taxi-data-api-python.yaml
├── .github
└── workflows
│ └── ci_cd.yml
├── .gitignore
├── Dockerfile.1stage
├── Dockerfile.2stage
├── Dockerfile.naive
├── Makefile
├── README.md
├── docker-compose.yml
├── media
├── kibana.gif
├── kubernetes_cluster.gif
└── yt_cover.png
├── poetry.lock
├── pyproject.toml
├── src
├── __init__.py
├── api.py
├── backend.py
├── config.py
├── middleware.py
└── utils.py
├── taxi-data-api-rust
├── Cargo.lock
├── Cargo.toml
├── Dockerfile
├── Makefile
├── README.md
└── src
│ ├── backend.rs
│ └── main.rs
└── tests
├── __init__.py
└── test_read_parquet.py
/.gimlet/electric-paper-taxi-data-api-python.yaml:
--------------------------------------------------------------------------------
1 | app: taxi-data-api-python
2 | env: electric-paper
3 | namespace: default
4 | chart:
5 | repository: https://chart.onechart.dev
6 | name: onechart
7 | version: 0.70.0
8 | values:
9 | containerPort: 8000
10 | gitRepository: Paulescu/taxi-data-api-python
11 | gitSha: '{{ .SHA }}'
12 | image:
13 | context: .
14 | dockerfile: ""
15 | registry: public
16 | repository: ghcr.io/paulescu/taxi-data-api-python
17 | strategy: dynamic
18 | tag: '{{ .SHA }}'
19 | ingress:
20 | annotations:
21 | cert-manager.io/cluster-issuer: letsencrypt
22 | kubernetes.io/ingress.class: nginx
23 | host: paulescu-taxi-data-api-python-ayolbhnl.gimlet.app
24 | tlsEnabled: true
25 | resources:
26 | ignoreLimits: true
27 |
--------------------------------------------------------------------------------
/.github/workflows/ci_cd.yml:
--------------------------------------------------------------------------------
1 | name: CI/CD
2 | on:
3 | push:
4 | branches:
5 | - '*'
6 | paths-ignore:
7 | - 'README.md'
8 | jobs:
9 | cancel-previous-runs:
10 | name: 🧹 Cancel previous runs
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: 🛑 Cancel Previous Runs
14 | uses: styfle/cancel-workflow-action@0.10.1
15 | with:
16 | access_token: ${{ secrets.GITHUB_TOKEN }}
17 | - name: ⬇️ Check out
18 | uses: actions/checkout@v3
19 | - run: echo "Building"
20 |
21 | tests:
22 | name: 🧪 Run tests
23 | runs-on: ubuntu-latest
24 | needs:
25 | - "cancel-previous-runs"
26 | steps:
27 | - name: ⬇️ Check out
28 | uses: actions/checkout@v4
29 | - name: 🐍 Set up Python 3.10
30 | uses: actions/setup-python@v4
31 | with:
32 | python-version: '3.10'
33 | - name: 📦 Install Poetry
34 | uses: snok/install-poetry@v1
35 | - name: 📦 Install dependencies
36 | run: poetry install
37 | - name: 🧪 Run tests
38 | run: poetry run pytest tests/
39 |
40 | docker-build:
41 | name: 📦 Docker build
42 | runs-on: ubuntu-latest
43 | needs:
44 | - "tests"
45 | steps:
46 | - name: ⬇️ Check out
47 | uses: actions/checkout@v4
48 | - name: 🐋 Set up Docker Buildx
49 | uses: docker/setup-buildx-action@v3
50 | - name: Login to GitHub Container Registry
51 | uses: docker/login-action@v3
52 | with:
53 | registry: ghcr.io
54 | username: ${{ github.repository_owner }}
55 | password: ${{ secrets.PAT }} # `PAT` is a secret that contains your Personal Access Token with `write:packages` scope
56 | - name: 🐋 Build and push docker image
57 | uses: docker/build-push-action@v6
58 | with:
59 | context: .
60 | file: Dockerfile.2stage
61 | platforms: linux/amd64
62 | push: true
63 | tags: ghcr.io/paulescu/taxi-data-api-python:${{ github.sha }}
64 |
65 | deploy:
66 | name: 🧑🚀 Deploy
67 | runs-on: ubuntu-latest
68 | needs:
69 | - "docker-build"
70 | if: github.ref == 'refs/heads/main'
71 | environment: production
72 | steps:
73 | - name: ⬇️ Check out
74 | uses: actions/checkout@v4
75 | - name: 🚀 Deploy / Production
76 | uses: gimlet-io/gimlet-artifact-shipper-action@v0.9.0
77 | with:
78 | DEPLOY: "true"
79 | ENV: "electric-paper"
80 | APP: "taxi-data-api-python"
81 | env:
82 | GIMLET_SERVER: ${{ secrets.GIMLET_SERVER }}
83 | GIMLET_TOKEN: ${{ secrets.GIMLET_TOKEN }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 | .ruff_cache/
6 |
7 | # C extensions
8 | *.so
9 |
10 | # Distribution / packaging
11 | .Python
12 | #build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 | cover/
54 |
55 | # Translations
56 | *.mo
57 | *.pot
58 |
59 | # Django stuff:
60 | *.log
61 | local_settings.py
62 | db.sqlite3
63 | db.sqlite3-journal
64 |
65 | # Flask stuff:
66 | instance/
67 | .webassets-cache
68 |
69 | # Scrapy stuff:import comet_ml
70 | .scrapy
71 |
72 | # Sphinx documentation
73 | docs/_build/
74 |
75 | # PyBuilder
76 | .pybuilder/
77 | target/
78 |
79 | # Jupyter Notebook
80 | .ipynb_checkpoints
81 |
82 | # IPython
83 | profile_default/
84 | ipython_config.py
85 |
86 | # pyenv
87 | # For a library or package, you might want to ignore these files since the code is
88 | # intended to run in multiple environments; otherwise, check them in:
89 | # .python-version
90 |
91 | # pipenv
92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
95 | # install all needed dependencies.
96 | #Pipfile.lock
97 |
98 | # poetry
99 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
100 | # This is especially recommended for binary packages to ensure reproducibility, and is more
101 | # commonly ignored for libraries.
102 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
103 | #poetry.lock
104 |
105 | # pdm
106 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
107 | #pdm.lock
108 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
109 | # in version control.
110 | # https://pdm.fming.dev/#use-with-ide
111 | .pdm.toml
112 |
113 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
114 | __pypackages__/
115 |
116 | # Celery stuff
117 | celerybeat-schedule
118 | celerybeat.pid
119 |
120 | # SageMath parsed files
121 | *.sage.py
122 |
123 | # Environments
124 | .env
125 | .venv
126 | env/
127 | venv/
128 | ENV/
129 | env.bak/
130 | venv.bak/
131 |
132 | # Spyder project settings
133 | .spyderproject
134 | .spyproject
135 |
136 | # Rope project settings
137 | .ropeproject
138 |
139 | # mkdocs documentation
140 | /site
141 |
142 | # mypy
143 | .mypy_cache/
144 | .dmypy.json
145 | dmypy.json
146 |
147 | # Pyre type checker
148 | .pyre/
149 |
150 | # pytype static type analyzer
151 | .pytype/
152 |
153 | # Cython debug symbols
154 | cython_debug/
155 |
156 | # PyCharm
157 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
158 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
159 | # and can be added to the global gitignore or merged into this file. For a more nuclear
160 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
161 | #.idea/
162 |
163 | # VSCode
164 | .vscode/*
165 | !.vscode/settings.json
166 | !.vscode/tasks.json
167 | !.vscode/launch.json
168 | !.vscode/extensions.json
169 | !.vscode/*.code-snippets
170 |
171 | # Local History for Visual Studio Code
172 | .history/
173 |
174 | # Built Visual Studio Code Extensions
175 | *.vsix
176 |
177 | # Artifacts
178 | results/
179 | output*/
180 | model_cache/
181 | output*
182 | user_data.sh
183 |
184 | set_env_variables.sh
185 | logs/
186 | .DS_Store
187 | gradio_cached_examples
188 | trust_policy.json
189 |
190 | .TODOS
191 | ca.cert
192 | *.pkl
193 | **/state
194 | **/setup_credentials.sh
195 | *.csv
196 | **/credentials.env
197 | .venv/
198 | certificates/
199 | **.parquet
--------------------------------------------------------------------------------
/Dockerfile.1stage:
--------------------------------------------------------------------------------
1 | # Use the official Python image from the Docker Hub
2 | FROM python:3.10-slim
3 |
4 | # Set environment variables
5 | ENV PYTHONDONTWRITEBYTECODE=1
6 | ENV PYTHONUNBUFFERED=1
7 |
8 | # Set the working directory
9 | WORKDIR /app
10 |
11 | # Install Poetry
12 | RUN pip install poetry
13 |
14 | # Copy only the pyproject.toml and poetry.lock files to leverage Docker cache
15 | COPY pyproject.toml poetry.lock README.md /app/
16 |
17 | # Install dependencies
18 | RUN poetry install --no-root
19 |
20 | # Copy the rest of the application code
21 | COPY . /app
22 |
23 | # Expose the port the app runs on
24 | EXPOSE 8000
25 |
26 | # Run the application
27 | CMD ["poetry", "run", "uvicorn", "src.api:app", "--host", "0.0.0.0", "--port", "8000"]
28 |
--------------------------------------------------------------------------------
/Dockerfile.2stage:
--------------------------------------------------------------------------------
1 | # Stage 1: Build stage
2 | FROM python:3.10-slim AS builder
3 |
4 | # Set environment variables
5 | ENV PYTHONDONTWRITEBYTECODE=1
6 | ENV PYTHONUNBUFFERED=1
7 |
8 | # Set the working directory
9 | WORKDIR /app
10 |
11 | # Install Poetry
12 | RUN pip install poetry
13 |
14 | # Copy only the pyproject.toml and poetry.lock files to leverage Docker cache
15 | COPY pyproject.toml poetry.lock README.md /app/
16 |
17 | # Install dependencies
18 | RUN poetry config virtualenvs.create false \
19 | && poetry install --no-dev --no-root
20 |
21 | # Copy the rest of the application code
22 | COPY . /app
23 |
24 | # Stage 2: Runtime stage
25 | FROM python:3.10-slim
26 |
27 | # Set environment variables
28 | ENV PYTHONDONTWRITEBYTECODE=1
29 | ENV PYTHONUNBUFFERED=1
30 |
31 | # Set the working directory
32 | WORKDIR /app
33 |
34 | # Copy only the necessary files from the builder stage
35 | COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
36 | COPY --from=builder /usr/local/bin /usr/local/bin
37 | COPY --from=builder /app /app
38 |
39 | # Expose the port the app runs on
40 | EXPOSE 8000
41 |
42 | # Run the application
43 | CMD ["uvicorn", "src.api:app", "--host", "0.0.0.0", "--port", "8000"]
--------------------------------------------------------------------------------
/Dockerfile.naive:
--------------------------------------------------------------------------------
1 | # Use the official Python image from the Docker Hub
2 | FROM python:3.10-slim
3 |
4 | # Set environment variables
5 | ENV PYTHONDONTWRITEBYTECODE=1
6 | ENV PYTHONUNBUFFERED=1
7 |
8 | # Set the working directory
9 | WORKDIR /app
10 |
11 | # Install Poetry
12 | RUN pip install poetry
13 |
14 | # Copy application code into the image
15 | COPY . /app
16 |
17 | # Install dependencies
18 | RUN poetry install --no-root
19 |
20 | # Expose the port the app runs on
21 | EXPOSE 8000
22 |
23 | # Run the application
24 | CMD ["poetry", "run", "uvicorn", "src.api:app", "--host", "0.0.0.0", "--port", "8000"]
25 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # feel free to change the PORT value if you have another service running on port 8092
2 | export PORT=8095
3 |
4 | install:
5 | @echo "Downloading and installing Python Poetry"
6 | curl -sSL https://install.python-poetry.org | python3 -
7 | poetry env use $(shell which python3.10)
8 | poetry install
9 |
10 | run-dev:
11 | poetry run uvicorn src.api:app --reload --port $(PORT)
12 |
13 | build-naive:
14 | @echo "Building naive image"
15 | @time docker build -f Dockerfile.naive -t taxi-data-api-python:naive-build .
16 |
17 | @echo "Naive image size"
18 | @docker images --format "{{.Size}}" taxi-data-api-python:naive-build
19 |
20 | build-single-stage:
21 | @echo "Building single-stage image"
22 | @time docker build -f Dockerfile.1stage -t taxi-data-api-python:single-stage-build .
23 |
24 | @echo "Single-stage image size"
25 | @docker images --format "{{.Size}}" taxi-data-api-python:single-stage-build
26 |
27 | build-multi-stage:
28 | @echo "Building multi-stage image"
29 | @time docker build -f Dockerfile.2stage -t taxi-data-api-python:multi-stage-build .
30 |
31 | @echo "Multi-stage image size"
32 | @docker images --format "{{.Size}}" taxi-data-api-python:multi-stage-build
33 |
34 | build: build-multi-stage
35 |
36 | run: build
37 | docker run \
38 | -e ELASTICSEARCH_HOST=http://elasticsearch:9200 \
39 | -e ELASTICSEARCH_INDEX=taxi_data_api \
40 | --network elasticsearch \
41 | -p $(PORT):8000 \
42 | taxi-data-api-python:multi-stage-build
43 |
44 | test:
45 | poetry run pytest tests/
46 |
47 | lint:
48 | poetry run ruff check --fix .
49 |
50 | format:
51 | poetry run ruff format .
52 |
53 | all: lint format test build run
54 |
55 | # Commands to check the API works as expected when running locally
56 | health-check-local:
57 | curl -X GET "http://localhost:$(PORT)/health"
58 |
59 | sample-request-local:
60 | curl -X GET "http://localhost:$(PORT)/trips?from_ms=1674561748000&n_results=100"
61 |
62 | sample-request-no-results-local:
63 | curl -X GET "http://localhost:$(PORT)/trips?from_ms=1727430298000&n_results=100"
64 |
65 | many-requests-local:
66 | @N=$${N:-10}; \
67 | for i in $$(seq 1 $$N); do \
68 | echo "Request $$i:"; \
69 | $(MAKE) sample-request-local; \
70 | echo; \
71 | done
72 |
73 | # Commands to check the API from the production environment works as expected
74 | health-check-production:
75 | curl -X GET "https://paulescu-taxi-data-api-python-ayolbhnl.gimlet.app/health"
76 |
77 | sample-request-production:
78 | curl -X GET "https://paulescu-taxi-data-api-python-ayolbhnl.gimlet.app/trips?from_ms=1674561748000&n_results=100"
79 |
80 | sample-request-no-results-production:
81 | curl -X GET "https://paulescu-taxi-data-api-python-ayolbhnl.gimlet.app/trips?from_ms=1727430298000&n_results=100"
82 |
83 | # Command to check the size of the local Docker images
84 | check-image-sizes: build-naive build-single-stage build-multi-stage
85 | @echo "Naive image size"
86 | @docker images --format "{{.Size}}" taxi-data-api-python:naive-build
87 |
88 | @echo "Single-stage image size"
89 | @docker images --format "{{.Size}}" taxi-data-api-python:single-stage-build
90 |
91 | @echo "Multi-stage image size"
92 | @docker images --format "{{.Size}}" taxi-data-api-python:multi-stage-build
93 |
94 | # Commands to start and stop the Elasticsearch and Kibana containers
95 | start-infra:
96 | docker compose up -d
97 |
98 | stop-infra:
99 | docker compose down
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Real-World ML
3 |
Build and deploy a professional REST API to Kubernetes with Gimlet 🚀
4 |
5 |
6 |
7 |
13 |
14 |
15 | #### Table of contents
16 | * [Our goal 🎯](#our-goal)
17 | * [How to run the API locally? 🏃](#how-to-run-the-api-locally)
18 | * [How to deploy the API to Kubernetes with Gimlet? 🚀](#how-to-deploy-the-api-to-kubernetes-with-gimlet)
19 | * [How to monitor our API with Elasticsearch and Kibana? 🔎](#how-to-monitor-our-api-with-elasticsearch-and-kibana)
20 | * [See it in action 🎬](#see-it-in-action)
21 | * [Wanna learn more real-world ML? 🧠](#wanna-learn-more-real-world-ml)
22 |
23 | ## Our goal
24 |
25 | Let’s **build** and **deploy** a production-ready REST API that can serve data on historical taxi rides in NYC.
26 |
27 | The original data is stored in one-month parquet files [on this website](https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page), and our goal is to make it easily accessible to the WORLD through a REST API.
28 |
29 |
30 | ## How to run the API locally?
31 |
32 | Git clone this repository, cd into the root directory of the project and then run the following commands using make.
33 |
34 | 1. Install [Python Poetry](https://python-poetry.org/docs/#installation) (if necessary)
35 | and create an isolated virtual environmnet for development purposes.
36 | ```
37 | $ make install
38 | ```
39 |
40 | 2. Test, build and run the dockerized REST API with
41 | ```
42 | $ make all
43 | ```
44 |
45 | 3. Check the API is up and running locally, and that you can connect to it
46 | ```
47 | $ make health-check-local
48 | ```
49 |
50 | 4. Send a sample request to the local API
51 | ```
52 | $ make sample-request-local
53 | ```
54 |
55 | Good job. The API is up and running locally. However, until you don’t deploy it to a production environment, and make it accessible to
56 |
57 | * your clients 💁🏻♀️
58 | * your colleagues 👨🏻💼
59 | * or the whole world 🌏
60 |
61 | your real-world impact is **ZERO**.
62 |
63 | Let me show you how to deploy this API to a production Kubernetes cluster.
64 |
65 |
66 | > **What is Kubernetes? ☸📦**
67 | >
68 | > Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and management of your Dockerized apps
69 | >
70 | > It is currently the most widely used container orchestration platform in the world, and it has become the de facto standard due to its robust features, large community support, and backing from major tech companies.
71 |
72 | ## How to deploy the API to Kubernetes with Gimlet?
73 |
74 | [Gimlet](https://gimlet.io/) is a tool that helps you quickly deploy your apps to ANY Kubernetes cluster.
75 |
76 | - You can do it entirely from the Gimlet UI, as explained in this article.
77 |
78 | or
79 |
80 | - You can adjust the [gimlet manifest in this repository](https://github.com/Paulescu/taxi-data-api-python/blob/main/.gimlet/electric-paper-taxi-data-api-python.yaml), to automatically deploy your code changes to the main branch.
81 |
82 | ## How to monitor our API with Elasticsearch and Kibana?
83 |
84 | These are the steps:
85 |
86 | 1. Spin up Elasticsearch and Kibana with the docker compose
87 | 2. Add middleware to FastAPI app
88 | 3. Build a dashboard with Kibana
89 |
90 |
91 |
92 | ## See it in action
93 |
94 | [👉🏽 Click here to try the API](https://paulescu-taxi-data-api-python-ayolbhnl.gimlet.app/trips?from_ms=1674561817000&n_results=100)
95 |
96 |
97 | ## Wanna learn more real-world ML?
98 |
99 | Join more than 19k builders to the [**Real-World ML Newsletter**](https://www.realworldml.net/subscribe). Every Saturday morning.
100 |
101 | ### [👉🏽 Click here to subscribe for FREE](https://www.realworldml.net/subscribe)
102 |
103 | ### [**👉🏽 My live courses on Real World ML**](https://www.realworldml.net/courses)
104 |
105 |
106 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | name: elastic_search_and_kibana
2 |
3 | services:
4 | elasticsearch:
5 | image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
6 | container_name: elasticsearch
7 | environment:
8 | - discovery.type=single-node
9 | - ES_JAVA_OPTS=-Xms512m -Xmx512m
10 | ports:
11 | - "9200:9200"
12 | - "9300:9300"
13 | volumes:
14 | - elasticsearch_data:/usr/share/elasticsearch/data
15 | networks:
16 | - elasticsearch
17 |
18 | kibana:
19 | image: docker.elastic.co/kibana/kibana:7.14.0
20 | container_name: kibana
21 | ports:
22 | - "5601:5601"
23 | environment:
24 | - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
25 | depends_on:
26 | - elasticsearch
27 | volumes:
28 | - kibana_data:/usr/share/kibana/data
29 | networks:
30 | - elasticsearch
31 |
32 | networks:
33 | elasticsearch:
34 | driver: bridge
35 | name: elasticsearch
36 |
37 | volumes:
38 | elasticsearch_data:
39 | kibana_data:
40 |
--------------------------------------------------------------------------------
/media/kibana.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paulescu/taxi-data-api-python/1ec743d2626c26a785ea624a8d231f6c84f245ae/media/kibana.gif
--------------------------------------------------------------------------------
/media/kubernetes_cluster.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paulescu/taxi-data-api-python/1ec743d2626c26a785ea624a8d231f6c84f245ae/media/kubernetes_cluster.gif
--------------------------------------------------------------------------------
/media/yt_cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paulescu/taxi-data-api-python/1ec743d2626c26a785ea624a8d231f6c84f245ae/media/yt_cover.png
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "src"
3 | version = "0.1.0"
4 | description = ""
5 | authors = ["Paulescu "]
6 | readme = "README.md"
7 |
8 | [tool.poetry.dependencies]
9 | python = "^3.10"
10 | fastapi = {extras = ["all"], version = "^0.115.2"}
11 | uvicorn = "^0.30.6"
12 | loguru = "^0.7.2"
13 | pandas = "^2.2.3"
14 | requests = "^2.32.3"
15 | fastparquet = "^2024.5.0"
16 | fire = "^0.6.0"
17 | pyarrow = "^17.0.0"
18 | elasticsearch = "^8.15.1"
19 |
20 |
21 | [tool.poetry.group.dev.dependencies]
22 | ruff = "^0.6.8"
23 | pytest = "^8.3.3"
24 |
25 | [build-system]
26 | requires = ["poetry-core"]
27 | build-backend = "poetry.core.masonry.api"
28 |
29 | [tool.ruff]
30 | line-length = 88
31 |
32 | [tool.ruff.format]
33 | quote-style = "single"
34 | indent-style = "space"
35 | docstring-code-format = true
36 |
37 | [tool.ruff.lint]
38 | extend-select = ["I"]
--------------------------------------------------------------------------------
/src/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paulescu/taxi-data-api-python/1ec743d2626c26a785ea624a8d231f6c84f245ae/src/__init__.py
--------------------------------------------------------------------------------
/src/api.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | from fastapi import FastAPI, Query
4 | from loguru import logger
5 | from pydantic import BaseModel
6 |
7 | from src.backend import Trip, get_trips
8 | from src.middleware import TimingMiddleware
9 |
10 | app = FastAPI()
11 |
12 | app.add_middleware(TimingMiddleware)
13 |
14 |
15 | class TripsResponse(BaseModel):
16 | trips: Optional[list[Trip]] = None
17 | next_from_ms: Optional[int] = None
18 | message: Optional[str] = None
19 |
20 |
21 | @app.get('/trips', response_model=TripsResponse)
22 | def get_trip(
23 | from_ms: int = Query(..., description='Unix milliseconds'),
24 | n_results: int = Query(100, description='Number of results to output'),
25 | ):
26 | # Log the received parameters
27 | logger.info(
28 | f'Received request with params from_ms: {from_ms}, n_results: {n_results}'
29 | )
30 |
31 | # get the trips from the backend
32 | trips: list[Trip] = get_trips(from_ms, n_results)
33 |
34 | # format the response object TripsResponse
35 | if len(trips) > 0:
36 | return TripsResponse(
37 | trips=trips,
38 | next_from_ms=trips[-1].tpep_pickup_datetime_ms,
39 | message=f'Success. Returned {len(trips)} trips.',
40 | )
41 | else:
42 | return TripsResponse(message='No trips found for the given time range.')
43 |
44 |
45 | @app.get('/health')
46 | def health_check():
47 | return {'status': 'Healthy!!!'}
48 |
--------------------------------------------------------------------------------
/src/backend.py:
--------------------------------------------------------------------------------
1 | import os
2 | from datetime import datetime
3 | from typing import Optional
4 |
5 | import pandas as pd
6 | import requests
7 | from loguru import logger
8 | from pydantic import BaseModel
9 |
10 | CACHE_DIR = os.getenv('CACHE_DIR', '/tmp/taxi-data-api-python/')
11 | if not os.path.exists(CACHE_DIR):
12 | os.makedirs(CACHE_DIR)
13 |
14 |
15 | class Trip(BaseModel):
16 | tpep_pickup_datetime: datetime
17 | tpep_dropoff_datetime: datetime
18 | trip_distance: float
19 | fare_amount: float
20 |
21 | @property
22 | def tpep_pickup_datetime_ms(self) -> int:
23 | return int(self.tpep_pickup_datetime.timestamp() * 1000)
24 |
25 |
26 | def get_trips(from_ms: int, n_results: int) -> list[Trip]:
27 | """
28 | Returns a list of sorted trips from the given from_ms timestamp, with a maximum of n_results.
29 | The trips are returned in chronological order.
30 |
31 | Args:
32 | from_ms: The timestamp in milliseconds to start the search from.
33 | n_results: The maximum number of results to return.
34 |
35 | Returns:
36 | A list of trips.
37 | """
38 | from src.utils import get_year_and_month
39 |
40 | year, month = get_year_and_month(from_ms)
41 | logger.info(f'Extracted year: {year}, month: {month}')
42 |
43 | # load parquet file with the data
44 | df: Optional[pd.DataFrame] = read_parquet_file(year, month)
45 |
46 | if df is None:
47 | logger.info(f'No trips found for the given year: {year}, month: {month}')
48 | return []
49 |
50 | # Convert datetime to Unix timestamp in milliseconds
51 | df['tpep_pickup_datetime_ms'] = (
52 | df['tpep_pickup_datetime'].astype(int) / 10**3
53 | ).astype(int)
54 |
55 | # filter df to only include rows where tpep_pickup_datetime_ms is greater than from_ms
56 | df = df[df['tpep_pickup_datetime_ms'] > from_ms]
57 |
58 | # get the first n_results rows
59 | df = df.head(n_results)
60 |
61 | # convert df to list of Trip
62 | trips = df.to_dict(orient='records')
63 | trips = [Trip(**trip) for trip in trips]
64 |
65 | # Uncomment to test the API with a delay
66 | # from time import sleep
67 | # sleep(0.3)
68 |
69 | return trips
70 |
71 |
72 | def download_parquet_file(year: int, month: int):
73 | """
74 | Download the parquet file for the given year and month from the NYC Taxi and Limousine Commission.
75 |
76 | https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page
77 |
78 | Args:
79 | year: The year to download the file for.
80 | month: The month to download the file for.
81 | """
82 | # URL to download the file from
83 | url = f'https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_{year}-{month:02d}.parquet'
84 |
85 | # Download the file
86 | response = requests.get(url)
87 | if response.status_code == 200:
88 | with open(f'{CACHE_DIR}/yellow_tripdata_{year}-{month:02d}.parquet', 'wb') as f:
89 | f.write(response.content)
90 | logger.info(f'Downloaded file: yellow_tripdata_{year}-{month:02d}.parquet')
91 | else:
92 | logger.info(f'Failed to download file: {response.status_code}')
93 |
94 |
95 | def read_parquet_file(year: int, month: int) -> Optional[pd.DataFrame]:
96 | """
97 | Read the parquet file for the given year and month.
98 |
99 | Args:
100 | year: The year to read the file for.
101 | month: The month to read the file for.
102 |
103 | Returns:
104 | A pandas DataFrame with the data, or None if the file couldn't be read.
105 | """
106 | # check if the file exists
107 | if not os.path.exists(f'{CACHE_DIR}/yellow_tripdata_{year}-{month:02d}.parquet'):
108 | logger.info(f'File not found: yellow_tripdata_{year}-{month:02d}.parquet')
109 | logger.info(f'Downloading file: yellow_tripdata_{year}-{month:02d}.parquet')
110 | download_parquet_file(year, month)
111 |
112 | logger.info(f'Reading file: yellow_tripdata_{year}-{month:02d}.parquet')
113 | try:
114 | df = pd.read_parquet(
115 | f'{CACHE_DIR}/yellow_tripdata_{year}-{month:02d}.parquet', engine='pyarrow'
116 | )
117 | except Exception as e:
118 | logger.info(f'Failed to read file: {e}')
119 | return None
120 |
121 | # filter the df to only include the columns we need
122 | df = df[
123 | [
124 | 'tpep_pickup_datetime',
125 | 'tpep_dropoff_datetime',
126 | 'trip_distance',
127 | 'fare_amount',
128 | ]
129 | ]
130 |
131 | # filter rows where tpep_pickup_datetime is in that year and month
132 | df = df[df['tpep_pickup_datetime'].dt.year == year]
133 | df = df[df['tpep_pickup_datetime'].dt.month == month]
134 |
135 | # sort the df by tpep_pickup_datetime
136 | df = df.sort_values(by='tpep_pickup_datetime')
137 |
138 | return df
139 |
140 |
141 | if __name__ == '__main__':
142 | # used for debugging purposes
143 | # import argparse
144 |
145 | # # argparse
146 | # parser = argparse.ArgumentParser()
147 | # parser.add_argument("--year", type=int, required=True)
148 | # parser.add_argument("--month", type=int, required=True)
149 | # args = parser.parse_args()
150 |
151 | # df = read_parquet_file(args.year, args.month)
152 |
153 | # # df = read_parquet_file(2023, 2)
154 | # print(df.head())
155 | # print(df.tail())
156 |
157 | trips = get_trips(from_ms=1674561748000, n_results=100)
158 |
--------------------------------------------------------------------------------
/src/config.py:
--------------------------------------------------------------------------------
1 | from pydantic import Field
2 | from pydantic_settings import BaseSettings
3 |
4 |
5 | class ElasticsearchConfig(BaseSettings):
6 | host: str = Field(default='http://localhost:9200', alias='ELASTICSEARCH_HOST')
7 | index: str = Field(default='taxi_data_api', alias='ELASTICSEARCH_INDEX')
8 |
9 |
10 | elasticsearch_config = ElasticsearchConfig()
11 |
--------------------------------------------------------------------------------
/src/middleware.py:
--------------------------------------------------------------------------------
1 | import time
2 | from datetime import datetime
3 |
4 | from elasticsearch import Elasticsearch
5 | from fastapi import Request
6 | from loguru import logger
7 | from starlette.middleware.base import BaseHTTPMiddleware
8 |
9 | from src.config import elasticsearch_config
10 |
11 | # Initialize Elasticsearch client
12 | es = Elasticsearch([elasticsearch_config.host])
13 |
14 |
15 | class TimingMiddleware(BaseHTTPMiddleware):
16 | async def dispatch(self, request: Request, call_next):
17 | if request.url.path == '/trips':
18 | start_time = time.time()
19 | response = await call_next(request)
20 | process_time = time.time() - start_time
21 |
22 | # Log to Elasticsearch
23 | try:
24 | es.index(
25 | index=elasticsearch_config.index,
26 | body={
27 | 'endpoint': '/trips',
28 | 'method': request.method,
29 | 'process_time': process_time,
30 | 'timestamp': datetime.utcnow().isoformat(),
31 | },
32 | )
33 | except Exception as e:
34 | logger.error(f'Error logging to Elasticsearch: {e}')
35 |
36 | return response
37 |
38 | return await call_next(request)
39 |
--------------------------------------------------------------------------------
/src/utils.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from typing import Tuple
3 |
4 |
5 | def get_year_and_month(from_ms: int) -> Tuple[int, int]:
6 | """
7 | Get the year and month from a given Unix milliseconds timestamp.
8 |
9 | Args:
10 | from_ms (int): Unix milliseconds timestamp.
11 |
12 | Returns:
13 | Tuple[int, int]: Year and month.
14 | """
15 | # Convert from_ms to a datetime object
16 | dt = datetime.fromtimestamp(from_ms / 1000)
17 |
18 | # Extract year and month
19 | year = dt.year
20 | month = dt.month
21 |
22 | return year, month
23 |
--------------------------------------------------------------------------------
/taxi-data-api-rust/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "actix-codec"
7 | version = "0.5.2"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a"
10 | dependencies = [
11 | "bitflags",
12 | "bytes",
13 | "futures-core",
14 | "futures-sink",
15 | "memchr",
16 | "pin-project-lite",
17 | "tokio",
18 | "tokio-util",
19 | "tracing",
20 | ]
21 |
22 | [[package]]
23 | name = "actix-http"
24 | version = "3.9.0"
25 | source = "registry+https://github.com/rust-lang/crates.io-index"
26 | checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4"
27 | dependencies = [
28 | "actix-codec",
29 | "actix-rt",
30 | "actix-service",
31 | "actix-utils",
32 | "ahash",
33 | "base64 0.22.1",
34 | "bitflags",
35 | "brotli 6.0.0",
36 | "bytes",
37 | "bytestring",
38 | "derive_more",
39 | "encoding_rs",
40 | "flate2",
41 | "futures-core",
42 | "h2 0.3.26",
43 | "http 0.2.12",
44 | "httparse",
45 | "httpdate",
46 | "itoa",
47 | "language-tags",
48 | "local-channel",
49 | "mime",
50 | "percent-encoding",
51 | "pin-project-lite",
52 | "rand",
53 | "sha1",
54 | "smallvec",
55 | "tokio",
56 | "tokio-util",
57 | "tracing",
58 | "zstd",
59 | ]
60 |
61 | [[package]]
62 | name = "actix-macros"
63 | version = "0.2.4"
64 | source = "registry+https://github.com/rust-lang/crates.io-index"
65 | checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
66 | dependencies = [
67 | "quote",
68 | "syn 2.0.85",
69 | ]
70 |
71 | [[package]]
72 | name = "actix-router"
73 | version = "0.5.3"
74 | source = "registry+https://github.com/rust-lang/crates.io-index"
75 | checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8"
76 | dependencies = [
77 | "bytestring",
78 | "cfg-if",
79 | "http 0.2.12",
80 | "regex",
81 | "regex-lite",
82 | "serde",
83 | "tracing",
84 | ]
85 |
86 | [[package]]
87 | name = "actix-rt"
88 | version = "2.10.0"
89 | source = "registry+https://github.com/rust-lang/crates.io-index"
90 | checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208"
91 | dependencies = [
92 | "futures-core",
93 | "tokio",
94 | ]
95 |
96 | [[package]]
97 | name = "actix-server"
98 | version = "2.5.0"
99 | source = "registry+https://github.com/rust-lang/crates.io-index"
100 | checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894"
101 | dependencies = [
102 | "actix-rt",
103 | "actix-service",
104 | "actix-utils",
105 | "futures-core",
106 | "futures-util",
107 | "mio",
108 | "socket2",
109 | "tokio",
110 | "tracing",
111 | ]
112 |
113 | [[package]]
114 | name = "actix-service"
115 | version = "2.0.2"
116 | source = "registry+https://github.com/rust-lang/crates.io-index"
117 | checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a"
118 | dependencies = [
119 | "futures-core",
120 | "paste",
121 | "pin-project-lite",
122 | ]
123 |
124 | [[package]]
125 | name = "actix-utils"
126 | version = "3.0.1"
127 | source = "registry+https://github.com/rust-lang/crates.io-index"
128 | checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8"
129 | dependencies = [
130 | "local-waker",
131 | "pin-project-lite",
132 | ]
133 |
134 | [[package]]
135 | name = "actix-web"
136 | version = "4.9.0"
137 | source = "registry+https://github.com/rust-lang/crates.io-index"
138 | checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38"
139 | dependencies = [
140 | "actix-codec",
141 | "actix-http",
142 | "actix-macros",
143 | "actix-router",
144 | "actix-rt",
145 | "actix-server",
146 | "actix-service",
147 | "actix-utils",
148 | "actix-web-codegen",
149 | "ahash",
150 | "bytes",
151 | "bytestring",
152 | "cfg-if",
153 | "cookie",
154 | "derive_more",
155 | "encoding_rs",
156 | "futures-core",
157 | "futures-util",
158 | "impl-more",
159 | "itoa",
160 | "language-tags",
161 | "log",
162 | "mime",
163 | "once_cell",
164 | "pin-project-lite",
165 | "regex",
166 | "regex-lite",
167 | "serde",
168 | "serde_json",
169 | "serde_urlencoded",
170 | "smallvec",
171 | "socket2",
172 | "time",
173 | "url",
174 | ]
175 |
176 | [[package]]
177 | name = "actix-web-codegen"
178 | version = "4.3.0"
179 | source = "registry+https://github.com/rust-lang/crates.io-index"
180 | checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8"
181 | dependencies = [
182 | "actix-router",
183 | "proc-macro2",
184 | "quote",
185 | "syn 2.0.85",
186 | ]
187 |
188 | [[package]]
189 | name = "addr2line"
190 | version = "0.24.2"
191 | source = "registry+https://github.com/rust-lang/crates.io-index"
192 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
193 | dependencies = [
194 | "gimli",
195 | ]
196 |
197 | [[package]]
198 | name = "adler2"
199 | version = "2.0.0"
200 | source = "registry+https://github.com/rust-lang/crates.io-index"
201 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
202 |
203 | [[package]]
204 | name = "ahash"
205 | version = "0.8.11"
206 | source = "registry+https://github.com/rust-lang/crates.io-index"
207 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
208 | dependencies = [
209 | "cfg-if",
210 | "getrandom",
211 | "once_cell",
212 | "version_check",
213 | "zerocopy",
214 | ]
215 |
216 | [[package]]
217 | name = "aho-corasick"
218 | version = "1.1.3"
219 | source = "registry+https://github.com/rust-lang/crates.io-index"
220 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
221 | dependencies = [
222 | "memchr",
223 | ]
224 |
225 | [[package]]
226 | name = "alloc-no-stdlib"
227 | version = "2.0.4"
228 | source = "registry+https://github.com/rust-lang/crates.io-index"
229 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
230 |
231 | [[package]]
232 | name = "alloc-stdlib"
233 | version = "0.2.2"
234 | source = "registry+https://github.com/rust-lang/crates.io-index"
235 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
236 | dependencies = [
237 | "alloc-no-stdlib",
238 | ]
239 |
240 | [[package]]
241 | name = "allocator-api2"
242 | version = "0.2.18"
243 | source = "registry+https://github.com/rust-lang/crates.io-index"
244 | checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
245 |
246 | [[package]]
247 | name = "android-tzdata"
248 | version = "0.1.1"
249 | source = "registry+https://github.com/rust-lang/crates.io-index"
250 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
251 |
252 | [[package]]
253 | name = "android_system_properties"
254 | version = "0.1.5"
255 | source = "registry+https://github.com/rust-lang/crates.io-index"
256 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
257 | dependencies = [
258 | "libc",
259 | ]
260 |
261 | [[package]]
262 | name = "anstream"
263 | version = "0.6.17"
264 | source = "registry+https://github.com/rust-lang/crates.io-index"
265 | checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338"
266 | dependencies = [
267 | "anstyle",
268 | "anstyle-parse",
269 | "anstyle-query",
270 | "anstyle-wincon",
271 | "colorchoice",
272 | "is_terminal_polyfill",
273 | "utf8parse",
274 | ]
275 |
276 | [[package]]
277 | name = "anstyle"
278 | version = "1.0.9"
279 | source = "registry+https://github.com/rust-lang/crates.io-index"
280 | checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56"
281 |
282 | [[package]]
283 | name = "anstyle-parse"
284 | version = "0.2.6"
285 | source = "registry+https://github.com/rust-lang/crates.io-index"
286 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
287 | dependencies = [
288 | "utf8parse",
289 | ]
290 |
291 | [[package]]
292 | name = "anstyle-query"
293 | version = "1.1.2"
294 | source = "registry+https://github.com/rust-lang/crates.io-index"
295 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
296 | dependencies = [
297 | "windows-sys 0.59.0",
298 | ]
299 |
300 | [[package]]
301 | name = "anstyle-wincon"
302 | version = "3.0.6"
303 | source = "registry+https://github.com/rust-lang/crates.io-index"
304 | checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
305 | dependencies = [
306 | "anstyle",
307 | "windows-sys 0.59.0",
308 | ]
309 |
310 | [[package]]
311 | name = "anyhow"
312 | version = "1.0.91"
313 | source = "registry+https://github.com/rust-lang/crates.io-index"
314 | checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8"
315 |
316 | [[package]]
317 | name = "argminmax"
318 | version = "0.6.2"
319 | source = "registry+https://github.com/rust-lang/crates.io-index"
320 | checksum = "52424b59d69d69d5056d508b260553afd91c57e21849579cd1f50ee8b8b88eaa"
321 | dependencies = [
322 | "num-traits",
323 | ]
324 |
325 | [[package]]
326 | name = "array-init-cursor"
327 | version = "0.2.0"
328 | source = "registry+https://github.com/rust-lang/crates.io-index"
329 | checksum = "bf7d0a018de4f6aa429b9d33d69edf69072b1c5b1cb8d3e4a5f7ef898fc3eb76"
330 |
331 | [[package]]
332 | name = "arrow-format"
333 | version = "0.8.1"
334 | source = "registry+https://github.com/rust-lang/crates.io-index"
335 | checksum = "07884ea216994cdc32a2d5f8274a8bee979cfe90274b83f86f440866ee3132c7"
336 | dependencies = [
337 | "planus",
338 | "serde",
339 | ]
340 |
341 | [[package]]
342 | name = "async-stream"
343 | version = "0.3.6"
344 | source = "registry+https://github.com/rust-lang/crates.io-index"
345 | checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
346 | dependencies = [
347 | "async-stream-impl",
348 | "futures-core",
349 | "pin-project-lite",
350 | ]
351 |
352 | [[package]]
353 | name = "async-stream-impl"
354 | version = "0.3.6"
355 | source = "registry+https://github.com/rust-lang/crates.io-index"
356 | checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
357 | dependencies = [
358 | "proc-macro2",
359 | "quote",
360 | "syn 2.0.85",
361 | ]
362 |
363 | [[package]]
364 | name = "async-trait"
365 | version = "0.1.83"
366 | source = "registry+https://github.com/rust-lang/crates.io-index"
367 | checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
368 | dependencies = [
369 | "proc-macro2",
370 | "quote",
371 | "syn 2.0.85",
372 | ]
373 |
374 | [[package]]
375 | name = "atoi"
376 | version = "2.0.0"
377 | source = "registry+https://github.com/rust-lang/crates.io-index"
378 | checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
379 | dependencies = [
380 | "num-traits",
381 | ]
382 |
383 | [[package]]
384 | name = "atoi_simd"
385 | version = "0.15.6"
386 | source = "registry+https://github.com/rust-lang/crates.io-index"
387 | checksum = "9ae037714f313c1353189ead58ef9eec30a8e8dc101b2622d461418fd59e28a9"
388 |
389 | [[package]]
390 | name = "atomic-waker"
391 | version = "1.1.2"
392 | source = "registry+https://github.com/rust-lang/crates.io-index"
393 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
394 |
395 | [[package]]
396 | name = "autocfg"
397 | version = "1.4.0"
398 | source = "registry+https://github.com/rust-lang/crates.io-index"
399 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
400 |
401 | [[package]]
402 | name = "backtrace"
403 | version = "0.3.74"
404 | source = "registry+https://github.com/rust-lang/crates.io-index"
405 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
406 | dependencies = [
407 | "addr2line",
408 | "cfg-if",
409 | "libc",
410 | "miniz_oxide",
411 | "object",
412 | "rustc-demangle",
413 | "windows-targets",
414 | ]
415 |
416 | [[package]]
417 | name = "base64"
418 | version = "0.21.7"
419 | source = "registry+https://github.com/rust-lang/crates.io-index"
420 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
421 |
422 | [[package]]
423 | name = "base64"
424 | version = "0.22.1"
425 | source = "registry+https://github.com/rust-lang/crates.io-index"
426 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
427 |
428 | [[package]]
429 | name = "bitflags"
430 | version = "2.6.0"
431 | source = "registry+https://github.com/rust-lang/crates.io-index"
432 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
433 |
434 | [[package]]
435 | name = "block-buffer"
436 | version = "0.10.4"
437 | source = "registry+https://github.com/rust-lang/crates.io-index"
438 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
439 | dependencies = [
440 | "generic-array",
441 | ]
442 |
443 | [[package]]
444 | name = "brotli"
445 | version = "3.5.0"
446 | source = "registry+https://github.com/rust-lang/crates.io-index"
447 | checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391"
448 | dependencies = [
449 | "alloc-no-stdlib",
450 | "alloc-stdlib",
451 | "brotli-decompressor 2.5.1",
452 | ]
453 |
454 | [[package]]
455 | name = "brotli"
456 | version = "6.0.0"
457 | source = "registry+https://github.com/rust-lang/crates.io-index"
458 | checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b"
459 | dependencies = [
460 | "alloc-no-stdlib",
461 | "alloc-stdlib",
462 | "brotli-decompressor 4.0.1",
463 | ]
464 |
465 | [[package]]
466 | name = "brotli-decompressor"
467 | version = "2.5.1"
468 | source = "registry+https://github.com/rust-lang/crates.io-index"
469 | checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
470 | dependencies = [
471 | "alloc-no-stdlib",
472 | "alloc-stdlib",
473 | ]
474 |
475 | [[package]]
476 | name = "brotli-decompressor"
477 | version = "4.0.1"
478 | source = "registry+https://github.com/rust-lang/crates.io-index"
479 | checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362"
480 | dependencies = [
481 | "alloc-no-stdlib",
482 | "alloc-stdlib",
483 | ]
484 |
485 | [[package]]
486 | name = "bumpalo"
487 | version = "3.16.0"
488 | source = "registry+https://github.com/rust-lang/crates.io-index"
489 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
490 |
491 | [[package]]
492 | name = "bytemuck"
493 | version = "1.19.0"
494 | source = "registry+https://github.com/rust-lang/crates.io-index"
495 | checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d"
496 | dependencies = [
497 | "bytemuck_derive",
498 | ]
499 |
500 | [[package]]
501 | name = "bytemuck_derive"
502 | version = "1.8.0"
503 | source = "registry+https://github.com/rust-lang/crates.io-index"
504 | checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec"
505 | dependencies = [
506 | "proc-macro2",
507 | "quote",
508 | "syn 2.0.85",
509 | ]
510 |
511 | [[package]]
512 | name = "byteorder"
513 | version = "1.5.0"
514 | source = "registry+https://github.com/rust-lang/crates.io-index"
515 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
516 |
517 | [[package]]
518 | name = "bytes"
519 | version = "1.8.0"
520 | source = "registry+https://github.com/rust-lang/crates.io-index"
521 | checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
522 |
523 | [[package]]
524 | name = "bytestring"
525 | version = "1.3.1"
526 | source = "registry+https://github.com/rust-lang/crates.io-index"
527 | checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72"
528 | dependencies = [
529 | "bytes",
530 | ]
531 |
532 | [[package]]
533 | name = "cc"
534 | version = "1.1.31"
535 | source = "registry+https://github.com/rust-lang/crates.io-index"
536 | checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
537 | dependencies = [
538 | "jobserver",
539 | "libc",
540 | "shlex",
541 | ]
542 |
543 | [[package]]
544 | name = "cfg-if"
545 | version = "1.0.0"
546 | source = "registry+https://github.com/rust-lang/crates.io-index"
547 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
548 |
549 | [[package]]
550 | name = "chrono"
551 | version = "0.4.38"
552 | source = "registry+https://github.com/rust-lang/crates.io-index"
553 | checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
554 | dependencies = [
555 | "android-tzdata",
556 | "iana-time-zone",
557 | "js-sys",
558 | "num-traits",
559 | "serde",
560 | "wasm-bindgen",
561 | "windows-targets",
562 | ]
563 |
564 | [[package]]
565 | name = "colorchoice"
566 | version = "1.0.3"
567 | source = "registry+https://github.com/rust-lang/crates.io-index"
568 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
569 |
570 | [[package]]
571 | name = "comfy-table"
572 | version = "7.1.1"
573 | source = "registry+https://github.com/rust-lang/crates.io-index"
574 | checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7"
575 | dependencies = [
576 | "crossterm",
577 | "strum",
578 | "strum_macros 0.26.4",
579 | "unicode-width",
580 | ]
581 |
582 | [[package]]
583 | name = "convert_case"
584 | version = "0.4.0"
585 | source = "registry+https://github.com/rust-lang/crates.io-index"
586 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
587 |
588 | [[package]]
589 | name = "cookie"
590 | version = "0.16.2"
591 | source = "registry+https://github.com/rust-lang/crates.io-index"
592 | checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
593 | dependencies = [
594 | "percent-encoding",
595 | "time",
596 | "version_check",
597 | ]
598 |
599 | [[package]]
600 | name = "core-foundation"
601 | version = "0.9.4"
602 | source = "registry+https://github.com/rust-lang/crates.io-index"
603 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
604 | dependencies = [
605 | "core-foundation-sys",
606 | "libc",
607 | ]
608 |
609 | [[package]]
610 | name = "core-foundation-sys"
611 | version = "0.8.7"
612 | source = "registry+https://github.com/rust-lang/crates.io-index"
613 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
614 |
615 | [[package]]
616 | name = "cpufeatures"
617 | version = "0.2.14"
618 | source = "registry+https://github.com/rust-lang/crates.io-index"
619 | checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
620 | dependencies = [
621 | "libc",
622 | ]
623 |
624 | [[package]]
625 | name = "crc32fast"
626 | version = "1.4.2"
627 | source = "registry+https://github.com/rust-lang/crates.io-index"
628 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
629 | dependencies = [
630 | "cfg-if",
631 | ]
632 |
633 | [[package]]
634 | name = "crossbeam-channel"
635 | version = "0.5.13"
636 | source = "registry+https://github.com/rust-lang/crates.io-index"
637 | checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
638 | dependencies = [
639 | "crossbeam-utils",
640 | ]
641 |
642 | [[package]]
643 | name = "crossbeam-deque"
644 | version = "0.8.5"
645 | source = "registry+https://github.com/rust-lang/crates.io-index"
646 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
647 | dependencies = [
648 | "crossbeam-epoch",
649 | "crossbeam-utils",
650 | ]
651 |
652 | [[package]]
653 | name = "crossbeam-epoch"
654 | version = "0.9.18"
655 | source = "registry+https://github.com/rust-lang/crates.io-index"
656 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
657 | dependencies = [
658 | "crossbeam-utils",
659 | ]
660 |
661 | [[package]]
662 | name = "crossbeam-queue"
663 | version = "0.3.11"
664 | source = "registry+https://github.com/rust-lang/crates.io-index"
665 | checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
666 | dependencies = [
667 | "crossbeam-utils",
668 | ]
669 |
670 | [[package]]
671 | name = "crossbeam-utils"
672 | version = "0.8.20"
673 | source = "registry+https://github.com/rust-lang/crates.io-index"
674 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
675 |
676 | [[package]]
677 | name = "crossterm"
678 | version = "0.27.0"
679 | source = "registry+https://github.com/rust-lang/crates.io-index"
680 | checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
681 | dependencies = [
682 | "bitflags",
683 | "crossterm_winapi",
684 | "libc",
685 | "parking_lot",
686 | "winapi",
687 | ]
688 |
689 | [[package]]
690 | name = "crossterm_winapi"
691 | version = "0.9.1"
692 | source = "registry+https://github.com/rust-lang/crates.io-index"
693 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
694 | dependencies = [
695 | "winapi",
696 | ]
697 |
698 | [[package]]
699 | name = "crypto-common"
700 | version = "0.1.6"
701 | source = "registry+https://github.com/rust-lang/crates.io-index"
702 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
703 | dependencies = [
704 | "generic-array",
705 | "typenum",
706 | ]
707 |
708 | [[package]]
709 | name = "deranged"
710 | version = "0.3.11"
711 | source = "registry+https://github.com/rust-lang/crates.io-index"
712 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
713 | dependencies = [
714 | "powerfmt",
715 | ]
716 |
717 | [[package]]
718 | name = "derive_more"
719 | version = "0.99.18"
720 | source = "registry+https://github.com/rust-lang/crates.io-index"
721 | checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
722 | dependencies = [
723 | "convert_case",
724 | "proc-macro2",
725 | "quote",
726 | "rustc_version",
727 | "syn 2.0.85",
728 | ]
729 |
730 | [[package]]
731 | name = "digest"
732 | version = "0.10.7"
733 | source = "registry+https://github.com/rust-lang/crates.io-index"
734 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
735 | dependencies = [
736 | "block-buffer",
737 | "crypto-common",
738 | ]
739 |
740 | [[package]]
741 | name = "dyn-clone"
742 | version = "1.0.17"
743 | source = "registry+https://github.com/rust-lang/crates.io-index"
744 | checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
745 |
746 | [[package]]
747 | name = "either"
748 | version = "1.13.0"
749 | source = "registry+https://github.com/rust-lang/crates.io-index"
750 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
751 |
752 | [[package]]
753 | name = "encoding_rs"
754 | version = "0.8.35"
755 | source = "registry+https://github.com/rust-lang/crates.io-index"
756 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
757 | dependencies = [
758 | "cfg-if",
759 | ]
760 |
761 | [[package]]
762 | name = "enum_dispatch"
763 | version = "0.3.13"
764 | source = "registry+https://github.com/rust-lang/crates.io-index"
765 | checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd"
766 | dependencies = [
767 | "once_cell",
768 | "proc-macro2",
769 | "quote",
770 | "syn 2.0.85",
771 | ]
772 |
773 | [[package]]
774 | name = "env_filter"
775 | version = "0.1.2"
776 | source = "registry+https://github.com/rust-lang/crates.io-index"
777 | checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
778 | dependencies = [
779 | "log",
780 | "regex",
781 | ]
782 |
783 | [[package]]
784 | name = "env_logger"
785 | version = "0.11.5"
786 | source = "registry+https://github.com/rust-lang/crates.io-index"
787 | checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
788 | dependencies = [
789 | "anstream",
790 | "anstyle",
791 | "env_filter",
792 | "humantime",
793 | "log",
794 | ]
795 |
796 | [[package]]
797 | name = "equivalent"
798 | version = "1.0.1"
799 | source = "registry+https://github.com/rust-lang/crates.io-index"
800 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
801 |
802 | [[package]]
803 | name = "errno"
804 | version = "0.3.9"
805 | source = "registry+https://github.com/rust-lang/crates.io-index"
806 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
807 | dependencies = [
808 | "libc",
809 | "windows-sys 0.52.0",
810 | ]
811 |
812 | [[package]]
813 | name = "ethnum"
814 | version = "1.5.0"
815 | source = "registry+https://github.com/rust-lang/crates.io-index"
816 | checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c"
817 |
818 | [[package]]
819 | name = "fallible-streaming-iterator"
820 | version = "0.1.9"
821 | source = "registry+https://github.com/rust-lang/crates.io-index"
822 | checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
823 |
824 | [[package]]
825 | name = "fast-float"
826 | version = "0.2.0"
827 | source = "registry+https://github.com/rust-lang/crates.io-index"
828 | checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c"
829 |
830 | [[package]]
831 | name = "fastrand"
832 | version = "2.1.1"
833 | source = "registry+https://github.com/rust-lang/crates.io-index"
834 | checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
835 |
836 | [[package]]
837 | name = "flate2"
838 | version = "1.0.34"
839 | source = "registry+https://github.com/rust-lang/crates.io-index"
840 | checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
841 | dependencies = [
842 | "crc32fast",
843 | "miniz_oxide",
844 | ]
845 |
846 | [[package]]
847 | name = "fnv"
848 | version = "1.0.7"
849 | source = "registry+https://github.com/rust-lang/crates.io-index"
850 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
851 |
852 | [[package]]
853 | name = "foreign-types"
854 | version = "0.3.2"
855 | source = "registry+https://github.com/rust-lang/crates.io-index"
856 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
857 | dependencies = [
858 | "foreign-types-shared",
859 | ]
860 |
861 | [[package]]
862 | name = "foreign-types-shared"
863 | version = "0.1.1"
864 | source = "registry+https://github.com/rust-lang/crates.io-index"
865 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
866 |
867 | [[package]]
868 | name = "foreign_vec"
869 | version = "0.1.0"
870 | source = "registry+https://github.com/rust-lang/crates.io-index"
871 | checksum = "ee1b05cbd864bcaecbd3455d6d967862d446e4ebfc3c2e5e5b9841e53cba6673"
872 |
873 | [[package]]
874 | name = "form_urlencoded"
875 | version = "1.2.1"
876 | source = "registry+https://github.com/rust-lang/crates.io-index"
877 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
878 | dependencies = [
879 | "percent-encoding",
880 | ]
881 |
882 | [[package]]
883 | name = "futures"
884 | version = "0.3.31"
885 | source = "registry+https://github.com/rust-lang/crates.io-index"
886 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
887 | dependencies = [
888 | "futures-channel",
889 | "futures-core",
890 | "futures-executor",
891 | "futures-io",
892 | "futures-sink",
893 | "futures-task",
894 | "futures-util",
895 | ]
896 |
897 | [[package]]
898 | name = "futures-channel"
899 | version = "0.3.31"
900 | source = "registry+https://github.com/rust-lang/crates.io-index"
901 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
902 | dependencies = [
903 | "futures-core",
904 | "futures-sink",
905 | ]
906 |
907 | [[package]]
908 | name = "futures-core"
909 | version = "0.3.31"
910 | source = "registry+https://github.com/rust-lang/crates.io-index"
911 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
912 |
913 | [[package]]
914 | name = "futures-executor"
915 | version = "0.3.31"
916 | source = "registry+https://github.com/rust-lang/crates.io-index"
917 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
918 | dependencies = [
919 | "futures-core",
920 | "futures-task",
921 | "futures-util",
922 | ]
923 |
924 | [[package]]
925 | name = "futures-io"
926 | version = "0.3.31"
927 | source = "registry+https://github.com/rust-lang/crates.io-index"
928 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
929 |
930 | [[package]]
931 | name = "futures-macro"
932 | version = "0.3.31"
933 | source = "registry+https://github.com/rust-lang/crates.io-index"
934 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
935 | dependencies = [
936 | "proc-macro2",
937 | "quote",
938 | "syn 2.0.85",
939 | ]
940 |
941 | [[package]]
942 | name = "futures-sink"
943 | version = "0.3.31"
944 | source = "registry+https://github.com/rust-lang/crates.io-index"
945 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
946 |
947 | [[package]]
948 | name = "futures-task"
949 | version = "0.3.31"
950 | source = "registry+https://github.com/rust-lang/crates.io-index"
951 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
952 |
953 | [[package]]
954 | name = "futures-util"
955 | version = "0.3.31"
956 | source = "registry+https://github.com/rust-lang/crates.io-index"
957 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
958 | dependencies = [
959 | "futures-channel",
960 | "futures-core",
961 | "futures-io",
962 | "futures-macro",
963 | "futures-sink",
964 | "futures-task",
965 | "memchr",
966 | "pin-project-lite",
967 | "pin-utils",
968 | "slab",
969 | ]
970 |
971 | [[package]]
972 | name = "generic-array"
973 | version = "0.14.7"
974 | source = "registry+https://github.com/rust-lang/crates.io-index"
975 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
976 | dependencies = [
977 | "typenum",
978 | "version_check",
979 | ]
980 |
981 | [[package]]
982 | name = "getrandom"
983 | version = "0.2.15"
984 | source = "registry+https://github.com/rust-lang/crates.io-index"
985 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
986 | dependencies = [
987 | "cfg-if",
988 | "js-sys",
989 | "libc",
990 | "wasi",
991 | "wasm-bindgen",
992 | ]
993 |
994 | [[package]]
995 | name = "gimli"
996 | version = "0.31.1"
997 | source = "registry+https://github.com/rust-lang/crates.io-index"
998 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
999 |
1000 | [[package]]
1001 | name = "glob"
1002 | version = "0.3.1"
1003 | source = "registry+https://github.com/rust-lang/crates.io-index"
1004 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
1005 |
1006 | [[package]]
1007 | name = "h2"
1008 | version = "0.3.26"
1009 | source = "registry+https://github.com/rust-lang/crates.io-index"
1010 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
1011 | dependencies = [
1012 | "bytes",
1013 | "fnv",
1014 | "futures-core",
1015 | "futures-sink",
1016 | "futures-util",
1017 | "http 0.2.12",
1018 | "indexmap",
1019 | "slab",
1020 | "tokio",
1021 | "tokio-util",
1022 | "tracing",
1023 | ]
1024 |
1025 | [[package]]
1026 | name = "h2"
1027 | version = "0.4.6"
1028 | source = "registry+https://github.com/rust-lang/crates.io-index"
1029 | checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205"
1030 | dependencies = [
1031 | "atomic-waker",
1032 | "bytes",
1033 | "fnv",
1034 | "futures-core",
1035 | "futures-sink",
1036 | "http 1.1.0",
1037 | "indexmap",
1038 | "slab",
1039 | "tokio",
1040 | "tokio-util",
1041 | "tracing",
1042 | ]
1043 |
1044 | [[package]]
1045 | name = "hashbrown"
1046 | version = "0.14.5"
1047 | source = "registry+https://github.com/rust-lang/crates.io-index"
1048 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
1049 | dependencies = [
1050 | "ahash",
1051 | "allocator-api2",
1052 | "rayon",
1053 | ]
1054 |
1055 | [[package]]
1056 | name = "hashbrown"
1057 | version = "0.15.0"
1058 | source = "registry+https://github.com/rust-lang/crates.io-index"
1059 | checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
1060 |
1061 | [[package]]
1062 | name = "heck"
1063 | version = "0.4.1"
1064 | source = "registry+https://github.com/rust-lang/crates.io-index"
1065 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
1066 |
1067 | [[package]]
1068 | name = "heck"
1069 | version = "0.5.0"
1070 | source = "registry+https://github.com/rust-lang/crates.io-index"
1071 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
1072 |
1073 | [[package]]
1074 | name = "hermit-abi"
1075 | version = "0.3.9"
1076 | source = "registry+https://github.com/rust-lang/crates.io-index"
1077 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
1078 |
1079 | [[package]]
1080 | name = "home"
1081 | version = "0.5.9"
1082 | source = "registry+https://github.com/rust-lang/crates.io-index"
1083 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
1084 | dependencies = [
1085 | "windows-sys 0.52.0",
1086 | ]
1087 |
1088 | [[package]]
1089 | name = "http"
1090 | version = "0.2.12"
1091 | source = "registry+https://github.com/rust-lang/crates.io-index"
1092 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
1093 | dependencies = [
1094 | "bytes",
1095 | "fnv",
1096 | "itoa",
1097 | ]
1098 |
1099 | [[package]]
1100 | name = "http"
1101 | version = "1.1.0"
1102 | source = "registry+https://github.com/rust-lang/crates.io-index"
1103 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
1104 | dependencies = [
1105 | "bytes",
1106 | "fnv",
1107 | "itoa",
1108 | ]
1109 |
1110 | [[package]]
1111 | name = "http-body"
1112 | version = "1.0.1"
1113 | source = "registry+https://github.com/rust-lang/crates.io-index"
1114 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
1115 | dependencies = [
1116 | "bytes",
1117 | "http 1.1.0",
1118 | ]
1119 |
1120 | [[package]]
1121 | name = "http-body-util"
1122 | version = "0.1.2"
1123 | source = "registry+https://github.com/rust-lang/crates.io-index"
1124 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
1125 | dependencies = [
1126 | "bytes",
1127 | "futures-util",
1128 | "http 1.1.0",
1129 | "http-body",
1130 | "pin-project-lite",
1131 | ]
1132 |
1133 | [[package]]
1134 | name = "httparse"
1135 | version = "1.9.5"
1136 | source = "registry+https://github.com/rust-lang/crates.io-index"
1137 | checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
1138 |
1139 | [[package]]
1140 | name = "httpdate"
1141 | version = "1.0.3"
1142 | source = "registry+https://github.com/rust-lang/crates.io-index"
1143 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
1144 |
1145 | [[package]]
1146 | name = "humantime"
1147 | version = "2.1.0"
1148 | source = "registry+https://github.com/rust-lang/crates.io-index"
1149 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
1150 |
1151 | [[package]]
1152 | name = "hyper"
1153 | version = "1.5.0"
1154 | source = "registry+https://github.com/rust-lang/crates.io-index"
1155 | checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a"
1156 | dependencies = [
1157 | "bytes",
1158 | "futures-channel",
1159 | "futures-util",
1160 | "h2 0.4.6",
1161 | "http 1.1.0",
1162 | "http-body",
1163 | "httparse",
1164 | "itoa",
1165 | "pin-project-lite",
1166 | "smallvec",
1167 | "tokio",
1168 | "want",
1169 | ]
1170 |
1171 | [[package]]
1172 | name = "hyper-rustls"
1173 | version = "0.27.3"
1174 | source = "registry+https://github.com/rust-lang/crates.io-index"
1175 | checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
1176 | dependencies = [
1177 | "futures-util",
1178 | "http 1.1.0",
1179 | "hyper",
1180 | "hyper-util",
1181 | "rustls",
1182 | "rustls-pki-types",
1183 | "tokio",
1184 | "tokio-rustls",
1185 | "tower-service",
1186 | ]
1187 |
1188 | [[package]]
1189 | name = "hyper-tls"
1190 | version = "0.6.0"
1191 | source = "registry+https://github.com/rust-lang/crates.io-index"
1192 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
1193 | dependencies = [
1194 | "bytes",
1195 | "http-body-util",
1196 | "hyper",
1197 | "hyper-util",
1198 | "native-tls",
1199 | "tokio",
1200 | "tokio-native-tls",
1201 | "tower-service",
1202 | ]
1203 |
1204 | [[package]]
1205 | name = "hyper-util"
1206 | version = "0.1.10"
1207 | source = "registry+https://github.com/rust-lang/crates.io-index"
1208 | checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
1209 | dependencies = [
1210 | "bytes",
1211 | "futures-channel",
1212 | "futures-util",
1213 | "http 1.1.0",
1214 | "http-body",
1215 | "hyper",
1216 | "pin-project-lite",
1217 | "socket2",
1218 | "tokio",
1219 | "tower-service",
1220 | "tracing",
1221 | ]
1222 |
1223 | [[package]]
1224 | name = "iana-time-zone"
1225 | version = "0.1.61"
1226 | source = "registry+https://github.com/rust-lang/crates.io-index"
1227 | checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
1228 | dependencies = [
1229 | "android_system_properties",
1230 | "core-foundation-sys",
1231 | "iana-time-zone-haiku",
1232 | "js-sys",
1233 | "wasm-bindgen",
1234 | "windows-core",
1235 | ]
1236 |
1237 | [[package]]
1238 | name = "iana-time-zone-haiku"
1239 | version = "0.1.2"
1240 | source = "registry+https://github.com/rust-lang/crates.io-index"
1241 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
1242 | dependencies = [
1243 | "cc",
1244 | ]
1245 |
1246 | [[package]]
1247 | name = "idna"
1248 | version = "0.5.0"
1249 | source = "registry+https://github.com/rust-lang/crates.io-index"
1250 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
1251 | dependencies = [
1252 | "unicode-bidi",
1253 | "unicode-normalization",
1254 | ]
1255 |
1256 | [[package]]
1257 | name = "impl-more"
1258 | version = "0.1.8"
1259 | source = "registry+https://github.com/rust-lang/crates.io-index"
1260 | checksum = "aae21c3177a27788957044151cc2800043d127acaa460a47ebb9b84dfa2c6aa0"
1261 |
1262 | [[package]]
1263 | name = "indexmap"
1264 | version = "2.6.0"
1265 | source = "registry+https://github.com/rust-lang/crates.io-index"
1266 | checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
1267 | dependencies = [
1268 | "equivalent",
1269 | "hashbrown 0.15.0",
1270 | ]
1271 |
1272 | [[package]]
1273 | name = "ipnet"
1274 | version = "2.10.1"
1275 | source = "registry+https://github.com/rust-lang/crates.io-index"
1276 | checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
1277 |
1278 | [[package]]
1279 | name = "is_terminal_polyfill"
1280 | version = "1.70.1"
1281 | source = "registry+https://github.com/rust-lang/crates.io-index"
1282 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
1283 |
1284 | [[package]]
1285 | name = "itoa"
1286 | version = "1.0.11"
1287 | source = "registry+https://github.com/rust-lang/crates.io-index"
1288 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
1289 |
1290 | [[package]]
1291 | name = "jobserver"
1292 | version = "0.1.32"
1293 | source = "registry+https://github.com/rust-lang/crates.io-index"
1294 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
1295 | dependencies = [
1296 | "libc",
1297 | ]
1298 |
1299 | [[package]]
1300 | name = "js-sys"
1301 | version = "0.3.72"
1302 | source = "registry+https://github.com/rust-lang/crates.io-index"
1303 | checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
1304 | dependencies = [
1305 | "wasm-bindgen",
1306 | ]
1307 |
1308 | [[package]]
1309 | name = "language-tags"
1310 | version = "0.3.2"
1311 | source = "registry+https://github.com/rust-lang/crates.io-index"
1312 | checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
1313 |
1314 | [[package]]
1315 | name = "libc"
1316 | version = "0.2.161"
1317 | source = "registry+https://github.com/rust-lang/crates.io-index"
1318 | checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
1319 |
1320 | [[package]]
1321 | name = "libm"
1322 | version = "0.2.11"
1323 | source = "registry+https://github.com/rust-lang/crates.io-index"
1324 | checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
1325 |
1326 | [[package]]
1327 | name = "linux-raw-sys"
1328 | version = "0.4.14"
1329 | source = "registry+https://github.com/rust-lang/crates.io-index"
1330 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
1331 |
1332 | [[package]]
1333 | name = "local-channel"
1334 | version = "0.1.5"
1335 | source = "registry+https://github.com/rust-lang/crates.io-index"
1336 | checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8"
1337 | dependencies = [
1338 | "futures-core",
1339 | "futures-sink",
1340 | "local-waker",
1341 | ]
1342 |
1343 | [[package]]
1344 | name = "local-waker"
1345 | version = "0.1.4"
1346 | source = "registry+https://github.com/rust-lang/crates.io-index"
1347 | checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487"
1348 |
1349 | [[package]]
1350 | name = "lock_api"
1351 | version = "0.4.12"
1352 | source = "registry+https://github.com/rust-lang/crates.io-index"
1353 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
1354 | dependencies = [
1355 | "autocfg",
1356 | "scopeguard",
1357 | ]
1358 |
1359 | [[package]]
1360 | name = "log"
1361 | version = "0.4.22"
1362 | source = "registry+https://github.com/rust-lang/crates.io-index"
1363 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
1364 |
1365 | [[package]]
1366 | name = "lz4"
1367 | version = "1.28.0"
1368 | source = "registry+https://github.com/rust-lang/crates.io-index"
1369 | checksum = "4d1febb2b4a79ddd1980eede06a8f7902197960aa0383ffcfdd62fe723036725"
1370 | dependencies = [
1371 | "lz4-sys",
1372 | ]
1373 |
1374 | [[package]]
1375 | name = "lz4-sys"
1376 | version = "1.11.1+lz4-1.10.0"
1377 | source = "registry+https://github.com/rust-lang/crates.io-index"
1378 | checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6"
1379 | dependencies = [
1380 | "cc",
1381 | "libc",
1382 | ]
1383 |
1384 | [[package]]
1385 | name = "memchr"
1386 | version = "2.7.4"
1387 | source = "registry+https://github.com/rust-lang/crates.io-index"
1388 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
1389 |
1390 | [[package]]
1391 | name = "memmap2"
1392 | version = "0.7.1"
1393 | source = "registry+https://github.com/rust-lang/crates.io-index"
1394 | checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6"
1395 | dependencies = [
1396 | "libc",
1397 | ]
1398 |
1399 | [[package]]
1400 | name = "mime"
1401 | version = "0.3.17"
1402 | source = "registry+https://github.com/rust-lang/crates.io-index"
1403 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
1404 |
1405 | [[package]]
1406 | name = "miniz_oxide"
1407 | version = "0.8.0"
1408 | source = "registry+https://github.com/rust-lang/crates.io-index"
1409 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
1410 | dependencies = [
1411 | "adler2",
1412 | ]
1413 |
1414 | [[package]]
1415 | name = "mio"
1416 | version = "1.0.2"
1417 | source = "registry+https://github.com/rust-lang/crates.io-index"
1418 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
1419 | dependencies = [
1420 | "hermit-abi",
1421 | "libc",
1422 | "log",
1423 | "wasi",
1424 | "windows-sys 0.52.0",
1425 | ]
1426 |
1427 | [[package]]
1428 | name = "multiversion"
1429 | version = "0.7.4"
1430 | source = "registry+https://github.com/rust-lang/crates.io-index"
1431 | checksum = "c4851161a11d3ad0bf9402d90ffc3967bf231768bfd7aeb61755ad06dbf1a142"
1432 | dependencies = [
1433 | "multiversion-macros",
1434 | "target-features",
1435 | ]
1436 |
1437 | [[package]]
1438 | name = "multiversion-macros"
1439 | version = "0.7.4"
1440 | source = "registry+https://github.com/rust-lang/crates.io-index"
1441 | checksum = "79a74ddee9e0c27d2578323c13905793e91622148f138ba29738f9dddb835e90"
1442 | dependencies = [
1443 | "proc-macro2",
1444 | "quote",
1445 | "syn 1.0.109",
1446 | "target-features",
1447 | ]
1448 |
1449 | [[package]]
1450 | name = "native-tls"
1451 | version = "0.2.12"
1452 | source = "registry+https://github.com/rust-lang/crates.io-index"
1453 | checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
1454 | dependencies = [
1455 | "libc",
1456 | "log",
1457 | "openssl",
1458 | "openssl-probe",
1459 | "openssl-sys",
1460 | "schannel",
1461 | "security-framework",
1462 | "security-framework-sys",
1463 | "tempfile",
1464 | ]
1465 |
1466 | [[package]]
1467 | name = "now"
1468 | version = "0.1.3"
1469 | source = "registry+https://github.com/rust-lang/crates.io-index"
1470 | checksum = "6d89e9874397a1f0a52fc1f197a8effd9735223cb2390e9dcc83ac6cd02923d0"
1471 | dependencies = [
1472 | "chrono",
1473 | ]
1474 |
1475 | [[package]]
1476 | name = "ntapi"
1477 | version = "0.4.1"
1478 | source = "registry+https://github.com/rust-lang/crates.io-index"
1479 | checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
1480 | dependencies = [
1481 | "winapi",
1482 | ]
1483 |
1484 | [[package]]
1485 | name = "num-conv"
1486 | version = "0.1.0"
1487 | source = "registry+https://github.com/rust-lang/crates.io-index"
1488 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
1489 |
1490 | [[package]]
1491 | name = "num-traits"
1492 | version = "0.2.19"
1493 | source = "registry+https://github.com/rust-lang/crates.io-index"
1494 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
1495 | dependencies = [
1496 | "autocfg",
1497 | "libm",
1498 | ]
1499 |
1500 | [[package]]
1501 | name = "object"
1502 | version = "0.36.5"
1503 | source = "registry+https://github.com/rust-lang/crates.io-index"
1504 | checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
1505 | dependencies = [
1506 | "memchr",
1507 | ]
1508 |
1509 | [[package]]
1510 | name = "once_cell"
1511 | version = "1.20.2"
1512 | source = "registry+https://github.com/rust-lang/crates.io-index"
1513 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
1514 |
1515 | [[package]]
1516 | name = "openssl"
1517 | version = "0.10.68"
1518 | source = "registry+https://github.com/rust-lang/crates.io-index"
1519 | checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
1520 | dependencies = [
1521 | "bitflags",
1522 | "cfg-if",
1523 | "foreign-types",
1524 | "libc",
1525 | "once_cell",
1526 | "openssl-macros",
1527 | "openssl-sys",
1528 | ]
1529 |
1530 | [[package]]
1531 | name = "openssl-macros"
1532 | version = "0.1.1"
1533 | source = "registry+https://github.com/rust-lang/crates.io-index"
1534 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
1535 | dependencies = [
1536 | "proc-macro2",
1537 | "quote",
1538 | "syn 2.0.85",
1539 | ]
1540 |
1541 | [[package]]
1542 | name = "openssl-probe"
1543 | version = "0.1.5"
1544 | source = "registry+https://github.com/rust-lang/crates.io-index"
1545 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
1546 |
1547 | [[package]]
1548 | name = "openssl-sys"
1549 | version = "0.9.104"
1550 | source = "registry+https://github.com/rust-lang/crates.io-index"
1551 | checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
1552 | dependencies = [
1553 | "cc",
1554 | "libc",
1555 | "pkg-config",
1556 | "vcpkg",
1557 | ]
1558 |
1559 | [[package]]
1560 | name = "parking_lot"
1561 | version = "0.12.3"
1562 | source = "registry+https://github.com/rust-lang/crates.io-index"
1563 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
1564 | dependencies = [
1565 | "lock_api",
1566 | "parking_lot_core",
1567 | ]
1568 |
1569 | [[package]]
1570 | name = "parking_lot_core"
1571 | version = "0.9.10"
1572 | source = "registry+https://github.com/rust-lang/crates.io-index"
1573 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
1574 | dependencies = [
1575 | "cfg-if",
1576 | "libc",
1577 | "redox_syscall",
1578 | "smallvec",
1579 | "windows-targets",
1580 | ]
1581 |
1582 | [[package]]
1583 | name = "parquet-format-safe"
1584 | version = "0.2.4"
1585 | source = "registry+https://github.com/rust-lang/crates.io-index"
1586 | checksum = "1131c54b167dd4e4799ce762e1ab01549ebb94d5bdd13e6ec1b467491c378e1f"
1587 | dependencies = [
1588 | "async-trait",
1589 | "futures",
1590 | ]
1591 |
1592 | [[package]]
1593 | name = "paste"
1594 | version = "1.0.15"
1595 | source = "registry+https://github.com/rust-lang/crates.io-index"
1596 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
1597 |
1598 | [[package]]
1599 | name = "percent-encoding"
1600 | version = "2.3.1"
1601 | source = "registry+https://github.com/rust-lang/crates.io-index"
1602 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
1603 |
1604 | [[package]]
1605 | name = "pin-project-lite"
1606 | version = "0.2.15"
1607 | source = "registry+https://github.com/rust-lang/crates.io-index"
1608 | checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
1609 |
1610 | [[package]]
1611 | name = "pin-utils"
1612 | version = "0.1.0"
1613 | source = "registry+https://github.com/rust-lang/crates.io-index"
1614 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1615 |
1616 | [[package]]
1617 | name = "pkg-config"
1618 | version = "0.3.31"
1619 | source = "registry+https://github.com/rust-lang/crates.io-index"
1620 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
1621 |
1622 | [[package]]
1623 | name = "planus"
1624 | version = "0.3.1"
1625 | source = "registry+https://github.com/rust-lang/crates.io-index"
1626 | checksum = "fc1691dd09e82f428ce8d6310bd6d5da2557c82ff17694d2a32cad7242aea89f"
1627 | dependencies = [
1628 | "array-init-cursor",
1629 | ]
1630 |
1631 | [[package]]
1632 | name = "polars"
1633 | version = "0.35.4"
1634 | source = "registry+https://github.com/rust-lang/crates.io-index"
1635 | checksum = "df8e52f9236eb722da0990a70bbb1216dcc7a77bcb00c63439d2d982823e90d5"
1636 | dependencies = [
1637 | "getrandom",
1638 | "polars-core",
1639 | "polars-io",
1640 | "polars-lazy",
1641 | "polars-ops",
1642 | "polars-sql",
1643 | "polars-time",
1644 | "version_check",
1645 | ]
1646 |
1647 | [[package]]
1648 | name = "polars-arrow"
1649 | version = "0.35.4"
1650 | source = "registry+https://github.com/rust-lang/crates.io-index"
1651 | checksum = "dd503430a6d9779b07915d858865fe998317ef3cfef8973881f578ac5d4baae7"
1652 | dependencies = [
1653 | "ahash",
1654 | "arrow-format",
1655 | "atoi_simd",
1656 | "bytemuck",
1657 | "chrono",
1658 | "dyn-clone",
1659 | "either",
1660 | "ethnum",
1661 | "fast-float",
1662 | "foreign_vec",
1663 | "futures",
1664 | "getrandom",
1665 | "hashbrown 0.14.5",
1666 | "itoa",
1667 | "lz4",
1668 | "multiversion",
1669 | "num-traits",
1670 | "polars-error",
1671 | "polars-utils",
1672 | "rustc_version",
1673 | "ryu",
1674 | "simdutf8",
1675 | "streaming-iterator",
1676 | "strength_reduce",
1677 | "zstd",
1678 | ]
1679 |
1680 | [[package]]
1681 | name = "polars-core"
1682 | version = "0.35.4"
1683 | source = "registry+https://github.com/rust-lang/crates.io-index"
1684 | checksum = "ae73d5b8e55decde670caba1cc82b61f14bfb9a72503198f0997d657a98dcfd6"
1685 | dependencies = [
1686 | "ahash",
1687 | "bitflags",
1688 | "bytemuck",
1689 | "chrono",
1690 | "comfy-table",
1691 | "either",
1692 | "hashbrown 0.14.5",
1693 | "indexmap",
1694 | "num-traits",
1695 | "once_cell",
1696 | "polars-arrow",
1697 | "polars-error",
1698 | "polars-row",
1699 | "polars-utils",
1700 | "rand",
1701 | "rand_distr",
1702 | "rayon",
1703 | "regex",
1704 | "smartstring",
1705 | "thiserror",
1706 | "version_check",
1707 | "xxhash-rust",
1708 | ]
1709 |
1710 | [[package]]
1711 | name = "polars-error"
1712 | version = "0.35.4"
1713 | source = "registry+https://github.com/rust-lang/crates.io-index"
1714 | checksum = "eb0520d68eaa9993ae0c741409d1526beff5b8f48e1d73e4381616f8152cf488"
1715 | dependencies = [
1716 | "arrow-format",
1717 | "regex",
1718 | "simdutf8",
1719 | "thiserror",
1720 | ]
1721 |
1722 | [[package]]
1723 | name = "polars-io"
1724 | version = "0.35.4"
1725 | source = "registry+https://github.com/rust-lang/crates.io-index"
1726 | checksum = "96e10a0745acd6009db64bef0ceb9e23a70b1c27b26a0a6517c91f3e6363bc06"
1727 | dependencies = [
1728 | "ahash",
1729 | "async-trait",
1730 | "atoi_simd",
1731 | "bytes",
1732 | "chrono",
1733 | "fast-float",
1734 | "futures",
1735 | "home",
1736 | "itoa",
1737 | "memchr",
1738 | "memmap2",
1739 | "num-traits",
1740 | "once_cell",
1741 | "percent-encoding",
1742 | "polars-arrow",
1743 | "polars-core",
1744 | "polars-error",
1745 | "polars-parquet",
1746 | "polars-time",
1747 | "polars-utils",
1748 | "rayon",
1749 | "regex",
1750 | "ryu",
1751 | "simdutf8",
1752 | "smartstring",
1753 | "tokio",
1754 | "tokio-util",
1755 | ]
1756 |
1757 | [[package]]
1758 | name = "polars-lazy"
1759 | version = "0.35.4"
1760 | source = "registry+https://github.com/rust-lang/crates.io-index"
1761 | checksum = "3555f759705be6dd0d3762d16a0b8787b2dc4da73b57465f3b2bf1a070ba8f20"
1762 | dependencies = [
1763 | "ahash",
1764 | "bitflags",
1765 | "glob",
1766 | "once_cell",
1767 | "polars-arrow",
1768 | "polars-core",
1769 | "polars-io",
1770 | "polars-ops",
1771 | "polars-pipe",
1772 | "polars-plan",
1773 | "polars-time",
1774 | "polars-utils",
1775 | "rayon",
1776 | "smartstring",
1777 | "version_check",
1778 | ]
1779 |
1780 | [[package]]
1781 | name = "polars-ops"
1782 | version = "0.35.4"
1783 | source = "registry+https://github.com/rust-lang/crates.io-index"
1784 | checksum = "1a7eb218296aaa7f79945f08288ca32ca3cf25fa505649eeee689ec21eebf636"
1785 | dependencies = [
1786 | "ahash",
1787 | "argminmax",
1788 | "bytemuck",
1789 | "either",
1790 | "hashbrown 0.14.5",
1791 | "indexmap",
1792 | "memchr",
1793 | "num-traits",
1794 | "polars-arrow",
1795 | "polars-core",
1796 | "polars-error",
1797 | "polars-utils",
1798 | "rayon",
1799 | "regex",
1800 | "smartstring",
1801 | "version_check",
1802 | ]
1803 |
1804 | [[package]]
1805 | name = "polars-parquet"
1806 | version = "0.35.4"
1807 | source = "registry+https://github.com/rust-lang/crates.io-index"
1808 | checksum = "146010e4b7dd4d2d0e58ddc762f6361f77d7a0385c54471199370c17164f67dd"
1809 | dependencies = [
1810 | "ahash",
1811 | "async-stream",
1812 | "base64 0.21.7",
1813 | "brotli 3.5.0",
1814 | "ethnum",
1815 | "flate2",
1816 | "futures",
1817 | "lz4",
1818 | "num-traits",
1819 | "parquet-format-safe",
1820 | "polars-arrow",
1821 | "polars-error",
1822 | "polars-utils",
1823 | "seq-macro",
1824 | "simdutf8",
1825 | "snap",
1826 | "streaming-decompression",
1827 | "zstd",
1828 | ]
1829 |
1830 | [[package]]
1831 | name = "polars-pipe"
1832 | version = "0.35.4"
1833 | source = "registry+https://github.com/rust-lang/crates.io-index"
1834 | checksum = "66094e7df64c932a9a7bdfe7df0c65efdcb192096e11a6a765a9778f78b4bdec"
1835 | dependencies = [
1836 | "crossbeam-channel",
1837 | "crossbeam-queue",
1838 | "enum_dispatch",
1839 | "hashbrown 0.14.5",
1840 | "num-traits",
1841 | "polars-arrow",
1842 | "polars-core",
1843 | "polars-io",
1844 | "polars-ops",
1845 | "polars-plan",
1846 | "polars-row",
1847 | "polars-utils",
1848 | "rayon",
1849 | "smartstring",
1850 | "version_check",
1851 | ]
1852 |
1853 | [[package]]
1854 | name = "polars-plan"
1855 | version = "0.35.4"
1856 | source = "registry+https://github.com/rust-lang/crates.io-index"
1857 | checksum = "10e32a0958ef854b132bad7f8369cb3237254635d5e864c99505bc0bc1035fbc"
1858 | dependencies = [
1859 | "ahash",
1860 | "bytemuck",
1861 | "once_cell",
1862 | "percent-encoding",
1863 | "polars-arrow",
1864 | "polars-core",
1865 | "polars-io",
1866 | "polars-ops",
1867 | "polars-parquet",
1868 | "polars-time",
1869 | "polars-utils",
1870 | "rayon",
1871 | "regex",
1872 | "smartstring",
1873 | "strum_macros 0.25.3",
1874 | "version_check",
1875 | ]
1876 |
1877 | [[package]]
1878 | name = "polars-row"
1879 | version = "0.35.4"
1880 | source = "registry+https://github.com/rust-lang/crates.io-index"
1881 | checksum = "d135ab81cac2906ba74ea8984c7e6025d081ae5867615bcefb4d84dfdb456dac"
1882 | dependencies = [
1883 | "polars-arrow",
1884 | "polars-error",
1885 | "polars-utils",
1886 | ]
1887 |
1888 | [[package]]
1889 | name = "polars-sql"
1890 | version = "0.35.4"
1891 | source = "registry+https://github.com/rust-lang/crates.io-index"
1892 | checksum = "b8dbd7786849a5e3ad1fde188bf38141632f626e3a57319b0bbf7a5f1d75519e"
1893 | dependencies = [
1894 | "polars-arrow",
1895 | "polars-core",
1896 | "polars-error",
1897 | "polars-lazy",
1898 | "polars-plan",
1899 | "rand",
1900 | "serde",
1901 | "serde_json",
1902 | "sqlparser",
1903 | ]
1904 |
1905 | [[package]]
1906 | name = "polars-time"
1907 | version = "0.35.4"
1908 | source = "registry+https://github.com/rust-lang/crates.io-index"
1909 | checksum = "aae56f79e9cedd617773c1c8f5ca84a31a8b1d593714959d5f799e7bdd98fe51"
1910 | dependencies = [
1911 | "atoi",
1912 | "chrono",
1913 | "now",
1914 | "once_cell",
1915 | "polars-arrow",
1916 | "polars-core",
1917 | "polars-error",
1918 | "polars-ops",
1919 | "polars-utils",
1920 | "regex",
1921 | "smartstring",
1922 | ]
1923 |
1924 | [[package]]
1925 | name = "polars-utils"
1926 | version = "0.35.4"
1927 | source = "registry+https://github.com/rust-lang/crates.io-index"
1928 | checksum = "da6ce68169fe61d46958c8eab7447360f30f2f23f6e24a0ce703a14b0a3cfbfc"
1929 | dependencies = [
1930 | "ahash",
1931 | "bytemuck",
1932 | "hashbrown 0.14.5",
1933 | "indexmap",
1934 | "num-traits",
1935 | "once_cell",
1936 | "polars-error",
1937 | "rayon",
1938 | "smartstring",
1939 | "sysinfo",
1940 | "version_check",
1941 | ]
1942 |
1943 | [[package]]
1944 | name = "powerfmt"
1945 | version = "0.2.0"
1946 | source = "registry+https://github.com/rust-lang/crates.io-index"
1947 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
1948 |
1949 | [[package]]
1950 | name = "ppv-lite86"
1951 | version = "0.2.20"
1952 | source = "registry+https://github.com/rust-lang/crates.io-index"
1953 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
1954 | dependencies = [
1955 | "zerocopy",
1956 | ]
1957 |
1958 | [[package]]
1959 | name = "proc-macro2"
1960 | version = "1.0.89"
1961 | source = "registry+https://github.com/rust-lang/crates.io-index"
1962 | checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
1963 | dependencies = [
1964 | "unicode-ident",
1965 | ]
1966 |
1967 | [[package]]
1968 | name = "quote"
1969 | version = "1.0.37"
1970 | source = "registry+https://github.com/rust-lang/crates.io-index"
1971 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
1972 | dependencies = [
1973 | "proc-macro2",
1974 | ]
1975 |
1976 | [[package]]
1977 | name = "rand"
1978 | version = "0.8.5"
1979 | source = "registry+https://github.com/rust-lang/crates.io-index"
1980 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
1981 | dependencies = [
1982 | "libc",
1983 | "rand_chacha",
1984 | "rand_core",
1985 | ]
1986 |
1987 | [[package]]
1988 | name = "rand_chacha"
1989 | version = "0.3.1"
1990 | source = "registry+https://github.com/rust-lang/crates.io-index"
1991 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1992 | dependencies = [
1993 | "ppv-lite86",
1994 | "rand_core",
1995 | ]
1996 |
1997 | [[package]]
1998 | name = "rand_core"
1999 | version = "0.6.4"
2000 | source = "registry+https://github.com/rust-lang/crates.io-index"
2001 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
2002 | dependencies = [
2003 | "getrandom",
2004 | ]
2005 |
2006 | [[package]]
2007 | name = "rand_distr"
2008 | version = "0.4.3"
2009 | source = "registry+https://github.com/rust-lang/crates.io-index"
2010 | checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
2011 | dependencies = [
2012 | "num-traits",
2013 | "rand",
2014 | ]
2015 |
2016 | [[package]]
2017 | name = "rayon"
2018 | version = "1.10.0"
2019 | source = "registry+https://github.com/rust-lang/crates.io-index"
2020 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
2021 | dependencies = [
2022 | "either",
2023 | "rayon-core",
2024 | ]
2025 |
2026 | [[package]]
2027 | name = "rayon-core"
2028 | version = "1.12.1"
2029 | source = "registry+https://github.com/rust-lang/crates.io-index"
2030 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
2031 | dependencies = [
2032 | "crossbeam-deque",
2033 | "crossbeam-utils",
2034 | ]
2035 |
2036 | [[package]]
2037 | name = "redox_syscall"
2038 | version = "0.5.7"
2039 | source = "registry+https://github.com/rust-lang/crates.io-index"
2040 | checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
2041 | dependencies = [
2042 | "bitflags",
2043 | ]
2044 |
2045 | [[package]]
2046 | name = "regex"
2047 | version = "1.11.1"
2048 | source = "registry+https://github.com/rust-lang/crates.io-index"
2049 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
2050 | dependencies = [
2051 | "aho-corasick",
2052 | "memchr",
2053 | "regex-automata",
2054 | "regex-syntax",
2055 | ]
2056 |
2057 | [[package]]
2058 | name = "regex-automata"
2059 | version = "0.4.8"
2060 | source = "registry+https://github.com/rust-lang/crates.io-index"
2061 | checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
2062 | dependencies = [
2063 | "aho-corasick",
2064 | "memchr",
2065 | "regex-syntax",
2066 | ]
2067 |
2068 | [[package]]
2069 | name = "regex-lite"
2070 | version = "0.1.6"
2071 | source = "registry+https://github.com/rust-lang/crates.io-index"
2072 | checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a"
2073 |
2074 | [[package]]
2075 | name = "regex-syntax"
2076 | version = "0.8.5"
2077 | source = "registry+https://github.com/rust-lang/crates.io-index"
2078 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
2079 |
2080 | [[package]]
2081 | name = "reqwest"
2082 | version = "0.12.9"
2083 | source = "registry+https://github.com/rust-lang/crates.io-index"
2084 | checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f"
2085 | dependencies = [
2086 | "base64 0.22.1",
2087 | "bytes",
2088 | "encoding_rs",
2089 | "futures-core",
2090 | "futures-util",
2091 | "h2 0.4.6",
2092 | "http 1.1.0",
2093 | "http-body",
2094 | "http-body-util",
2095 | "hyper",
2096 | "hyper-rustls",
2097 | "hyper-tls",
2098 | "hyper-util",
2099 | "ipnet",
2100 | "js-sys",
2101 | "log",
2102 | "mime",
2103 | "native-tls",
2104 | "once_cell",
2105 | "percent-encoding",
2106 | "pin-project-lite",
2107 | "rustls-pemfile",
2108 | "serde",
2109 | "serde_json",
2110 | "serde_urlencoded",
2111 | "sync_wrapper",
2112 | "system-configuration",
2113 | "tokio",
2114 | "tokio-native-tls",
2115 | "tower-service",
2116 | "url",
2117 | "wasm-bindgen",
2118 | "wasm-bindgen-futures",
2119 | "web-sys",
2120 | "windows-registry",
2121 | ]
2122 |
2123 | [[package]]
2124 | name = "ring"
2125 | version = "0.17.8"
2126 | source = "registry+https://github.com/rust-lang/crates.io-index"
2127 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
2128 | dependencies = [
2129 | "cc",
2130 | "cfg-if",
2131 | "getrandom",
2132 | "libc",
2133 | "spin",
2134 | "untrusted",
2135 | "windows-sys 0.52.0",
2136 | ]
2137 |
2138 | [[package]]
2139 | name = "rustc-demangle"
2140 | version = "0.1.24"
2141 | source = "registry+https://github.com/rust-lang/crates.io-index"
2142 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
2143 |
2144 | [[package]]
2145 | name = "rustc_version"
2146 | version = "0.4.1"
2147 | source = "registry+https://github.com/rust-lang/crates.io-index"
2148 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
2149 | dependencies = [
2150 | "semver",
2151 | ]
2152 |
2153 | [[package]]
2154 | name = "rustix"
2155 | version = "0.38.38"
2156 | source = "registry+https://github.com/rust-lang/crates.io-index"
2157 | checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a"
2158 | dependencies = [
2159 | "bitflags",
2160 | "errno",
2161 | "libc",
2162 | "linux-raw-sys",
2163 | "windows-sys 0.52.0",
2164 | ]
2165 |
2166 | [[package]]
2167 | name = "rustls"
2168 | version = "0.23.16"
2169 | source = "registry+https://github.com/rust-lang/crates.io-index"
2170 | checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e"
2171 | dependencies = [
2172 | "once_cell",
2173 | "rustls-pki-types",
2174 | "rustls-webpki",
2175 | "subtle",
2176 | "zeroize",
2177 | ]
2178 |
2179 | [[package]]
2180 | name = "rustls-pemfile"
2181 | version = "2.2.0"
2182 | source = "registry+https://github.com/rust-lang/crates.io-index"
2183 | checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
2184 | dependencies = [
2185 | "rustls-pki-types",
2186 | ]
2187 |
2188 | [[package]]
2189 | name = "rustls-pki-types"
2190 | version = "1.10.0"
2191 | source = "registry+https://github.com/rust-lang/crates.io-index"
2192 | checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
2193 |
2194 | [[package]]
2195 | name = "rustls-webpki"
2196 | version = "0.102.8"
2197 | source = "registry+https://github.com/rust-lang/crates.io-index"
2198 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
2199 | dependencies = [
2200 | "ring",
2201 | "rustls-pki-types",
2202 | "untrusted",
2203 | ]
2204 |
2205 | [[package]]
2206 | name = "rustversion"
2207 | version = "1.0.18"
2208 | source = "registry+https://github.com/rust-lang/crates.io-index"
2209 | checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
2210 |
2211 | [[package]]
2212 | name = "ryu"
2213 | version = "1.0.18"
2214 | source = "registry+https://github.com/rust-lang/crates.io-index"
2215 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
2216 |
2217 | [[package]]
2218 | name = "schannel"
2219 | version = "0.1.26"
2220 | source = "registry+https://github.com/rust-lang/crates.io-index"
2221 | checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1"
2222 | dependencies = [
2223 | "windows-sys 0.59.0",
2224 | ]
2225 |
2226 | [[package]]
2227 | name = "scopeguard"
2228 | version = "1.2.0"
2229 | source = "registry+https://github.com/rust-lang/crates.io-index"
2230 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
2231 |
2232 | [[package]]
2233 | name = "security-framework"
2234 | version = "2.11.1"
2235 | source = "registry+https://github.com/rust-lang/crates.io-index"
2236 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
2237 | dependencies = [
2238 | "bitflags",
2239 | "core-foundation",
2240 | "core-foundation-sys",
2241 | "libc",
2242 | "security-framework-sys",
2243 | ]
2244 |
2245 | [[package]]
2246 | name = "security-framework-sys"
2247 | version = "2.12.0"
2248 | source = "registry+https://github.com/rust-lang/crates.io-index"
2249 | checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6"
2250 | dependencies = [
2251 | "core-foundation-sys",
2252 | "libc",
2253 | ]
2254 |
2255 | [[package]]
2256 | name = "semver"
2257 | version = "1.0.23"
2258 | source = "registry+https://github.com/rust-lang/crates.io-index"
2259 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
2260 |
2261 | [[package]]
2262 | name = "seq-macro"
2263 | version = "0.3.5"
2264 | source = "registry+https://github.com/rust-lang/crates.io-index"
2265 | checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4"
2266 |
2267 | [[package]]
2268 | name = "serde"
2269 | version = "1.0.214"
2270 | source = "registry+https://github.com/rust-lang/crates.io-index"
2271 | checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
2272 | dependencies = [
2273 | "serde_derive",
2274 | ]
2275 |
2276 | [[package]]
2277 | name = "serde_derive"
2278 | version = "1.0.214"
2279 | source = "registry+https://github.com/rust-lang/crates.io-index"
2280 | checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
2281 | dependencies = [
2282 | "proc-macro2",
2283 | "quote",
2284 | "syn 2.0.85",
2285 | ]
2286 |
2287 | [[package]]
2288 | name = "serde_json"
2289 | version = "1.0.132"
2290 | source = "registry+https://github.com/rust-lang/crates.io-index"
2291 | checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
2292 | dependencies = [
2293 | "itoa",
2294 | "memchr",
2295 | "ryu",
2296 | "serde",
2297 | ]
2298 |
2299 | [[package]]
2300 | name = "serde_urlencoded"
2301 | version = "0.7.1"
2302 | source = "registry+https://github.com/rust-lang/crates.io-index"
2303 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
2304 | dependencies = [
2305 | "form_urlencoded",
2306 | "itoa",
2307 | "ryu",
2308 | "serde",
2309 | ]
2310 |
2311 | [[package]]
2312 | name = "sha1"
2313 | version = "0.10.6"
2314 | source = "registry+https://github.com/rust-lang/crates.io-index"
2315 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
2316 | dependencies = [
2317 | "cfg-if",
2318 | "cpufeatures",
2319 | "digest",
2320 | ]
2321 |
2322 | [[package]]
2323 | name = "shlex"
2324 | version = "1.3.0"
2325 | source = "registry+https://github.com/rust-lang/crates.io-index"
2326 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
2327 |
2328 | [[package]]
2329 | name = "signal-hook-registry"
2330 | version = "1.4.2"
2331 | source = "registry+https://github.com/rust-lang/crates.io-index"
2332 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
2333 | dependencies = [
2334 | "libc",
2335 | ]
2336 |
2337 | [[package]]
2338 | name = "simdutf8"
2339 | version = "0.1.5"
2340 | source = "registry+https://github.com/rust-lang/crates.io-index"
2341 | checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
2342 |
2343 | [[package]]
2344 | name = "slab"
2345 | version = "0.4.9"
2346 | source = "registry+https://github.com/rust-lang/crates.io-index"
2347 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
2348 | dependencies = [
2349 | "autocfg",
2350 | ]
2351 |
2352 | [[package]]
2353 | name = "smallvec"
2354 | version = "1.13.2"
2355 | source = "registry+https://github.com/rust-lang/crates.io-index"
2356 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
2357 |
2358 | [[package]]
2359 | name = "smartstring"
2360 | version = "1.0.1"
2361 | source = "registry+https://github.com/rust-lang/crates.io-index"
2362 | checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
2363 | dependencies = [
2364 | "autocfg",
2365 | "static_assertions",
2366 | "version_check",
2367 | ]
2368 |
2369 | [[package]]
2370 | name = "snap"
2371 | version = "1.1.1"
2372 | source = "registry+https://github.com/rust-lang/crates.io-index"
2373 | checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b"
2374 |
2375 | [[package]]
2376 | name = "socket2"
2377 | version = "0.5.7"
2378 | source = "registry+https://github.com/rust-lang/crates.io-index"
2379 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
2380 | dependencies = [
2381 | "libc",
2382 | "windows-sys 0.52.0",
2383 | ]
2384 |
2385 | [[package]]
2386 | name = "spin"
2387 | version = "0.9.8"
2388 | source = "registry+https://github.com/rust-lang/crates.io-index"
2389 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
2390 |
2391 | [[package]]
2392 | name = "sqlparser"
2393 | version = "0.39.0"
2394 | source = "registry+https://github.com/rust-lang/crates.io-index"
2395 | checksum = "743b4dc2cbde11890ccb254a8fc9d537fa41b36da00de2a1c5e9848c9bc42bd7"
2396 | dependencies = [
2397 | "log",
2398 | ]
2399 |
2400 | [[package]]
2401 | name = "static_assertions"
2402 | version = "1.1.0"
2403 | source = "registry+https://github.com/rust-lang/crates.io-index"
2404 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
2405 |
2406 | [[package]]
2407 | name = "streaming-decompression"
2408 | version = "0.1.2"
2409 | source = "registry+https://github.com/rust-lang/crates.io-index"
2410 | checksum = "bf6cc3b19bfb128a8ad11026086e31d3ce9ad23f8ea37354b31383a187c44cf3"
2411 | dependencies = [
2412 | "fallible-streaming-iterator",
2413 | ]
2414 |
2415 | [[package]]
2416 | name = "streaming-iterator"
2417 | version = "0.1.9"
2418 | source = "registry+https://github.com/rust-lang/crates.io-index"
2419 | checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
2420 |
2421 | [[package]]
2422 | name = "strength_reduce"
2423 | version = "0.2.4"
2424 | source = "registry+https://github.com/rust-lang/crates.io-index"
2425 | checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82"
2426 |
2427 | [[package]]
2428 | name = "strum"
2429 | version = "0.26.3"
2430 | source = "registry+https://github.com/rust-lang/crates.io-index"
2431 | checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
2432 |
2433 | [[package]]
2434 | name = "strum_macros"
2435 | version = "0.25.3"
2436 | source = "registry+https://github.com/rust-lang/crates.io-index"
2437 | checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
2438 | dependencies = [
2439 | "heck 0.4.1",
2440 | "proc-macro2",
2441 | "quote",
2442 | "rustversion",
2443 | "syn 2.0.85",
2444 | ]
2445 |
2446 | [[package]]
2447 | name = "strum_macros"
2448 | version = "0.26.4"
2449 | source = "registry+https://github.com/rust-lang/crates.io-index"
2450 | checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
2451 | dependencies = [
2452 | "heck 0.5.0",
2453 | "proc-macro2",
2454 | "quote",
2455 | "rustversion",
2456 | "syn 2.0.85",
2457 | ]
2458 |
2459 | [[package]]
2460 | name = "subtle"
2461 | version = "2.6.1"
2462 | source = "registry+https://github.com/rust-lang/crates.io-index"
2463 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
2464 |
2465 | [[package]]
2466 | name = "syn"
2467 | version = "1.0.109"
2468 | source = "registry+https://github.com/rust-lang/crates.io-index"
2469 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
2470 | dependencies = [
2471 | "proc-macro2",
2472 | "quote",
2473 | "unicode-ident",
2474 | ]
2475 |
2476 | [[package]]
2477 | name = "syn"
2478 | version = "2.0.85"
2479 | source = "registry+https://github.com/rust-lang/crates.io-index"
2480 | checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
2481 | dependencies = [
2482 | "proc-macro2",
2483 | "quote",
2484 | "unicode-ident",
2485 | ]
2486 |
2487 | [[package]]
2488 | name = "sync_wrapper"
2489 | version = "1.0.1"
2490 | source = "registry+https://github.com/rust-lang/crates.io-index"
2491 | checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
2492 | dependencies = [
2493 | "futures-core",
2494 | ]
2495 |
2496 | [[package]]
2497 | name = "sysinfo"
2498 | version = "0.29.11"
2499 | source = "registry+https://github.com/rust-lang/crates.io-index"
2500 | checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666"
2501 | dependencies = [
2502 | "cfg-if",
2503 | "core-foundation-sys",
2504 | "libc",
2505 | "ntapi",
2506 | "once_cell",
2507 | "winapi",
2508 | ]
2509 |
2510 | [[package]]
2511 | name = "system-configuration"
2512 | version = "0.6.1"
2513 | source = "registry+https://github.com/rust-lang/crates.io-index"
2514 | checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
2515 | dependencies = [
2516 | "bitflags",
2517 | "core-foundation",
2518 | "system-configuration-sys",
2519 | ]
2520 |
2521 | [[package]]
2522 | name = "system-configuration-sys"
2523 | version = "0.6.0"
2524 | source = "registry+https://github.com/rust-lang/crates.io-index"
2525 | checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
2526 | dependencies = [
2527 | "core-foundation-sys",
2528 | "libc",
2529 | ]
2530 |
2531 | [[package]]
2532 | name = "target-features"
2533 | version = "0.1.6"
2534 | source = "registry+https://github.com/rust-lang/crates.io-index"
2535 | checksum = "c1bbb9f3c5c463a01705937a24fdabc5047929ac764b2d5b9cf681c1f5041ed5"
2536 |
2537 | [[package]]
2538 | name = "taxi-data-api-rust"
2539 | version = "0.1.0"
2540 | dependencies = [
2541 | "actix-web",
2542 | "anyhow",
2543 | "chrono",
2544 | "env_logger",
2545 | "log",
2546 | "polars",
2547 | "rand",
2548 | "reqwest",
2549 | "serde",
2550 | "serde_json",
2551 | "tokio",
2552 | ]
2553 |
2554 | [[package]]
2555 | name = "tempfile"
2556 | version = "3.13.0"
2557 | source = "registry+https://github.com/rust-lang/crates.io-index"
2558 | checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
2559 | dependencies = [
2560 | "cfg-if",
2561 | "fastrand",
2562 | "once_cell",
2563 | "rustix",
2564 | "windows-sys 0.59.0",
2565 | ]
2566 |
2567 | [[package]]
2568 | name = "thiserror"
2569 | version = "1.0.65"
2570 | source = "registry+https://github.com/rust-lang/crates.io-index"
2571 | checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
2572 | dependencies = [
2573 | "thiserror-impl",
2574 | ]
2575 |
2576 | [[package]]
2577 | name = "thiserror-impl"
2578 | version = "1.0.65"
2579 | source = "registry+https://github.com/rust-lang/crates.io-index"
2580 | checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
2581 | dependencies = [
2582 | "proc-macro2",
2583 | "quote",
2584 | "syn 2.0.85",
2585 | ]
2586 |
2587 | [[package]]
2588 | name = "time"
2589 | version = "0.3.36"
2590 | source = "registry+https://github.com/rust-lang/crates.io-index"
2591 | checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
2592 | dependencies = [
2593 | "deranged",
2594 | "itoa",
2595 | "num-conv",
2596 | "powerfmt",
2597 | "serde",
2598 | "time-core",
2599 | "time-macros",
2600 | ]
2601 |
2602 | [[package]]
2603 | name = "time-core"
2604 | version = "0.1.2"
2605 | source = "registry+https://github.com/rust-lang/crates.io-index"
2606 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
2607 |
2608 | [[package]]
2609 | name = "time-macros"
2610 | version = "0.2.18"
2611 | source = "registry+https://github.com/rust-lang/crates.io-index"
2612 | checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
2613 | dependencies = [
2614 | "num-conv",
2615 | "time-core",
2616 | ]
2617 |
2618 | [[package]]
2619 | name = "tinyvec"
2620 | version = "1.8.0"
2621 | source = "registry+https://github.com/rust-lang/crates.io-index"
2622 | checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
2623 | dependencies = [
2624 | "tinyvec_macros",
2625 | ]
2626 |
2627 | [[package]]
2628 | name = "tinyvec_macros"
2629 | version = "0.1.1"
2630 | source = "registry+https://github.com/rust-lang/crates.io-index"
2631 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
2632 |
2633 | [[package]]
2634 | name = "tokio"
2635 | version = "1.41.0"
2636 | source = "registry+https://github.com/rust-lang/crates.io-index"
2637 | checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb"
2638 | dependencies = [
2639 | "backtrace",
2640 | "bytes",
2641 | "libc",
2642 | "mio",
2643 | "parking_lot",
2644 | "pin-project-lite",
2645 | "signal-hook-registry",
2646 | "socket2",
2647 | "tokio-macros",
2648 | "windows-sys 0.52.0",
2649 | ]
2650 |
2651 | [[package]]
2652 | name = "tokio-macros"
2653 | version = "2.4.0"
2654 | source = "registry+https://github.com/rust-lang/crates.io-index"
2655 | checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
2656 | dependencies = [
2657 | "proc-macro2",
2658 | "quote",
2659 | "syn 2.0.85",
2660 | ]
2661 |
2662 | [[package]]
2663 | name = "tokio-native-tls"
2664 | version = "0.3.1"
2665 | source = "registry+https://github.com/rust-lang/crates.io-index"
2666 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
2667 | dependencies = [
2668 | "native-tls",
2669 | "tokio",
2670 | ]
2671 |
2672 | [[package]]
2673 | name = "tokio-rustls"
2674 | version = "0.26.0"
2675 | source = "registry+https://github.com/rust-lang/crates.io-index"
2676 | checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
2677 | dependencies = [
2678 | "rustls",
2679 | "rustls-pki-types",
2680 | "tokio",
2681 | ]
2682 |
2683 | [[package]]
2684 | name = "tokio-util"
2685 | version = "0.7.12"
2686 | source = "registry+https://github.com/rust-lang/crates.io-index"
2687 | checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
2688 | dependencies = [
2689 | "bytes",
2690 | "futures-core",
2691 | "futures-sink",
2692 | "pin-project-lite",
2693 | "tokio",
2694 | ]
2695 |
2696 | [[package]]
2697 | name = "tower-service"
2698 | version = "0.3.3"
2699 | source = "registry+https://github.com/rust-lang/crates.io-index"
2700 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
2701 |
2702 | [[package]]
2703 | name = "tracing"
2704 | version = "0.1.40"
2705 | source = "registry+https://github.com/rust-lang/crates.io-index"
2706 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
2707 | dependencies = [
2708 | "log",
2709 | "pin-project-lite",
2710 | "tracing-core",
2711 | ]
2712 |
2713 | [[package]]
2714 | name = "tracing-core"
2715 | version = "0.1.32"
2716 | source = "registry+https://github.com/rust-lang/crates.io-index"
2717 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
2718 | dependencies = [
2719 | "once_cell",
2720 | ]
2721 |
2722 | [[package]]
2723 | name = "try-lock"
2724 | version = "0.2.5"
2725 | source = "registry+https://github.com/rust-lang/crates.io-index"
2726 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
2727 |
2728 | [[package]]
2729 | name = "typenum"
2730 | version = "1.17.0"
2731 | source = "registry+https://github.com/rust-lang/crates.io-index"
2732 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
2733 |
2734 | [[package]]
2735 | name = "unicode-bidi"
2736 | version = "0.3.17"
2737 | source = "registry+https://github.com/rust-lang/crates.io-index"
2738 | checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
2739 |
2740 | [[package]]
2741 | name = "unicode-ident"
2742 | version = "1.0.13"
2743 | source = "registry+https://github.com/rust-lang/crates.io-index"
2744 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
2745 |
2746 | [[package]]
2747 | name = "unicode-normalization"
2748 | version = "0.1.24"
2749 | source = "registry+https://github.com/rust-lang/crates.io-index"
2750 | checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
2751 | dependencies = [
2752 | "tinyvec",
2753 | ]
2754 |
2755 | [[package]]
2756 | name = "unicode-width"
2757 | version = "0.1.14"
2758 | source = "registry+https://github.com/rust-lang/crates.io-index"
2759 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
2760 |
2761 | [[package]]
2762 | name = "untrusted"
2763 | version = "0.9.0"
2764 | source = "registry+https://github.com/rust-lang/crates.io-index"
2765 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
2766 |
2767 | [[package]]
2768 | name = "url"
2769 | version = "2.5.2"
2770 | source = "registry+https://github.com/rust-lang/crates.io-index"
2771 | checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
2772 | dependencies = [
2773 | "form_urlencoded",
2774 | "idna",
2775 | "percent-encoding",
2776 | ]
2777 |
2778 | [[package]]
2779 | name = "utf8parse"
2780 | version = "0.2.2"
2781 | source = "registry+https://github.com/rust-lang/crates.io-index"
2782 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
2783 |
2784 | [[package]]
2785 | name = "vcpkg"
2786 | version = "0.2.15"
2787 | source = "registry+https://github.com/rust-lang/crates.io-index"
2788 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
2789 |
2790 | [[package]]
2791 | name = "version_check"
2792 | version = "0.9.5"
2793 | source = "registry+https://github.com/rust-lang/crates.io-index"
2794 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
2795 |
2796 | [[package]]
2797 | name = "want"
2798 | version = "0.3.1"
2799 | source = "registry+https://github.com/rust-lang/crates.io-index"
2800 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
2801 | dependencies = [
2802 | "try-lock",
2803 | ]
2804 |
2805 | [[package]]
2806 | name = "wasi"
2807 | version = "0.11.0+wasi-snapshot-preview1"
2808 | source = "registry+https://github.com/rust-lang/crates.io-index"
2809 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
2810 |
2811 | [[package]]
2812 | name = "wasm-bindgen"
2813 | version = "0.2.95"
2814 | source = "registry+https://github.com/rust-lang/crates.io-index"
2815 | checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
2816 | dependencies = [
2817 | "cfg-if",
2818 | "once_cell",
2819 | "wasm-bindgen-macro",
2820 | ]
2821 |
2822 | [[package]]
2823 | name = "wasm-bindgen-backend"
2824 | version = "0.2.95"
2825 | source = "registry+https://github.com/rust-lang/crates.io-index"
2826 | checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
2827 | dependencies = [
2828 | "bumpalo",
2829 | "log",
2830 | "once_cell",
2831 | "proc-macro2",
2832 | "quote",
2833 | "syn 2.0.85",
2834 | "wasm-bindgen-shared",
2835 | ]
2836 |
2837 | [[package]]
2838 | name = "wasm-bindgen-futures"
2839 | version = "0.4.45"
2840 | source = "registry+https://github.com/rust-lang/crates.io-index"
2841 | checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b"
2842 | dependencies = [
2843 | "cfg-if",
2844 | "js-sys",
2845 | "wasm-bindgen",
2846 | "web-sys",
2847 | ]
2848 |
2849 | [[package]]
2850 | name = "wasm-bindgen-macro"
2851 | version = "0.2.95"
2852 | source = "registry+https://github.com/rust-lang/crates.io-index"
2853 | checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
2854 | dependencies = [
2855 | "quote",
2856 | "wasm-bindgen-macro-support",
2857 | ]
2858 |
2859 | [[package]]
2860 | name = "wasm-bindgen-macro-support"
2861 | version = "0.2.95"
2862 | source = "registry+https://github.com/rust-lang/crates.io-index"
2863 | checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
2864 | dependencies = [
2865 | "proc-macro2",
2866 | "quote",
2867 | "syn 2.0.85",
2868 | "wasm-bindgen-backend",
2869 | "wasm-bindgen-shared",
2870 | ]
2871 |
2872 | [[package]]
2873 | name = "wasm-bindgen-shared"
2874 | version = "0.2.95"
2875 | source = "registry+https://github.com/rust-lang/crates.io-index"
2876 | checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
2877 |
2878 | [[package]]
2879 | name = "web-sys"
2880 | version = "0.3.72"
2881 | source = "registry+https://github.com/rust-lang/crates.io-index"
2882 | checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112"
2883 | dependencies = [
2884 | "js-sys",
2885 | "wasm-bindgen",
2886 | ]
2887 |
2888 | [[package]]
2889 | name = "winapi"
2890 | version = "0.3.9"
2891 | source = "registry+https://github.com/rust-lang/crates.io-index"
2892 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
2893 | dependencies = [
2894 | "winapi-i686-pc-windows-gnu",
2895 | "winapi-x86_64-pc-windows-gnu",
2896 | ]
2897 |
2898 | [[package]]
2899 | name = "winapi-i686-pc-windows-gnu"
2900 | version = "0.4.0"
2901 | source = "registry+https://github.com/rust-lang/crates.io-index"
2902 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
2903 |
2904 | [[package]]
2905 | name = "winapi-x86_64-pc-windows-gnu"
2906 | version = "0.4.0"
2907 | source = "registry+https://github.com/rust-lang/crates.io-index"
2908 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
2909 |
2910 | [[package]]
2911 | name = "windows-core"
2912 | version = "0.52.0"
2913 | source = "registry+https://github.com/rust-lang/crates.io-index"
2914 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
2915 | dependencies = [
2916 | "windows-targets",
2917 | ]
2918 |
2919 | [[package]]
2920 | name = "windows-registry"
2921 | version = "0.2.0"
2922 | source = "registry+https://github.com/rust-lang/crates.io-index"
2923 | checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
2924 | dependencies = [
2925 | "windows-result",
2926 | "windows-strings",
2927 | "windows-targets",
2928 | ]
2929 |
2930 | [[package]]
2931 | name = "windows-result"
2932 | version = "0.2.0"
2933 | source = "registry+https://github.com/rust-lang/crates.io-index"
2934 | checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
2935 | dependencies = [
2936 | "windows-targets",
2937 | ]
2938 |
2939 | [[package]]
2940 | name = "windows-strings"
2941 | version = "0.1.0"
2942 | source = "registry+https://github.com/rust-lang/crates.io-index"
2943 | checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
2944 | dependencies = [
2945 | "windows-result",
2946 | "windows-targets",
2947 | ]
2948 |
2949 | [[package]]
2950 | name = "windows-sys"
2951 | version = "0.52.0"
2952 | source = "registry+https://github.com/rust-lang/crates.io-index"
2953 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
2954 | dependencies = [
2955 | "windows-targets",
2956 | ]
2957 |
2958 | [[package]]
2959 | name = "windows-sys"
2960 | version = "0.59.0"
2961 | source = "registry+https://github.com/rust-lang/crates.io-index"
2962 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
2963 | dependencies = [
2964 | "windows-targets",
2965 | ]
2966 |
2967 | [[package]]
2968 | name = "windows-targets"
2969 | version = "0.52.6"
2970 | source = "registry+https://github.com/rust-lang/crates.io-index"
2971 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
2972 | dependencies = [
2973 | "windows_aarch64_gnullvm",
2974 | "windows_aarch64_msvc",
2975 | "windows_i686_gnu",
2976 | "windows_i686_gnullvm",
2977 | "windows_i686_msvc",
2978 | "windows_x86_64_gnu",
2979 | "windows_x86_64_gnullvm",
2980 | "windows_x86_64_msvc",
2981 | ]
2982 |
2983 | [[package]]
2984 | name = "windows_aarch64_gnullvm"
2985 | version = "0.52.6"
2986 | source = "registry+https://github.com/rust-lang/crates.io-index"
2987 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
2988 |
2989 | [[package]]
2990 | name = "windows_aarch64_msvc"
2991 | version = "0.52.6"
2992 | source = "registry+https://github.com/rust-lang/crates.io-index"
2993 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
2994 |
2995 | [[package]]
2996 | name = "windows_i686_gnu"
2997 | version = "0.52.6"
2998 | source = "registry+https://github.com/rust-lang/crates.io-index"
2999 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
3000 |
3001 | [[package]]
3002 | name = "windows_i686_gnullvm"
3003 | version = "0.52.6"
3004 | source = "registry+https://github.com/rust-lang/crates.io-index"
3005 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
3006 |
3007 | [[package]]
3008 | name = "windows_i686_msvc"
3009 | version = "0.52.6"
3010 | source = "registry+https://github.com/rust-lang/crates.io-index"
3011 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
3012 |
3013 | [[package]]
3014 | name = "windows_x86_64_gnu"
3015 | version = "0.52.6"
3016 | source = "registry+https://github.com/rust-lang/crates.io-index"
3017 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
3018 |
3019 | [[package]]
3020 | name = "windows_x86_64_gnullvm"
3021 | version = "0.52.6"
3022 | source = "registry+https://github.com/rust-lang/crates.io-index"
3023 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
3024 |
3025 | [[package]]
3026 | name = "windows_x86_64_msvc"
3027 | version = "0.52.6"
3028 | source = "registry+https://github.com/rust-lang/crates.io-index"
3029 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
3030 |
3031 | [[package]]
3032 | name = "xxhash-rust"
3033 | version = "0.8.12"
3034 | source = "registry+https://github.com/rust-lang/crates.io-index"
3035 | checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984"
3036 |
3037 | [[package]]
3038 | name = "zerocopy"
3039 | version = "0.7.35"
3040 | source = "registry+https://github.com/rust-lang/crates.io-index"
3041 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
3042 | dependencies = [
3043 | "byteorder",
3044 | "zerocopy-derive",
3045 | ]
3046 |
3047 | [[package]]
3048 | name = "zerocopy-derive"
3049 | version = "0.7.35"
3050 | source = "registry+https://github.com/rust-lang/crates.io-index"
3051 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
3052 | dependencies = [
3053 | "proc-macro2",
3054 | "quote",
3055 | "syn 2.0.85",
3056 | ]
3057 |
3058 | [[package]]
3059 | name = "zeroize"
3060 | version = "1.8.1"
3061 | source = "registry+https://github.com/rust-lang/crates.io-index"
3062 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
3063 |
3064 | [[package]]
3065 | name = "zstd"
3066 | version = "0.13.2"
3067 | source = "registry+https://github.com/rust-lang/crates.io-index"
3068 | checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9"
3069 | dependencies = [
3070 | "zstd-safe",
3071 | ]
3072 |
3073 | [[package]]
3074 | name = "zstd-safe"
3075 | version = "7.2.1"
3076 | source = "registry+https://github.com/rust-lang/crates.io-index"
3077 | checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059"
3078 | dependencies = [
3079 | "zstd-sys",
3080 | ]
3081 |
3082 | [[package]]
3083 | name = "zstd-sys"
3084 | version = "2.0.13+zstd.1.5.6"
3085 | source = "registry+https://github.com/rust-lang/crates.io-index"
3086 | checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa"
3087 | dependencies = [
3088 | "cc",
3089 | "pkg-config",
3090 | ]
3091 |
--------------------------------------------------------------------------------
/taxi-data-api-rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "taxi-data-api-rust"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | actix-web = "4.9.0"
8 | anyhow = "1.0.91"
9 | chrono = { version = "0.4.38", features = ["serde"] }
10 | env_logger = "0.11.5"
11 | log = "0.4.22"
12 | rand = "0.8.5"
13 | reqwest = { version = "0.12.9", features = ["json"] }
14 | serde = { version = "1.0.214", features = ["derive"] }
15 | serde_json = "1.0.132"
16 | tokio = { version = "1.0", features = ["full"] }
17 | polars = { version = "0.35", features = ["parquet", "lazy"] }
--------------------------------------------------------------------------------
/taxi-data-api-rust/Dockerfile:
--------------------------------------------------------------------------------
1 | ### Build stage
2 | FROM rust:1.76-slim as builder
3 | WORKDIR /usr/src/app
4 | # Install OpenSSL development packages for compilation
5 | RUN apt-get update && \
6 | apt-get install -y pkg-config libssl-dev && \
7 | rm -rf /var/lib/apt/lists/*
8 |
9 | # Copy only the necessary files for building
10 | COPY Cargo.toml Cargo.lock ./
11 | COPY src src/
12 |
13 | # Build the application
14 | RUN cargo build --release
15 |
16 |
17 | ### Runtime stage
18 | FROM debian:bookworm-slim
19 | WORKDIR /usr/local/bin
20 | COPY --from=builder /usr/src/app/target/release/taxi-data-api-rust .
21 | RUN apt-get update && apt-get install -y libssl-dev ca-certificates && rm -rf /var/lib/apt/lists/*
22 |
23 | # Run as non-root user for better security
24 | # RUN useradd -m myapp
25 | # USER myapp
26 |
27 | EXPOSE 8080
28 | CMD ["./taxi-data-api-rust"]
--------------------------------------------------------------------------------
/taxi-data-api-rust/Makefile:
--------------------------------------------------------------------------------
1 | export PORT=8089
2 |
3 | # Runs the API locally
4 | run-dev:
5 | cargo run
6 |
7 | # Commands to check the API works as expected when running locally
8 | health-check-local:
9 | curl -X GET "http://localhost:$(PORT)/health"
10 |
11 | sample-request-local:
12 | curl -X GET "http://localhost:$(PORT)/trips?from_ms=1714204800000&n_results=100"
13 |
14 | sample-request-no-results-local:
15 | curl -X GET "http://localhost:$(PORT)/trips?from_ms=1727430298000&n_results=100"
16 |
17 | build:
18 | docker build -t taxi-data-api-rust .
19 |
20 | run: build
21 | docker run -p $(PORT):8080 taxi-data-api-rust
--------------------------------------------------------------------------------
/taxi-data-api-rust/README.md:
--------------------------------------------------------------------------------
1 | # Steps
2 |
3 | - [ ] Create Rust project structure
4 | - [ ] Don't forget Rust analyzer
5 | - [ ] Add actix-web
6 | - [ ] Create the HttpServer
7 | - [ ] Add /health endpoint
8 |
9 | - [ ] Easy error handling with anyhow
10 |
11 | - [ ] Set port from env variable
12 | - [ ] Add middleware for logging
13 | - [ ] Add /trips endpoint
14 | - [ ] Create another module backend.rs with the get_trips function
15 | - [ ] Implement the get_trips function
16 |
17 |
18 | ## Notes
19 |
20 | `unwrap()` extracts the value from an `Option` or a `Result` type, but it does that in
21 | a dangerous way. It will Panic and crash the program if the valueis None or Err.
22 |
23 | Alternatives:
24 | * `expect()` with a meaningfull message
25 | * Patter matching with `match`
26 | * `unwrap_or()` to provide a default value
27 | * `ok_or()` to convert to a Result
--------------------------------------------------------------------------------
/taxi-data-api-rust/src/backend.rs:
--------------------------------------------------------------------------------
1 | use chrono::{DateTime, Utc, Datelike};
2 | use serde::Serialize;
3 | use log::{info, error};
4 | use anyhow::Result;
5 | use polars::prelude::*;
6 | use rand::Rng;
7 |
8 | #[derive(Debug, Serialize, Clone)]
9 | pub struct Trip {
10 | tpep_pickup_datetime: DateTime,
11 | tpep_dropoff_datetime: DateTime,
12 | trip_distance: f64,
13 | fare_amount: f64,
14 | }
15 |
16 | pub async fn get_fake_trips(from_ms: i64, n_results: i64) -> Result> {
17 | // Create a random number generator
18 | let mut rng = rand::thread_rng();
19 |
20 | // Create n_results fake trips
21 | let trips = (0..n_results).map(|_| {
22 | let random_seconds = rng.gen_range(0..60);
23 | let pickup_time = DateTime::::from_timestamp(from_ms / 1000 + random_seconds, 0).unwrap();
24 | let dropoff_time = DateTime::::from_timestamp(from_ms / 1000 + random_seconds + rng.gen_range(300..3600), 0).unwrap();
25 |
26 | Trip {
27 | tpep_pickup_datetime: pickup_time,
28 | tpep_dropoff_datetime: dropoff_time,
29 | trip_distance: rng.gen_range(0.5..20.0),
30 | fare_amount: rng.gen_range(2.5..100.0),
31 | }
32 | }).collect();
33 |
34 | Ok(trips)
35 | }
36 |
37 | /// Reads taxi trip data from a parquet file and returns a vector of Trip structs
38 | ///
39 | /// # Arguments
40 | ///
41 | /// * `file_path` - Path to the parquet file containing taxi trip data
42 | /// * `from_ms` - Unix timestamp in milliseconds to filter trips after this time
43 | /// * `n_results` - Maximum number of trips to return
44 | ///
45 | /// # Returns
46 | ///
47 | /// Returns a Result containing a Vec of Trip structs if successful, or an error if the
48 | /// file cannot be read or the data is invalid
49 | fn get_trips_from_file(
50 | file_path: &str,
51 | from_ms: i64,
52 | n_results: i64
53 | ) -> Result> {
54 |
55 | let df = LazyFrame::scan_parquet(file_path, Default::default())?
56 | .select([
57 | col("tpep_pickup_datetime"),
58 | col("tpep_dropoff_datetime"),
59 | col("trip_distance"),
60 | col("fare_amount"),
61 | ])
62 | .filter(col("tpep_pickup_datetime").gt_eq(lit(from_ms * 1_000_000)))
63 | .sort("tpep_pickup_datetime", Default::default())
64 | .limit(n_results as u32)
65 | .collect()?;
66 |
67 | let pickup_series = df
68 | .column("tpep_pickup_datetime")?
69 | .datetime()
70 | .expect("pickup datetime column should be datetime type");
71 |
72 | let dropoff_series = df
73 | .column("tpep_dropoff_datetime")?
74 | .datetime()
75 | .expect("dropoff datetime column should be datetime type");
76 |
77 | let distance_series = df
78 | .column("trip_distance")?
79 | .f64()
80 | .expect("distance column should be f64 type");
81 |
82 | let fare_series = df
83 | .column("fare_amount")?
84 | .f64()
85 | .expect("fare column should be f64 type");
86 |
87 | // Convert to Vec
88 | let trips: Vec = (0..df.height()).map(|i| {
89 | Trip {
90 | tpep_pickup_datetime: DateTime::::from_timestamp_nanos(pickup_series.get(i).unwrap()),
91 | tpep_dropoff_datetime: DateTime::::from_timestamp_nanos(dropoff_series.get(i).unwrap()),
92 | trip_distance: distance_series.get(i).unwrap(),
93 | fare_amount: fare_series.get(i).unwrap(),
94 | }
95 | })
96 | .collect();
97 |
98 | Ok(trips)
99 | }
100 |
101 | pub async fn get_trips(from_ms: i64, n_results: i64) -> Result> {
102 |
103 | let (year, month) = get_year_and_month(from_ms);
104 | info!("Extracted year: {}, month: {}", year, month);
105 |
106 | // Download the parquet file
107 | info!("Downloading parquet file for year: {}, month: {}", year, month);
108 | let file_path = download_parquet_file(year, month).await?;
109 |
110 | // Get the trips from the file
111 | let trips = get_trips_from_file(&file_path, from_ms, n_results)?;
112 |
113 | // TODO: Fake data for now
114 | // let trips = get_fake_trips();
115 |
116 | info!("Returning {} trips", trips.len());
117 | Ok(trips)
118 | }
119 |
120 | pub async fn download_parquet_file(year: i32, month: i32) -> Result {
121 |
122 | let url = format!(
123 | "https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_{}-{:02}.parquet",
124 | year,
125 | month
126 | );
127 | let file_path = format!("yellow_tripdata_{}-{:02}.parquet", year, month);
128 |
129 | // Check if the file already exists. If it does, return the file path.
130 | if tokio::fs::try_exists(&file_path).await? {
131 | info!("File {} already exists", &file_path);
132 | return Ok(file_path);
133 | }
134 |
135 | info!("Downloading file from {}", &url);
136 | let response = reqwest::get(&url).await?;
137 | if response.status().is_success() {
138 |
139 | let bytes = response.bytes().await?;
140 |
141 | // async copy of bytes to file
142 | tokio::fs::write(&file_path, bytes).await?;
143 |
144 | info!("File {} downloaded successfully", &file_path);
145 | } else {
146 | error!("Failed to download file");
147 | }
148 | Ok(file_path)
149 | }
150 |
151 | pub fn get_year_and_month(from_ms: i64) -> (i32, i32) {
152 | let datetime = DateTime::::from_timestamp(from_ms / 1000, 0).unwrap();
153 | (datetime.year(), datetime.month() as i32)
154 | }
155 |
--------------------------------------------------------------------------------
/taxi-data-api-rust/src/main.rs:
--------------------------------------------------------------------------------
1 | use actix_web::{App, HttpServer, web, HttpResponse};
2 | use log::{info, error};
3 | use std::env;
4 | use serde::Deserialize;
5 | use env_logger::Env;
6 |
7 | mod backend;
8 | use crate::backend::{get_trips, get_fake_trips};
9 |
10 | async fn health() -> HttpResponse {
11 | HttpResponse::Ok().json(serde_json::json!({
12 | "status": "healthy",
13 | "timestamp": chrono::Utc::now().to_rfc3339()
14 | }))
15 | }
16 |
17 | #[derive(Deserialize)]
18 | struct TripsQuery {
19 | from_ms: i64,
20 | n_results: i64
21 | }
22 |
23 | async fn trips(query: web::Query) -> HttpResponse {
24 | match get_fake_trips(query.from_ms, query.n_results).await {
25 | Ok(trips) => HttpResponse::Ok().json(trips),
26 | Err(e) => HttpResponse::InternalServerError().body(e.to_string())
27 | }
28 | }
29 |
30 | #[actix_web::main]
31 | async fn main() -> std::io::Result<()> {
32 |
33 | // Initialize the logger
34 | env_logger::init_from_env(Env::new().default_filter_or("info"));
35 |
36 | let port = env::var("PORT")
37 | .unwrap_or_else(|_| "8080".to_string())
38 | .parse::()
39 | .expect("PORT must be a valid number");
40 |
41 | info!("Starting server on port {}", port);
42 |
43 | HttpServer::new(|| {
44 | App::new()
45 | .wrap(actix_web::middleware::Logger::default())
46 | .route("/health", web::get().to(health))
47 | .route("/trips", web::get().to(trips))
48 | })
49 | .bind(("0.0.0.0", port))?
50 | .run()
51 | .await.map_err(|e| {
52 | error!("Error starting server: {}", e);
53 | e
54 | })
55 | }
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paulescu/taxi-data-api-python/1ec743d2626c26a785ea624a8d231f6c84f245ae/tests/__init__.py
--------------------------------------------------------------------------------
/tests/test_read_parquet.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 |
3 | from src.backend import read_parquet_file
4 |
5 |
6 | def test_read_parquet_file_returns_non_empty_dataframe():
7 | # Arrange
8 | year = 2024
9 | month = 1
10 |
11 | # Act
12 | result = read_parquet_file(year, month)
13 |
14 | # Assert
15 | assert result is not None
16 | assert isinstance(result, pd.DataFrame)
17 | assert not result.empty
18 |
--------------------------------------------------------------------------------