responseapi 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- responseapi-1.0.0/.github/workflows/publish.yml +35 -0
- responseapi-1.0.0/.gitignore +10 -0
- responseapi-1.0.0/.python-version +1 -0
- responseapi-1.0.0/LICENSE +21 -0
- responseapi-1.0.0/PKG-INFO +227 -0
- responseapi-1.0.0/README.md +204 -0
- responseapi-1.0.0/pyproject.toml +38 -0
- responseapi-1.0.0/src/responseapi/__init__.py +31 -0
- responseapi-1.0.0/src/responseapi/_exceptions/__init__.py +3 -0
- responseapi-1.0.0/src/responseapi/_exceptions/api_exception.py +36 -0
- responseapi-1.0.0/src/responseapi/_interceptors/__init__.py +15 -0
- responseapi-1.0.0/src/responseapi/_interceptors/handlers.py +66 -0
- responseapi-1.0.0/src/responseapi/_schemas/__init__.py +6 -0
- responseapi-1.0.0/src/responseapi/_schemas/response_schema.py +46 -0
- responseapi-1.0.0/src/responseapi/_services/__init__.py +3 -0
- responseapi-1.0.0/src/responseapi/_services/response_service.py +64 -0
- responseapi-1.0.0/src/responseapi/py.typed +1 -0
- responseapi-1.0.0/uv.lock +285 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build-and-publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout code
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v3
|
|
21
|
+
with:
|
|
22
|
+
enable-cache: true
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
|
|
29
|
+
- name: Build package
|
|
30
|
+
run: uv build
|
|
31
|
+
|
|
32
|
+
- name: Publish package to PyPI
|
|
33
|
+
env:
|
|
34
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
|
35
|
+
run: uv publish
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 responseapi Authors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: responseapi
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A clean, production-grade standardized response envelope framework for FastAPI applications.
|
|
5
|
+
Author-email: Dev Raj Khadka <devrajkhadka941@gmail.com>, Aryan Tamang <aryantamangcs@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: api-design,exception-handler,fastapi,jsonresponse,middleware,openapi,pydantic
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Framework :: FastAPI
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Requires-Dist: fastapi>=0.100.0
|
|
21
|
+
Requires-Dist: pydantic>=2.0.0
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# responseapi
|
|
25
|
+
|
|
26
|
+
[](https://pypi.org/project/responseapi/)
|
|
27
|
+
[](https://pypi.org/project/responseapi/)
|
|
28
|
+
[](https://opensource.org/licenses/MIT)
|
|
29
|
+
|
|
30
|
+
A clean, production-grade standardized response envelope framework for **FastAPI** applications.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 📌 Features
|
|
35
|
+
|
|
36
|
+
- **Standardized Response Format**: Enforces unified JSON response envelopes for both success and error responses across your API.
|
|
37
|
+
- **Automated Exception Handling**: Seamlessly intercepts domain-level `APIException`, FastAPI `HTTPException`, `RequestValidationError`, and unhandled server errors.
|
|
38
|
+
- **Pydantic & OpenAPI Integration**: Generic models (`APISuccessResponseModel`, `CustomSuccessResponseSchema`, `CustomErrorResponseSchema`) for type safety and automatic OpenAPI schema generation.
|
|
39
|
+
- **Structured Logging**: Built-in exception logging using `loguru`.
|
|
40
|
+
- **Zero Boilerplate**: Simple registration via `register_exception_handlers(app)`.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 🚀 Installation
|
|
45
|
+
|
|
46
|
+
Install via `pip`:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install responseapi
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or using `uv`:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv add responseapi
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or using `poetry`:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
poetry add responseapi
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 💡 Quickstart
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from fastapi import FastAPI
|
|
70
|
+
from responseapi import (
|
|
71
|
+
APIResponse,
|
|
72
|
+
APIException,
|
|
73
|
+
register_exception_handlers,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
app = FastAPI(title="My API")
|
|
77
|
+
|
|
78
|
+
# Register standardized exception handlers
|
|
79
|
+
register_exception_handlers(app)
|
|
80
|
+
|
|
81
|
+
@app.get("/users/{user_id}")
|
|
82
|
+
def get_user(user_id: int):
|
|
83
|
+
if user_id <= 0:
|
|
84
|
+
raise APIException(
|
|
85
|
+
error="User not found",
|
|
86
|
+
errors={"user_id": "Must be a positive integer"},
|
|
87
|
+
status_code=404,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return APIResponse.success(
|
|
91
|
+
data={"user_id": user_id, "username": "johndoe"},
|
|
92
|
+
message="User details retrieved successfully",
|
|
93
|
+
)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 📦 Response Envelopes
|
|
99
|
+
|
|
100
|
+
### 1. Success Response Structure (`HTTP 200 OK`)
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"success": true,
|
|
105
|
+
"message": "User details retrieved successfully",
|
|
106
|
+
"data": {
|
|
107
|
+
"user_id": 1,
|
|
108
|
+
"username": "johndoe"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 2. Error Response Structure (`HTTP 400 / 404 / 422 / 500`)
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"success": false,
|
|
118
|
+
"error": "User not found",
|
|
119
|
+
"errors": {
|
|
120
|
+
"user_id": "Must be a positive integer"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 📖 API Reference
|
|
128
|
+
|
|
129
|
+
### `APIResponse`
|
|
130
|
+
|
|
131
|
+
Factory class to return standardized `JSONResponse` objects:
|
|
132
|
+
|
|
133
|
+
- `APIResponse.success(data=None, message="Operation completed successfully", status_code=200, headers=None)`
|
|
134
|
+
- `APIResponse.error(error="An error occurred", errors=None, status_code=400, headers=None)`
|
|
135
|
+
|
|
136
|
+
### `APIException`
|
|
137
|
+
|
|
138
|
+
Custom domain exception for raising controlled errors:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
raise APIException(
|
|
142
|
+
error="Insufficient funds",
|
|
143
|
+
errors={"balance": 10.0, "required": 50.0},
|
|
144
|
+
status_code=400
|
|
145
|
+
)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `register_exception_handlers(app: FastAPI, include_unhandled: bool = True)`
|
|
149
|
+
|
|
150
|
+
Registers error handlers for:
|
|
151
|
+
- `APIException` -> Returns `APIResponse.error(...)`
|
|
152
|
+
- `HTTPException` -> Returns `APIResponse.error(...)`
|
|
153
|
+
- `RequestValidationError` -> Returns validation errors formatted with status `422`
|
|
154
|
+
- `Exception` (optional) -> Catches unhandled errors and returns status `500`
|
|
155
|
+
|
|
156
|
+
### Pydantic Models & Schemas
|
|
157
|
+
|
|
158
|
+
- `APISuccessResponseModel[T]`: Pydantic generic model for standard success envelopes.
|
|
159
|
+
- `CustomSuccessResponseSchema[T]`: Pydantic generic schema for success payloads.
|
|
160
|
+
- `CustomErrorResponseSchema[T]`: Pydantic generic schema for error payloads.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 🛠️ Deploying / Publishing to PyPI
|
|
165
|
+
|
|
166
|
+
Follow these instructions to build and publish `responseapi` to **PyPI** (Python Package Index).
|
|
167
|
+
|
|
168
|
+
### 1. Prerequisites
|
|
169
|
+
|
|
170
|
+
Ensure you have a PyPI account registered at [pypi.org](https://pypi.org) and an API token or Trusted Publisher configuration set up.
|
|
171
|
+
|
|
172
|
+
### 2. Build the Package
|
|
173
|
+
|
|
174
|
+
You can build the package using `uv` or standard Python `build`:
|
|
175
|
+
|
|
176
|
+
#### Using `uv`:
|
|
177
|
+
```bash
|
|
178
|
+
uv build
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### Using `build`:
|
|
182
|
+
```bash
|
|
183
|
+
pip install build twine
|
|
184
|
+
python -m build
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This generates distribution archives in the `dist/` directory:
|
|
188
|
+
- `dist/responseapi-1.0.0-py3-none-any.whl` (Wheel)
|
|
189
|
+
- `dist/responseapi-1.0.0.tar.gz` (Source distribution)
|
|
190
|
+
|
|
191
|
+
### 3. Upload to PyPI
|
|
192
|
+
|
|
193
|
+
#### Option A: Using `uv publish`
|
|
194
|
+
|
|
195
|
+
Set your API token and publish:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
uv publish --token <your-pypi-token>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Or publish to **TestPyPI** first to verify:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
uv publish --publish-url https://test.pypi.org/legacy/ --token <your-testpypi-token>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Option B: Using `twine`
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
twine check dist/*
|
|
211
|
+
twine upload dist/* -u __token__ -p <your-pypi-token>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### 4. Automated Publishing via GitHub Actions (Recommended)
|
|
215
|
+
|
|
216
|
+
This project includes a `.github/workflows/publish.yml` GitHub Actions workflow.
|
|
217
|
+
|
|
218
|
+
1. Go to your GitHub repository **Settings > Secrets and variables > Actions**.
|
|
219
|
+
2. Create a secret named `PYPI_API_TOKEN` containing your PyPI API token.
|
|
220
|
+
3. Push a new release or git tag (e.g., `git tag v1.0.0 && git push origin v1.0.0`).
|
|
221
|
+
4. GitHub Actions will automatically test, build, and publish the package to PyPI!
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 📄 License
|
|
226
|
+
|
|
227
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# responseapi
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/responseapi/)
|
|
4
|
+
[](https://pypi.org/project/responseapi/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
A clean, production-grade standardized response envelope framework for **FastAPI** applications.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 📌 Features
|
|
12
|
+
|
|
13
|
+
- **Standardized Response Format**: Enforces unified JSON response envelopes for both success and error responses across your API.
|
|
14
|
+
- **Automated Exception Handling**: Seamlessly intercepts domain-level `APIException`, FastAPI `HTTPException`, `RequestValidationError`, and unhandled server errors.
|
|
15
|
+
- **Pydantic & OpenAPI Integration**: Generic models (`APISuccessResponseModel`, `CustomSuccessResponseSchema`, `CustomErrorResponseSchema`) for type safety and automatic OpenAPI schema generation.
|
|
16
|
+
- **Structured Logging**: Built-in exception logging using `loguru`.
|
|
17
|
+
- **Zero Boilerplate**: Simple registration via `register_exception_handlers(app)`.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🚀 Installation
|
|
22
|
+
|
|
23
|
+
Install via `pip`:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install responseapi
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Or using `uv`:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
uv add responseapi
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or using `poetry`:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
poetry add responseapi
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 💡 Quickstart
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from fastapi import FastAPI
|
|
47
|
+
from responseapi import (
|
|
48
|
+
APIResponse,
|
|
49
|
+
APIException,
|
|
50
|
+
register_exception_handlers,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
app = FastAPI(title="My API")
|
|
54
|
+
|
|
55
|
+
# Register standardized exception handlers
|
|
56
|
+
register_exception_handlers(app)
|
|
57
|
+
|
|
58
|
+
@app.get("/users/{user_id}")
|
|
59
|
+
def get_user(user_id: int):
|
|
60
|
+
if user_id <= 0:
|
|
61
|
+
raise APIException(
|
|
62
|
+
error="User not found",
|
|
63
|
+
errors={"user_id": "Must be a positive integer"},
|
|
64
|
+
status_code=404,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return APIResponse.success(
|
|
68
|
+
data={"user_id": user_id, "username": "johndoe"},
|
|
69
|
+
message="User details retrieved successfully",
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 📦 Response Envelopes
|
|
76
|
+
|
|
77
|
+
### 1. Success Response Structure (`HTTP 200 OK`)
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"success": true,
|
|
82
|
+
"message": "User details retrieved successfully",
|
|
83
|
+
"data": {
|
|
84
|
+
"user_id": 1,
|
|
85
|
+
"username": "johndoe"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. Error Response Structure (`HTTP 400 / 404 / 422 / 500`)
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"success": false,
|
|
95
|
+
"error": "User not found",
|
|
96
|
+
"errors": {
|
|
97
|
+
"user_id": "Must be a positive integer"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 📖 API Reference
|
|
105
|
+
|
|
106
|
+
### `APIResponse`
|
|
107
|
+
|
|
108
|
+
Factory class to return standardized `JSONResponse` objects:
|
|
109
|
+
|
|
110
|
+
- `APIResponse.success(data=None, message="Operation completed successfully", status_code=200, headers=None)`
|
|
111
|
+
- `APIResponse.error(error="An error occurred", errors=None, status_code=400, headers=None)`
|
|
112
|
+
|
|
113
|
+
### `APIException`
|
|
114
|
+
|
|
115
|
+
Custom domain exception for raising controlled errors:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
raise APIException(
|
|
119
|
+
error="Insufficient funds",
|
|
120
|
+
errors={"balance": 10.0, "required": 50.0},
|
|
121
|
+
status_code=400
|
|
122
|
+
)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `register_exception_handlers(app: FastAPI, include_unhandled: bool = True)`
|
|
126
|
+
|
|
127
|
+
Registers error handlers for:
|
|
128
|
+
- `APIException` -> Returns `APIResponse.error(...)`
|
|
129
|
+
- `HTTPException` -> Returns `APIResponse.error(...)`
|
|
130
|
+
- `RequestValidationError` -> Returns validation errors formatted with status `422`
|
|
131
|
+
- `Exception` (optional) -> Catches unhandled errors and returns status `500`
|
|
132
|
+
|
|
133
|
+
### Pydantic Models & Schemas
|
|
134
|
+
|
|
135
|
+
- `APISuccessResponseModel[T]`: Pydantic generic model for standard success envelopes.
|
|
136
|
+
- `CustomSuccessResponseSchema[T]`: Pydantic generic schema for success payloads.
|
|
137
|
+
- `CustomErrorResponseSchema[T]`: Pydantic generic schema for error payloads.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 🛠️ Deploying / Publishing to PyPI
|
|
142
|
+
|
|
143
|
+
Follow these instructions to build and publish `responseapi` to **PyPI** (Python Package Index).
|
|
144
|
+
|
|
145
|
+
### 1. Prerequisites
|
|
146
|
+
|
|
147
|
+
Ensure you have a PyPI account registered at [pypi.org](https://pypi.org) and an API token or Trusted Publisher configuration set up.
|
|
148
|
+
|
|
149
|
+
### 2. Build the Package
|
|
150
|
+
|
|
151
|
+
You can build the package using `uv` or standard Python `build`:
|
|
152
|
+
|
|
153
|
+
#### Using `uv`:
|
|
154
|
+
```bash
|
|
155
|
+
uv build
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### Using `build`:
|
|
159
|
+
```bash
|
|
160
|
+
pip install build twine
|
|
161
|
+
python -m build
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This generates distribution archives in the `dist/` directory:
|
|
165
|
+
- `dist/responseapi-1.0.0-py3-none-any.whl` (Wheel)
|
|
166
|
+
- `dist/responseapi-1.0.0.tar.gz` (Source distribution)
|
|
167
|
+
|
|
168
|
+
### 3. Upload to PyPI
|
|
169
|
+
|
|
170
|
+
#### Option A: Using `uv publish`
|
|
171
|
+
|
|
172
|
+
Set your API token and publish:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
uv publish --token <your-pypi-token>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Or publish to **TestPyPI** first to verify:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
uv publish --publish-url https://test.pypi.org/legacy/ --token <your-testpypi-token>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### Option B: Using `twine`
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
twine check dist/*
|
|
188
|
+
twine upload dist/* -u __token__ -p <your-pypi-token>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 4. Automated Publishing via GitHub Actions (Recommended)
|
|
192
|
+
|
|
193
|
+
This project includes a `.github/workflows/publish.yml` GitHub Actions workflow.
|
|
194
|
+
|
|
195
|
+
1. Go to your GitHub repository **Settings > Secrets and variables > Actions**.
|
|
196
|
+
2. Create a secret named `PYPI_API_TOKEN` containing your PyPI API token.
|
|
197
|
+
3. Push a new release or git tag (e.g., `git tag v1.0.0 && git push origin v1.0.0`).
|
|
198
|
+
4. GitHub Actions will automatically test, build, and publish the package to PyPI!
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 📄 License
|
|
203
|
+
|
|
204
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "responseapi"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "A clean, production-grade standardized response envelope framework for FastAPI applications."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
keywords = ["fastapi", "pydantic", "openapi", "jsonresponse", "api-design", "middleware", "exception-handler"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Dev Raj Khadka", email = "devrajkhadka941@gmail.com" },
|
|
15
|
+
{ name = "Aryan Tamang", email = "aryantamangcs@gmail.com" }
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 5 - Production/Stable",
|
|
19
|
+
"Framework :: FastAPI",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"fastapi>=0.100.0",
|
|
31
|
+
"pydantic>=2.0.0",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
# [project.urls]
|
|
35
|
+
# Homepage = "https://github.com/your-org/responseapi"
|
|
36
|
+
# Documentation = "https://github.com/your-org/responseapi#readme"
|
|
37
|
+
# Repository = "https://github.com/your-org/responseapi"
|
|
38
|
+
# Issues = "https://github.com/your-org/responseapi/issues"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from responseapi._exceptions.api_exception import APIException
|
|
2
|
+
from responseapi._interceptors.handlers import (
|
|
3
|
+
api_exception_handler,
|
|
4
|
+
http_exception_handler,
|
|
5
|
+
register_exception_handlers,
|
|
6
|
+
unhandled_exception_handler,
|
|
7
|
+
validation_exception_handler,
|
|
8
|
+
)
|
|
9
|
+
from responseapi._schemas.response_schema import (
|
|
10
|
+
CustomErrorResponseSchema,
|
|
11
|
+
CustomSuccessResponseSchema,
|
|
12
|
+
)
|
|
13
|
+
from responseapi._services.response_service import APIResponse
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"APIException",
|
|
17
|
+
"APIResponse",
|
|
18
|
+
"CustomErrorResponseSchema",
|
|
19
|
+
"CustomSuccessResponseSchema",
|
|
20
|
+
"api_exception_handler",
|
|
21
|
+
"http_exception_handler",
|
|
22
|
+
"register_exception_handlers",
|
|
23
|
+
"unhandled_exception_handler",
|
|
24
|
+
"validation_exception_handler",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def __getattr__(name: str):
|
|
29
|
+
if name in __all__:
|
|
30
|
+
return globals()[name]
|
|
31
|
+
raise AttributeError(f"module {__name__} has no attribute {name}")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from typing import Any, Mapping
|
|
2
|
+
|
|
3
|
+
from fastapi import status
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class APIException(Exception):
|
|
7
|
+
"""Custom API Exception for domain-level errors.
|
|
8
|
+
|
|
9
|
+
This exception mirrors FastAPI's ``HTTPException`` style but is a plain
|
|
10
|
+
``Exception`` that you can raise from your business logic.
|
|
11
|
+
|
|
12
|
+
Parameters
|
|
13
|
+
----------
|
|
14
|
+
error:
|
|
15
|
+
Human-readable error message that will be exposed to the client.
|
|
16
|
+
errors:
|
|
17
|
+
Optional extra error data (e.g., validation errors) placed under
|
|
18
|
+
an ``errors`` key in the JSON response.
|
|
19
|
+
status_code:
|
|
20
|
+
HTTP status code to return. Defaults to ``400 Bad Request``.
|
|
21
|
+
headers:
|
|
22
|
+
Optional extra HTTP headers to include in the response.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
error: str = "An error occurred",
|
|
28
|
+
errors: Any = None,
|
|
29
|
+
status_code: int = status.HTTP_400_BAD_REQUEST,
|
|
30
|
+
headers: Mapping[str, str] | None = None,
|
|
31
|
+
) -> None:
|
|
32
|
+
super().__init__(error)
|
|
33
|
+
self.error = error
|
|
34
|
+
self.errors = errors
|
|
35
|
+
self.status_code = status_code
|
|
36
|
+
self.headers = headers
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from responseapi._interceptors.handlers import (
|
|
2
|
+
api_exception_handler,
|
|
3
|
+
http_exception_handler,
|
|
4
|
+
register_exception_handlers,
|
|
5
|
+
unhandled_exception_handler,
|
|
6
|
+
validation_exception_handler,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"api_exception_handler",
|
|
11
|
+
"http_exception_handler",
|
|
12
|
+
"validation_exception_handler",
|
|
13
|
+
"unhandled_exception_handler",
|
|
14
|
+
"register_exception_handlers",
|
|
15
|
+
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from fastapi import FastAPI, Request, status
|
|
2
|
+
from fastapi.exceptions import HTTPException, RequestValidationError
|
|
3
|
+
from fastapi.responses import JSONResponse
|
|
4
|
+
|
|
5
|
+
from responseapi._exceptions.api_exception import APIException
|
|
6
|
+
from responseapi._services.response_service import APIResponse
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def api_exception_handler(_: Request, exc: APIException) -> JSONResponse:
|
|
10
|
+
"""
|
|
11
|
+
Handles Domain-level APIExceptions cleanly
|
|
12
|
+
"""
|
|
13
|
+
return APIResponse.error(
|
|
14
|
+
error=exc.error,
|
|
15
|
+
errors=exc.errors,
|
|
16
|
+
status_code=exc.status_code,
|
|
17
|
+
headers=getattr(exc, "headers", None),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def http_exception_handler(_: Request, exc: HTTPException) -> JSONResponse:
|
|
22
|
+
"""
|
|
23
|
+
Handles HTTPExceptions cleanly
|
|
24
|
+
"""
|
|
25
|
+
return APIResponse.error(
|
|
26
|
+
error=str(exc.detail) if hasattr(exc, "detail") else str(exc),
|
|
27
|
+
errors=getattr(exc, "errors", None),
|
|
28
|
+
status_code=exc.status_code,
|
|
29
|
+
headers=getattr(exc, "headers", None),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def validation_exception_handler(
|
|
34
|
+
_: Request, exc: RequestValidationError
|
|
35
|
+
) -> JSONResponse:
|
|
36
|
+
"""
|
|
37
|
+
Handles ValidationExceptions cleanly
|
|
38
|
+
"""
|
|
39
|
+
return APIResponse.error(
|
|
40
|
+
error="Validation error",
|
|
41
|
+
errors=exc.errors(),
|
|
42
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
async def unhandled_exception_handler(_: Request, exc: Exception) -> JSONResponse:
|
|
47
|
+
"""
|
|
48
|
+
Handles unhandled exceptions cleanly
|
|
49
|
+
"""
|
|
50
|
+
return APIResponse.error(
|
|
51
|
+
error="Internal server error",
|
|
52
|
+
errors=str(exc),
|
|
53
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def register_exception_handlers(app: FastAPI, include_unhandled: bool = True) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Hook all responseapi exception interceptors in the FastAPI lifecycle
|
|
60
|
+
"""
|
|
61
|
+
app.add_exception_handler(APIException, api_exception_handler)
|
|
62
|
+
app.add_exception_handler(HTTPException, http_exception_handler)
|
|
63
|
+
app.add_exception_handler(RequestValidationError, validation_exception_handler)
|
|
64
|
+
|
|
65
|
+
if include_unhandled:
|
|
66
|
+
app.add_exception_handler(Exception, unhandled_exception_handler)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import field
|
|
4
|
+
from typing import Generic, List, Optional, TypeVar, Union
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
T = TypeVar("T")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(slots=True)
|
|
12
|
+
class CustomSuccessResponseSchema(Generic[T]):
|
|
13
|
+
"""Custom success response schema for API endpoints.
|
|
14
|
+
|
|
15
|
+
Attributes
|
|
16
|
+
----------
|
|
17
|
+
success: bool
|
|
18
|
+
Indicates the request succeeded.
|
|
19
|
+
data: Optional[Union[T, List[T]]]
|
|
20
|
+
The payload returned by the endpoint. Can be a single object or a list.
|
|
21
|
+
message: Optional[str]
|
|
22
|
+
Human‑readable description of the result.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
success: bool = field(default=True)
|
|
26
|
+
data: Optional[Union[T, List[T]]] = field(default=None)
|
|
27
|
+
message: Optional[str] = field(default=None)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(slots=True)
|
|
31
|
+
class CustomErrorResponseSchema(Generic[T]):
|
|
32
|
+
"""Custom error response schema for API endpoints.
|
|
33
|
+
|
|
34
|
+
Attributes
|
|
35
|
+
----------
|
|
36
|
+
success: bool
|
|
37
|
+
Always ``False`` for error responses.
|
|
38
|
+
errors: Optional[Union[T, List[T]]]
|
|
39
|
+
Detailed error information.
|
|
40
|
+
error: Optional[str]
|
|
41
|
+
Short error message.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
success: bool = field(default=False)
|
|
45
|
+
errors: Optional[Union[T, List[T]]] = field(default=None)
|
|
46
|
+
error: Optional[str] = field(default=None)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from fastapi import status
|
|
4
|
+
from fastapi.encoders import jsonable_encoder
|
|
5
|
+
from fastapi.responses import JSONResponse
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class APIResponse:
|
|
9
|
+
"""
|
|
10
|
+
Factory class for constructing standardized API JSON responses.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def success(
|
|
15
|
+
data: Any = None,
|
|
16
|
+
message: str = "Operation completed successfully",
|
|
17
|
+
status_code: int = status.HTTP_200_OK,
|
|
18
|
+
headers: dict[str, str] | None = None,
|
|
19
|
+
) -> JSONResponse:
|
|
20
|
+
"""
|
|
21
|
+
Generates a standard HTTP success response
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
if status_code == status.HTTP_204_NO_CONTENT:
|
|
25
|
+
return JSONResponse(
|
|
26
|
+
status_code=status_code,
|
|
27
|
+
content=None,
|
|
28
|
+
headers=headers,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
payload = {
|
|
32
|
+
"success": True,
|
|
33
|
+
"message": message,
|
|
34
|
+
"data": jsonable_encoder(data),
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return JSONResponse(
|
|
38
|
+
content=payload,
|
|
39
|
+
status_code=status_code,
|
|
40
|
+
headers=headers,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def error(
|
|
45
|
+
error: str = "An error occurred",
|
|
46
|
+
errors: Any = None,
|
|
47
|
+
status_code: int = status.HTTP_400_BAD_REQUEST,
|
|
48
|
+
headers: dict[str, str] | None = None,
|
|
49
|
+
) -> JSONResponse:
|
|
50
|
+
"""
|
|
51
|
+
Generates a standard HTTP error response
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
payload = {
|
|
55
|
+
"success": False,
|
|
56
|
+
"error": error,
|
|
57
|
+
"errors": jsonable_encoder(errors),
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return JSONResponse(
|
|
61
|
+
content=payload,
|
|
62
|
+
status_code=status_code,
|
|
63
|
+
headers=headers,
|
|
64
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 3
|
|
3
|
+
requires-python = ">=3.10"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "annotated-doc"
|
|
7
|
+
version = "0.0.4"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" }
|
|
10
|
+
wheels = [
|
|
11
|
+
{ url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" },
|
|
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.14.2"
|
|
26
|
+
source = { registry = "https://pypi.org/simple" }
|
|
27
|
+
dependencies = [
|
|
28
|
+
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
|
29
|
+
{ name = "idna" },
|
|
30
|
+
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
|
31
|
+
]
|
|
32
|
+
sdist = { url = "https://files.pythonhosted.org/packages/61/cc/a381afa6efea9f496eff839d4a6a1aed3bfafc7b3ab4b0d1b243a12573dd/anyio-4.14.2.tar.gz", hash = "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f", size = 260176, upload-time = "2026-07-12T20:29:07.082Z" }
|
|
33
|
+
wheels = [
|
|
34
|
+
{ url = "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494", size = 125813, upload-time = "2026-07-12T20:29:05.763Z" },
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[[package]]
|
|
38
|
+
name = "colorama"
|
|
39
|
+
version = "0.4.6"
|
|
40
|
+
source = { registry = "https://pypi.org/simple" }
|
|
41
|
+
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" }
|
|
42
|
+
wheels = [
|
|
43
|
+
{ 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" },
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[[package]]
|
|
47
|
+
name = "exceptiongroup"
|
|
48
|
+
version = "1.3.1"
|
|
49
|
+
source = { registry = "https://pypi.org/simple" }
|
|
50
|
+
dependencies = [
|
|
51
|
+
{ name = "typing-extensions" },
|
|
52
|
+
]
|
|
53
|
+
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" }
|
|
54
|
+
wheels = [
|
|
55
|
+
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
[[package]]
|
|
59
|
+
name = "fastapi"
|
|
60
|
+
version = "0.139.2"
|
|
61
|
+
source = { registry = "https://pypi.org/simple" }
|
|
62
|
+
dependencies = [
|
|
63
|
+
{ name = "annotated-doc" },
|
|
64
|
+
{ name = "pydantic" },
|
|
65
|
+
{ name = "starlette" },
|
|
66
|
+
{ name = "typing-extensions" },
|
|
67
|
+
{ name = "typing-inspection" },
|
|
68
|
+
]
|
|
69
|
+
sdist = { url = "https://files.pythonhosted.org/packages/cd/95/d3f0ae10836324a2eab98a52b61210ac609f08200bf4bb0dc8132d32f78a/fastapi-0.139.2.tar.gz", hash = "sha256:333145a6891e9b5b3cfceb69baf817e8240cde4d4588ae5a10bf56ffacb6255e", size = 423428, upload-time = "2026-07-16T15:06:17.912Z" }
|
|
70
|
+
wheels = [
|
|
71
|
+
{ url = "https://files.pythonhosted.org/packages/5f/c7/cb03251d9dfb177246a9809a76f189d21df32dbd4a845951881d11323b7f/fastapi-0.139.2-py3-none-any.whl", hash = "sha256:b9ad015a835173d59865e2f5d8296fbc2b317bf56a2ba1a5bfbdd03de2fd4b1c", size = 130234, upload-time = "2026-07-16T15:06:19.557Z" },
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
[[package]]
|
|
75
|
+
name = "idna"
|
|
76
|
+
version = "3.18"
|
|
77
|
+
source = { registry = "https://pypi.org/simple" }
|
|
78
|
+
sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" }
|
|
79
|
+
wheels = [
|
|
80
|
+
{ url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" },
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
[[package]]
|
|
84
|
+
name = "loguru"
|
|
85
|
+
version = "0.7.3"
|
|
86
|
+
source = { registry = "https://pypi.org/simple" }
|
|
87
|
+
dependencies = [
|
|
88
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
89
|
+
{ name = "win32-setctime", marker = "sys_platform == 'win32'" },
|
|
90
|
+
]
|
|
91
|
+
sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" }
|
|
92
|
+
wheels = [
|
|
93
|
+
{ url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" },
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
[[package]]
|
|
97
|
+
name = "pydantic"
|
|
98
|
+
version = "2.13.4"
|
|
99
|
+
source = { registry = "https://pypi.org/simple" }
|
|
100
|
+
dependencies = [
|
|
101
|
+
{ name = "annotated-types" },
|
|
102
|
+
{ name = "pydantic-core" },
|
|
103
|
+
{ name = "typing-extensions" },
|
|
104
|
+
{ name = "typing-inspection" },
|
|
105
|
+
]
|
|
106
|
+
sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" }
|
|
107
|
+
wheels = [
|
|
108
|
+
{ url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" },
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
[[package]]
|
|
112
|
+
name = "pydantic-core"
|
|
113
|
+
version = "2.46.4"
|
|
114
|
+
source = { registry = "https://pypi.org/simple" }
|
|
115
|
+
dependencies = [
|
|
116
|
+
{ name = "typing-extensions" },
|
|
117
|
+
]
|
|
118
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" }
|
|
119
|
+
wheels = [
|
|
120
|
+
{ url = "https://files.pythonhosted.org/packages/e7/08/f1ba952f1c8ae5581c70fa9c6da89f247b83e3dd8c09c035d5d7931fc23d/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4", size = 2113146, upload-time = "2026-05-06T13:37:36.537Z" },
|
|
121
|
+
{ url = "https://files.pythonhosted.org/packages/56/c6/65f646c7ff09bd257f660434adb45c4dfcbbcebcc030562fecf6f5bf887d/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5", size = 1949769, upload-time = "2026-05-06T13:37:46.365Z" },
|
|
122
|
+
{ url = "https://files.pythonhosted.org/packages/64/ba/bfb1d928fd5b49e1258935ff104ae356e9fd89384a55bf9f847e9193ad40/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba", size = 1974958, upload-time = "2026-05-06T13:37:28.611Z" },
|
|
123
|
+
{ url = "https://files.pythonhosted.org/packages/4e/74/76223bfb117b64af743c9b6670d1364516f5c0604f96b48f3272f6af6cc6/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b", size = 2042118, upload-time = "2026-05-06T13:36:55.216Z" },
|
|
124
|
+
{ url = "https://files.pythonhosted.org/packages/cb/7b/848732968bc8f48f3187542f08358b9d842db564147b256669426ebb1652/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c", size = 2222876, upload-time = "2026-05-06T13:38:25.455Z" },
|
|
125
|
+
{ url = "https://files.pythonhosted.org/packages/b5/2f/e90b63ee2e14bd8d3db8f705a6d75d64e6ee1b7c2c8833747ce706e1e0ce/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50", size = 2286703, upload-time = "2026-05-06T13:37:53.304Z" },
|
|
126
|
+
{ url = "https://files.pythonhosted.org/packages/ba/1e/acc4d70f88a0a277e4a1fa77ebb985ceabaf900430f875bf9338e11c9420/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd", size = 2092042, upload-time = "2026-05-06T13:38:46.981Z" },
|
|
127
|
+
{ url = "https://files.pythonhosted.org/packages/a9/da/0a422b57bf8504102bf3c4ccea9c41bab5a5cee6a54650acf8faf67f5a24/pydantic_core-2.46.4-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01", size = 2117231, upload-time = "2026-05-06T13:39:23.146Z" },
|
|
128
|
+
{ url = "https://files.pythonhosted.org/packages/bd/2a/2ac13c3af305843e23c5078c53d135656b3f05a2fd78cb7bbbb12e97b473/pydantic_core-2.46.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d", size = 2168388, upload-time = "2026-05-06T13:40:08.06Z" },
|
|
129
|
+
{ url = "https://files.pythonhosted.org/packages/72/04/2beacf7e1607e93eefe4aed1b4709f079b905fb77530179d4f7c71745f22/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4", size = 2184769, upload-time = "2026-05-06T13:38:13.901Z" },
|
|
130
|
+
{ url = "https://files.pythonhosted.org/packages/9e/29/d2b9fd9f539133548eaf622c06a4ce176cb46ac59f32d0359c4abc0de047/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f", size = 2319312, upload-time = "2026-05-06T13:39:08.24Z" },
|
|
131
|
+
{ url = "https://files.pythonhosted.org/packages/7c/af/0f7a5b85fec6075bea96e3ef9187de38fccced0de92c1e7feda8d5cc7bb9/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39", size = 2361817, upload-time = "2026-05-06T13:38:43.2Z" },
|
|
132
|
+
{ url = "https://files.pythonhosted.org/packages/25/a4/73363fec545fd3ec025490bdda2743c56d0dd5b6266b1a53bbe9e4265375/pydantic_core-2.46.4-cp310-cp310-win32.whl", hash = "sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d", size = 1987085, upload-time = "2026-05-06T13:39:25.497Z" },
|
|
133
|
+
{ url = "https://files.pythonhosted.org/packages/01/aa/62f082da2c91fac1c234bc9ee0066257ce83f0604abd72e4c9d5991f2d84/pydantic_core-2.46.4-cp310-cp310-win_amd64.whl", hash = "sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf", size = 2074311, upload-time = "2026-05-06T13:39:59.922Z" },
|
|
134
|
+
{ url = "https://files.pythonhosted.org/packages/5c/fa/6d7708d2cfc1a832acb6aeb0cd16e801902df8a0f583bb3b4b527fde022e/pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594", size = 2111872, upload-time = "2026-05-06T13:40:27.596Z" },
|
|
135
|
+
{ url = "https://files.pythonhosted.org/packages/ae/6f/aa064a3e74b5745afbdf250594f38e7ead05e2d651bcb35994b9417a0d4d/pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c", size = 1948255, upload-time = "2026-05-06T13:39:12.574Z" },
|
|
136
|
+
{ url = "https://files.pythonhosted.org/packages/43/3a/41114a9f7569b84b4d84e7a018c57c56347dac30c0d4a872946ec4e36c46/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826", size = 1972827, upload-time = "2026-05-06T13:38:19.841Z" },
|
|
137
|
+
{ url = "https://files.pythonhosted.org/packages/ef/25/1ab42e8048fe551934d9884e8d64daa7e990ad386f310a15981aeb6a5b08/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04", size = 2041051, upload-time = "2026-05-06T13:38:10.447Z" },
|
|
138
|
+
{ url = "https://files.pythonhosted.org/packages/94/c2/1a934597ddf08da410385b3b7aae91956a5a76c635effef456074fad7e88/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e", size = 2221314, upload-time = "2026-05-06T13:40:13.089Z" },
|
|
139
|
+
{ url = "https://files.pythonhosted.org/packages/02/6d/9e8ad178c9c4df27ad3c8f25d1fe2a7ab0d2ba0559fad4aee5d3d1f16771/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3", size = 2285146, upload-time = "2026-05-06T13:38:59.224Z" },
|
|
140
|
+
{ url = "https://files.pythonhosted.org/packages/80/50/540cd3aeefc041beb111125c4bff779831a2111fc6b15a9138cda277d32c/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4", size = 2089685, upload-time = "2026-05-06T13:38:17.762Z" },
|
|
141
|
+
{ url = "https://files.pythonhosted.org/packages/6b/a4/b440ad35f05f6a38f89fa0f149accb3f0e02be94ca5e15f3c449a61b4bc9/pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398", size = 2115420, upload-time = "2026-05-06T13:37:58.195Z" },
|
|
142
|
+
{ url = "https://files.pythonhosted.org/packages/99/61/de4f55db8dfd57bfdfa9a12ec90fe1b57c4f41062f7ca86f08586b3e0ac0/pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3", size = 2165122, upload-time = "2026-05-06T13:37:01.167Z" },
|
|
143
|
+
{ url = "https://files.pythonhosted.org/packages/f7/52/7c529d7bdb2d1068bd52f51fe32572c8301f9a4febf1948f10639f1436f5/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848", size = 2182573, upload-time = "2026-05-06T13:38:45.04Z" },
|
|
144
|
+
{ url = "https://files.pythonhosted.org/packages/37/b3/7c40325848ba78247f2812dcf9c7274e38cd801820ca6dd9fe63bcfb0eb4/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3", size = 2317139, upload-time = "2026-05-06T13:37:15.539Z" },
|
|
145
|
+
{ url = "https://files.pythonhosted.org/packages/d9/37/f913f81a657c865b75da6c0dbed79876073c2a43b5bd9edbe8da785e4d49/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109", size = 2360433, upload-time = "2026-05-06T13:37:30.099Z" },
|
|
146
|
+
{ url = "https://files.pythonhosted.org/packages/c4/67/6acaa1be2567f9256b056d8477158cac7240813956ce86e49deae8e173b4/pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda", size = 1985513, upload-time = "2026-05-06T13:38:15.669Z" },
|
|
147
|
+
{ url = "https://files.pythonhosted.org/packages/aa/e6/c505f83dfeda9a2e5c995cfd872949e4d05e12f7feb3dca72f633daefa94/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33", size = 2071114, upload-time = "2026-05-06T13:40:35.416Z" },
|
|
148
|
+
{ url = "https://files.pythonhosted.org/packages/0f/da/7a263a96d965d9d0df5e8de8a475f33495451117035b09acb110288c381f/pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d", size = 2044298, upload-time = "2026-05-06T13:38:29.754Z" },
|
|
149
|
+
{ url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" },
|
|
150
|
+
{ url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" },
|
|
151
|
+
{ url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" },
|
|
152
|
+
{ url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" },
|
|
153
|
+
{ url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" },
|
|
154
|
+
{ url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" },
|
|
155
|
+
{ url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" },
|
|
156
|
+
{ url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" },
|
|
157
|
+
{ url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" },
|
|
158
|
+
{ url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" },
|
|
159
|
+
{ url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" },
|
|
160
|
+
{ url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" },
|
|
161
|
+
{ url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" },
|
|
162
|
+
{ url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" },
|
|
163
|
+
{ url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" },
|
|
164
|
+
{ url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" },
|
|
165
|
+
{ url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" },
|
|
166
|
+
{ url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" },
|
|
167
|
+
{ url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" },
|
|
168
|
+
{ url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" },
|
|
169
|
+
{ url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" },
|
|
170
|
+
{ url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" },
|
|
171
|
+
{ url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" },
|
|
172
|
+
{ url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" },
|
|
173
|
+
{ url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" },
|
|
174
|
+
{ url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" },
|
|
175
|
+
{ url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" },
|
|
176
|
+
{ url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" },
|
|
177
|
+
{ url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" },
|
|
178
|
+
{ url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" },
|
|
179
|
+
{ url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" },
|
|
180
|
+
{ url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" },
|
|
181
|
+
{ url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" },
|
|
182
|
+
{ url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" },
|
|
183
|
+
{ url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" },
|
|
184
|
+
{ url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" },
|
|
185
|
+
{ url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" },
|
|
186
|
+
{ url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" },
|
|
187
|
+
{ url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" },
|
|
188
|
+
{ url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" },
|
|
189
|
+
{ url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" },
|
|
190
|
+
{ url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" },
|
|
191
|
+
{ url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" },
|
|
192
|
+
{ url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" },
|
|
193
|
+
{ url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" },
|
|
194
|
+
{ url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" },
|
|
195
|
+
{ url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" },
|
|
196
|
+
{ url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" },
|
|
197
|
+
{ url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" },
|
|
198
|
+
{ url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" },
|
|
199
|
+
{ url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" },
|
|
200
|
+
{ url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" },
|
|
201
|
+
{ url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" },
|
|
202
|
+
{ url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" },
|
|
203
|
+
{ url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" },
|
|
204
|
+
{ url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" },
|
|
205
|
+
{ url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" },
|
|
206
|
+
{ url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" },
|
|
207
|
+
{ url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" },
|
|
208
|
+
{ url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" },
|
|
209
|
+
{ url = "https://files.pythonhosted.org/packages/ee/a4/73995fd4ebbb46ba0ee51e6fa049b8f02c40daebb762208feda8a6b7894d/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c", size = 2111589, upload-time = "2026-05-06T13:37:10.817Z" },
|
|
210
|
+
{ url = "https://files.pythonhosted.org/packages/fb/7f/f37d3a5e8bfcc2e403f5c57a730f2d815693fb42119e8ea48b3789335af1/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b", size = 1944552, upload-time = "2026-05-06T13:36:56.717Z" },
|
|
211
|
+
{ url = "https://files.pythonhosted.org/packages/15/3c/d7eb777b3ff43e8433a4efb39a17aa8fd98a4ee8561a24a67ef5db07b2d6/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b", size = 1982984, upload-time = "2026-05-06T13:39:06.207Z" },
|
|
212
|
+
{ url = "https://files.pythonhosted.org/packages/63/87/70b9f40170a81afd55ca26c9b2acb25c20d64bcfbf888fafecb3ba077d4c/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea", size = 2138417, upload-time = "2026-05-06T13:39:45.476Z" },
|
|
213
|
+
{ url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" },
|
|
214
|
+
{ url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" },
|
|
215
|
+
{ url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" },
|
|
216
|
+
{ url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" },
|
|
217
|
+
{ url = "https://files.pythonhosted.org/packages/11/cb/428de0385b6c8d44b716feba566abfacfbd23ee3c4439faa789a1456242f/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0", size = 2112782, upload-time = "2026-05-06T13:37:04.016Z" },
|
|
218
|
+
{ url = "https://files.pythonhosted.org/packages/0b/b5/6a17bdadd0fc1f170adfd05a20d37c832f52b117b4d9131da1f41bb097ce/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7", size = 1952146, upload-time = "2026-05-06T13:39:43.092Z" },
|
|
219
|
+
{ url = "https://files.pythonhosted.org/packages/2a/dc/03734d80e362cd43ef65428e9de77c730ce7f2f11c60d2b1e1b39f0fbf99/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2", size = 2134492, upload-time = "2026-05-06T13:36:58.124Z" },
|
|
220
|
+
{ url = "https://files.pythonhosted.org/packages/de/df/5e5ffc085ed07cc22d298134d3d911c63e91f6a0eb91fe646750a3209910/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9", size = 2156604, upload-time = "2026-05-06T13:37:49.88Z" },
|
|
221
|
+
{ url = "https://files.pythonhosted.org/packages/81/44/6e112a4253e56f5705467cbab7ab5e91ee7398ba3d56d358635958893d3e/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf", size = 2183828, upload-time = "2026-05-06T13:37:43.053Z" },
|
|
222
|
+
{ url = "https://files.pythonhosted.org/packages/ac/ad/5565071e937d8e752842ac241463944c9eb14c87e2d269f2658a5bd05e98/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30", size = 2310000, upload-time = "2026-05-06T13:37:56.694Z" },
|
|
223
|
+
{ url = "https://files.pythonhosted.org/packages/4f/c3/66883a5cec183e7fba4d024b4cbbe61851a63750ef606b0afecc46d1f2bf/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc", size = 2361286, upload-time = "2026-05-06T13:40:05.667Z" },
|
|
224
|
+
{ url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" },
|
|
225
|
+
]
|
|
226
|
+
|
|
227
|
+
[[package]]
|
|
228
|
+
name = "responseapi"
|
|
229
|
+
version = "1.0.0"
|
|
230
|
+
source = { editable = "." }
|
|
231
|
+
dependencies = [
|
|
232
|
+
{ name = "fastapi" },
|
|
233
|
+
{ name = "loguru" },
|
|
234
|
+
{ name = "pydantic" },
|
|
235
|
+
]
|
|
236
|
+
|
|
237
|
+
[package.metadata]
|
|
238
|
+
requires-dist = [
|
|
239
|
+
{ name = "fastapi", specifier = ">=0.100.0" },
|
|
240
|
+
{ name = "loguru", specifier = ">=0.7.0" },
|
|
241
|
+
{ name = "pydantic", specifier = ">=2.0.0" },
|
|
242
|
+
]
|
|
243
|
+
|
|
244
|
+
[[package]]
|
|
245
|
+
name = "starlette"
|
|
246
|
+
version = "1.3.1"
|
|
247
|
+
source = { registry = "https://pypi.org/simple" }
|
|
248
|
+
dependencies = [
|
|
249
|
+
{ name = "anyio" },
|
|
250
|
+
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
|
251
|
+
]
|
|
252
|
+
sdist = { url = "https://files.pythonhosted.org/packages/eb/e3/7c1dc7381d9f8ab7d854328ebfa884e62cb3f3d8549ddfd37c7814f42afa/starlette-1.3.1.tar.gz", hash = "sha256:05d0213193f2fbaae60e2ecb593b4add4262ad4e46536b54abe36f11a71724e0", size = 2703240, upload-time = "2026-06-12T09:23:11.602Z" }
|
|
253
|
+
wheels = [
|
|
254
|
+
{ url = "https://files.pythonhosted.org/packages/ec/bb/2799cc2ede3ed41131f8975621e7213dfc7ef4acbbaadfa440f32500c370/starlette-1.3.1-py3-none-any.whl", hash = "sha256:c7372aae11c3c3f26a42df7bd626cec2f47d03483d261d369516a615a53714c6", size = 73632, upload-time = "2026-06-12T09:23:10.017Z" },
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
[[package]]
|
|
258
|
+
name = "typing-extensions"
|
|
259
|
+
version = "4.16.0"
|
|
260
|
+
source = { registry = "https://pypi.org/simple" }
|
|
261
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
|
|
262
|
+
wheels = [
|
|
263
|
+
{ url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
[[package]]
|
|
267
|
+
name = "typing-inspection"
|
|
268
|
+
version = "0.4.2"
|
|
269
|
+
source = { registry = "https://pypi.org/simple" }
|
|
270
|
+
dependencies = [
|
|
271
|
+
{ name = "typing-extensions" },
|
|
272
|
+
]
|
|
273
|
+
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" }
|
|
274
|
+
wheels = [
|
|
275
|
+
{ 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" },
|
|
276
|
+
]
|
|
277
|
+
|
|
278
|
+
[[package]]
|
|
279
|
+
name = "win32-setctime"
|
|
280
|
+
version = "1.2.0"
|
|
281
|
+
source = { registry = "https://pypi.org/simple" }
|
|
282
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" }
|
|
283
|
+
wheels = [
|
|
284
|
+
{ url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" },
|
|
285
|
+
]
|