sks01dev commited on
Commit
d64524a
·
verified ·
1 Parent(s): 1a2595f

Upload 15 files

Browse files
Files changed (15) hide show
  1. .gitattributes +1 -35
  2. .python-version +1 -0
  3. Dockerfile +27 -0
  4. main.py +6 -0
  5. marketing.py +18 -0
  6. model.bin +3 -0
  7. ping.py +11 -0
  8. predict.py +55 -0
  9. pyproject.toml +16 -0
  10. readme.md +186 -0
  11. requirements.txt +3 -0
  12. train.py +64 -0
  13. uv.lock +518 -0
  14. venv +0 -0
  15. workshop-uv-fastapi.ipynb +1986 -0
.gitattributes CHANGED
@@ -1,35 +1 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ model.bin filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.python-version ADDED
@@ -0,0 +1 @@
 
 
1
+ 3.12
Dockerfile ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.12.1-slim-bookworm
2
+
3
+ # Install uv by copying it directly from its container image (much faster and smaller than pip)
4
+ COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
5
+
6
+ # Install uv (the fast package manager)
7
+ RUN pip install uv
8
+
9
+ # Set the working directory
10
+ WORKDIR /app
11
+
12
+ # Add the virtual environment’s bin directory to PATH so Python tools work globally
13
+
14
+ # Copy dependency files
15
+ COPY pyproject.toml uv.lock ./
16
+
17
+ # Install dependencies from the lock file
18
+ RUN uv sync --frozen --no-cache
19
+
20
+ # Copy the FastAPI app and model
21
+ COPY predict.py model.bin ./
22
+
23
+ # Expose port (optional but good practice)
24
+ EXPOSE 9696
25
+
26
+ # Start the FastAPI app with uvicorn
27
+ ENTRYPOINT ["uvicorn", "predict:app", "--host", "0.0.0.0", "--port", "9696"]
main.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ def main():
2
+ print("Hello from week-5!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
marketing.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+
3
+ url = 'http://localhost:9696/predict'
4
+
5
+ customer = {
6
+ "lead_source": "paid_ads",
7
+ "number_of_courses_viewed": 5,
8
+ "annual_income": 79450.0
9
+ }
10
+
11
+ response = requests.post(url, json=customer)
12
+ predictions = response.json()
13
+
14
+ print(f"Respose: {predictions}")
15
+ if predictions['converted'] >= 0.5:
16
+ print('Customer is likely to convert, send promo mails')
17
+ else:
18
+ print('Customer is not likely to convert')
model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4b078a596e9c0121e2674dc5d962fe368ea88d944c7c431a37b4d10b7fbd80fa
3
+ size 1300
ping.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ import uvicorn
3
+
4
+ app = FastAPI(title='ping')
5
+
6
+ @app.get("/ping")
7
+ def ping():
8
+ return "Pong!"
9
+
10
+ if __name__ == "__main__":
11
+ uvicorn.run(app, host="0.0.0.0", port=9696)
predict.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from typing import Literal
3
+ import uvicorn
4
+ import pickle
5
+ # for data validation, so the data input by the user is realistic
6
+ from pydantic import BaseModel, Field
7
+
8
+ # request data
9
+ class Customer(BaseModel):
10
+ lead_source: Literal['organic_search', 'social_media', 'paid_ads', 'referral', 'events'] = Field(
11
+ ...,
12
+ description="Source of the lead",
13
+ )
14
+ annual_income: float = Field(..., ge=0, le=109899)
15
+ number_of_courses_viewed: int = Field(..., ge=0, le=9)
16
+
17
+ # sample data
18
+ model_config = {
19
+ "json_schema_extra": {
20
+ "examples": [
21
+ {
22
+ # This dictionary below is the sample that will appear in the Swagger UI
23
+ "lead_source": "paid_ads",
24
+ "annual_income": 79276.0, # Note: Use a float (79276.0) for consistency
25
+ "number_of_courses_viewed": 2,
26
+ }
27
+ ]
28
+ }
29
+ }
30
+
31
+
32
+ # response data
33
+ class PredictResponse(BaseModel):
34
+ convert_probability: float
35
+ converted: bool
36
+
37
+ app = FastAPI(title="Customer Conversion Predictor")
38
+
39
+ # Load the pre-trained model
40
+ with open("model.bin", "rb") as f_in:
41
+ pipeline = pickle.load(f_in)
42
+
43
+ # Helper function to get prediction from the loaded model
44
+ def predict_single(customer_dict: dict) -> float:
45
+ return pipeline.predict_proba([customer_dict])[0, 1]
46
+
47
+ # Define the prediction endpoint
48
+ @app.post("/predict", response_model=PredictResponse)
49
+ def predict(customer: Customer):
50
+ prob = predict_single(customer.model_dump())
51
+ return PredictResponse(convert_probability=prob, converted=(prob >= 0.5))
52
+
53
+ # Run the app for local development
54
+ if __name__ == "__main__":
55
+ uvicorn.run("predict:app", host="0.0.0.0", port=9696)
pyproject.toml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "week-5"
3
+ version = "0.1.0"
4
+ description = "Customer Conversion Predictor"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "fastapi>=0.120.0",
9
+ "scikit-learn>=1.7.2",
10
+ "uvicorn>=0.38.0",
11
+ ]
12
+
13
+ [dependency-groups]
14
+ dev = [
15
+ "requests>=2.32.5",
16
+ ]
readme.md ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # Customer Conversion Prediction API
3
+
4
+ [![Python](https://img.shields.io/badge/python-3.12%2F3.13-blue)](https://www.python.org/)
5
+ [![FastAPI](https://img.shields.io/badge/FastAPI-0.100-green)](https://fastapi.tiangolo.com/)
6
+ [![Docker](https://img.shields.io/badge/docker-ready-blue?logo=docker)](https://www.docker.com/)
7
+ [![License](https://img.shields.io/badge/license-MIT-lightgrey)](LICENSE)
8
+
9
+ This project demonstrates **deploying a machine learning model with FastAPI and Docker**.
10
+ The model predicts the probability of a lead converting to a customer based on simple features.
11
+
12
+ ---
13
+
14
+ ## Table of Contents
15
+
16
+ - [Project Overview](#project-overview)
17
+ - [Requirements](#requirements)
18
+ - [Setup & Installation](#setup--installation)
19
+ - [Running Locally](#running-locally)
20
+ - [Docker Deployment](#docker-deployment)
21
+ - [Using the API](#using-the-api)
22
+ - [Project Structure](#project-structure)
23
+ - [License](#license)
24
+
25
+ ---
26
+
27
+ ## Project Overview
28
+
29
+ We use a pre-trained **Logistic Regression model** with a `DictVectorizer` to process input features:
30
+
31
+ - `lead_source` (categorical: `organic_search`, `social_media`, `paid_ads`, `referral`, `events`)
32
+ - `annual_income` (numeric)
33
+ - `number_of_courses_viewed` (numeric)
34
+
35
+ The model is served via **FastAPI**, and can be deployed using **Docker**.
36
+
37
+ ---
38
+
39
+ ## Requirements
40
+
41
+ - Python 3.12 or 3.13
42
+ - [FastAPI](https://fastapi.tiangolo.com/)
43
+ - [Uvicorn](https://www.uvicorn.org/)
44
+ - [uv](https://uv-lang.org/) (for dependency management)
45
+ - [Docker](https://www.docker.com/)
46
+
47
+ ---
48
+
49
+ ## Setup & Installation
50
+
51
+ ### 1. Clone the repository
52
+
53
+ ```bash
54
+ git clone <your-repo-url>
55
+ cd <repo-folder>
56
+ ````
57
+
58
+ ### 2. Install dependencies with `uv`
59
+
60
+ ```bash
61
+ # Install uv globally if not already
62
+ pip install uv
63
+
64
+ # Initialize uv project
65
+ uv init
66
+
67
+ # Install dependencies from pyproject.toml
68
+ uv sync --frozen
69
+ ```
70
+
71
+ ### 3. Verify Python and library versions
72
+
73
+ ```bash
74
+ python --version
75
+ uv --version
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Running Locally
81
+
82
+ 1. Make sure the `model.bin` file is in the project directory.
83
+ 2. Run the FastAPI server:
84
+
85
+ ```bash
86
+ uvicorn predict:app --host 0.0.0.0 --port 9696
87
+ ```
88
+
89
+ 3. Open API docs in your browser:
90
+ [http://localhost:9696/docs](http://localhost:9696/docs)
91
+
92
+ ---
93
+
94
+ ## Docker Deployment
95
+
96
+ ### 1. Build Docker image
97
+
98
+ ```bash
99
+ docker build -t customer-conversion-prediction .
100
+ ```
101
+
102
+ ### 2. Run container
103
+
104
+ ```bash
105
+ docker run -d -p 9696:9696 customer-conversion-prediction
106
+ ```
107
+
108
+ * Access the API at `http://localhost:9696/predict`.
109
+
110
+ ### 3. Test API inside Python
111
+
112
+ ```python
113
+ import requests
114
+
115
+ url = "http://localhost:9696/predict"
116
+ client = {
117
+ "lead_source": "organic_search",
118
+ "number_of_courses_viewed": 4,
119
+ "annual_income": 80304.0
120
+ }
121
+
122
+ response = requests.post(url, json=client)
123
+ print(response.json())
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Using the API
129
+
130
+ ### Request format
131
+
132
+ ```json
133
+ {
134
+ "lead_source": "paid_ads",
135
+ "number_of_courses_viewed": 2,
136
+ "annual_income": 79276.0
137
+ }
138
+ ```
139
+
140
+ ### Response format
141
+
142
+ ```json
143
+ {
144
+ "convert_probability": 0.533,
145
+ "converted": true
146
+ }
147
+ ```
148
+
149
+ * `convert_probability`: probability of conversion
150
+ * `converted`: True if probability >= 0.5, else False
151
+
152
+ ---
153
+
154
+ ## Project Structure
155
+
156
+ ```
157
+ .
158
+ ├── Dockerfile
159
+ ├── model.bin
160
+ ├── pyproject.toml
161
+ ├── uv.lock
162
+ ├── predict.py
163
+ └── README.md
164
+ ```
165
+
166
+ * `Dockerfile`: defines container image
167
+ * `predict.py`: FastAPI app and prediction code
168
+ * `model.bin`: pre-trained ML model
169
+ * `pyproject.toml` & `uv.lock`: dependency management
170
+ * `README.md`: project documentation
171
+
172
+ ---
173
+
174
+ ## License
175
+
176
+ This project is for educational purposes for **ML Zoomcamp 2025**.
177
+
178
+ ---
179
+
180
+ ## References
181
+
182
+ * [FastAPI Documentation](https://fastapi.tiangolo.com/)
183
+ * [Uvicorn Documentation](https://www.uvicorn.org/)
184
+ * [Docker Documentation](https://docs.docker.com/)
185
+ * [Scikit-Learn Pipeline](https://scikit-learn.org/stable/modules/compose.html)
186
+
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ venv requirements.txt
2
+ pipenv poetry
3
+ uv
train.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # This is a starter notebook for an updated module 5 of ML Zoomcamp
5
+ #
6
+ # The code is based on the modules 3 and 4. We use the same dataset: [telco customer churn](https://www.kaggle.com/datasets/blastchar/telco-customer-churn)
7
+
8
+ # Import the necessary libraries
9
+ import numpy as np
10
+ import pandas as pd
11
+ import sklearn
12
+ import pickle
13
+ from sklearn.linear_model import LogisticRegression
14
+ from sklearn.pipeline import make_pipeline
15
+ from sklearn.feature_extraction import DictVectorizer
16
+
17
+
18
+ print(f'pandas=={pd.__version__}')
19
+ print(f'numpy=={np.__version__}')
20
+ print(f'sklearn=={sklearn.__version__}')
21
+
22
+
23
+ # Load the data
24
+ def load_data():
25
+ data_url = "https://raw.githubusercontent.com/alexeygrigorev/datasets/master/course_lead_scoring.csv"
26
+ df = pd.read_csv(data_url)
27
+ return df
28
+
29
+
30
+
31
+ def train_model(df):
32
+ # Preprocessing using DictVectorizer and Training the Logistic Regressio model
33
+ categorical = ['lead_source']
34
+ numeric = ['number_of_courses_viewed', 'annual_income']
35
+
36
+ df[categorical] = df[categorical].fillna('NA')
37
+ df[numeric] = df[numeric].fillna(0)
38
+
39
+ train_dict = df[categorical + numeric].to_dict(orient='records')
40
+
41
+ pipeline = make_pipeline(
42
+ DictVectorizer(),
43
+ LogisticRegression(solver='liblinear')
44
+ )
45
+
46
+ # the target variable
47
+ y_train = df.converted
48
+
49
+ pipeline.fit(train_dict, y_train)
50
+ return pipeline
51
+
52
+
53
+ def save_model(filename, model):
54
+ with open(filename, 'wb') as f_out:
55
+ pickle.dump(model, f_out)
56
+
57
+ print(f"Model saved to {filename}")
58
+
59
+
60
+ df = load_data()
61
+ pipeline = train_model(df)
62
+ save_model('model.bin', pipeline)
63
+
64
+
uv.lock ADDED
@@ -0,0 +1,518 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version = 1
2
+ revision = 3
3
+ requires-python = ">=3.12"
4
+
5
+ [[package]]
6
+ name = "annotated-doc"
7
+ version = "0.0.3"
8
+ source = { registry = "https://pypi.org/simple" }
9
+ sdist = { url = "https://files.pythonhosted.org/packages/d7/a6/dc46877b911e40c00d395771ea710d5e77b6de7bacd5fdcd78d70cc5a48f/annotated_doc-0.0.3.tar.gz", hash = "sha256:e18370014c70187422c33e945053ff4c286f453a984eba84d0dbfa0c935adeda", size = 5535, upload-time = "2025-10-24T14:57:10.718Z" }
10
+ wheels = [
11
+ { url = "https://files.pythonhosted.org/packages/02/b7/cf592cb5de5cb3bade3357f8d2cf42bf103bbe39f459824b4939fd212911/annotated_doc-0.0.3-py3-none-any.whl", hash = "sha256:348ec6664a76f1fd3be81f43dffbee4c7e8ce931ba71ec67cc7f4ade7fbbb580", size = 5488, upload-time = "2025-10-24T14:57:09.462Z" },
12
+ ]
13
+
14
+ [[package]]
15
+ name = "annotated-types"
16
+ version = "0.7.0"
17
+ source = { registry = "https://pypi.org/simple" }
18
+ sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
19
+ wheels = [
20
+ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
21
+ ]
22
+
23
+ [[package]]
24
+ name = "anyio"
25
+ version = "4.11.0"
26
+ source = { registry = "https://pypi.org/simple" }
27
+ dependencies = [
28
+ { name = "idna" },
29
+ { name = "sniffio" },
30
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
31
+ ]
32
+ sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" }
33
+ wheels = [
34
+ { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" },
35
+ ]
36
+
37
+ [[package]]
38
+ name = "certifi"
39
+ version = "2025.10.5"
40
+ source = { registry = "https://pypi.org/simple" }
41
+ sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" }
42
+ wheels = [
43
+ { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" },
44
+ ]
45
+
46
+ [[package]]
47
+ name = "charset-normalizer"
48
+ version = "3.4.4"
49
+ source = { registry = "https://pypi.org/simple" }
50
+ sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" }
51
+ wheels = [
52
+ { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" },
53
+ { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" },
54
+ { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" },
55
+ { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" },
56
+ { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" },
57
+ { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" },
58
+ { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" },
59
+ { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" },
60
+ { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" },
61
+ { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" },
62
+ { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" },
63
+ { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" },
64
+ { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" },
65
+ { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" },
66
+ { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" },
67
+ { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" },
68
+ { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" },
69
+ { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" },
70
+ { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" },
71
+ { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" },
72
+ { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" },
73
+ { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" },
74
+ { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" },
75
+ { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" },
76
+ { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" },
77
+ { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" },
78
+ { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" },
79
+ { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" },
80
+ { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" },
81
+ { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" },
82
+ { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" },
83
+ { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" },
84
+ { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" },
85
+ { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" },
86
+ { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" },
87
+ { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" },
88
+ { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" },
89
+ { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" },
90
+ { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" },
91
+ { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" },
92
+ { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" },
93
+ { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" },
94
+ { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" },
95
+ { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" },
96
+ { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" },
97
+ { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" },
98
+ { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" },
99
+ { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" },
100
+ { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" },
101
+ ]
102
+
103
+ [[package]]
104
+ name = "click"
105
+ version = "8.3.0"
106
+ source = { registry = "https://pypi.org/simple" }
107
+ dependencies = [
108
+ { name = "colorama", marker = "sys_platform == 'win32'" },
109
+ ]
110
+ sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" }
111
+ wheels = [
112
+ { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" },
113
+ ]
114
+
115
+ [[package]]
116
+ name = "colorama"
117
+ version = "0.4.6"
118
+ source = { registry = "https://pypi.org/simple" }
119
+ sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
120
+ wheels = [
121
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
122
+ ]
123
+
124
+ [[package]]
125
+ name = "fastapi"
126
+ version = "0.120.0"
127
+ source = { registry = "https://pypi.org/simple" }
128
+ dependencies = [
129
+ { name = "annotated-doc" },
130
+ { name = "pydantic" },
131
+ { name = "starlette" },
132
+ { name = "typing-extensions" },
133
+ ]
134
+ sdist = { url = "https://files.pythonhosted.org/packages/f7/0e/7f29e8f7219e4526747db182e1afb5a4b6abc3201768fb38d81fa2536241/fastapi-0.120.0.tar.gz", hash = "sha256:6ce2c1cfb7000ac14ffd8ddb2bc12e62d023a36c20ec3710d09d8e36fab177a0", size = 337603, upload-time = "2025-10-23T20:56:34.743Z" }
135
+ wheels = [
136
+ { url = "https://files.pythonhosted.org/packages/1d/60/7a639ceaba54aec4e1d5676498c568abc654b95762d456095b6cb529b1ca/fastapi-0.120.0-py3-none-any.whl", hash = "sha256:84009182e530c47648da2f07eb380b44b69889a4acfd9e9035ee4605c5cfc469", size = 108243, upload-time = "2025-10-23T20:56:33.281Z" },
137
+ ]
138
+
139
+ [[package]]
140
+ name = "h11"
141
+ version = "0.16.0"
142
+ source = { registry = "https://pypi.org/simple" }
143
+ sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
144
+ wheels = [
145
+ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
146
+ ]
147
+
148
+ [[package]]
149
+ name = "idna"
150
+ version = "3.11"
151
+ source = { registry = "https://pypi.org/simple" }
152
+ sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" }
153
+ wheels = [
154
+ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
155
+ ]
156
+
157
+ [[package]]
158
+ name = "joblib"
159
+ version = "1.5.2"
160
+ source = { registry = "https://pypi.org/simple" }
161
+ sdist = { url = "https://files.pythonhosted.org/packages/e8/5d/447af5ea094b9e4c4054f82e223ada074c552335b9b4b2d14bd9b35a67c4/joblib-1.5.2.tar.gz", hash = "sha256:3faa5c39054b2f03ca547da9b2f52fde67c06240c31853f306aea97f13647b55", size = 331077, upload-time = "2025-08-27T12:15:46.575Z" }
162
+ wheels = [
163
+ { url = "https://files.pythonhosted.org/packages/1e/e8/685f47e0d754320684db4425a0967f7d3fa70126bffd76110b7009a0090f/joblib-1.5.2-py3-none-any.whl", hash = "sha256:4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241", size = 308396, upload-time = "2025-08-27T12:15:45.188Z" },
164
+ ]
165
+
166
+ [[package]]
167
+ name = "numpy"
168
+ version = "2.3.4"
169
+ source = { registry = "https://pypi.org/simple" }
170
+ sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187, upload-time = "2025-10-15T16:18:11.77Z" }
171
+ wheels = [
172
+ { url = "https://files.pythonhosted.org/packages/96/7a/02420400b736f84317e759291b8edaeee9dc921f72b045475a9cbdb26b17/numpy-2.3.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ef1b5a3e808bc40827b5fa2c8196151a4c5abe110e1726949d7abddfe5c7ae11", size = 20957727, upload-time = "2025-10-15T16:15:44.9Z" },
173
+ { url = "https://files.pythonhosted.org/packages/18/90/a014805d627aa5750f6f0e878172afb6454552da929144b3c07fcae1bb13/numpy-2.3.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2f91f496a87235c6aaf6d3f3d89b17dba64996abadccb289f48456cff931ca9", size = 14187262, upload-time = "2025-10-15T16:15:47.761Z" },
174
+ { url = "https://files.pythonhosted.org/packages/c7/e4/0a94b09abe89e500dc748e7515f21a13e30c5c3fe3396e6d4ac108c25fca/numpy-2.3.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f77e5b3d3da652b474cc80a14084927a5e86a5eccf54ca8ca5cbd697bf7f2667", size = 5115992, upload-time = "2025-10-15T16:15:50.144Z" },
175
+ { url = "https://files.pythonhosted.org/packages/88/dd/db77c75b055c6157cbd4f9c92c4458daef0dd9cbe6d8d2fe7f803cb64c37/numpy-2.3.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:8ab1c5f5ee40d6e01cbe96de5863e39b215a4d24e7d007cad56c7184fdf4aeef", size = 6648672, upload-time = "2025-10-15T16:15:52.442Z" },
176
+ { url = "https://files.pythonhosted.org/packages/e1/e6/e31b0d713719610e406c0ea3ae0d90760465b086da8783e2fd835ad59027/numpy-2.3.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77b84453f3adcb994ddbd0d1c5d11db2d6bda1a2b7fd5ac5bd4649d6f5dc682e", size = 14284156, upload-time = "2025-10-15T16:15:54.351Z" },
177
+ { url = "https://files.pythonhosted.org/packages/f9/58/30a85127bfee6f108282107caf8e06a1f0cc997cb6b52cdee699276fcce4/numpy-2.3.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4121c5beb58a7f9e6dfdee612cb24f4df5cd4db6e8261d7f4d7450a997a65d6a", size = 16641271, upload-time = "2025-10-15T16:15:56.67Z" },
178
+ { url = "https://files.pythonhosted.org/packages/06/f2/2e06a0f2adf23e3ae29283ad96959267938d0efd20a2e25353b70065bfec/numpy-2.3.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65611ecbb00ac9846efe04db15cbe6186f562f6bb7e5e05f077e53a599225d16", size = 16059531, upload-time = "2025-10-15T16:15:59.412Z" },
179
+ { url = "https://files.pythonhosted.org/packages/b0/e7/b106253c7c0d5dc352b9c8fab91afd76a93950998167fa3e5afe4ef3a18f/numpy-2.3.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dabc42f9c6577bcc13001b8810d300fe814b4cfbe8a92c873f269484594f9786", size = 18578983, upload-time = "2025-10-15T16:16:01.804Z" },
180
+ { url = "https://files.pythonhosted.org/packages/73/e3/04ecc41e71462276ee867ccbef26a4448638eadecf1bc56772c9ed6d0255/numpy-2.3.4-cp312-cp312-win32.whl", hash = "sha256:a49d797192a8d950ca59ee2d0337a4d804f713bb5c3c50e8db26d49666e351dc", size = 6291380, upload-time = "2025-10-15T16:16:03.938Z" },
181
+ { url = "https://files.pythonhosted.org/packages/3d/a8/566578b10d8d0e9955b1b6cd5db4e9d4592dd0026a941ff7994cedda030a/numpy-2.3.4-cp312-cp312-win_amd64.whl", hash = "sha256:985f1e46358f06c2a09921e8921e2c98168ed4ae12ccd6e5e87a4f1857923f32", size = 12787999, upload-time = "2025-10-15T16:16:05.801Z" },
182
+ { url = "https://files.pythonhosted.org/packages/58/22/9c903a957d0a8071b607f5b1bff0761d6e608b9a965945411f867d515db1/numpy-2.3.4-cp312-cp312-win_arm64.whl", hash = "sha256:4635239814149e06e2cb9db3dd584b2fa64316c96f10656983b8026a82e6e4db", size = 10197412, upload-time = "2025-10-15T16:16:07.854Z" },
183
+ { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335, upload-time = "2025-10-15T16:16:10.304Z" },
184
+ { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878, upload-time = "2025-10-15T16:16:12.595Z" },
185
+ { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673, upload-time = "2025-10-15T16:16:14.877Z" },
186
+ { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438, upload-time = "2025-10-15T16:16:16.805Z" },
187
+ { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290, upload-time = "2025-10-15T16:16:18.764Z" },
188
+ { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543, upload-time = "2025-10-15T16:16:21.072Z" },
189
+ { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117, upload-time = "2025-10-15T16:16:23.369Z" },
190
+ { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788, upload-time = "2025-10-15T16:16:27.496Z" },
191
+ { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620, upload-time = "2025-10-15T16:16:29.811Z" },
192
+ { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672, upload-time = "2025-10-15T16:16:31.589Z" },
193
+ { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702, upload-time = "2025-10-15T16:16:33.902Z" },
194
+ { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003, upload-time = "2025-10-15T16:16:36.101Z" },
195
+ { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980, upload-time = "2025-10-15T16:16:39.124Z" },
196
+ { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472, upload-time = "2025-10-15T16:16:41.168Z" },
197
+ { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342, upload-time = "2025-10-15T16:16:43.777Z" },
198
+ { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338, upload-time = "2025-10-15T16:16:46.081Z" },
199
+ { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392, upload-time = "2025-10-15T16:16:48.455Z" },
200
+ { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998, upload-time = "2025-10-15T16:16:51.114Z" },
201
+ { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574, upload-time = "2025-10-15T16:16:53.429Z" },
202
+ { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135, upload-time = "2025-10-15T16:16:55.992Z" },
203
+ { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582, upload-time = "2025-10-15T16:16:57.943Z" },
204
+ { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691, upload-time = "2025-10-15T16:17:00.048Z" },
205
+ { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580, upload-time = "2025-10-15T16:17:02.509Z" },
206
+ { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056, upload-time = "2025-10-15T16:17:04.873Z" },
207
+ { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555, upload-time = "2025-10-15T16:17:07.499Z" },
208
+ { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581, upload-time = "2025-10-15T16:17:09.774Z" },
209
+ { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186, upload-time = "2025-10-15T16:17:11.937Z" },
210
+ { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601, upload-time = "2025-10-15T16:17:14.391Z" },
211
+ { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219, upload-time = "2025-10-15T16:17:17.058Z" },
212
+ { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702, upload-time = "2025-10-15T16:17:19.379Z" },
213
+ { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136, upload-time = "2025-10-15T16:17:22.886Z" },
214
+ { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542, upload-time = "2025-10-15T16:17:24.783Z" },
215
+ { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213, upload-time = "2025-10-15T16:17:26.935Z" },
216
+ { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280, upload-time = "2025-10-15T16:17:29.638Z" },
217
+ { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930, upload-time = "2025-10-15T16:17:32.384Z" },
218
+ { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504, upload-time = "2025-10-15T16:17:34.515Z" },
219
+ { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405, upload-time = "2025-10-15T16:17:36.128Z" },
220
+ { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866, upload-time = "2025-10-15T16:17:38.884Z" },
221
+ { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296, upload-time = "2025-10-15T16:17:41.564Z" },
222
+ { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046, upload-time = "2025-10-15T16:17:43.901Z" },
223
+ { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691, upload-time = "2025-10-15T16:17:46.247Z" },
224
+ { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782, upload-time = "2025-10-15T16:17:48.872Z" },
225
+ { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301, upload-time = "2025-10-15T16:17:50.938Z" },
226
+ { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532, upload-time = "2025-10-15T16:17:53.48Z" },
227
+ ]
228
+
229
+ [[package]]
230
+ name = "pydantic"
231
+ version = "2.12.3"
232
+ source = { registry = "https://pypi.org/simple" }
233
+ dependencies = [
234
+ { name = "annotated-types" },
235
+ { name = "pydantic-core" },
236
+ { name = "typing-extensions" },
237
+ { name = "typing-inspection" },
238
+ ]
239
+ sdist = { url = "https://files.pythonhosted.org/packages/f3/1e/4f0a3233767010308f2fd6bd0814597e3f63f1dc98304a9112b8759df4ff/pydantic-2.12.3.tar.gz", hash = "sha256:1da1c82b0fc140bb0103bc1441ffe062154c8d38491189751ee00fd8ca65ce74", size = 819383, upload-time = "2025-10-17T15:04:21.222Z" }
240
+ wheels = [
241
+ { url = "https://files.pythonhosted.org/packages/a1/6b/83661fa77dcefa195ad5f8cd9af3d1a7450fd57cc883ad04d65446ac2029/pydantic-2.12.3-py3-none-any.whl", hash = "sha256:6986454a854bc3bc6e5443e1369e06a3a456af9d339eda45510f517d9ea5c6bf", size = 462431, upload-time = "2025-10-17T15:04:19.346Z" },
242
+ ]
243
+
244
+ [[package]]
245
+ name = "pydantic-core"
246
+ version = "2.41.4"
247
+ source = { registry = "https://pypi.org/simple" }
248
+ dependencies = [
249
+ { name = "typing-extensions" },
250
+ ]
251
+ sdist = { url = "https://files.pythonhosted.org/packages/df/18/d0944e8eaaa3efd0a91b0f1fc537d3be55ad35091b6a87638211ba691964/pydantic_core-2.41.4.tar.gz", hash = "sha256:70e47929a9d4a1905a67e4b687d5946026390568a8e952b92824118063cee4d5", size = 457557, upload-time = "2025-10-14T10:23:47.909Z" }
252
+ wheels = [
253
+ { url = "https://files.pythonhosted.org/packages/e9/81/d3b3e95929c4369d30b2a66a91db63c8ed0a98381ae55a45da2cd1cc1288/pydantic_core-2.41.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ab06d77e053d660a6faaf04894446df7b0a7e7aba70c2797465a0a1af00fc887", size = 2099043, upload-time = "2025-10-14T10:20:28.561Z" },
254
+ { url = "https://files.pythonhosted.org/packages/58/da/46fdac49e6717e3a94fc9201403e08d9d61aa7a770fab6190b8740749047/pydantic_core-2.41.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c53ff33e603a9c1179a9364b0a24694f183717b2e0da2b5ad43c316c956901b2", size = 1910699, upload-time = "2025-10-14T10:20:30.217Z" },
255
+ { url = "https://files.pythonhosted.org/packages/1e/63/4d948f1b9dd8e991a5a98b77dd66c74641f5f2e5225fee37994b2e07d391/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:304c54176af2c143bd181d82e77c15c41cbacea8872a2225dd37e6544dce9999", size = 1952121, upload-time = "2025-10-14T10:20:32.246Z" },
256
+ { url = "https://files.pythonhosted.org/packages/b2/a7/e5fc60a6f781fc634ecaa9ecc3c20171d238794cef69ae0af79ac11b89d7/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:025ba34a4cf4fb32f917d5d188ab5e702223d3ba603be4d8aca2f82bede432a4", size = 2041590, upload-time = "2025-10-14T10:20:34.332Z" },
257
+ { url = "https://files.pythonhosted.org/packages/70/69/dce747b1d21d59e85af433428978a1893c6f8a7068fa2bb4a927fba7a5ff/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9f5f30c402ed58f90c70e12eff65547d3ab74685ffe8283c719e6bead8ef53f", size = 2219869, upload-time = "2025-10-14T10:20:35.965Z" },
258
+ { url = "https://files.pythonhosted.org/packages/83/6a/c070e30e295403bf29c4df1cb781317b6a9bac7cd07b8d3acc94d501a63c/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd96e5d15385d301733113bcaa324c8bcf111275b7675a9c6e88bfb19fc05e3b", size = 2345169, upload-time = "2025-10-14T10:20:37.627Z" },
259
+ { url = "https://files.pythonhosted.org/packages/f0/83/06d001f8043c336baea7fd202a9ac7ad71f87e1c55d8112c50b745c40324/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98f348cbb44fae6e9653c1055db7e29de67ea6a9ca03a5fa2c2e11a47cff0e47", size = 2070165, upload-time = "2025-10-14T10:20:39.246Z" },
260
+ { url = "https://files.pythonhosted.org/packages/14/0a/e567c2883588dd12bcbc110232d892cf385356f7c8a9910311ac997ab715/pydantic_core-2.41.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec22626a2d14620a83ca583c6f5a4080fa3155282718b6055c2ea48d3ef35970", size = 2189067, upload-time = "2025-10-14T10:20:41.015Z" },
261
+ { url = "https://files.pythonhosted.org/packages/f4/1d/3d9fca34273ba03c9b1c5289f7618bc4bd09c3ad2289b5420481aa051a99/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a95d4590b1f1a43bf33ca6d647b990a88f4a3824a8c4572c708f0b45a5290ed", size = 2132997, upload-time = "2025-10-14T10:20:43.106Z" },
262
+ { url = "https://files.pythonhosted.org/packages/52/70/d702ef7a6cd41a8afc61f3554922b3ed8d19dd54c3bd4bdbfe332e610827/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:f9672ab4d398e1b602feadcffcdd3af44d5f5e6ddc15bc7d15d376d47e8e19f8", size = 2307187, upload-time = "2025-10-14T10:20:44.849Z" },
263
+ { url = "https://files.pythonhosted.org/packages/68/4c/c06be6e27545d08b802127914156f38d10ca287a9e8489342793de8aae3c/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:84d8854db5f55fead3b579f04bda9a36461dab0730c5d570e1526483e7bb8431", size = 2305204, upload-time = "2025-10-14T10:20:46.781Z" },
264
+ { url = "https://files.pythonhosted.org/packages/b0/e5/35ae4919bcd9f18603419e23c5eaf32750224a89d41a8df1a3704b69f77e/pydantic_core-2.41.4-cp312-cp312-win32.whl", hash = "sha256:9be1c01adb2ecc4e464392c36d17f97e9110fbbc906bcbe1c943b5b87a74aabd", size = 1972536, upload-time = "2025-10-14T10:20:48.39Z" },
265
+ { url = "https://files.pythonhosted.org/packages/1e/c2/49c5bb6d2a49eb2ee3647a93e3dae7080c6409a8a7558b075027644e879c/pydantic_core-2.41.4-cp312-cp312-win_amd64.whl", hash = "sha256:d682cf1d22bab22a5be08539dca3d1593488a99998f9f412137bc323179067ff", size = 2031132, upload-time = "2025-10-14T10:20:50.421Z" },
266
+ { url = "https://files.pythonhosted.org/packages/06/23/936343dbcba6eec93f73e95eb346810fc732f71ba27967b287b66f7b7097/pydantic_core-2.41.4-cp312-cp312-win_arm64.whl", hash = "sha256:833eebfd75a26d17470b58768c1834dfc90141b7afc6eb0429c21fc5a21dcfb8", size = 1969483, upload-time = "2025-10-14T10:20:52.35Z" },
267
+ { url = "https://files.pythonhosted.org/packages/13/d0/c20adabd181a029a970738dfe23710b52a31f1258f591874fcdec7359845/pydantic_core-2.41.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:85e050ad9e5f6fe1004eec65c914332e52f429bc0ae12d6fa2092407a462c746", size = 2105688, upload-time = "2025-10-14T10:20:54.448Z" },
268
+ { url = "https://files.pythonhosted.org/packages/00/b6/0ce5c03cec5ae94cca220dfecddc453c077d71363b98a4bbdb3c0b22c783/pydantic_core-2.41.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7393f1d64792763a48924ba31d1e44c2cfbc05e3b1c2c9abb4ceeadd912cced", size = 1910807, upload-time = "2025-10-14T10:20:56.115Z" },
269
+ { url = "https://files.pythonhosted.org/packages/68/3e/800d3d02c8beb0b5c069c870cbb83799d085debf43499c897bb4b4aaff0d/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94dab0940b0d1fb28bcab847adf887c66a27a40291eedf0b473be58761c9799a", size = 1956669, upload-time = "2025-10-14T10:20:57.874Z" },
270
+ { url = "https://files.pythonhosted.org/packages/60/a4/24271cc71a17f64589be49ab8bd0751f6a0a03046c690df60989f2f95c2c/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de7c42f897e689ee6f9e93c4bec72b99ae3b32a2ade1c7e4798e690ff5246e02", size = 2051629, upload-time = "2025-10-14T10:21:00.006Z" },
271
+ { url = "https://files.pythonhosted.org/packages/68/de/45af3ca2f175d91b96bfb62e1f2d2f1f9f3b14a734afe0bfeff079f78181/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:664b3199193262277b8b3cd1e754fb07f2c6023289c815a1e1e8fb415cb247b1", size = 2224049, upload-time = "2025-10-14T10:21:01.801Z" },
272
+ { url = "https://files.pythonhosted.org/packages/af/8f/ae4e1ff84672bf869d0a77af24fd78387850e9497753c432875066b5d622/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d95b253b88f7d308b1c0b417c4624f44553ba4762816f94e6986819b9c273fb2", size = 2342409, upload-time = "2025-10-14T10:21:03.556Z" },
273
+ { url = "https://files.pythonhosted.org/packages/18/62/273dd70b0026a085c7b74b000394e1ef95719ea579c76ea2f0cc8893736d/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1351f5bbdbbabc689727cb91649a00cb9ee7203e0a6e54e9f5ba9e22e384b84", size = 2069635, upload-time = "2025-10-14T10:21:05.385Z" },
274
+ { url = "https://files.pythonhosted.org/packages/30/03/cf485fff699b4cdaea469bc481719d3e49f023241b4abb656f8d422189fc/pydantic_core-2.41.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1affa4798520b148d7182da0615d648e752de4ab1a9566b7471bc803d88a062d", size = 2194284, upload-time = "2025-10-14T10:21:07.122Z" },
275
+ { url = "https://files.pythonhosted.org/packages/f9/7e/c8e713db32405dfd97211f2fc0a15d6bf8adb7640f3d18544c1f39526619/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7b74e18052fea4aa8dea2fb7dbc23d15439695da6cbe6cfc1b694af1115df09d", size = 2137566, upload-time = "2025-10-14T10:21:08.981Z" },
276
+ { url = "https://files.pythonhosted.org/packages/04/f7/db71fd4cdccc8b75990f79ccafbbd66757e19f6d5ee724a6252414483fb4/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:285b643d75c0e30abda9dc1077395624f314a37e3c09ca402d4015ef5979f1a2", size = 2316809, upload-time = "2025-10-14T10:21:10.805Z" },
277
+ { url = "https://files.pythonhosted.org/packages/76/63/a54973ddb945f1bca56742b48b144d85c9fc22f819ddeb9f861c249d5464/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f52679ff4218d713b3b33f88c89ccbf3a5c2c12ba665fb80ccc4192b4608dbab", size = 2311119, upload-time = "2025-10-14T10:21:12.583Z" },
278
+ { url = "https://files.pythonhosted.org/packages/f8/03/5d12891e93c19218af74843a27e32b94922195ded2386f7b55382f904d2f/pydantic_core-2.41.4-cp313-cp313-win32.whl", hash = "sha256:ecde6dedd6fff127c273c76821bb754d793be1024bc33314a120f83a3c69460c", size = 1981398, upload-time = "2025-10-14T10:21:14.584Z" },
279
+ { url = "https://files.pythonhosted.org/packages/be/d8/fd0de71f39db91135b7a26996160de71c073d8635edfce8b3c3681be0d6d/pydantic_core-2.41.4-cp313-cp313-win_amd64.whl", hash = "sha256:d081a1f3800f05409ed868ebb2d74ac39dd0c1ff6c035b5162356d76030736d4", size = 2030735, upload-time = "2025-10-14T10:21:16.432Z" },
280
+ { url = "https://files.pythonhosted.org/packages/72/86/c99921c1cf6650023c08bfab6fe2d7057a5142628ef7ccfa9921f2dda1d5/pydantic_core-2.41.4-cp313-cp313-win_arm64.whl", hash = "sha256:f8e49c9c364a7edcbe2a310f12733aad95b022495ef2a8d653f645e5d20c1564", size = 1973209, upload-time = "2025-10-14T10:21:18.213Z" },
281
+ { url = "https://files.pythonhosted.org/packages/36/0d/b5706cacb70a8414396efdda3d72ae0542e050b591119e458e2490baf035/pydantic_core-2.41.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ed97fd56a561f5eb5706cebe94f1ad7c13b84d98312a05546f2ad036bafe87f4", size = 1877324, upload-time = "2025-10-14T10:21:20.363Z" },
282
+ { url = "https://files.pythonhosted.org/packages/de/2d/cba1fa02cfdea72dfb3a9babb067c83b9dff0bbcb198368e000a6b756ea7/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a870c307bf1ee91fc58a9a61338ff780d01bfae45922624816878dce784095d2", size = 1884515, upload-time = "2025-10-14T10:21:22.339Z" },
283
+ { url = "https://files.pythonhosted.org/packages/07/ea/3df927c4384ed9b503c9cc2d076cf983b4f2adb0c754578dfb1245c51e46/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25e97bc1f5f8f7985bdc2335ef9e73843bb561eb1fa6831fdfc295c1c2061cf", size = 2042819, upload-time = "2025-10-14T10:21:26.683Z" },
284
+ { url = "https://files.pythonhosted.org/packages/6a/ee/df8e871f07074250270a3b1b82aad4cd0026b588acd5d7d3eb2fcb1471a3/pydantic_core-2.41.4-cp313-cp313t-win_amd64.whl", hash = "sha256:d405d14bea042f166512add3091c1af40437c2e7f86988f3915fabd27b1e9cd2", size = 1995866, upload-time = "2025-10-14T10:21:28.951Z" },
285
+ { url = "https://files.pythonhosted.org/packages/fc/de/b20f4ab954d6d399499c33ec4fafc46d9551e11dc1858fb7f5dca0748ceb/pydantic_core-2.41.4-cp313-cp313t-win_arm64.whl", hash = "sha256:19f3684868309db5263a11bace3c45d93f6f24afa2ffe75a647583df22a2ff89", size = 1970034, upload-time = "2025-10-14T10:21:30.869Z" },
286
+ { url = "https://files.pythonhosted.org/packages/54/28/d3325da57d413b9819365546eb9a6e8b7cbd9373d9380efd5f74326143e6/pydantic_core-2.41.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:e9205d97ed08a82ebb9a307e92914bb30e18cdf6f6b12ca4bedadb1588a0bfe1", size = 2102022, upload-time = "2025-10-14T10:21:32.809Z" },
287
+ { url = "https://files.pythonhosted.org/packages/9e/24/b58a1bc0d834bf1acc4361e61233ee217169a42efbdc15a60296e13ce438/pydantic_core-2.41.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82df1f432b37d832709fbcc0e24394bba04a01b6ecf1ee87578145c19cde12ac", size = 1905495, upload-time = "2025-10-14T10:21:34.812Z" },
288
+ { url = "https://files.pythonhosted.org/packages/fb/a4/71f759cc41b7043e8ecdaab81b985a9b6cad7cec077e0b92cff8b71ecf6b/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3b4cc4539e055cfa39a3763c939f9d409eb40e85813257dcd761985a108554", size = 1956131, upload-time = "2025-10-14T10:21:36.924Z" },
289
+ { url = "https://files.pythonhosted.org/packages/b0/64/1e79ac7aa51f1eec7c4cda8cbe456d5d09f05fdd68b32776d72168d54275/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1eb1754fce47c63d2ff57fdb88c351a6c0150995890088b33767a10218eaa4e", size = 2052236, upload-time = "2025-10-14T10:21:38.927Z" },
290
+ { url = "https://files.pythonhosted.org/packages/e9/e3/a3ffc363bd4287b80f1d43dc1c28ba64831f8dfc237d6fec8f2661138d48/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6ab5ab30ef325b443f379ddb575a34969c333004fca5a1daa0133a6ffaad616", size = 2223573, upload-time = "2025-10-14T10:21:41.574Z" },
291
+ { url = "https://files.pythonhosted.org/packages/28/27/78814089b4d2e684a9088ede3790763c64693c3d1408ddc0a248bc789126/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31a41030b1d9ca497634092b46481b937ff9397a86f9f51bd41c4767b6fc04af", size = 2342467, upload-time = "2025-10-14T10:21:44.018Z" },
292
+ { url = "https://files.pythonhosted.org/packages/92/97/4de0e2a1159cb85ad737e03306717637842c88c7fd6d97973172fb183149/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a44ac1738591472c3d020f61c6df1e4015180d6262ebd39bf2aeb52571b60f12", size = 2063754, upload-time = "2025-10-14T10:21:46.466Z" },
293
+ { url = "https://files.pythonhosted.org/packages/0f/50/8cb90ce4b9efcf7ae78130afeb99fd1c86125ccdf9906ef64b9d42f37c25/pydantic_core-2.41.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d72f2b5e6e82ab8f94ea7d0d42f83c487dc159c5240d8f83beae684472864e2d", size = 2196754, upload-time = "2025-10-14T10:21:48.486Z" },
294
+ { url = "https://files.pythonhosted.org/packages/34/3b/ccdc77af9cd5082723574a1cc1bcae7a6acacc829d7c0a06201f7886a109/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c4d1e854aaf044487d31143f541f7aafe7b482ae72a022c664b2de2e466ed0ad", size = 2137115, upload-time = "2025-10-14T10:21:50.63Z" },
295
+ { url = "https://files.pythonhosted.org/packages/ca/ba/e7c7a02651a8f7c52dc2cff2b64a30c313e3b57c7d93703cecea76c09b71/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b568af94267729d76e6ee5ececda4e283d07bbb28e8148bb17adad93d025d25a", size = 2317400, upload-time = "2025-10-14T10:21:52.959Z" },
296
+ { url = "https://files.pythonhosted.org/packages/2c/ba/6c533a4ee8aec6b812c643c49bb3bd88d3f01e3cebe451bb85512d37f00f/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6d55fb8b1e8929b341cc313a81a26e0d48aa3b519c1dbaadec3a6a2b4fcad025", size = 2312070, upload-time = "2025-10-14T10:21:55.419Z" },
297
+ { url = "https://files.pythonhosted.org/packages/22/ae/f10524fcc0ab8d7f96cf9a74c880243576fd3e72bd8ce4f81e43d22bcab7/pydantic_core-2.41.4-cp314-cp314-win32.whl", hash = "sha256:5b66584e549e2e32a1398df11da2e0a7eff45d5c2d9db9d5667c5e6ac764d77e", size = 1982277, upload-time = "2025-10-14T10:21:57.474Z" },
298
+ { url = "https://files.pythonhosted.org/packages/b4/dc/e5aa27aea1ad4638f0c3fb41132f7eb583bd7420ee63204e2d4333a3bbf9/pydantic_core-2.41.4-cp314-cp314-win_amd64.whl", hash = "sha256:557a0aab88664cc552285316809cab897716a372afaf8efdbef756f8b890e894", size = 2024608, upload-time = "2025-10-14T10:21:59.557Z" },
299
+ { url = "https://files.pythonhosted.org/packages/3e/61/51d89cc2612bd147198e120a13f150afbf0bcb4615cddb049ab10b81b79e/pydantic_core-2.41.4-cp314-cp314-win_arm64.whl", hash = "sha256:3f1ea6f48a045745d0d9f325989d8abd3f1eaf47dd00485912d1a3a63c623a8d", size = 1967614, upload-time = "2025-10-14T10:22:01.847Z" },
300
+ { url = "https://files.pythonhosted.org/packages/0d/c2/472f2e31b95eff099961fa050c376ab7156a81da194f9edb9f710f68787b/pydantic_core-2.41.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6c1fe4c5404c448b13188dd8bd2ebc2bdd7e6727fa61ff481bcc2cca894018da", size = 1876904, upload-time = "2025-10-14T10:22:04.062Z" },
301
+ { url = "https://files.pythonhosted.org/packages/4a/07/ea8eeb91173807ecdae4f4a5f4b150a520085b35454350fc219ba79e66a3/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:523e7da4d43b113bf8e7b49fa4ec0c35bf4fe66b2230bfc5c13cc498f12c6c3e", size = 1882538, upload-time = "2025-10-14T10:22:06.39Z" },
302
+ { url = "https://files.pythonhosted.org/packages/1e/29/b53a9ca6cd366bfc928823679c6a76c7a4c69f8201c0ba7903ad18ebae2f/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5729225de81fb65b70fdb1907fcf08c75d498f4a6f15af005aabb1fdadc19dfa", size = 2041183, upload-time = "2025-10-14T10:22:08.812Z" },
303
+ { url = "https://files.pythonhosted.org/packages/c7/3d/f8c1a371ceebcaf94d6dd2d77c6cf4b1c078e13a5837aee83f760b4f7cfd/pydantic_core-2.41.4-cp314-cp314t-win_amd64.whl", hash = "sha256:de2cfbb09e88f0f795fd90cf955858fc2c691df65b1f21f0aa00b99f3fbc661d", size = 1993542, upload-time = "2025-10-14T10:22:11.332Z" },
304
+ { url = "https://files.pythonhosted.org/packages/8a/ac/9fc61b4f9d079482a290afe8d206b8f490e9fd32d4fc03ed4fc698214e01/pydantic_core-2.41.4-cp314-cp314t-win_arm64.whl", hash = "sha256:d34f950ae05a83e0ede899c595f312ca976023ea1db100cd5aa188f7005e3ab0", size = 1973897, upload-time = "2025-10-14T10:22:13.444Z" },
305
+ { url = "https://files.pythonhosted.org/packages/c4/48/ae937e5a831b7c0dc646b2ef788c27cd003894882415300ed21927c21efa/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:4f5d640aeebb438517150fdeec097739614421900e4a08db4a3ef38898798537", size = 2112087, upload-time = "2025-10-14T10:22:56.818Z" },
306
+ { url = "https://files.pythonhosted.org/packages/5e/db/6db8073e3d32dae017da7e0d16a9ecb897d0a4d92e00634916e486097961/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:4a9ab037b71927babc6d9e7fc01aea9e66dc2a4a34dff06ef0724a4049629f94", size = 1920387, upload-time = "2025-10-14T10:22:59.342Z" },
307
+ { url = "https://files.pythonhosted.org/packages/0d/c1/dd3542d072fcc336030d66834872f0328727e3b8de289c662faa04aa270e/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4dab9484ec605c3016df9ad4fd4f9a390bc5d816a3b10c6550f8424bb80b18c", size = 1951495, upload-time = "2025-10-14T10:23:02.089Z" },
308
+ { url = "https://files.pythonhosted.org/packages/2b/c6/db8d13a1f8ab3f1eb08c88bd00fd62d44311e3456d1e85c0e59e0a0376e7/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8a5028425820731d8c6c098ab642d7b8b999758e24acae03ed38a66eca8335", size = 2139008, upload-time = "2025-10-14T10:23:04.539Z" },
309
+ ]
310
+
311
+ [[package]]
312
+ name = "requests"
313
+ version = "2.32.5"
314
+ source = { registry = "https://pypi.org/simple" }
315
+ dependencies = [
316
+ { name = "certifi" },
317
+ { name = "charset-normalizer" },
318
+ { name = "idna" },
319
+ { name = "urllib3" },
320
+ ]
321
+ sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" }
322
+ wheels = [
323
+ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
324
+ ]
325
+
326
+ [[package]]
327
+ name = "scikit-learn"
328
+ version = "1.7.2"
329
+ source = { registry = "https://pypi.org/simple" }
330
+ dependencies = [
331
+ { name = "joblib" },
332
+ { name = "numpy" },
333
+ { name = "scipy" },
334
+ { name = "threadpoolctl" },
335
+ ]
336
+ sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" }
337
+ wheels = [
338
+ { url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818, upload-time = "2025-09-09T08:20:43.19Z" },
339
+ { url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997, upload-time = "2025-09-09T08:20:45.468Z" },
340
+ { url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381, upload-time = "2025-09-09T08:20:47.982Z" },
341
+ { url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296, upload-time = "2025-09-09T08:20:50.366Z" },
342
+ { url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256, upload-time = "2025-09-09T08:20:52.627Z" },
343
+ { url = "https://files.pythonhosted.org/packages/ae/93/a3038cb0293037fd335f77f31fe053b89c72f17b1c8908c576c29d953e84/scikit_learn-1.7.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b7dacaa05e5d76759fb071558a8b5130f4845166d88654a0f9bdf3eb57851b7", size = 9212382, upload-time = "2025-09-09T08:20:54.731Z" },
344
+ { url = "https://files.pythonhosted.org/packages/40/dd/9a88879b0c1104259136146e4742026b52df8540c39fec21a6383f8292c7/scikit_learn-1.7.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:abebbd61ad9e1deed54cca45caea8ad5f79e1b93173dece40bb8e0c658dbe6fe", size = 8592042, upload-time = "2025-09-09T08:20:57.313Z" },
345
+ { url = "https://files.pythonhosted.org/packages/46/af/c5e286471b7d10871b811b72ae794ac5fe2989c0a2df07f0ec723030f5f5/scikit_learn-1.7.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:502c18e39849c0ea1a5d681af1dbcf15f6cce601aebb657aabbfe84133c1907f", size = 9434180, upload-time = "2025-09-09T08:20:59.671Z" },
346
+ { url = "https://files.pythonhosted.org/packages/f1/fd/df59faa53312d585023b2da27e866524ffb8faf87a68516c23896c718320/scikit_learn-1.7.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a4c328a71785382fe3fe676a9ecf2c86189249beff90bf85e22bdb7efaf9ae0", size = 9283660, upload-time = "2025-09-09T08:21:01.71Z" },
347
+ { url = "https://files.pythonhosted.org/packages/a7/c7/03000262759d7b6f38c836ff9d512f438a70d8a8ddae68ee80de72dcfb63/scikit_learn-1.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:63a9afd6f7b229aad94618c01c252ce9e6fa97918c5ca19c9a17a087d819440c", size = 8702057, upload-time = "2025-09-09T08:21:04.234Z" },
348
+ { url = "https://files.pythonhosted.org/packages/55/87/ef5eb1f267084532c8e4aef98a28b6ffe7425acbfd64b5e2f2e066bc29b3/scikit_learn-1.7.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9acb6c5e867447b4e1390930e3944a005e2cb115922e693c08a323421a6966e8", size = 9558731, upload-time = "2025-09-09T08:21:06.381Z" },
349
+ { url = "https://files.pythonhosted.org/packages/93/f8/6c1e3fc14b10118068d7938878a9f3f4e6d7b74a8ddb1e5bed65159ccda8/scikit_learn-1.7.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:2a41e2a0ef45063e654152ec9d8bcfc39f7afce35b08902bfe290c2498a67a6a", size = 9038852, upload-time = "2025-09-09T08:21:08.628Z" },
350
+ { url = "https://files.pythonhosted.org/packages/83/87/066cafc896ee540c34becf95d30375fe5cbe93c3b75a0ee9aa852cd60021/scikit_learn-1.7.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98335fb98509b73385b3ab2bd0639b1f610541d3988ee675c670371d6a87aa7c", size = 9527094, upload-time = "2025-09-09T08:21:11.486Z" },
351
+ { url = "https://files.pythonhosted.org/packages/9c/2b/4903e1ccafa1f6453b1ab78413938c8800633988c838aa0be386cbb33072/scikit_learn-1.7.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191e5550980d45449126e23ed1d5e9e24b2c68329ee1f691a3987476e115e09c", size = 9367436, upload-time = "2025-09-09T08:21:13.602Z" },
352
+ { url = "https://files.pythonhosted.org/packages/b5/aa/8444be3cfb10451617ff9d177b3c190288f4563e6c50ff02728be67ad094/scikit_learn-1.7.2-cp313-cp313t-win_amd64.whl", hash = "sha256:57dc4deb1d3762c75d685507fbd0bc17160144b2f2ba4ccea5dc285ab0d0e973", size = 9275749, upload-time = "2025-09-09T08:21:15.96Z" },
353
+ { url = "https://files.pythonhosted.org/packages/d9/82/dee5acf66837852e8e68df6d8d3a6cb22d3df997b733b032f513d95205b7/scikit_learn-1.7.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fa8f63940e29c82d1e67a45d5297bdebbcb585f5a5a50c4914cc2e852ab77f33", size = 9208906, upload-time = "2025-09-09T08:21:18.557Z" },
354
+ { url = "https://files.pythonhosted.org/packages/3c/30/9029e54e17b87cb7d50d51a5926429c683d5b4c1732f0507a6c3bed9bf65/scikit_learn-1.7.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:f95dc55b7902b91331fa4e5845dd5bde0580c9cd9612b1b2791b7e80c3d32615", size = 8627836, upload-time = "2025-09-09T08:21:20.695Z" },
355
+ { url = "https://files.pythonhosted.org/packages/60/18/4a52c635c71b536879f4b971c2cedf32c35ee78f48367885ed8025d1f7ee/scikit_learn-1.7.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9656e4a53e54578ad10a434dc1f993330568cfee176dff07112b8785fb413106", size = 9426236, upload-time = "2025-09-09T08:21:22.645Z" },
356
+ { url = "https://files.pythonhosted.org/packages/99/7e/290362f6ab582128c53445458a5befd471ed1ea37953d5bcf80604619250/scikit_learn-1.7.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96dc05a854add0e50d3f47a1ef21a10a595016da5b007c7d9cd9d0bffd1fcc61", size = 9312593, upload-time = "2025-09-09T08:21:24.65Z" },
357
+ { url = "https://files.pythonhosted.org/packages/8e/87/24f541b6d62b1794939ae6422f8023703bbf6900378b2b34e0b4384dfefd/scikit_learn-1.7.2-cp314-cp314-win_amd64.whl", hash = "sha256:bb24510ed3f9f61476181e4db51ce801e2ba37541def12dc9333b946fc7a9cf8", size = 8820007, upload-time = "2025-09-09T08:21:26.713Z" },
358
+ ]
359
+
360
+ [[package]]
361
+ name = "scipy"
362
+ version = "1.16.2"
363
+ source = { registry = "https://pypi.org/simple" }
364
+ dependencies = [
365
+ { name = "numpy" },
366
+ ]
367
+ sdist = { url = "https://files.pythonhosted.org/packages/4c/3b/546a6f0bfe791bbb7f8d591613454d15097e53f906308ec6f7c1ce588e8e/scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b", size = 30580599, upload-time = "2025-09-11T17:48:08.271Z" }
368
+ wheels = [
369
+ { url = "https://files.pythonhosted.org/packages/b7/8d/6396e00db1282279a4ddd507c5f5e11f606812b608ee58517ce8abbf883f/scipy-1.16.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:89d6c100fa5c48472047632e06f0876b3c4931aac1f4291afc81a3644316bb0d", size = 36646259, upload-time = "2025-09-11T17:40:39.329Z" },
370
+ { url = "https://files.pythonhosted.org/packages/3b/93/ea9edd7e193fceb8eef149804491890bde73fb169c896b61aa3e2d1e4e77/scipy-1.16.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ca748936cd579d3f01928b30a17dc474550b01272d8046e3e1ee593f23620371", size = 28888976, upload-time = "2025-09-11T17:40:46.82Z" },
371
+ { url = "https://files.pythonhosted.org/packages/91/4d/281fddc3d80fd738ba86fd3aed9202331180b01e2c78eaae0642f22f7e83/scipy-1.16.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:fac4f8ce2ddb40e2e3d0f7ec36d2a1e7f92559a2471e59aec37bd8d9de01fec0", size = 20879905, upload-time = "2025-09-11T17:40:52.545Z" },
372
+ { url = "https://files.pythonhosted.org/packages/69/40/b33b74c84606fd301b2915f0062e45733c6ff5708d121dd0deaa8871e2d0/scipy-1.16.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:033570f1dcefd79547a88e18bccacff025c8c647a330381064f561d43b821232", size = 23553066, upload-time = "2025-09-11T17:40:59.014Z" },
373
+ { url = "https://files.pythonhosted.org/packages/55/a7/22c739e2f21a42cc8f16bc76b47cff4ed54fbe0962832c589591c2abec34/scipy-1.16.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ea3421209bf00c8a5ef2227de496601087d8f638a2363ee09af059bd70976dc1", size = 33336407, upload-time = "2025-09-11T17:41:06.796Z" },
374
+ { url = "https://files.pythonhosted.org/packages/53/11/a0160990b82999b45874dc60c0c183d3a3a969a563fffc476d5a9995c407/scipy-1.16.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f66bd07ba6f84cd4a380b41d1bf3c59ea488b590a2ff96744845163309ee8e2f", size = 35673281, upload-time = "2025-09-11T17:41:15.055Z" },
375
+ { url = "https://files.pythonhosted.org/packages/96/53/7ef48a4cfcf243c3d0f1643f5887c81f29fdf76911c4e49331828e19fc0a/scipy-1.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e9feab931bd2aea4a23388c962df6468af3d808ddf2d40f94a81c5dc38f32ef", size = 36004222, upload-time = "2025-09-11T17:41:23.868Z" },
376
+ { url = "https://files.pythonhosted.org/packages/49/7f/71a69e0afd460049d41c65c630c919c537815277dfea214031005f474d78/scipy-1.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03dfc75e52f72cf23ec2ced468645321407faad8f0fe7b1f5b49264adbc29cb1", size = 38664586, upload-time = "2025-09-11T17:41:31.021Z" },
377
+ { url = "https://files.pythonhosted.org/packages/34/95/20e02ca66fb495a95fba0642fd48e0c390d0ece9b9b14c6e931a60a12dea/scipy-1.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:0ce54e07bbb394b417457409a64fd015be623f36e330ac49306433ffe04bc97e", size = 38550641, upload-time = "2025-09-11T17:41:36.61Z" },
378
+ { url = "https://files.pythonhosted.org/packages/92/ad/13646b9beb0a95528ca46d52b7babafbe115017814a611f2065ee4e61d20/scipy-1.16.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a8ffaa4ac0df81a0b94577b18ee079f13fecdb924df3328fc44a7dc5ac46851", size = 25456070, upload-time = "2025-09-11T17:41:41.3Z" },
379
+ { url = "https://files.pythonhosted.org/packages/c1/27/c5b52f1ee81727a9fc457f5ac1e9bf3d6eab311805ea615c83c27ba06400/scipy-1.16.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:84f7bf944b43e20b8a894f5fe593976926744f6c185bacfcbdfbb62736b5cc70", size = 36604856, upload-time = "2025-09-11T17:41:47.695Z" },
380
+ { url = "https://files.pythonhosted.org/packages/32/a9/15c20d08e950b540184caa8ced675ba1128accb0e09c653780ba023a4110/scipy-1.16.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5c39026d12edc826a1ef2ad35ad1e6d7f087f934bb868fc43fa3049c8b8508f9", size = 28864626, upload-time = "2025-09-11T17:41:52.642Z" },
381
+ { url = "https://files.pythonhosted.org/packages/4c/fc/ea36098df653cca26062a627c1a94b0de659e97127c8491e18713ca0e3b9/scipy-1.16.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e52729ffd45b68777c5319560014d6fd251294200625d9d70fd8626516fc49f5", size = 20855689, upload-time = "2025-09-11T17:41:57.886Z" },
382
+ { url = "https://files.pythonhosted.org/packages/dc/6f/d0b53be55727f3e6d7c72687ec18ea6d0047cf95f1f77488b99a2bafaee1/scipy-1.16.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:024dd4a118cccec09ca3209b7e8e614931a6ffb804b2a601839499cb88bdf925", size = 23512151, upload-time = "2025-09-11T17:42:02.303Z" },
383
+ { url = "https://files.pythonhosted.org/packages/11/85/bf7dab56e5c4b1d3d8eef92ca8ede788418ad38a7dc3ff50262f00808760/scipy-1.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a5dc7ee9c33019973a470556081b0fd3c9f4c44019191039f9769183141a4d9", size = 33329824, upload-time = "2025-09-11T17:42:07.549Z" },
384
+ { url = "https://files.pythonhosted.org/packages/da/6a/1a927b14ddc7714111ea51f4e568203b2bb6ed59bdd036d62127c1a360c8/scipy-1.16.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c2275ff105e508942f99d4e3bc56b6ef5e4b3c0af970386ca56b777608ce95b7", size = 35681881, upload-time = "2025-09-11T17:42:13.255Z" },
385
+ { url = "https://files.pythonhosted.org/packages/c1/5f/331148ea5780b4fcc7007a4a6a6ee0a0c1507a796365cc642d4d226e1c3a/scipy-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:af80196eaa84f033e48444d2e0786ec47d328ba00c71e4299b602235ffef9acb", size = 36006219, upload-time = "2025-09-11T17:42:18.765Z" },
386
+ { url = "https://files.pythonhosted.org/packages/46/3a/e991aa9d2aec723b4a8dcfbfc8365edec5d5e5f9f133888067f1cbb7dfc1/scipy-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9fb1eb735fe3d6ed1f89918224e3385fbf6f9e23757cacc35f9c78d3b712dd6e", size = 38682147, upload-time = "2025-09-11T17:42:25.177Z" },
387
+ { url = "https://files.pythonhosted.org/packages/a1/57/0f38e396ad19e41b4c5db66130167eef8ee620a49bc7d0512e3bb67e0cab/scipy-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:fda714cf45ba43c9d3bae8f2585c777f64e3f89a2e073b668b32ede412d8f52c", size = 38520766, upload-time = "2025-09-11T17:43:25.342Z" },
388
+ { url = "https://files.pythonhosted.org/packages/1b/a5/85d3e867b6822d331e26c862a91375bb7746a0b458db5effa093d34cdb89/scipy-1.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:2f5350da923ccfd0b00e07c3e5cfb316c1c0d6c1d864c07a72d092e9f20db104", size = 25451169, upload-time = "2025-09-11T17:43:30.198Z" },
389
+ { url = "https://files.pythonhosted.org/packages/09/d9/60679189bcebda55992d1a45498de6d080dcaf21ce0c8f24f888117e0c2d/scipy-1.16.2-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:53d8d2ee29b925344c13bda64ab51785f016b1b9617849dac10897f0701b20c1", size = 37012682, upload-time = "2025-09-11T17:42:30.677Z" },
390
+ { url = "https://files.pythonhosted.org/packages/83/be/a99d13ee4d3b7887a96f8c71361b9659ba4ef34da0338f14891e102a127f/scipy-1.16.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:9e05e33657efb4c6a9d23bd8300101536abd99c85cca82da0bffff8d8764d08a", size = 29389926, upload-time = "2025-09-11T17:42:35.845Z" },
391
+ { url = "https://files.pythonhosted.org/packages/bf/0a/130164a4881cec6ca8c00faf3b57926f28ed429cd6001a673f83c7c2a579/scipy-1.16.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7fe65b36036357003b3ef9d37547abeefaa353b237e989c21027b8ed62b12d4f", size = 21381152, upload-time = "2025-09-11T17:42:40.07Z" },
392
+ { url = "https://files.pythonhosted.org/packages/47/a6/503ffb0310ae77fba874e10cddfc4a1280bdcca1d13c3751b8c3c2996cf8/scipy-1.16.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6406d2ac6d40b861cccf57f49592f9779071655e9f75cd4f977fa0bdd09cb2e4", size = 23914410, upload-time = "2025-09-11T17:42:44.313Z" },
393
+ { url = "https://files.pythonhosted.org/packages/fa/c7/1147774bcea50d00c02600aadaa919facbd8537997a62496270133536ed6/scipy-1.16.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff4dc42bd321991fbf611c23fc35912d690f731c9914bf3af8f417e64aca0f21", size = 33481880, upload-time = "2025-09-11T17:42:49.325Z" },
394
+ { url = "https://files.pythonhosted.org/packages/6a/74/99d5415e4c3e46b2586f30cdbecb95e101c7192628a484a40dd0d163811a/scipy-1.16.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:654324826654d4d9133e10675325708fb954bc84dae6e9ad0a52e75c6b1a01d7", size = 35791425, upload-time = "2025-09-11T17:42:54.711Z" },
395
+ { url = "https://files.pythonhosted.org/packages/1b/ee/a6559de7c1cc710e938c0355d9d4fbcd732dac4d0d131959d1f3b63eb29c/scipy-1.16.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63870a84cd15c44e65220eaed2dac0e8f8b26bbb991456a033c1d9abfe8a94f8", size = 36178622, upload-time = "2025-09-11T17:43:00.375Z" },
396
+ { url = "https://files.pythonhosted.org/packages/4e/7b/f127a5795d5ba8ece4e0dce7d4a9fb7cb9e4f4757137757d7a69ab7d4f1a/scipy-1.16.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fa01f0f6a3050fa6a9771a95d5faccc8e2f5a92b4a2e5440a0fa7264a2398472", size = 38783985, upload-time = "2025-09-11T17:43:06.661Z" },
397
+ { url = "https://files.pythonhosted.org/packages/3e/9f/bc81c1d1e033951eb5912cd3750cc005943afa3e65a725d2443a3b3c4347/scipy-1.16.2-cp313-cp313t-win_amd64.whl", hash = "sha256:116296e89fba96f76353a8579820c2512f6e55835d3fad7780fece04367de351", size = 38631367, upload-time = "2025-09-11T17:43:14.44Z" },
398
+ { url = "https://files.pythonhosted.org/packages/d6/5e/2cc7555fd81d01814271412a1d59a289d25f8b63208a0a16c21069d55d3e/scipy-1.16.2-cp313-cp313t-win_arm64.whl", hash = "sha256:98e22834650be81d42982360382b43b17f7ba95e0e6993e2a4f5b9ad9283a94d", size = 25787992, upload-time = "2025-09-11T17:43:19.745Z" },
399
+ { url = "https://files.pythonhosted.org/packages/8b/ac/ad8951250516db71619f0bd3b2eb2448db04b720a003dd98619b78b692c0/scipy-1.16.2-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:567e77755019bb7461513c87f02bb73fb65b11f049aaaa8ca17cfaa5a5c45d77", size = 36595109, upload-time = "2025-09-11T17:43:35.713Z" },
400
+ { url = "https://files.pythonhosted.org/packages/ff/f6/5779049ed119c5b503b0f3dc6d6f3f68eefc3a9190d4ad4c276f854f051b/scipy-1.16.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:17d9bb346194e8967296621208fcdfd39b55498ef7d2f376884d5ac47cec1a70", size = 28859110, upload-time = "2025-09-11T17:43:40.814Z" },
401
+ { url = "https://files.pythonhosted.org/packages/82/09/9986e410ae38bf0a0c737ff8189ac81a93b8e42349aac009891c054403d7/scipy-1.16.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:0a17541827a9b78b777d33b623a6dcfe2ef4a25806204d08ead0768f4e529a88", size = 20850110, upload-time = "2025-09-11T17:43:44.981Z" },
402
+ { url = "https://files.pythonhosted.org/packages/0d/ad/485cdef2d9215e2a7df6d61b81d2ac073dfacf6ae24b9ae87274c4e936ae/scipy-1.16.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:d7d4c6ba016ffc0f9568d012f5f1eb77ddd99412aea121e6fa8b4c3b7cbad91f", size = 23497014, upload-time = "2025-09-11T17:43:49.074Z" },
403
+ { url = "https://files.pythonhosted.org/packages/a7/74/f6a852e5d581122b8f0f831f1d1e32fb8987776ed3658e95c377d308ed86/scipy-1.16.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9702c4c023227785c779cba2e1d6f7635dbb5b2e0936cdd3a4ecb98d78fd41eb", size = 33401155, upload-time = "2025-09-11T17:43:54.661Z" },
404
+ { url = "https://files.pythonhosted.org/packages/d9/f5/61d243bbc7c6e5e4e13dde9887e84a5cbe9e0f75fd09843044af1590844e/scipy-1.16.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d1cdf0ac28948d225decdefcc45ad7dd91716c29ab56ef32f8e0d50657dffcc7", size = 35691174, upload-time = "2025-09-11T17:44:00.101Z" },
405
+ { url = "https://files.pythonhosted.org/packages/03/99/59933956331f8cc57e406cdb7a483906c74706b156998f322913e789c7e1/scipy-1.16.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:70327d6aa572a17c2941cdfb20673f82e536e91850a2e4cb0c5b858b690e1548", size = 36070752, upload-time = "2025-09-11T17:44:05.619Z" },
406
+ { url = "https://files.pythonhosted.org/packages/c6/7d/00f825cfb47ee19ef74ecf01244b43e95eae74e7e0ff796026ea7cd98456/scipy-1.16.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5221c0b2a4b58aa7c4ed0387d360fd90ee9086d383bb34d9f2789fafddc8a936", size = 38701010, upload-time = "2025-09-11T17:44:11.322Z" },
407
+ { url = "https://files.pythonhosted.org/packages/e4/9f/b62587029980378304ba5a8563d376c96f40b1e133daacee76efdcae32de/scipy-1.16.2-cp314-cp314-win_amd64.whl", hash = "sha256:f5a85d7b2b708025af08f060a496dd261055b617d776fc05a1a1cc69e09fe9ff", size = 39360061, upload-time = "2025-09-11T17:45:09.814Z" },
408
+ { url = "https://files.pythonhosted.org/packages/82/04/7a2f1609921352c7fbee0815811b5050582f67f19983096c4769867ca45f/scipy-1.16.2-cp314-cp314-win_arm64.whl", hash = "sha256:2cc73a33305b4b24556957d5857d6253ce1e2dcd67fa0ff46d87d1670b3e1e1d", size = 26126914, upload-time = "2025-09-11T17:45:14.73Z" },
409
+ { url = "https://files.pythonhosted.org/packages/51/b9/60929ce350c16b221928725d2d1d7f86cf96b8bc07415547057d1196dc92/scipy-1.16.2-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:9ea2a3fed83065d77367775d689401a703d0f697420719ee10c0780bcab594d8", size = 37013193, upload-time = "2025-09-11T17:44:16.757Z" },
410
+ { url = "https://files.pythonhosted.org/packages/2a/41/ed80e67782d4bc5fc85a966bc356c601afddd175856ba7c7bb6d9490607e/scipy-1.16.2-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7280d926f11ca945c3ef92ba960fa924e1465f8d07ce3a9923080363390624c4", size = 29390172, upload-time = "2025-09-11T17:44:21.783Z" },
411
+ { url = "https://files.pythonhosted.org/packages/c4/a3/2f673ace4090452696ccded5f5f8efffb353b8f3628f823a110e0170b605/scipy-1.16.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:8afae1756f6a1fe04636407ef7dbece33d826a5d462b74f3d0eb82deabefd831", size = 21381326, upload-time = "2025-09-11T17:44:25.982Z" },
412
+ { url = "https://files.pythonhosted.org/packages/42/bf/59df61c5d51395066c35836b78136accf506197617c8662e60ea209881e1/scipy-1.16.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:5c66511f29aa8d233388e7416a3f20d5cae7a2744d5cee2ecd38c081f4e861b3", size = 23915036, upload-time = "2025-09-11T17:44:30.527Z" },
413
+ { url = "https://files.pythonhosted.org/packages/91/c3/edc7b300dc16847ad3672f1a6f3f7c5d13522b21b84b81c265f4f2760d4a/scipy-1.16.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efe6305aeaa0e96b0ccca5ff647a43737d9a092064a3894e46c414db84bc54ac", size = 33484341, upload-time = "2025-09-11T17:44:35.981Z" },
414
+ { url = "https://files.pythonhosted.org/packages/26/c7/24d1524e72f06ff141e8d04b833c20db3021020563272ccb1b83860082a9/scipy-1.16.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f3a337d9ae06a1e8d655ee9d8ecb835ea5ddcdcbd8d23012afa055ab014f374", size = 35790840, upload-time = "2025-09-11T17:44:41.76Z" },
415
+ { url = "https://files.pythonhosted.org/packages/aa/b7/5aaad984eeedd56858dc33d75efa59e8ce798d918e1033ef62d2708f2c3d/scipy-1.16.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bab3605795d269067d8ce78a910220262711b753de8913d3deeaedb5dded3bb6", size = 36174716, upload-time = "2025-09-11T17:44:47.316Z" },
416
+ { url = "https://files.pythonhosted.org/packages/fd/c2/e276a237acb09824822b0ada11b028ed4067fdc367a946730979feacb870/scipy-1.16.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b0348d8ddb55be2a844c518cd8cc8deeeb8aeba707cf834db5758fc89b476a2c", size = 38790088, upload-time = "2025-09-11T17:44:53.011Z" },
417
+ { url = "https://files.pythonhosted.org/packages/c6/b4/5c18a766e8353015439f3780f5fc473f36f9762edc1a2e45da3ff5a31b21/scipy-1.16.2-cp314-cp314t-win_amd64.whl", hash = "sha256:26284797e38b8a75e14ea6631d29bda11e76ceaa6ddb6fdebbfe4c4d90faf2f9", size = 39457455, upload-time = "2025-09-11T17:44:58.899Z" },
418
+ { url = "https://files.pythonhosted.org/packages/97/30/2f9a5243008f76dfc5dee9a53dfb939d9b31e16ce4bd4f2e628bfc5d89d2/scipy-1.16.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d2a4472c231328d4de38d5f1f68fdd6d28a615138f842580a8a321b5845cf779", size = 26448374, upload-time = "2025-09-11T17:45:03.45Z" },
419
+ ]
420
+
421
+ [[package]]
422
+ name = "sniffio"
423
+ version = "1.3.1"
424
+ source = { registry = "https://pypi.org/simple" }
425
+ sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
426
+ wheels = [
427
+ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
428
+ ]
429
+
430
+ [[package]]
431
+ name = "starlette"
432
+ version = "0.48.0"
433
+ source = { registry = "https://pypi.org/simple" }
434
+ dependencies = [
435
+ { name = "anyio" },
436
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
437
+ ]
438
+ sdist = { url = "https://files.pythonhosted.org/packages/a7/a5/d6f429d43394057b67a6b5bbe6eae2f77a6bf7459d961fdb224bf206eee6/starlette-0.48.0.tar.gz", hash = "sha256:7e8cee469a8ab2352911528110ce9088fdc6a37d9876926e73da7ce4aa4c7a46", size = 2652949, upload-time = "2025-09-13T08:41:05.699Z" }
439
+ wheels = [
440
+ { url = "https://files.pythonhosted.org/packages/be/72/2db2f49247d0a18b4f1bb9a5a39a0162869acf235f3a96418363947b3d46/starlette-0.48.0-py3-none-any.whl", hash = "sha256:0764ca97b097582558ecb498132ed0c7d942f233f365b86ba37770e026510659", size = 73736, upload-time = "2025-09-13T08:41:03.869Z" },
441
+ ]
442
+
443
+ [[package]]
444
+ name = "threadpoolctl"
445
+ version = "3.6.0"
446
+ source = { registry = "https://pypi.org/simple" }
447
+ sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" }
448
+ wheels = [
449
+ { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" },
450
+ ]
451
+
452
+ [[package]]
453
+ name = "typing-extensions"
454
+ version = "4.15.0"
455
+ source = { registry = "https://pypi.org/simple" }
456
+ sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
457
+ wheels = [
458
+ { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
459
+ ]
460
+
461
+ [[package]]
462
+ name = "typing-inspection"
463
+ version = "0.4.2"
464
+ source = { registry = "https://pypi.org/simple" }
465
+ dependencies = [
466
+ { name = "typing-extensions" },
467
+ ]
468
+ sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
469
+ wheels = [
470
+ { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
471
+ ]
472
+
473
+ [[package]]
474
+ name = "urllib3"
475
+ version = "2.5.0"
476
+ source = { registry = "https://pypi.org/simple" }
477
+ sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" }
478
+ wheels = [
479
+ { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" },
480
+ ]
481
+
482
+ [[package]]
483
+ name = "uvicorn"
484
+ version = "0.38.0"
485
+ source = { registry = "https://pypi.org/simple" }
486
+ dependencies = [
487
+ { name = "click" },
488
+ { name = "h11" },
489
+ ]
490
+ sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" }
491
+ wheels = [
492
+ { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" },
493
+ ]
494
+
495
+ [[package]]
496
+ name = "week-5"
497
+ version = "0.1.0"
498
+ source = { virtual = "." }
499
+ dependencies = [
500
+ { name = "fastapi" },
501
+ { name = "scikit-learn" },
502
+ { name = "uvicorn" },
503
+ ]
504
+
505
+ [package.dev-dependencies]
506
+ dev = [
507
+ { name = "requests" },
508
+ ]
509
+
510
+ [package.metadata]
511
+ requires-dist = [
512
+ { name = "fastapi", specifier = ">=0.120.0" },
513
+ { name = "scikit-learn", specifier = ">=1.7.2" },
514
+ { name = "uvicorn", specifier = ">=0.38.0" },
515
+ ]
516
+
517
+ [package.metadata.requires-dev]
518
+ dev = [{ name = "requests", specifier = ">=2.32.5" }]
venv ADDED
File without changes
workshop-uv-fastapi.ipynb ADDED
@@ -0,0 +1,1986 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "4458df13-d0f7-462e-bc80-42169bb1a62b",
6
+ "metadata": {},
7
+ "source": [
8
+ "This is a starter notebook for an updated module 5 of ML Zoomcamp\n",
9
+ "\n",
10
+ "The code is based on the modules 3 and 4. We use the same dataset: [telco customer churn](https://www.kaggle.com/datasets/blastchar/telco-customer-churn)"
11
+ ]
12
+ },
13
+ {
14
+ "cell_type": "code",
15
+ "execution_count": 1,
16
+ "id": "a16177e8-cbd2-4088-9bb0-07a0cfb3eee6",
17
+ "metadata": {},
18
+ "outputs": [],
19
+ "source": [
20
+ "import pandas as pd\n",
21
+ "import numpy as np\n",
22
+ "import sklearn"
23
+ ]
24
+ },
25
+ {
26
+ "cell_type": "code",
27
+ "execution_count": 2,
28
+ "id": "498798c7-1848-47f0-9789-5881ae3658bd",
29
+ "metadata": {},
30
+ "outputs": [
31
+ {
32
+ "name": "stdout",
33
+ "output_type": "stream",
34
+ "text": [
35
+ "pandas==2.3.1\n",
36
+ "numpy==2.3.1\n",
37
+ "sklearn==1.7.0\n"
38
+ ]
39
+ }
40
+ ],
41
+ "source": [
42
+ "print(f'pandas=={pd.__version__}')\n",
43
+ "print(f'numpy=={np.__version__}')\n",
44
+ "print(f'sklearn=={sklearn.__version__}')"
45
+ ]
46
+ },
47
+ {
48
+ "cell_type": "code",
49
+ "execution_count": 4,
50
+ "id": "e9e9464c-d8ed-45ea-9e8c-70e6d73842f7",
51
+ "metadata": {},
52
+ "outputs": [],
53
+ "source": [
54
+ "# Import the necessary libraries\n",
55
+ "import numpy as np\n",
56
+ "import pandas as pd\n",
57
+ "from sklearn.linear_model import LogisticRegression\n",
58
+ "from sklearn.pipeline import make_pipeline\n",
59
+ "from sklearn.feature_extraction import DictVectorizer"
60
+ ]
61
+ },
62
+ {
63
+ "cell_type": "code",
64
+ "execution_count": 8,
65
+ "id": "54ff5e16-47a9-43ab-975b-37605ee75d19",
66
+ "metadata": {
67
+ "scrolled": true
68
+ },
69
+ "outputs": [
70
+ {
71
+ "data": {
72
+ "text/html": [
73
+ "<div>\n",
74
+ "<style scoped>\n",
75
+ " .dataframe tbody tr th:only-of-type {\n",
76
+ " vertical-align: middle;\n",
77
+ " }\n",
78
+ "\n",
79
+ " .dataframe tbody tr th {\n",
80
+ " vertical-align: top;\n",
81
+ " }\n",
82
+ "\n",
83
+ " .dataframe thead th {\n",
84
+ " text-align: right;\n",
85
+ " }\n",
86
+ "</style>\n",
87
+ "<table border=\"1\" class=\"dataframe\">\n",
88
+ " <thead>\n",
89
+ " <tr style=\"text-align: right;\">\n",
90
+ " <th></th>\n",
91
+ " <th>lead_source</th>\n",
92
+ " <th>industry</th>\n",
93
+ " <th>number_of_courses_viewed</th>\n",
94
+ " <th>annual_income</th>\n",
95
+ " <th>employment_status</th>\n",
96
+ " <th>location</th>\n",
97
+ " <th>interaction_count</th>\n",
98
+ " <th>lead_score</th>\n",
99
+ " <th>converted</th>\n",
100
+ " </tr>\n",
101
+ " </thead>\n",
102
+ " <tbody>\n",
103
+ " <tr>\n",
104
+ " <th>0</th>\n",
105
+ " <td>paid_ads</td>\n",
106
+ " <td>NaN</td>\n",
107
+ " <td>1</td>\n",
108
+ " <td>79450.0</td>\n",
109
+ " <td>unemployed</td>\n",
110
+ " <td>south_america</td>\n",
111
+ " <td>4</td>\n",
112
+ " <td>0.94</td>\n",
113
+ " <td>1</td>\n",
114
+ " </tr>\n",
115
+ " <tr>\n",
116
+ " <th>1</th>\n",
117
+ " <td>social_media</td>\n",
118
+ " <td>retail</td>\n",
119
+ " <td>1</td>\n",
120
+ " <td>46992.0</td>\n",
121
+ " <td>employed</td>\n",
122
+ " <td>south_america</td>\n",
123
+ " <td>1</td>\n",
124
+ " <td>0.80</td>\n",
125
+ " <td>0</td>\n",
126
+ " </tr>\n",
127
+ " <tr>\n",
128
+ " <th>2</th>\n",
129
+ " <td>events</td>\n",
130
+ " <td>healthcare</td>\n",
131
+ " <td>5</td>\n",
132
+ " <td>78796.0</td>\n",
133
+ " <td>unemployed</td>\n",
134
+ " <td>australia</td>\n",
135
+ " <td>3</td>\n",
136
+ " <td>0.69</td>\n",
137
+ " <td>1</td>\n",
138
+ " </tr>\n",
139
+ " <tr>\n",
140
+ " <th>3</th>\n",
141
+ " <td>paid_ads</td>\n",
142
+ " <td>retail</td>\n",
143
+ " <td>2</td>\n",
144
+ " <td>83843.0</td>\n",
145
+ " <td>NaN</td>\n",
146
+ " <td>australia</td>\n",
147
+ " <td>1</td>\n",
148
+ " <td>0.87</td>\n",
149
+ " <td>0</td>\n",
150
+ " </tr>\n",
151
+ " <tr>\n",
152
+ " <th>4</th>\n",
153
+ " <td>referral</td>\n",
154
+ " <td>education</td>\n",
155
+ " <td>3</td>\n",
156
+ " <td>85012.0</td>\n",
157
+ " <td>self_employed</td>\n",
158
+ " <td>europe</td>\n",
159
+ " <td>3</td>\n",
160
+ " <td>0.62</td>\n",
161
+ " <td>1</td>\n",
162
+ " </tr>\n",
163
+ " </tbody>\n",
164
+ "</table>\n",
165
+ "</div>"
166
+ ],
167
+ "text/plain": [
168
+ " lead_source industry number_of_courses_viewed annual_income \\\n",
169
+ "0 paid_ads NaN 1 79450.0 \n",
170
+ "1 social_media retail 1 46992.0 \n",
171
+ "2 events healthcare 5 78796.0 \n",
172
+ "3 paid_ads retail 2 83843.0 \n",
173
+ "4 referral education 3 85012.0 \n",
174
+ "\n",
175
+ " employment_status location interaction_count lead_score converted \n",
176
+ "0 unemployed south_america 4 0.94 1 \n",
177
+ "1 employed south_america 1 0.80 0 \n",
178
+ "2 unemployed australia 3 0.69 1 \n",
179
+ "3 NaN australia 1 0.87 0 \n",
180
+ "4 self_employed europe 3 0.62 1 "
181
+ ]
182
+ },
183
+ "execution_count": 8,
184
+ "metadata": {},
185
+ "output_type": "execute_result"
186
+ }
187
+ ],
188
+ "source": [
189
+ "# Load the data\n",
190
+ "data_url = \"https://raw.githubusercontent.com/alexeygrigorev/datasets/master/course_lead_scoring.csv\"\n",
191
+ "df = pd.read_csv(data_url)\n",
192
+ "df.head()"
193
+ ]
194
+ },
195
+ {
196
+ "cell_type": "code",
197
+ "execution_count": 11,
198
+ "id": "963e0b2c-5d60-4d8a-a216-00cb869d516d",
199
+ "metadata": {},
200
+ "outputs": [],
201
+ "source": [
202
+ "# the target variable\n",
203
+ "y_train = df.converted"
204
+ ]
205
+ },
206
+ {
207
+ "cell_type": "code",
208
+ "execution_count": 14,
209
+ "id": "692ae989-fb9a-4219-9a01-18424176748d",
210
+ "metadata": {},
211
+ "outputs": [
212
+ {
213
+ "data": {
214
+ "text/html": [
215
+ "<style>#sk-container-id-2 {\n",
216
+ " /* Definition of color scheme common for light and dark mode */\n",
217
+ " --sklearn-color-text: #000;\n",
218
+ " --sklearn-color-text-muted: #666;\n",
219
+ " --sklearn-color-line: gray;\n",
220
+ " /* Definition of color scheme for unfitted estimators */\n",
221
+ " --sklearn-color-unfitted-level-0: #fff5e6;\n",
222
+ " --sklearn-color-unfitted-level-1: #f6e4d2;\n",
223
+ " --sklearn-color-unfitted-level-2: #ffe0b3;\n",
224
+ " --sklearn-color-unfitted-level-3: chocolate;\n",
225
+ " /* Definition of color scheme for fitted estimators */\n",
226
+ " --sklearn-color-fitted-level-0: #f0f8ff;\n",
227
+ " --sklearn-color-fitted-level-1: #d4ebff;\n",
228
+ " --sklearn-color-fitted-level-2: #b3dbfd;\n",
229
+ " --sklearn-color-fitted-level-3: cornflowerblue;\n",
230
+ "\n",
231
+ " /* Specific color for light theme */\n",
232
+ " --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
233
+ " --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
234
+ " --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
235
+ " --sklearn-color-icon: #696969;\n",
236
+ "\n",
237
+ " @media (prefers-color-scheme: dark) {\n",
238
+ " /* Redefinition of color scheme for dark theme */\n",
239
+ " --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
240
+ " --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
241
+ " --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
242
+ " --sklearn-color-icon: #878787;\n",
243
+ " }\n",
244
+ "}\n",
245
+ "\n",
246
+ "#sk-container-id-2 {\n",
247
+ " color: var(--sklearn-color-text);\n",
248
+ "}\n",
249
+ "\n",
250
+ "#sk-container-id-2 pre {\n",
251
+ " padding: 0;\n",
252
+ "}\n",
253
+ "\n",
254
+ "#sk-container-id-2 input.sk-hidden--visually {\n",
255
+ " border: 0;\n",
256
+ " clip: rect(1px 1px 1px 1px);\n",
257
+ " clip: rect(1px, 1px, 1px, 1px);\n",
258
+ " height: 1px;\n",
259
+ " margin: -1px;\n",
260
+ " overflow: hidden;\n",
261
+ " padding: 0;\n",
262
+ " position: absolute;\n",
263
+ " width: 1px;\n",
264
+ "}\n",
265
+ "\n",
266
+ "#sk-container-id-2 div.sk-dashed-wrapped {\n",
267
+ " border: 1px dashed var(--sklearn-color-line);\n",
268
+ " margin: 0 0.4em 0.5em 0.4em;\n",
269
+ " box-sizing: border-box;\n",
270
+ " padding-bottom: 0.4em;\n",
271
+ " background-color: var(--sklearn-color-background);\n",
272
+ "}\n",
273
+ "\n",
274
+ "#sk-container-id-2 div.sk-container {\n",
275
+ " /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
276
+ " but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
277
+ " so we also need the `!important` here to be able to override the\n",
278
+ " default hidden behavior on the sphinx rendered scikit-learn.org.\n",
279
+ " See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
280
+ " display: inline-block !important;\n",
281
+ " position: relative;\n",
282
+ "}\n",
283
+ "\n",
284
+ "#sk-container-id-2 div.sk-text-repr-fallback {\n",
285
+ " display: none;\n",
286
+ "}\n",
287
+ "\n",
288
+ "div.sk-parallel-item,\n",
289
+ "div.sk-serial,\n",
290
+ "div.sk-item {\n",
291
+ " /* draw centered vertical line to link estimators */\n",
292
+ " background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
293
+ " background-size: 2px 100%;\n",
294
+ " background-repeat: no-repeat;\n",
295
+ " background-position: center center;\n",
296
+ "}\n",
297
+ "\n",
298
+ "/* Parallel-specific style estimator block */\n",
299
+ "\n",
300
+ "#sk-container-id-2 div.sk-parallel-item::after {\n",
301
+ " content: \"\";\n",
302
+ " width: 100%;\n",
303
+ " border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
304
+ " flex-grow: 1;\n",
305
+ "}\n",
306
+ "\n",
307
+ "#sk-container-id-2 div.sk-parallel {\n",
308
+ " display: flex;\n",
309
+ " align-items: stretch;\n",
310
+ " justify-content: center;\n",
311
+ " background-color: var(--sklearn-color-background);\n",
312
+ " position: relative;\n",
313
+ "}\n",
314
+ "\n",
315
+ "#sk-container-id-2 div.sk-parallel-item {\n",
316
+ " display: flex;\n",
317
+ " flex-direction: column;\n",
318
+ "}\n",
319
+ "\n",
320
+ "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
321
+ " align-self: flex-end;\n",
322
+ " width: 50%;\n",
323
+ "}\n",
324
+ "\n",
325
+ "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
326
+ " align-self: flex-start;\n",
327
+ " width: 50%;\n",
328
+ "}\n",
329
+ "\n",
330
+ "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
331
+ " width: 0;\n",
332
+ "}\n",
333
+ "\n",
334
+ "/* Serial-specific style estimator block */\n",
335
+ "\n",
336
+ "#sk-container-id-2 div.sk-serial {\n",
337
+ " display: flex;\n",
338
+ " flex-direction: column;\n",
339
+ " align-items: center;\n",
340
+ " background-color: var(--sklearn-color-background);\n",
341
+ " padding-right: 1em;\n",
342
+ " padding-left: 1em;\n",
343
+ "}\n",
344
+ "\n",
345
+ "\n",
346
+ "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
347
+ "clickable and can be expanded/collapsed.\n",
348
+ "- Pipeline and ColumnTransformer use this feature and define the default style\n",
349
+ "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
350
+ "*/\n",
351
+ "\n",
352
+ "/* Pipeline and ColumnTransformer style (default) */\n",
353
+ "\n",
354
+ "#sk-container-id-2 div.sk-toggleable {\n",
355
+ " /* Default theme specific background. It is overwritten whether we have a\n",
356
+ " specific estimator or a Pipeline/ColumnTransformer */\n",
357
+ " background-color: var(--sklearn-color-background);\n",
358
+ "}\n",
359
+ "\n",
360
+ "/* Toggleable label */\n",
361
+ "#sk-container-id-2 label.sk-toggleable__label {\n",
362
+ " cursor: pointer;\n",
363
+ " display: flex;\n",
364
+ " width: 100%;\n",
365
+ " margin-bottom: 0;\n",
366
+ " padding: 0.5em;\n",
367
+ " box-sizing: border-box;\n",
368
+ " text-align: center;\n",
369
+ " align-items: start;\n",
370
+ " justify-content: space-between;\n",
371
+ " gap: 0.5em;\n",
372
+ "}\n",
373
+ "\n",
374
+ "#sk-container-id-2 label.sk-toggleable__label .caption {\n",
375
+ " font-size: 0.6rem;\n",
376
+ " font-weight: lighter;\n",
377
+ " color: var(--sklearn-color-text-muted);\n",
378
+ "}\n",
379
+ "\n",
380
+ "#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
381
+ " /* Arrow on the left of the label */\n",
382
+ " content: \"▸\";\n",
383
+ " float: left;\n",
384
+ " margin-right: 0.25em;\n",
385
+ " color: var(--sklearn-color-icon);\n",
386
+ "}\n",
387
+ "\n",
388
+ "#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
389
+ " color: var(--sklearn-color-text);\n",
390
+ "}\n",
391
+ "\n",
392
+ "/* Toggleable content - dropdown */\n",
393
+ "\n",
394
+ "#sk-container-id-2 div.sk-toggleable__content {\n",
395
+ " display: none;\n",
396
+ " text-align: left;\n",
397
+ " /* unfitted */\n",
398
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
399
+ "}\n",
400
+ "\n",
401
+ "#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
402
+ " /* fitted */\n",
403
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
404
+ "}\n",
405
+ "\n",
406
+ "#sk-container-id-2 div.sk-toggleable__content pre {\n",
407
+ " margin: 0.2em;\n",
408
+ " border-radius: 0.25em;\n",
409
+ " color: var(--sklearn-color-text);\n",
410
+ " /* unfitted */\n",
411
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
412
+ "}\n",
413
+ "\n",
414
+ "#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
415
+ " /* unfitted */\n",
416
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
417
+ "}\n",
418
+ "\n",
419
+ "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
420
+ " /* Expand drop-down */\n",
421
+ " display: block;\n",
422
+ " width: 100%;\n",
423
+ " overflow: visible;\n",
424
+ "}\n",
425
+ "\n",
426
+ "#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
427
+ " content: \"▾\";\n",
428
+ "}\n",
429
+ "\n",
430
+ "/* Pipeline/ColumnTransformer-specific style */\n",
431
+ "\n",
432
+ "#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
433
+ " color: var(--sklearn-color-text);\n",
434
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
435
+ "}\n",
436
+ "\n",
437
+ "#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
438
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
439
+ "}\n",
440
+ "\n",
441
+ "/* Estimator-specific style */\n",
442
+ "\n",
443
+ "/* Colorize estimator box */\n",
444
+ "#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
445
+ " /* unfitted */\n",
446
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
447
+ "}\n",
448
+ "\n",
449
+ "#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
450
+ " /* fitted */\n",
451
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
452
+ "}\n",
453
+ "\n",
454
+ "#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
455
+ "#sk-container-id-2 div.sk-label label {\n",
456
+ " /* The background is the default theme color */\n",
457
+ " color: var(--sklearn-color-text-on-default-background);\n",
458
+ "}\n",
459
+ "\n",
460
+ "/* On hover, darken the color of the background */\n",
461
+ "#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
462
+ " color: var(--sklearn-color-text);\n",
463
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
464
+ "}\n",
465
+ "\n",
466
+ "/* Label box, darken color on hover, fitted */\n",
467
+ "#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
468
+ " color: var(--sklearn-color-text);\n",
469
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
470
+ "}\n",
471
+ "\n",
472
+ "/* Estimator label */\n",
473
+ "\n",
474
+ "#sk-container-id-2 div.sk-label label {\n",
475
+ " font-family: monospace;\n",
476
+ " font-weight: bold;\n",
477
+ " display: inline-block;\n",
478
+ " line-height: 1.2em;\n",
479
+ "}\n",
480
+ "\n",
481
+ "#sk-container-id-2 div.sk-label-container {\n",
482
+ " text-align: center;\n",
483
+ "}\n",
484
+ "\n",
485
+ "/* Estimator-specific */\n",
486
+ "#sk-container-id-2 div.sk-estimator {\n",
487
+ " font-family: monospace;\n",
488
+ " border: 1px dotted var(--sklearn-color-border-box);\n",
489
+ " border-radius: 0.25em;\n",
490
+ " box-sizing: border-box;\n",
491
+ " margin-bottom: 0.5em;\n",
492
+ " /* unfitted */\n",
493
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
494
+ "}\n",
495
+ "\n",
496
+ "#sk-container-id-2 div.sk-estimator.fitted {\n",
497
+ " /* fitted */\n",
498
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
499
+ "}\n",
500
+ "\n",
501
+ "/* on hover */\n",
502
+ "#sk-container-id-2 div.sk-estimator:hover {\n",
503
+ " /* unfitted */\n",
504
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
505
+ "}\n",
506
+ "\n",
507
+ "#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
508
+ " /* fitted */\n",
509
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
510
+ "}\n",
511
+ "\n",
512
+ "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
513
+ "\n",
514
+ "/* Common style for \"i\" and \"?\" */\n",
515
+ "\n",
516
+ ".sk-estimator-doc-link,\n",
517
+ "a:link.sk-estimator-doc-link,\n",
518
+ "a:visited.sk-estimator-doc-link {\n",
519
+ " float: right;\n",
520
+ " font-size: smaller;\n",
521
+ " line-height: 1em;\n",
522
+ " font-family: monospace;\n",
523
+ " background-color: var(--sklearn-color-background);\n",
524
+ " border-radius: 1em;\n",
525
+ " height: 1em;\n",
526
+ " width: 1em;\n",
527
+ " text-decoration: none !important;\n",
528
+ " margin-left: 0.5em;\n",
529
+ " text-align: center;\n",
530
+ " /* unfitted */\n",
531
+ " border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
532
+ " color: var(--sklearn-color-unfitted-level-1);\n",
533
+ "}\n",
534
+ "\n",
535
+ ".sk-estimator-doc-link.fitted,\n",
536
+ "a:link.sk-estimator-doc-link.fitted,\n",
537
+ "a:visited.sk-estimator-doc-link.fitted {\n",
538
+ " /* fitted */\n",
539
+ " border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
540
+ " color: var(--sklearn-color-fitted-level-1);\n",
541
+ "}\n",
542
+ "\n",
543
+ "/* On hover */\n",
544
+ "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
545
+ ".sk-estimator-doc-link:hover,\n",
546
+ "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
547
+ ".sk-estimator-doc-link:hover {\n",
548
+ " /* unfitted */\n",
549
+ " background-color: var(--sklearn-color-unfitted-level-3);\n",
550
+ " color: var(--sklearn-color-background);\n",
551
+ " text-decoration: none;\n",
552
+ "}\n",
553
+ "\n",
554
+ "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
555
+ ".sk-estimator-doc-link.fitted:hover,\n",
556
+ "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
557
+ ".sk-estimator-doc-link.fitted:hover {\n",
558
+ " /* fitted */\n",
559
+ " background-color: var(--sklearn-color-fitted-level-3);\n",
560
+ " color: var(--sklearn-color-background);\n",
561
+ " text-decoration: none;\n",
562
+ "}\n",
563
+ "\n",
564
+ "/* Span, style for the box shown on hovering the info icon */\n",
565
+ ".sk-estimator-doc-link span {\n",
566
+ " display: none;\n",
567
+ " z-index: 9999;\n",
568
+ " position: relative;\n",
569
+ " font-weight: normal;\n",
570
+ " right: .2ex;\n",
571
+ " padding: .5ex;\n",
572
+ " margin: .5ex;\n",
573
+ " width: min-content;\n",
574
+ " min-width: 20ex;\n",
575
+ " max-width: 50ex;\n",
576
+ " color: var(--sklearn-color-text);\n",
577
+ " box-shadow: 2pt 2pt 4pt #999;\n",
578
+ " /* unfitted */\n",
579
+ " background: var(--sklearn-color-unfitted-level-0);\n",
580
+ " border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
581
+ "}\n",
582
+ "\n",
583
+ ".sk-estimator-doc-link.fitted span {\n",
584
+ " /* fitted */\n",
585
+ " background: var(--sklearn-color-fitted-level-0);\n",
586
+ " border: var(--sklearn-color-fitted-level-3);\n",
587
+ "}\n",
588
+ "\n",
589
+ ".sk-estimator-doc-link:hover span {\n",
590
+ " display: block;\n",
591
+ "}\n",
592
+ "\n",
593
+ "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
594
+ "\n",
595
+ "#sk-container-id-2 a.estimator_doc_link {\n",
596
+ " float: right;\n",
597
+ " font-size: 1rem;\n",
598
+ " line-height: 1em;\n",
599
+ " font-family: monospace;\n",
600
+ " background-color: var(--sklearn-color-background);\n",
601
+ " border-radius: 1rem;\n",
602
+ " height: 1rem;\n",
603
+ " width: 1rem;\n",
604
+ " text-decoration: none;\n",
605
+ " /* unfitted */\n",
606
+ " color: var(--sklearn-color-unfitted-level-1);\n",
607
+ " border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
608
+ "}\n",
609
+ "\n",
610
+ "#sk-container-id-2 a.estimator_doc_link.fitted {\n",
611
+ " /* fitted */\n",
612
+ " border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
613
+ " color: var(--sklearn-color-fitted-level-1);\n",
614
+ "}\n",
615
+ "\n",
616
+ "/* On hover */\n",
617
+ "#sk-container-id-2 a.estimator_doc_link:hover {\n",
618
+ " /* unfitted */\n",
619
+ " background-color: var(--sklearn-color-unfitted-level-3);\n",
620
+ " color: var(--sklearn-color-background);\n",
621
+ " text-decoration: none;\n",
622
+ "}\n",
623
+ "\n",
624
+ "#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
625
+ " /* fitted */\n",
626
+ " background-color: var(--sklearn-color-fitted-level-3);\n",
627
+ "}\n",
628
+ "\n",
629
+ ".estimator-table summary {\n",
630
+ " padding: .5rem;\n",
631
+ " font-family: monospace;\n",
632
+ " cursor: pointer;\n",
633
+ "}\n",
634
+ "\n",
635
+ ".estimator-table details[open] {\n",
636
+ " padding-left: 0.1rem;\n",
637
+ " padding-right: 0.1rem;\n",
638
+ " padding-bottom: 0.3rem;\n",
639
+ "}\n",
640
+ "\n",
641
+ ".estimator-table .parameters-table {\n",
642
+ " margin-left: auto !important;\n",
643
+ " margin-right: auto !important;\n",
644
+ "}\n",
645
+ "\n",
646
+ ".estimator-table .parameters-table tr:nth-child(odd) {\n",
647
+ " background-color: #fff;\n",
648
+ "}\n",
649
+ "\n",
650
+ ".estimator-table .parameters-table tr:nth-child(even) {\n",
651
+ " background-color: #f6f6f6;\n",
652
+ "}\n",
653
+ "\n",
654
+ ".estimator-table .parameters-table tr:hover {\n",
655
+ " background-color: #e0e0e0;\n",
656
+ "}\n",
657
+ "\n",
658
+ ".estimator-table table td {\n",
659
+ " border: 1px solid rgba(106, 105, 104, 0.232);\n",
660
+ "}\n",
661
+ "\n",
662
+ ".user-set td {\n",
663
+ " color:rgb(255, 94, 0);\n",
664
+ " text-align: left;\n",
665
+ "}\n",
666
+ "\n",
667
+ ".user-set td.value pre {\n",
668
+ " color:rgb(255, 94, 0) !important;\n",
669
+ " background-color: transparent !important;\n",
670
+ "}\n",
671
+ "\n",
672
+ ".default td {\n",
673
+ " color: black;\n",
674
+ " text-align: left;\n",
675
+ "}\n",
676
+ "\n",
677
+ ".user-set td i,\n",
678
+ ".default td i {\n",
679
+ " color: black;\n",
680
+ "}\n",
681
+ "\n",
682
+ ".copy-paste-icon {\n",
683
+ " background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=);\n",
684
+ " background-repeat: no-repeat;\n",
685
+ " background-size: 14px 14px;\n",
686
+ " background-position: 0;\n",
687
+ " display: inline-block;\n",
688
+ " width: 14px;\n",
689
+ " height: 14px;\n",
690
+ " cursor: pointer;\n",
691
+ "}\n",
692
+ "</style><body><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>Pipeline(steps=[(&#x27;dictvectorizer&#x27;, DictVectorizer()),\n",
693
+ " (&#x27;logisticregression&#x27;, LogisticRegression(solver=&#x27;liblinear&#x27;))])</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item sk-dashed-wrapped\"><div class=\"sk-label-container\"><div class=\"sk-label fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-4\" type=\"checkbox\" ><label for=\"sk-estimator-id-4\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>Pipeline</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.pipeline.Pipeline.html\">?<span>Documentation for Pipeline</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
694
+ " <div class=\"estimator-table\">\n",
695
+ " <details>\n",
696
+ " <summary>Parameters</summary>\n",
697
+ " <table class=\"parameters-table\">\n",
698
+ " <tbody>\n",
699
+ " \n",
700
+ " <tr class=\"user-set\">\n",
701
+ " <td><i class=\"copy-paste-icon\"\n",
702
+ " onclick=\"copyToClipboard('steps',\n",
703
+ " this.parentElement.nextElementSibling)\"\n",
704
+ " ></i></td>\n",
705
+ " <td class=\"param\">steps&nbsp;</td>\n",
706
+ " <td class=\"value\">[(&#x27;dictvectorizer&#x27;, ...), (&#x27;logisticregression&#x27;, ...)]</td>\n",
707
+ " </tr>\n",
708
+ " \n",
709
+ "\n",
710
+ " <tr class=\"default\">\n",
711
+ " <td><i class=\"copy-paste-icon\"\n",
712
+ " onclick=\"copyToClipboard('transform_input',\n",
713
+ " this.parentElement.nextElementSibling)\"\n",
714
+ " ></i></td>\n",
715
+ " <td class=\"param\">transform_input&nbsp;</td>\n",
716
+ " <td class=\"value\">None</td>\n",
717
+ " </tr>\n",
718
+ " \n",
719
+ "\n",
720
+ " <tr class=\"default\">\n",
721
+ " <td><i class=\"copy-paste-icon\"\n",
722
+ " onclick=\"copyToClipboard('memory',\n",
723
+ " this.parentElement.nextElementSibling)\"\n",
724
+ " ></i></td>\n",
725
+ " <td class=\"param\">memory&nbsp;</td>\n",
726
+ " <td class=\"value\">None</td>\n",
727
+ " </tr>\n",
728
+ " \n",
729
+ "\n",
730
+ " <tr class=\"default\">\n",
731
+ " <td><i class=\"copy-paste-icon\"\n",
732
+ " onclick=\"copyToClipboard('verbose',\n",
733
+ " this.parentElement.nextElementSibling)\"\n",
734
+ " ></i></td>\n",
735
+ " <td class=\"param\">verbose&nbsp;</td>\n",
736
+ " <td class=\"value\">False</td>\n",
737
+ " </tr>\n",
738
+ " \n",
739
+ " </tbody>\n",
740
+ " </table>\n",
741
+ " </details>\n",
742
+ " </div>\n",
743
+ " </div></div></div><div class=\"sk-serial\"><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-5\" type=\"checkbox\" ><label for=\"sk-estimator-id-5\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>DictVectorizer</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.feature_extraction.DictVectorizer.html\">?<span>Documentation for DictVectorizer</span></a></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"dictvectorizer__\">\n",
744
+ " <div class=\"estimator-table\">\n",
745
+ " <details>\n",
746
+ " <summary>Parameters</summary>\n",
747
+ " <table class=\"parameters-table\">\n",
748
+ " <tbody>\n",
749
+ " \n",
750
+ " <tr class=\"default\">\n",
751
+ " <td><i class=\"copy-paste-icon\"\n",
752
+ " onclick=\"copyToClipboard('dtype',\n",
753
+ " this.parentElement.nextElementSibling)\"\n",
754
+ " ></i></td>\n",
755
+ " <td class=\"param\">dtype&nbsp;</td>\n",
756
+ " <td class=\"value\">&lt;class &#x27;numpy.float64&#x27;&gt;</td>\n",
757
+ " </tr>\n",
758
+ " \n",
759
+ "\n",
760
+ " <tr class=\"default\">\n",
761
+ " <td><i class=\"copy-paste-icon\"\n",
762
+ " onclick=\"copyToClipboard('separator',\n",
763
+ " this.parentElement.nextElementSibling)\"\n",
764
+ " ></i></td>\n",
765
+ " <td class=\"param\">separator&nbsp;</td>\n",
766
+ " <td class=\"value\">&#x27;=&#x27;</td>\n",
767
+ " </tr>\n",
768
+ " \n",
769
+ "\n",
770
+ " <tr class=\"default\">\n",
771
+ " <td><i class=\"copy-paste-icon\"\n",
772
+ " onclick=\"copyToClipboard('sparse',\n",
773
+ " this.parentElement.nextElementSibling)\"\n",
774
+ " ></i></td>\n",
775
+ " <td class=\"param\">sparse&nbsp;</td>\n",
776
+ " <td class=\"value\">True</td>\n",
777
+ " </tr>\n",
778
+ " \n",
779
+ "\n",
780
+ " <tr class=\"default\">\n",
781
+ " <td><i class=\"copy-paste-icon\"\n",
782
+ " onclick=\"copyToClipboard('sort',\n",
783
+ " this.parentElement.nextElementSibling)\"\n",
784
+ " ></i></td>\n",
785
+ " <td class=\"param\">sort&nbsp;</td>\n",
786
+ " <td class=\"value\">True</td>\n",
787
+ " </tr>\n",
788
+ " \n",
789
+ " </tbody>\n",
790
+ " </table>\n",
791
+ " </details>\n",
792
+ " </div>\n",
793
+ " </div></div></div><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-6\" type=\"checkbox\" ><label for=\"sk-estimator-id-6\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>LogisticRegression</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.linear_model.LogisticRegression.html\">?<span>Documentation for LogisticRegression</span></a></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"logisticregression__\">\n",
794
+ " <div class=\"estimator-table\">\n",
795
+ " <details>\n",
796
+ " <summary>Parameters</summary>\n",
797
+ " <table class=\"parameters-table\">\n",
798
+ " <tbody>\n",
799
+ " \n",
800
+ " <tr class=\"default\">\n",
801
+ " <td><i class=\"copy-paste-icon\"\n",
802
+ " onclick=\"copyToClipboard('penalty',\n",
803
+ " this.parentElement.nextElementSibling)\"\n",
804
+ " ></i></td>\n",
805
+ " <td class=\"param\">penalty&nbsp;</td>\n",
806
+ " <td class=\"value\">&#x27;l2&#x27;</td>\n",
807
+ " </tr>\n",
808
+ " \n",
809
+ "\n",
810
+ " <tr class=\"default\">\n",
811
+ " <td><i class=\"copy-paste-icon\"\n",
812
+ " onclick=\"copyToClipboard('dual',\n",
813
+ " this.parentElement.nextElementSibling)\"\n",
814
+ " ></i></td>\n",
815
+ " <td class=\"param\">dual&nbsp;</td>\n",
816
+ " <td class=\"value\">False</td>\n",
817
+ " </tr>\n",
818
+ " \n",
819
+ "\n",
820
+ " <tr class=\"default\">\n",
821
+ " <td><i class=\"copy-paste-icon\"\n",
822
+ " onclick=\"copyToClipboard('tol',\n",
823
+ " this.parentElement.nextElementSibling)\"\n",
824
+ " ></i></td>\n",
825
+ " <td class=\"param\">tol&nbsp;</td>\n",
826
+ " <td class=\"value\">0.0001</td>\n",
827
+ " </tr>\n",
828
+ " \n",
829
+ "\n",
830
+ " <tr class=\"default\">\n",
831
+ " <td><i class=\"copy-paste-icon\"\n",
832
+ " onclick=\"copyToClipboard('C',\n",
833
+ " this.parentElement.nextElementSibling)\"\n",
834
+ " ></i></td>\n",
835
+ " <td class=\"param\">C&nbsp;</td>\n",
836
+ " <td class=\"value\">1.0</td>\n",
837
+ " </tr>\n",
838
+ " \n",
839
+ "\n",
840
+ " <tr class=\"default\">\n",
841
+ " <td><i class=\"copy-paste-icon\"\n",
842
+ " onclick=\"copyToClipboard('fit_intercept',\n",
843
+ " this.parentElement.nextElementSibling)\"\n",
844
+ " ></i></td>\n",
845
+ " <td class=\"param\">fit_intercept&nbsp;</td>\n",
846
+ " <td class=\"value\">True</td>\n",
847
+ " </tr>\n",
848
+ " \n",
849
+ "\n",
850
+ " <tr class=\"default\">\n",
851
+ " <td><i class=\"copy-paste-icon\"\n",
852
+ " onclick=\"copyToClipboard('intercept_scaling',\n",
853
+ " this.parentElement.nextElementSibling)\"\n",
854
+ " ></i></td>\n",
855
+ " <td class=\"param\">intercept_scaling&nbsp;</td>\n",
856
+ " <td class=\"value\">1</td>\n",
857
+ " </tr>\n",
858
+ " \n",
859
+ "\n",
860
+ " <tr class=\"default\">\n",
861
+ " <td><i class=\"copy-paste-icon\"\n",
862
+ " onclick=\"copyToClipboard('class_weight',\n",
863
+ " this.parentElement.nextElementSibling)\"\n",
864
+ " ></i></td>\n",
865
+ " <td class=\"param\">class_weight&nbsp;</td>\n",
866
+ " <td class=\"value\">None</td>\n",
867
+ " </tr>\n",
868
+ " \n",
869
+ "\n",
870
+ " <tr class=\"default\">\n",
871
+ " <td><i class=\"copy-paste-icon\"\n",
872
+ " onclick=\"copyToClipboard('random_state',\n",
873
+ " this.parentElement.nextElementSibling)\"\n",
874
+ " ></i></td>\n",
875
+ " <td class=\"param\">random_state&nbsp;</td>\n",
876
+ " <td class=\"value\">None</td>\n",
877
+ " </tr>\n",
878
+ " \n",
879
+ "\n",
880
+ " <tr class=\"user-set\">\n",
881
+ " <td><i class=\"copy-paste-icon\"\n",
882
+ " onclick=\"copyToClipboard('solver',\n",
883
+ " this.parentElement.nextElementSibling)\"\n",
884
+ " ></i></td>\n",
885
+ " <td class=\"param\">solver&nbsp;</td>\n",
886
+ " <td class=\"value\">&#x27;liblinear&#x27;</td>\n",
887
+ " </tr>\n",
888
+ " \n",
889
+ "\n",
890
+ " <tr class=\"default\">\n",
891
+ " <td><i class=\"copy-paste-icon\"\n",
892
+ " onclick=\"copyToClipboard('max_iter',\n",
893
+ " this.parentElement.nextElementSibling)\"\n",
894
+ " ></i></td>\n",
895
+ " <td class=\"param\">max_iter&nbsp;</td>\n",
896
+ " <td class=\"value\">100</td>\n",
897
+ " </tr>\n",
898
+ " \n",
899
+ "\n",
900
+ " <tr class=\"default\">\n",
901
+ " <td><i class=\"copy-paste-icon\"\n",
902
+ " onclick=\"copyToClipboard('multi_class',\n",
903
+ " this.parentElement.nextElementSibling)\"\n",
904
+ " ></i></td>\n",
905
+ " <td class=\"param\">multi_class&nbsp;</td>\n",
906
+ " <td class=\"value\">&#x27;deprecated&#x27;</td>\n",
907
+ " </tr>\n",
908
+ " \n",
909
+ "\n",
910
+ " <tr class=\"default\">\n",
911
+ " <td><i class=\"copy-paste-icon\"\n",
912
+ " onclick=\"copyToClipboard('verbose',\n",
913
+ " this.parentElement.nextElementSibling)\"\n",
914
+ " ></i></td>\n",
915
+ " <td class=\"param\">verbose&nbsp;</td>\n",
916
+ " <td class=\"value\">0</td>\n",
917
+ " </tr>\n",
918
+ " \n",
919
+ "\n",
920
+ " <tr class=\"default\">\n",
921
+ " <td><i class=\"copy-paste-icon\"\n",
922
+ " onclick=\"copyToClipboard('warm_start',\n",
923
+ " this.parentElement.nextElementSibling)\"\n",
924
+ " ></i></td>\n",
925
+ " <td class=\"param\">warm_start&nbsp;</td>\n",
926
+ " <td class=\"value\">False</td>\n",
927
+ " </tr>\n",
928
+ " \n",
929
+ "\n",
930
+ " <tr class=\"default\">\n",
931
+ " <td><i class=\"copy-paste-icon\"\n",
932
+ " onclick=\"copyToClipboard('n_jobs',\n",
933
+ " this.parentElement.nextElementSibling)\"\n",
934
+ " ></i></td>\n",
935
+ " <td class=\"param\">n_jobs&nbsp;</td>\n",
936
+ " <td class=\"value\">None</td>\n",
937
+ " </tr>\n",
938
+ " \n",
939
+ "\n",
940
+ " <tr class=\"default\">\n",
941
+ " <td><i class=\"copy-paste-icon\"\n",
942
+ " onclick=\"copyToClipboard('l1_ratio',\n",
943
+ " this.parentElement.nextElementSibling)\"\n",
944
+ " ></i></td>\n",
945
+ " <td class=\"param\">l1_ratio&nbsp;</td>\n",
946
+ " <td class=\"value\">None</td>\n",
947
+ " </tr>\n",
948
+ " \n",
949
+ " </tbody>\n",
950
+ " </table>\n",
951
+ " </details>\n",
952
+ " </div>\n",
953
+ " </div></div></div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
954
+ " // Get the parameter prefix from the closest toggleable content\n",
955
+ " const toggleableContent = element.closest('.sk-toggleable__content');\n",
956
+ " const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
957
+ " const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
958
+ "\n",
959
+ " const originalStyle = element.style;\n",
960
+ " const computedStyle = window.getComputedStyle(element);\n",
961
+ " const originalWidth = computedStyle.width;\n",
962
+ " const originalHTML = element.innerHTML.replace('Copied!', '');\n",
963
+ "\n",
964
+ " navigator.clipboard.writeText(fullParamName)\n",
965
+ " .then(() => {\n",
966
+ " element.style.width = originalWidth;\n",
967
+ " element.style.color = 'green';\n",
968
+ " element.innerHTML = \"Copied!\";\n",
969
+ "\n",
970
+ " setTimeout(() => {\n",
971
+ " element.innerHTML = originalHTML;\n",
972
+ " element.style = originalStyle;\n",
973
+ " }, 2000);\n",
974
+ " })\n",
975
+ " .catch(err => {\n",
976
+ " console.error('Failed to copy:', err);\n",
977
+ " element.style.color = 'red';\n",
978
+ " element.innerHTML = \"Failed!\";\n",
979
+ " setTimeout(() => {\n",
980
+ " element.innerHTML = originalHTML;\n",
981
+ " element.style = originalStyle;\n",
982
+ " }, 2000);\n",
983
+ " });\n",
984
+ " return false;\n",
985
+ "}\n",
986
+ "\n",
987
+ "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
988
+ " const toggleableContent = element.closest('.sk-toggleable__content');\n",
989
+ " const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
990
+ " const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
991
+ " const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
992
+ "\n",
993
+ " element.setAttribute('title', fullParamName);\n",
994
+ "});\n",
995
+ "</script></body>"
996
+ ],
997
+ "text/plain": [
998
+ "Pipeline(steps=[('dictvectorizer', DictVectorizer()),\n",
999
+ " ('logisticregression', LogisticRegression(solver='liblinear'))])"
1000
+ ]
1001
+ },
1002
+ "execution_count": 14,
1003
+ "metadata": {},
1004
+ "output_type": "execute_result"
1005
+ }
1006
+ ],
1007
+ "source": [
1008
+ "# Preprocessing using DictVectorizer and Training the model \n",
1009
+ "categorical = ['lead_source']\n",
1010
+ "numeric = ['number_of_courses_viewed', 'annual_income']\n",
1011
+ "\n",
1012
+ "df[categorical] = df[categorical].fillna('NA')\n",
1013
+ "df[numeric] = df[numeric].fillna(0)\n",
1014
+ "\n",
1015
+ "train_dict = df[categorical + numeric].to_dict(orient='records')\n",
1016
+ "\n",
1017
+ "pipeline = make_pipeline(\n",
1018
+ " DictVectorizer(),\n",
1019
+ " LogisticRegression(solver='liblinear')\n",
1020
+ ")\n",
1021
+ "\n",
1022
+ "pipeline.fit(train_dict, y_train)"
1023
+ ]
1024
+ },
1025
+ {
1026
+ "cell_type": "code",
1027
+ "execution_count": 15,
1028
+ "id": "80f2002c-433b-4e77-9df7-965839859d4a",
1029
+ "metadata": {},
1030
+ "outputs": [
1031
+ {
1032
+ "data": {
1033
+ "text/plain": [
1034
+ "{'lead_source': 'paid_ads',\n",
1035
+ " 'number_of_courses_viewed': 1,\n",
1036
+ " 'annual_income': 79450.0}"
1037
+ ]
1038
+ },
1039
+ "execution_count": 15,
1040
+ "metadata": {},
1041
+ "output_type": "execute_result"
1042
+ }
1043
+ ],
1044
+ "source": [
1045
+ "train_dict[0]"
1046
+ ]
1047
+ },
1048
+ {
1049
+ "cell_type": "code",
1050
+ "execution_count": 21,
1051
+ "id": "7bbf2adb-11c4-4853-8f1b-fd22b5cf09b2",
1052
+ "metadata": {},
1053
+ "outputs": [
1054
+ {
1055
+ "data": {
1056
+ "text/plain": [
1057
+ "number_of_courses_viewed\n",
1058
+ "1 417\n",
1059
+ "2 388\n",
1060
+ "3 269\n",
1061
+ "0 181\n",
1062
+ "4 109\n",
1063
+ "5 67\n",
1064
+ "6 22\n",
1065
+ "7 6\n",
1066
+ "8 2\n",
1067
+ "9 1\n",
1068
+ "Name: count, dtype: int64"
1069
+ ]
1070
+ },
1071
+ "execution_count": 21,
1072
+ "metadata": {},
1073
+ "output_type": "execute_result"
1074
+ }
1075
+ ],
1076
+ "source": [
1077
+ "df.number_of_courses_viewed.value_counts()"
1078
+ ]
1079
+ },
1080
+ {
1081
+ "cell_type": "code",
1082
+ "execution_count": 26,
1083
+ "id": "5a613b8d-47bb-4e5a-8b80-117b49221d6c",
1084
+ "metadata": {},
1085
+ "outputs": [],
1086
+ "source": [
1087
+ "# sample customer data\n",
1088
+ "customer = {\n",
1089
+ " 'lead_source': 'organic_search',\n",
1090
+ " 'number_of_courses_viewed': 3,\n",
1091
+ " 'annual_income': 50450.0}"
1092
+ ]
1093
+ },
1094
+ {
1095
+ "cell_type": "code",
1096
+ "execution_count": 28,
1097
+ "id": "b91d20df-46a2-4580-9de0-f17d5bdc7f65",
1098
+ "metadata": {},
1099
+ "outputs": [
1100
+ {
1101
+ "data": {
1102
+ "text/plain": [
1103
+ "np.float64(0.6644010536277872)"
1104
+ ]
1105
+ },
1106
+ "execution_count": 28,
1107
+ "metadata": {},
1108
+ "output_type": "execute_result"
1109
+ }
1110
+ ],
1111
+ "source": [
1112
+ "# probability of this customer to get converted\n",
1113
+ "pipeline.predict_proba(customer)[0, 1] "
1114
+ ]
1115
+ },
1116
+ {
1117
+ "cell_type": "code",
1118
+ "execution_count": 29,
1119
+ "id": "96a4d3ac-d5e4-4890-a085-00298c231e28",
1120
+ "metadata": {},
1121
+ "outputs": [],
1122
+ "source": [
1123
+ "# save the model\n",
1124
+ "import pickle\n",
1125
+ "\n",
1126
+ "with open('model.bin', 'wb') as f:\n",
1127
+ " pickle.dump(pipeline, f)"
1128
+ ]
1129
+ },
1130
+ {
1131
+ "cell_type": "code",
1132
+ "execution_count": 31,
1133
+ "id": "7f99bdbb-1304-49e1-9f6f-fdc1fdcdba54",
1134
+ "metadata": {},
1135
+ "outputs": [],
1136
+ "source": [
1137
+ "# load the model\n",
1138
+ "\n",
1139
+ "with open('model.bin', 'rb') as f_in:\n",
1140
+ " model = pickle.load(f_in)"
1141
+ ]
1142
+ },
1143
+ {
1144
+ "cell_type": "code",
1145
+ "execution_count": 32,
1146
+ "id": "0ac0af36-e4e8-475f-896d-645a63877aff",
1147
+ "metadata": {},
1148
+ "outputs": [
1149
+ {
1150
+ "data": {
1151
+ "text/html": [
1152
+ "<style>#sk-container-id-3 {\n",
1153
+ " /* Definition of color scheme common for light and dark mode */\n",
1154
+ " --sklearn-color-text: #000;\n",
1155
+ " --sklearn-color-text-muted: #666;\n",
1156
+ " --sklearn-color-line: gray;\n",
1157
+ " /* Definition of color scheme for unfitted estimators */\n",
1158
+ " --sklearn-color-unfitted-level-0: #fff5e6;\n",
1159
+ " --sklearn-color-unfitted-level-1: #f6e4d2;\n",
1160
+ " --sklearn-color-unfitted-level-2: #ffe0b3;\n",
1161
+ " --sklearn-color-unfitted-level-3: chocolate;\n",
1162
+ " /* Definition of color scheme for fitted estimators */\n",
1163
+ " --sklearn-color-fitted-level-0: #f0f8ff;\n",
1164
+ " --sklearn-color-fitted-level-1: #d4ebff;\n",
1165
+ " --sklearn-color-fitted-level-2: #b3dbfd;\n",
1166
+ " --sklearn-color-fitted-level-3: cornflowerblue;\n",
1167
+ "\n",
1168
+ " /* Specific color for light theme */\n",
1169
+ " --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
1170
+ " --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
1171
+ " --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
1172
+ " --sklearn-color-icon: #696969;\n",
1173
+ "\n",
1174
+ " @media (prefers-color-scheme: dark) {\n",
1175
+ " /* Redefinition of color scheme for dark theme */\n",
1176
+ " --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
1177
+ " --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
1178
+ " --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
1179
+ " --sklearn-color-icon: #878787;\n",
1180
+ " }\n",
1181
+ "}\n",
1182
+ "\n",
1183
+ "#sk-container-id-3 {\n",
1184
+ " color: var(--sklearn-color-text);\n",
1185
+ "}\n",
1186
+ "\n",
1187
+ "#sk-container-id-3 pre {\n",
1188
+ " padding: 0;\n",
1189
+ "}\n",
1190
+ "\n",
1191
+ "#sk-container-id-3 input.sk-hidden--visually {\n",
1192
+ " border: 0;\n",
1193
+ " clip: rect(1px 1px 1px 1px);\n",
1194
+ " clip: rect(1px, 1px, 1px, 1px);\n",
1195
+ " height: 1px;\n",
1196
+ " margin: -1px;\n",
1197
+ " overflow: hidden;\n",
1198
+ " padding: 0;\n",
1199
+ " position: absolute;\n",
1200
+ " width: 1px;\n",
1201
+ "}\n",
1202
+ "\n",
1203
+ "#sk-container-id-3 div.sk-dashed-wrapped {\n",
1204
+ " border: 1px dashed var(--sklearn-color-line);\n",
1205
+ " margin: 0 0.4em 0.5em 0.4em;\n",
1206
+ " box-sizing: border-box;\n",
1207
+ " padding-bottom: 0.4em;\n",
1208
+ " background-color: var(--sklearn-color-background);\n",
1209
+ "}\n",
1210
+ "\n",
1211
+ "#sk-container-id-3 div.sk-container {\n",
1212
+ " /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
1213
+ " but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
1214
+ " so we also need the `!important` here to be able to override the\n",
1215
+ " default hidden behavior on the sphinx rendered scikit-learn.org.\n",
1216
+ " See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
1217
+ " display: inline-block !important;\n",
1218
+ " position: relative;\n",
1219
+ "}\n",
1220
+ "\n",
1221
+ "#sk-container-id-3 div.sk-text-repr-fallback {\n",
1222
+ " display: none;\n",
1223
+ "}\n",
1224
+ "\n",
1225
+ "div.sk-parallel-item,\n",
1226
+ "div.sk-serial,\n",
1227
+ "div.sk-item {\n",
1228
+ " /* draw centered vertical line to link estimators */\n",
1229
+ " background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
1230
+ " background-size: 2px 100%;\n",
1231
+ " background-repeat: no-repeat;\n",
1232
+ " background-position: center center;\n",
1233
+ "}\n",
1234
+ "\n",
1235
+ "/* Parallel-specific style estimator block */\n",
1236
+ "\n",
1237
+ "#sk-container-id-3 div.sk-parallel-item::after {\n",
1238
+ " content: \"\";\n",
1239
+ " width: 100%;\n",
1240
+ " border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
1241
+ " flex-grow: 1;\n",
1242
+ "}\n",
1243
+ "\n",
1244
+ "#sk-container-id-3 div.sk-parallel {\n",
1245
+ " display: flex;\n",
1246
+ " align-items: stretch;\n",
1247
+ " justify-content: center;\n",
1248
+ " background-color: var(--sklearn-color-background);\n",
1249
+ " position: relative;\n",
1250
+ "}\n",
1251
+ "\n",
1252
+ "#sk-container-id-3 div.sk-parallel-item {\n",
1253
+ " display: flex;\n",
1254
+ " flex-direction: column;\n",
1255
+ "}\n",
1256
+ "\n",
1257
+ "#sk-container-id-3 div.sk-parallel-item:first-child::after {\n",
1258
+ " align-self: flex-end;\n",
1259
+ " width: 50%;\n",
1260
+ "}\n",
1261
+ "\n",
1262
+ "#sk-container-id-3 div.sk-parallel-item:last-child::after {\n",
1263
+ " align-self: flex-start;\n",
1264
+ " width: 50%;\n",
1265
+ "}\n",
1266
+ "\n",
1267
+ "#sk-container-id-3 div.sk-parallel-item:only-child::after {\n",
1268
+ " width: 0;\n",
1269
+ "}\n",
1270
+ "\n",
1271
+ "/* Serial-specific style estimator block */\n",
1272
+ "\n",
1273
+ "#sk-container-id-3 div.sk-serial {\n",
1274
+ " display: flex;\n",
1275
+ " flex-direction: column;\n",
1276
+ " align-items: center;\n",
1277
+ " background-color: var(--sklearn-color-background);\n",
1278
+ " padding-right: 1em;\n",
1279
+ " padding-left: 1em;\n",
1280
+ "}\n",
1281
+ "\n",
1282
+ "\n",
1283
+ "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
1284
+ "clickable and can be expanded/collapsed.\n",
1285
+ "- Pipeline and ColumnTransformer use this feature and define the default style\n",
1286
+ "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
1287
+ "*/\n",
1288
+ "\n",
1289
+ "/* Pipeline and ColumnTransformer style (default) */\n",
1290
+ "\n",
1291
+ "#sk-container-id-3 div.sk-toggleable {\n",
1292
+ " /* Default theme specific background. It is overwritten whether we have a\n",
1293
+ " specific estimator or a Pipeline/ColumnTransformer */\n",
1294
+ " background-color: var(--sklearn-color-background);\n",
1295
+ "}\n",
1296
+ "\n",
1297
+ "/* Toggleable label */\n",
1298
+ "#sk-container-id-3 label.sk-toggleable__label {\n",
1299
+ " cursor: pointer;\n",
1300
+ " display: flex;\n",
1301
+ " width: 100%;\n",
1302
+ " margin-bottom: 0;\n",
1303
+ " padding: 0.5em;\n",
1304
+ " box-sizing: border-box;\n",
1305
+ " text-align: center;\n",
1306
+ " align-items: start;\n",
1307
+ " justify-content: space-between;\n",
1308
+ " gap: 0.5em;\n",
1309
+ "}\n",
1310
+ "\n",
1311
+ "#sk-container-id-3 label.sk-toggleable__label .caption {\n",
1312
+ " font-size: 0.6rem;\n",
1313
+ " font-weight: lighter;\n",
1314
+ " color: var(--sklearn-color-text-muted);\n",
1315
+ "}\n",
1316
+ "\n",
1317
+ "#sk-container-id-3 label.sk-toggleable__label-arrow:before {\n",
1318
+ " /* Arrow on the left of the label */\n",
1319
+ " content: \"▸\";\n",
1320
+ " float: left;\n",
1321
+ " margin-right: 0.25em;\n",
1322
+ " color: var(--sklearn-color-icon);\n",
1323
+ "}\n",
1324
+ "\n",
1325
+ "#sk-container-id-3 label.sk-toggleable__label-arrow:hover:before {\n",
1326
+ " color: var(--sklearn-color-text);\n",
1327
+ "}\n",
1328
+ "\n",
1329
+ "/* Toggleable content - dropdown */\n",
1330
+ "\n",
1331
+ "#sk-container-id-3 div.sk-toggleable__content {\n",
1332
+ " display: none;\n",
1333
+ " text-align: left;\n",
1334
+ " /* unfitted */\n",
1335
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
1336
+ "}\n",
1337
+ "\n",
1338
+ "#sk-container-id-3 div.sk-toggleable__content.fitted {\n",
1339
+ " /* fitted */\n",
1340
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
1341
+ "}\n",
1342
+ "\n",
1343
+ "#sk-container-id-3 div.sk-toggleable__content pre {\n",
1344
+ " margin: 0.2em;\n",
1345
+ " border-radius: 0.25em;\n",
1346
+ " color: var(--sklearn-color-text);\n",
1347
+ " /* unfitted */\n",
1348
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
1349
+ "}\n",
1350
+ "\n",
1351
+ "#sk-container-id-3 div.sk-toggleable__content.fitted pre {\n",
1352
+ " /* unfitted */\n",
1353
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
1354
+ "}\n",
1355
+ "\n",
1356
+ "#sk-container-id-3 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
1357
+ " /* Expand drop-down */\n",
1358
+ " display: block;\n",
1359
+ " width: 100%;\n",
1360
+ " overflow: visible;\n",
1361
+ "}\n",
1362
+ "\n",
1363
+ "#sk-container-id-3 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
1364
+ " content: \"▾\";\n",
1365
+ "}\n",
1366
+ "\n",
1367
+ "/* Pipeline/ColumnTransformer-specific style */\n",
1368
+ "\n",
1369
+ "#sk-container-id-3 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
1370
+ " color: var(--sklearn-color-text);\n",
1371
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
1372
+ "}\n",
1373
+ "\n",
1374
+ "#sk-container-id-3 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
1375
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
1376
+ "}\n",
1377
+ "\n",
1378
+ "/* Estimator-specific style */\n",
1379
+ "\n",
1380
+ "/* Colorize estimator box */\n",
1381
+ "#sk-container-id-3 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
1382
+ " /* unfitted */\n",
1383
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
1384
+ "}\n",
1385
+ "\n",
1386
+ "#sk-container-id-3 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
1387
+ " /* fitted */\n",
1388
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
1389
+ "}\n",
1390
+ "\n",
1391
+ "#sk-container-id-3 div.sk-label label.sk-toggleable__label,\n",
1392
+ "#sk-container-id-3 div.sk-label label {\n",
1393
+ " /* The background is the default theme color */\n",
1394
+ " color: var(--sklearn-color-text-on-default-background);\n",
1395
+ "}\n",
1396
+ "\n",
1397
+ "/* On hover, darken the color of the background */\n",
1398
+ "#sk-container-id-3 div.sk-label:hover label.sk-toggleable__label {\n",
1399
+ " color: var(--sklearn-color-text);\n",
1400
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
1401
+ "}\n",
1402
+ "\n",
1403
+ "/* Label box, darken color on hover, fitted */\n",
1404
+ "#sk-container-id-3 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
1405
+ " color: var(--sklearn-color-text);\n",
1406
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
1407
+ "}\n",
1408
+ "\n",
1409
+ "/* Estimator label */\n",
1410
+ "\n",
1411
+ "#sk-container-id-3 div.sk-label label {\n",
1412
+ " font-family: monospace;\n",
1413
+ " font-weight: bold;\n",
1414
+ " display: inline-block;\n",
1415
+ " line-height: 1.2em;\n",
1416
+ "}\n",
1417
+ "\n",
1418
+ "#sk-container-id-3 div.sk-label-container {\n",
1419
+ " text-align: center;\n",
1420
+ "}\n",
1421
+ "\n",
1422
+ "/* Estimator-specific */\n",
1423
+ "#sk-container-id-3 div.sk-estimator {\n",
1424
+ " font-family: monospace;\n",
1425
+ " border: 1px dotted var(--sklearn-color-border-box);\n",
1426
+ " border-radius: 0.25em;\n",
1427
+ " box-sizing: border-box;\n",
1428
+ " margin-bottom: 0.5em;\n",
1429
+ " /* unfitted */\n",
1430
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
1431
+ "}\n",
1432
+ "\n",
1433
+ "#sk-container-id-3 div.sk-estimator.fitted {\n",
1434
+ " /* fitted */\n",
1435
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
1436
+ "}\n",
1437
+ "\n",
1438
+ "/* on hover */\n",
1439
+ "#sk-container-id-3 div.sk-estimator:hover {\n",
1440
+ " /* unfitted */\n",
1441
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
1442
+ "}\n",
1443
+ "\n",
1444
+ "#sk-container-id-3 div.sk-estimator.fitted:hover {\n",
1445
+ " /* fitted */\n",
1446
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
1447
+ "}\n",
1448
+ "\n",
1449
+ "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
1450
+ "\n",
1451
+ "/* Common style for \"i\" and \"?\" */\n",
1452
+ "\n",
1453
+ ".sk-estimator-doc-link,\n",
1454
+ "a:link.sk-estimator-doc-link,\n",
1455
+ "a:visited.sk-estimator-doc-link {\n",
1456
+ " float: right;\n",
1457
+ " font-size: smaller;\n",
1458
+ " line-height: 1em;\n",
1459
+ " font-family: monospace;\n",
1460
+ " background-color: var(--sklearn-color-background);\n",
1461
+ " border-radius: 1em;\n",
1462
+ " height: 1em;\n",
1463
+ " width: 1em;\n",
1464
+ " text-decoration: none !important;\n",
1465
+ " margin-left: 0.5em;\n",
1466
+ " text-align: center;\n",
1467
+ " /* unfitted */\n",
1468
+ " border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
1469
+ " color: var(--sklearn-color-unfitted-level-1);\n",
1470
+ "}\n",
1471
+ "\n",
1472
+ ".sk-estimator-doc-link.fitted,\n",
1473
+ "a:link.sk-estimator-doc-link.fitted,\n",
1474
+ "a:visited.sk-estimator-doc-link.fitted {\n",
1475
+ " /* fitted */\n",
1476
+ " border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
1477
+ " color: var(--sklearn-color-fitted-level-1);\n",
1478
+ "}\n",
1479
+ "\n",
1480
+ "/* On hover */\n",
1481
+ "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
1482
+ ".sk-estimator-doc-link:hover,\n",
1483
+ "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
1484
+ ".sk-estimator-doc-link:hover {\n",
1485
+ " /* unfitted */\n",
1486
+ " background-color: var(--sklearn-color-unfitted-level-3);\n",
1487
+ " color: var(--sklearn-color-background);\n",
1488
+ " text-decoration: none;\n",
1489
+ "}\n",
1490
+ "\n",
1491
+ "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
1492
+ ".sk-estimator-doc-link.fitted:hover,\n",
1493
+ "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
1494
+ ".sk-estimator-doc-link.fitted:hover {\n",
1495
+ " /* fitted */\n",
1496
+ " background-color: var(--sklearn-color-fitted-level-3);\n",
1497
+ " color: var(--sklearn-color-background);\n",
1498
+ " text-decoration: none;\n",
1499
+ "}\n",
1500
+ "\n",
1501
+ "/* Span, style for the box shown on hovering the info icon */\n",
1502
+ ".sk-estimator-doc-link span {\n",
1503
+ " display: none;\n",
1504
+ " z-index: 9999;\n",
1505
+ " position: relative;\n",
1506
+ " font-weight: normal;\n",
1507
+ " right: .2ex;\n",
1508
+ " padding: .5ex;\n",
1509
+ " margin: .5ex;\n",
1510
+ " width: min-content;\n",
1511
+ " min-width: 20ex;\n",
1512
+ " max-width: 50ex;\n",
1513
+ " color: var(--sklearn-color-text);\n",
1514
+ " box-shadow: 2pt 2pt 4pt #999;\n",
1515
+ " /* unfitted */\n",
1516
+ " background: var(--sklearn-color-unfitted-level-0);\n",
1517
+ " border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
1518
+ "}\n",
1519
+ "\n",
1520
+ ".sk-estimator-doc-link.fitted span {\n",
1521
+ " /* fitted */\n",
1522
+ " background: var(--sklearn-color-fitted-level-0);\n",
1523
+ " border: var(--sklearn-color-fitted-level-3);\n",
1524
+ "}\n",
1525
+ "\n",
1526
+ ".sk-estimator-doc-link:hover span {\n",
1527
+ " display: block;\n",
1528
+ "}\n",
1529
+ "\n",
1530
+ "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
1531
+ "\n",
1532
+ "#sk-container-id-3 a.estimator_doc_link {\n",
1533
+ " float: right;\n",
1534
+ " font-size: 1rem;\n",
1535
+ " line-height: 1em;\n",
1536
+ " font-family: monospace;\n",
1537
+ " background-color: var(--sklearn-color-background);\n",
1538
+ " border-radius: 1rem;\n",
1539
+ " height: 1rem;\n",
1540
+ " width: 1rem;\n",
1541
+ " text-decoration: none;\n",
1542
+ " /* unfitted */\n",
1543
+ " color: var(--sklearn-color-unfitted-level-1);\n",
1544
+ " border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
1545
+ "}\n",
1546
+ "\n",
1547
+ "#sk-container-id-3 a.estimator_doc_link.fitted {\n",
1548
+ " /* fitted */\n",
1549
+ " border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
1550
+ " color: var(--sklearn-color-fitted-level-1);\n",
1551
+ "}\n",
1552
+ "\n",
1553
+ "/* On hover */\n",
1554
+ "#sk-container-id-3 a.estimator_doc_link:hover {\n",
1555
+ " /* unfitted */\n",
1556
+ " background-color: var(--sklearn-color-unfitted-level-3);\n",
1557
+ " color: var(--sklearn-color-background);\n",
1558
+ " text-decoration: none;\n",
1559
+ "}\n",
1560
+ "\n",
1561
+ "#sk-container-id-3 a.estimator_doc_link.fitted:hover {\n",
1562
+ " /* fitted */\n",
1563
+ " background-color: var(--sklearn-color-fitted-level-3);\n",
1564
+ "}\n",
1565
+ "\n",
1566
+ ".estimator-table summary {\n",
1567
+ " padding: .5rem;\n",
1568
+ " font-family: monospace;\n",
1569
+ " cursor: pointer;\n",
1570
+ "}\n",
1571
+ "\n",
1572
+ ".estimator-table details[open] {\n",
1573
+ " padding-left: 0.1rem;\n",
1574
+ " padding-right: 0.1rem;\n",
1575
+ " padding-bottom: 0.3rem;\n",
1576
+ "}\n",
1577
+ "\n",
1578
+ ".estimator-table .parameters-table {\n",
1579
+ " margin-left: auto !important;\n",
1580
+ " margin-right: auto !important;\n",
1581
+ "}\n",
1582
+ "\n",
1583
+ ".estimator-table .parameters-table tr:nth-child(odd) {\n",
1584
+ " background-color: #fff;\n",
1585
+ "}\n",
1586
+ "\n",
1587
+ ".estimator-table .parameters-table tr:nth-child(even) {\n",
1588
+ " background-color: #f6f6f6;\n",
1589
+ "}\n",
1590
+ "\n",
1591
+ ".estimator-table .parameters-table tr:hover {\n",
1592
+ " background-color: #e0e0e0;\n",
1593
+ "}\n",
1594
+ "\n",
1595
+ ".estimator-table table td {\n",
1596
+ " border: 1px solid rgba(106, 105, 104, 0.232);\n",
1597
+ "}\n",
1598
+ "\n",
1599
+ ".user-set td {\n",
1600
+ " color:rgb(255, 94, 0);\n",
1601
+ " text-align: left;\n",
1602
+ "}\n",
1603
+ "\n",
1604
+ ".user-set td.value pre {\n",
1605
+ " color:rgb(255, 94, 0) !important;\n",
1606
+ " background-color: transparent !important;\n",
1607
+ "}\n",
1608
+ "\n",
1609
+ ".default td {\n",
1610
+ " color: black;\n",
1611
+ " text-align: left;\n",
1612
+ "}\n",
1613
+ "\n",
1614
+ ".user-set td i,\n",
1615
+ ".default td i {\n",
1616
+ " color: black;\n",
1617
+ "}\n",
1618
+ "\n",
1619
+ ".copy-paste-icon {\n",
1620
+ " background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=);\n",
1621
+ " background-repeat: no-repeat;\n",
1622
+ " background-size: 14px 14px;\n",
1623
+ " background-position: 0;\n",
1624
+ " display: inline-block;\n",
1625
+ " width: 14px;\n",
1626
+ " height: 14px;\n",
1627
+ " cursor: pointer;\n",
1628
+ "}\n",
1629
+ "</style><body><div id=\"sk-container-id-3\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>Pipeline(steps=[(&#x27;dictvectorizer&#x27;, DictVectorizer()),\n",
1630
+ " (&#x27;logisticregression&#x27;, LogisticRegression(solver=&#x27;liblinear&#x27;))])</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item sk-dashed-wrapped\"><div class=\"sk-label-container\"><div class=\"sk-label fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-7\" type=\"checkbox\" ><label for=\"sk-estimator-id-7\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>Pipeline</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.pipeline.Pipeline.html\">?<span>Documentation for Pipeline</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
1631
+ " <div class=\"estimator-table\">\n",
1632
+ " <details>\n",
1633
+ " <summary>Parameters</summary>\n",
1634
+ " <table class=\"parameters-table\">\n",
1635
+ " <tbody>\n",
1636
+ " \n",
1637
+ " <tr class=\"user-set\">\n",
1638
+ " <td><i class=\"copy-paste-icon\"\n",
1639
+ " onclick=\"copyToClipboard('steps',\n",
1640
+ " this.parentElement.nextElementSibling)\"\n",
1641
+ " ></i></td>\n",
1642
+ " <td class=\"param\">steps&nbsp;</td>\n",
1643
+ " <td class=\"value\">[(&#x27;dictvectorizer&#x27;, ...), (&#x27;logisticregression&#x27;, ...)]</td>\n",
1644
+ " </tr>\n",
1645
+ " \n",
1646
+ "\n",
1647
+ " <tr class=\"default\">\n",
1648
+ " <td><i class=\"copy-paste-icon\"\n",
1649
+ " onclick=\"copyToClipboard('transform_input',\n",
1650
+ " this.parentElement.nextElementSibling)\"\n",
1651
+ " ></i></td>\n",
1652
+ " <td class=\"param\">transform_input&nbsp;</td>\n",
1653
+ " <td class=\"value\">None</td>\n",
1654
+ " </tr>\n",
1655
+ " \n",
1656
+ "\n",
1657
+ " <tr class=\"default\">\n",
1658
+ " <td><i class=\"copy-paste-icon\"\n",
1659
+ " onclick=\"copyToClipboard('memory',\n",
1660
+ " this.parentElement.nextElementSibling)\"\n",
1661
+ " ></i></td>\n",
1662
+ " <td class=\"param\">memory&nbsp;</td>\n",
1663
+ " <td class=\"value\">None</td>\n",
1664
+ " </tr>\n",
1665
+ " \n",
1666
+ "\n",
1667
+ " <tr class=\"default\">\n",
1668
+ " <td><i class=\"copy-paste-icon\"\n",
1669
+ " onclick=\"copyToClipboard('verbose',\n",
1670
+ " this.parentElement.nextElementSibling)\"\n",
1671
+ " ></i></td>\n",
1672
+ " <td class=\"param\">verbose&nbsp;</td>\n",
1673
+ " <td class=\"value\">False</td>\n",
1674
+ " </tr>\n",
1675
+ " \n",
1676
+ " </tbody>\n",
1677
+ " </table>\n",
1678
+ " </details>\n",
1679
+ " </div>\n",
1680
+ " </div></div></div><div class=\"sk-serial\"><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-8\" type=\"checkbox\" ><label for=\"sk-estimator-id-8\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>DictVectorizer</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.feature_extraction.DictVectorizer.html\">?<span>Documentation for DictVectorizer</span></a></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"dictvectorizer__\">\n",
1681
+ " <div class=\"estimator-table\">\n",
1682
+ " <details>\n",
1683
+ " <summary>Parameters</summary>\n",
1684
+ " <table class=\"parameters-table\">\n",
1685
+ " <tbody>\n",
1686
+ " \n",
1687
+ " <tr class=\"default\">\n",
1688
+ " <td><i class=\"copy-paste-icon\"\n",
1689
+ " onclick=\"copyToClipboard('dtype',\n",
1690
+ " this.parentElement.nextElementSibling)\"\n",
1691
+ " ></i></td>\n",
1692
+ " <td class=\"param\">dtype&nbsp;</td>\n",
1693
+ " <td class=\"value\">&lt;class &#x27;numpy.float64&#x27;&gt;</td>\n",
1694
+ " </tr>\n",
1695
+ " \n",
1696
+ "\n",
1697
+ " <tr class=\"default\">\n",
1698
+ " <td><i class=\"copy-paste-icon\"\n",
1699
+ " onclick=\"copyToClipboard('separator',\n",
1700
+ " this.parentElement.nextElementSibling)\"\n",
1701
+ " ></i></td>\n",
1702
+ " <td class=\"param\">separator&nbsp;</td>\n",
1703
+ " <td class=\"value\">&#x27;=&#x27;</td>\n",
1704
+ " </tr>\n",
1705
+ " \n",
1706
+ "\n",
1707
+ " <tr class=\"default\">\n",
1708
+ " <td><i class=\"copy-paste-icon\"\n",
1709
+ " onclick=\"copyToClipboard('sparse',\n",
1710
+ " this.parentElement.nextElementSibling)\"\n",
1711
+ " ></i></td>\n",
1712
+ " <td class=\"param\">sparse&nbsp;</td>\n",
1713
+ " <td class=\"value\">True</td>\n",
1714
+ " </tr>\n",
1715
+ " \n",
1716
+ "\n",
1717
+ " <tr class=\"default\">\n",
1718
+ " <td><i class=\"copy-paste-icon\"\n",
1719
+ " onclick=\"copyToClipboard('sort',\n",
1720
+ " this.parentElement.nextElementSibling)\"\n",
1721
+ " ></i></td>\n",
1722
+ " <td class=\"param\">sort&nbsp;</td>\n",
1723
+ " <td class=\"value\">True</td>\n",
1724
+ " </tr>\n",
1725
+ " \n",
1726
+ " </tbody>\n",
1727
+ " </table>\n",
1728
+ " </details>\n",
1729
+ " </div>\n",
1730
+ " </div></div></div><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-9\" type=\"checkbox\" ><label for=\"sk-estimator-id-9\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>LogisticRegression</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.linear_model.LogisticRegression.html\">?<span>Documentation for LogisticRegression</span></a></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"logisticregression__\">\n",
1731
+ " <div class=\"estimator-table\">\n",
1732
+ " <details>\n",
1733
+ " <summary>Parameters</summary>\n",
1734
+ " <table class=\"parameters-table\">\n",
1735
+ " <tbody>\n",
1736
+ " \n",
1737
+ " <tr class=\"default\">\n",
1738
+ " <td><i class=\"copy-paste-icon\"\n",
1739
+ " onclick=\"copyToClipboard('penalty',\n",
1740
+ " this.parentElement.nextElementSibling)\"\n",
1741
+ " ></i></td>\n",
1742
+ " <td class=\"param\">penalty&nbsp;</td>\n",
1743
+ " <td class=\"value\">&#x27;l2&#x27;</td>\n",
1744
+ " </tr>\n",
1745
+ " \n",
1746
+ "\n",
1747
+ " <tr class=\"default\">\n",
1748
+ " <td><i class=\"copy-paste-icon\"\n",
1749
+ " onclick=\"copyToClipboard('dual',\n",
1750
+ " this.parentElement.nextElementSibling)\"\n",
1751
+ " ></i></td>\n",
1752
+ " <td class=\"param\">dual&nbsp;</td>\n",
1753
+ " <td class=\"value\">False</td>\n",
1754
+ " </tr>\n",
1755
+ " \n",
1756
+ "\n",
1757
+ " <tr class=\"default\">\n",
1758
+ " <td><i class=\"copy-paste-icon\"\n",
1759
+ " onclick=\"copyToClipboard('tol',\n",
1760
+ " this.parentElement.nextElementSibling)\"\n",
1761
+ " ></i></td>\n",
1762
+ " <td class=\"param\">tol&nbsp;</td>\n",
1763
+ " <td class=\"value\">0.0001</td>\n",
1764
+ " </tr>\n",
1765
+ " \n",
1766
+ "\n",
1767
+ " <tr class=\"default\">\n",
1768
+ " <td><i class=\"copy-paste-icon\"\n",
1769
+ " onclick=\"copyToClipboard('C',\n",
1770
+ " this.parentElement.nextElementSibling)\"\n",
1771
+ " ></i></td>\n",
1772
+ " <td class=\"param\">C&nbsp;</td>\n",
1773
+ " <td class=\"value\">1.0</td>\n",
1774
+ " </tr>\n",
1775
+ " \n",
1776
+ "\n",
1777
+ " <tr class=\"default\">\n",
1778
+ " <td><i class=\"copy-paste-icon\"\n",
1779
+ " onclick=\"copyToClipboard('fit_intercept',\n",
1780
+ " this.parentElement.nextElementSibling)\"\n",
1781
+ " ></i></td>\n",
1782
+ " <td class=\"param\">fit_intercept&nbsp;</td>\n",
1783
+ " <td class=\"value\">True</td>\n",
1784
+ " </tr>\n",
1785
+ " \n",
1786
+ "\n",
1787
+ " <tr class=\"default\">\n",
1788
+ " <td><i class=\"copy-paste-icon\"\n",
1789
+ " onclick=\"copyToClipboard('intercept_scaling',\n",
1790
+ " this.parentElement.nextElementSibling)\"\n",
1791
+ " ></i></td>\n",
1792
+ " <td class=\"param\">intercept_scaling&nbsp;</td>\n",
1793
+ " <td class=\"value\">1</td>\n",
1794
+ " </tr>\n",
1795
+ " \n",
1796
+ "\n",
1797
+ " <tr class=\"default\">\n",
1798
+ " <td><i class=\"copy-paste-icon\"\n",
1799
+ " onclick=\"copyToClipboard('class_weight',\n",
1800
+ " this.parentElement.nextElementSibling)\"\n",
1801
+ " ></i></td>\n",
1802
+ " <td class=\"param\">class_weight&nbsp;</td>\n",
1803
+ " <td class=\"value\">None</td>\n",
1804
+ " </tr>\n",
1805
+ " \n",
1806
+ "\n",
1807
+ " <tr class=\"default\">\n",
1808
+ " <td><i class=\"copy-paste-icon\"\n",
1809
+ " onclick=\"copyToClipboard('random_state',\n",
1810
+ " this.parentElement.nextElementSibling)\"\n",
1811
+ " ></i></td>\n",
1812
+ " <td class=\"param\">random_state&nbsp;</td>\n",
1813
+ " <td class=\"value\">None</td>\n",
1814
+ " </tr>\n",
1815
+ " \n",
1816
+ "\n",
1817
+ " <tr class=\"user-set\">\n",
1818
+ " <td><i class=\"copy-paste-icon\"\n",
1819
+ " onclick=\"copyToClipboard('solver',\n",
1820
+ " this.parentElement.nextElementSibling)\"\n",
1821
+ " ></i></td>\n",
1822
+ " <td class=\"param\">solver&nbsp;</td>\n",
1823
+ " <td class=\"value\">&#x27;liblinear&#x27;</td>\n",
1824
+ " </tr>\n",
1825
+ " \n",
1826
+ "\n",
1827
+ " <tr class=\"default\">\n",
1828
+ " <td><i class=\"copy-paste-icon\"\n",
1829
+ " onclick=\"copyToClipboard('max_iter',\n",
1830
+ " this.parentElement.nextElementSibling)\"\n",
1831
+ " ></i></td>\n",
1832
+ " <td class=\"param\">max_iter&nbsp;</td>\n",
1833
+ " <td class=\"value\">100</td>\n",
1834
+ " </tr>\n",
1835
+ " \n",
1836
+ "\n",
1837
+ " <tr class=\"default\">\n",
1838
+ " <td><i class=\"copy-paste-icon\"\n",
1839
+ " onclick=\"copyToClipboard('multi_class',\n",
1840
+ " this.parentElement.nextElementSibling)\"\n",
1841
+ " ></i></td>\n",
1842
+ " <td class=\"param\">multi_class&nbsp;</td>\n",
1843
+ " <td class=\"value\">&#x27;deprecated&#x27;</td>\n",
1844
+ " </tr>\n",
1845
+ " \n",
1846
+ "\n",
1847
+ " <tr class=\"default\">\n",
1848
+ " <td><i class=\"copy-paste-icon\"\n",
1849
+ " onclick=\"copyToClipboard('verbose',\n",
1850
+ " this.parentElement.nextElementSibling)\"\n",
1851
+ " ></i></td>\n",
1852
+ " <td class=\"param\">verbose&nbsp;</td>\n",
1853
+ " <td class=\"value\">0</td>\n",
1854
+ " </tr>\n",
1855
+ " \n",
1856
+ "\n",
1857
+ " <tr class=\"default\">\n",
1858
+ " <td><i class=\"copy-paste-icon\"\n",
1859
+ " onclick=\"copyToClipboard('warm_start',\n",
1860
+ " this.parentElement.nextElementSibling)\"\n",
1861
+ " ></i></td>\n",
1862
+ " <td class=\"param\">warm_start&nbsp;</td>\n",
1863
+ " <td class=\"value\">False</td>\n",
1864
+ " </tr>\n",
1865
+ " \n",
1866
+ "\n",
1867
+ " <tr class=\"default\">\n",
1868
+ " <td><i class=\"copy-paste-icon\"\n",
1869
+ " onclick=\"copyToClipboard('n_jobs',\n",
1870
+ " this.parentElement.nextElementSibling)\"\n",
1871
+ " ></i></td>\n",
1872
+ " <td class=\"param\">n_jobs&nbsp;</td>\n",
1873
+ " <td class=\"value\">None</td>\n",
1874
+ " </tr>\n",
1875
+ " \n",
1876
+ "\n",
1877
+ " <tr class=\"default\">\n",
1878
+ " <td><i class=\"copy-paste-icon\"\n",
1879
+ " onclick=\"copyToClipboard('l1_ratio',\n",
1880
+ " this.parentElement.nextElementSibling)\"\n",
1881
+ " ></i></td>\n",
1882
+ " <td class=\"param\">l1_ratio&nbsp;</td>\n",
1883
+ " <td class=\"value\">None</td>\n",
1884
+ " </tr>\n",
1885
+ " \n",
1886
+ " </tbody>\n",
1887
+ " </table>\n",
1888
+ " </details>\n",
1889
+ " </div>\n",
1890
+ " </div></div></div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
1891
+ " // Get the parameter prefix from the closest toggleable content\n",
1892
+ " const toggleableContent = element.closest('.sk-toggleable__content');\n",
1893
+ " const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
1894
+ " const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
1895
+ "\n",
1896
+ " const originalStyle = element.style;\n",
1897
+ " const computedStyle = window.getComputedStyle(element);\n",
1898
+ " const originalWidth = computedStyle.width;\n",
1899
+ " const originalHTML = element.innerHTML.replace('Copied!', '');\n",
1900
+ "\n",
1901
+ " navigator.clipboard.writeText(fullParamName)\n",
1902
+ " .then(() => {\n",
1903
+ " element.style.width = originalWidth;\n",
1904
+ " element.style.color = 'green';\n",
1905
+ " element.innerHTML = \"Copied!\";\n",
1906
+ "\n",
1907
+ " setTimeout(() => {\n",
1908
+ " element.innerHTML = originalHTML;\n",
1909
+ " element.style = originalStyle;\n",
1910
+ " }, 2000);\n",
1911
+ " })\n",
1912
+ " .catch(err => {\n",
1913
+ " console.error('Failed to copy:', err);\n",
1914
+ " element.style.color = 'red';\n",
1915
+ " element.innerHTML = \"Failed!\";\n",
1916
+ " setTimeout(() => {\n",
1917
+ " element.innerHTML = originalHTML;\n",
1918
+ " element.style = originalStyle;\n",
1919
+ " }, 2000);\n",
1920
+ " });\n",
1921
+ " return false;\n",
1922
+ "}\n",
1923
+ "\n",
1924
+ "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
1925
+ " const toggleableContent = element.closest('.sk-toggleable__content');\n",
1926
+ " const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
1927
+ " const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
1928
+ " const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
1929
+ "\n",
1930
+ " element.setAttribute('title', fullParamName);\n",
1931
+ "});\n",
1932
+ "</script></body>"
1933
+ ],
1934
+ "text/plain": [
1935
+ "Pipeline(steps=[('dictvectorizer', DictVectorizer()),\n",
1936
+ " ('logisticregression', LogisticRegression(solver='liblinear'))])"
1937
+ ]
1938
+ },
1939
+ "execution_count": 32,
1940
+ "metadata": {},
1941
+ "output_type": "execute_result"
1942
+ }
1943
+ ],
1944
+ "source": [
1945
+ "model"
1946
+ ]
1947
+ },
1948
+ {
1949
+ "cell_type": "code",
1950
+ "execution_count": null,
1951
+ "id": "e4452cb3-f563-430c-ae69-09e2a5e24475",
1952
+ "metadata": {},
1953
+ "outputs": [],
1954
+ "source": []
1955
+ },
1956
+ {
1957
+ "cell_type": "code",
1958
+ "execution_count": null,
1959
+ "id": "8720b7f9-438b-436e-8151-b6b4e64850bd",
1960
+ "metadata": {},
1961
+ "outputs": [],
1962
+ "source": []
1963
+ }
1964
+ ],
1965
+ "metadata": {
1966
+ "kernelspec": {
1967
+ "display_name": "Python 3",
1968
+ "language": "python",
1969
+ "name": "python3"
1970
+ },
1971
+ "language_info": {
1972
+ "codemirror_mode": {
1973
+ "name": "ipython",
1974
+ "version": 3
1975
+ },
1976
+ "file_extension": ".py",
1977
+ "mimetype": "text/x-python",
1978
+ "name": "python",
1979
+ "nbconvert_exporter": "python",
1980
+ "pygments_lexer": "ipython3",
1981
+ "version": "3.12.1"
1982
+ }
1983
+ },
1984
+ "nbformat": 4,
1985
+ "nbformat_minor": 5
1986
+ }