feat(storage): add delete_href method to remove files and clean up empty directories
Build and Push Reader API Image / docker (push) Successful in 26s
Build and Push Reader API Image / docker (push) Successful in 26s
chore(docker): remove MongoDB service and related configurations from local setup feat(migrations): create ChapterMeta table and add search_name, size_bytes, mtime_epoch, lastScannedAt, review_status, and review_payload columns to SourceAsset chore(dependencies): remove motor and pymongo from project dependencies
This commit is contained in:
@@ -26,9 +26,17 @@ Legend:
|
|||||||
| Comment | `GET/POST /api/truyen/{id}/comments` | Y | Y | Y | |
|
| Comment | `GET/POST /api/truyen/{id}/comments` | Y | Y | Y | |
|
||||||
| Rating | `POST /api/truyen/{id}/rate` | Y | Y | N | Mobile chua thay rating flow |
|
| Rating | `POST /api/truyen/{id}/rate` | Y | Y | N | Mobile chua thay rating flow |
|
||||||
| Search | `GET /api/truyen/suggest` | Y | Y | N | Mobile search suggest can bo sung |
|
| Search | `GET /api/truyen/suggest` | Y | Y | N | Mobile search suggest can bo sung |
|
||||||
|
| Import | `GET /api/import/assets/search` | Y | Y | N | Web MOD import wizard step 1 |
|
||||||
|
| Import | `GET /api/import/assets/{id}/preview-metadata` | Y | Y | N | Web MOD import wizard step 2 |
|
||||||
|
| Import | `POST /api/import/assets/{id}/ai-suggest` | Y | Y | N | Gen toi da 6 genres + short description |
|
||||||
|
| Import | `POST /api/import/assets/{id}/review` | Y | Y | N | Save reviewed metadata before import |
|
||||||
|
| Import | `POST /api/import/assets/{id}/parse-preview` | Y | Y | N | TOC/regex-start preview (10 head/mid/tail samples) |
|
||||||
|
| Import | `POST /api/import/assets/{id}/start-import` | Y | Y | N | Start import session |
|
||||||
|
| Import | `GET /api/import/sessions/{sessionId}` | Y | Y | N | Poll import progress |
|
||||||
|
|
||||||
## Priority gaps de dong bo tiep
|
## Priority gaps de dong bo tiep
|
||||||
|
|
||||||
1. Mobile: `user/settings`, `recommendations`, `rate`, `suggest`.
|
1. Mobile: `user/settings`, `recommendations`, `rate`, `suggest`.
|
||||||
2. Web/Mobile chapter-read strategy can unify (`chapters/{id}` vs `by-number`).
|
2. Web/Mobile chapter-read strategy can unify (`chapters/{id}` vs `by-number`).
|
||||||
3. Chuan hoa error contract implementation theo `CONTRACT.md`.
|
3. Chuan hoa error contract implementation theo `CONTRACT.md`.
|
||||||
|
4. Mobile import flow currently not planned (MOD-only on web).
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Tinh nang backend cho web + mobile.
|
|||||||
| Domain | Endpoint Group | Status | Notes |
|
| Domain | Endpoint Group | Status | Notes |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| Content management | `/api/mod/*` | partial | da co nhieu route, tiep tuc bo sung nhu cau |
|
| Content management | `/api/mod/*` | partial | da co nhieu route, tiep tuc bo sung nhu cau |
|
||||||
|
| EPUB import | `/api/import/*` | done | review-first wizard APIs + progress session |
|
||||||
|
|
||||||
## Contract + Parity Responsibility
|
## Contract + Parity Responsibility
|
||||||
|
|
||||||
|
|||||||
@@ -36,3 +36,23 @@ Backend flow theo domain, de web/mobile follow giong nhau.
|
|||||||
- Comments: `/api/truyen/{id}/comments`.
|
- Comments: `/api/truyen/{id}/comments`.
|
||||||
- Rating: `/api/truyen/{id}/rate`.
|
- Rating: `/api/truyen/{id}/rate`.
|
||||||
- Rule: enforce auth + anti-invalid payload + stable error format.
|
- Rule: enforce auth + anti-invalid payload + stable error format.
|
||||||
|
|
||||||
|
## Flow E: EPUB Import (MOD/ADMIN)
|
||||||
|
|
||||||
|
- Step 1 search source:
|
||||||
|
- `/api/import/assets/search`
|
||||||
|
- Step 2 review metadata:
|
||||||
|
- `/api/import/assets/{id}/preview-metadata`
|
||||||
|
- `/api/import/assets/{id}/ai-suggest`
|
||||||
|
- `/api/import/assets/{id}/review`
|
||||||
|
- Step 3 chapter split preview:
|
||||||
|
- `/api/import/assets/{id}/parse-preview`
|
||||||
|
- split mode: `toc` or `regex` (chapter-start pattern only)
|
||||||
|
- Step 4 start import + progress:
|
||||||
|
- `/api/import/assets/{id}/start-import`
|
||||||
|
- `/api/import/sessions/{sessionId}`
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- No filesystem scan in search request path (scan by cron/incremental).
|
||||||
|
- Reviewer confirms metadata before import.
|
||||||
|
- Import writes NAS content + chapter refs, then updates novel counters.
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ This project is Python-first (FastAPI), with production-focused Docker setup and
|
|||||||
- FastAPI
|
- FastAPI
|
||||||
- UV (package manager / runner)
|
- UV (package manager / runner)
|
||||||
- PostgreSQL (structured data)
|
- PostgreSQL (structured data)
|
||||||
- MongoDB (chapter content + user recommendations)
|
|
||||||
|
|
||||||
## API Base URL
|
## API Base URL
|
||||||
|
|
||||||
@@ -27,7 +26,6 @@ Required keys:
|
|||||||
|
|
||||||
```env
|
```env
|
||||||
DATABASE_URL=postgresql://reader:reader@localhost:5432/reader
|
DATABASE_URL=postgresql://reader:reader@localhost:5432/reader
|
||||||
MONGODB_URI=mongodb://localhost:27017/reader
|
|
||||||
NEXTAUTH_SECRET=replace-with-strong-secret
|
NEXTAUTH_SECRET=replace-with-strong-secret
|
||||||
MOBILE_JWT_SECRET=replace-with-strong-secret
|
MOBILE_JWT_SECRET=replace-with-strong-secret
|
||||||
# Comma-separated allowed Google OAuth client IDs
|
# Comma-separated allowed Google OAuth client IDs
|
||||||
@@ -79,15 +77,15 @@ WEB_GOOGLE_CLIENT_ID=web-client-id.apps.googleusercontent.com
|
|||||||
WEB_GOOGLE_CLIENT_SECRET=replace-with-web-google-client-secret
|
WEB_GOOGLE_CLIENT_SECRET=replace-with-web-google-client-secret
|
||||||
```
|
```
|
||||||
|
|
||||||
### Full local stack (API local + Postgres + Mongo)
|
### Full local stack (API local + Postgres)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile localdb up -d --build api-local postgres mongo
|
docker compose --profile localdb up -d --build api-local postgres
|
||||||
```
|
```
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- `api` listens on port `8000` and is intended for external DB deployments.
|
- `api` listens on port `8000` and is intended for external DB deployments.
|
||||||
- `api-local` listens on port `8001` and automatically points to `postgres` + `mongo` containers.
|
- `api-local` listens on port `8001` and automatically points to `postgres` container.
|
||||||
- `web` listens on port `3000` and calls API internally through `http://api:8000`.
|
- `web` listens on port `3000` and calls API internally through `http://api:8000`.
|
||||||
|
|
||||||
### NAS mount points (chapter content + EPUB source)
|
### NAS mount points (chapter content + EPUB source)
|
||||||
@@ -153,6 +151,29 @@ For your EPUB structure (folder per novel, multiple `.epub` parts inside), mount
|
|||||||
- POST /api/truyen/{id}/rate
|
- POST /api/truyen/{id}/rate
|
||||||
- GET /api/truyen/suggest
|
- GET /api/truyen/suggest
|
||||||
- GET /api/chapters/{chapterId}
|
- GET /api/chapters/{chapterId}
|
||||||
|
- GET /api/import/assets/search
|
||||||
|
- GET /api/import/assets/{assetId}/preview-metadata
|
||||||
|
- POST /api/import/assets/{assetId}/ai-suggest
|
||||||
|
- POST /api/import/assets/{assetId}/review
|
||||||
|
- POST /api/import/assets/{assetId}/parse-preview
|
||||||
|
- POST /api/import/assets/{assetId}/start-import
|
||||||
|
- GET /api/import/sessions/{sessionId}
|
||||||
|
|
||||||
|
## Simple EPUB Import Flow (Review-first)
|
||||||
|
|
||||||
|
MOD/ADMIN flow on new import wizard:
|
||||||
|
|
||||||
|
1. Search source EPUB by name (DB index): `GET /api/import/assets/search`
|
||||||
|
2. Review/edit metadata: `GET /api/import/assets/{id}/preview-metadata` + `POST /api/import/assets/{id}/review`
|
||||||
|
3. Preview chapter split (TOC or regex-start): `POST /api/import/assets/{id}/parse-preview`
|
||||||
|
4. Start import and poll progress:
|
||||||
|
- `POST /api/import/assets/{id}/start-import`
|
||||||
|
- `GET /api/import/sessions/{sessionId}`
|
||||||
|
|
||||||
|
AI assist in step 2:
|
||||||
|
- `POST /api/import/assets/{id}/ai-suggest`
|
||||||
|
- Returns up to 6 genres + 1 short description.
|
||||||
|
- New genres are allowed and created immediately on apply.
|
||||||
|
|
||||||
## NAS Migration Ops
|
## NAS Migration Ops
|
||||||
|
|
||||||
@@ -160,7 +181,7 @@ For your EPUB structure (folder per novel, multiple `.epub` parts inside), mount
|
|||||||
|
|
||||||
Run SQL in `migrations/2026_04_nas_content_storage.sql` against PostgreSQL.
|
Run SQL in `migrations/2026_04_nas_content_storage.sql` against PostgreSQL.
|
||||||
|
|
||||||
### 2) Backfill existing chapter content from Mongo -> NAS + ChapterContentRef
|
### 2) Backfill existing chapter content to NAS + ChapterContentRef
|
||||||
|
|
||||||
Dry-run first:
|
Dry-run first:
|
||||||
|
|
||||||
@@ -197,8 +218,7 @@ CHAPTER_CONTENT_MODE=nas_first
|
|||||||
```
|
```
|
||||||
|
|
||||||
Values:
|
Values:
|
||||||
- `nas_first` (default): read NAS ref first, fallback Mongo.
|
- `nas_first` (default): read NAS ref first.
|
||||||
- `mongo_first`: keep Mongo-first during cautious rollout.
|
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -8,7 +8,6 @@ class Settings(BaseSettings):
|
|||||||
app_env: str = "development"
|
app_env: str = "development"
|
||||||
|
|
||||||
database_url: str
|
database_url: str
|
||||||
mongodb_uri: str = ""
|
|
||||||
|
|
||||||
google_client_id: str = ""
|
google_client_id: str = ""
|
||||||
nextauth_secret: str = ""
|
nextauth_secret: str = ""
|
||||||
@@ -22,13 +21,15 @@ class Settings(BaseSettings):
|
|||||||
r2_public_base_url: str = ""
|
r2_public_base_url: str = ""
|
||||||
nas_content_root: str = "./data/content"
|
nas_content_root: str = "./data/content"
|
||||||
epub_source_root: str = "./data/epub-source"
|
epub_source_root: str = "./data/epub-source"
|
||||||
chapter_content_mode: str = "nas_first" # nas_first | mongo_first
|
chapter_content_mode: str = "nas_first"
|
||||||
auto_schema_bootstrap: str = "false"
|
auto_schema_bootstrap: str = "false"
|
||||||
|
|
||||||
deepseek_key: str = ""
|
deepseek_key: str = ""
|
||||||
deepseek_model: str = "deepseek-chat"
|
deepseek_model: str = "deepseek-chat"
|
||||||
openrouter_key: str = ""
|
openrouter_key: str = ""
|
||||||
openrouter_paused: str = "true"
|
openrouter_paused: str = "true"
|
||||||
|
import_scan_interval_minutes: int = 30
|
||||||
|
import_scan_limit: int = 2000
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def google_client_id_list(self) -> list[str]:
|
def google_client_id_list(self) -> list[str]:
|
||||||
|
|||||||
+3220
-138
File diff suppressed because it is too large
Load Diff
@@ -29,5 +29,19 @@ class NasContentStorage:
|
|||||||
digest = hashlib.sha256(content.encode("utf-8")).hexdigest()
|
digest = hashlib.sha256(content.encode("utf-8")).hexdigest()
|
||||||
return {"href": href, "sha256": digest, "size": len(content.encode("utf-8"))}
|
return {"href": href, "sha256": digest, "size": len(content.encode("utf-8"))}
|
||||||
|
|
||||||
|
def delete_href(self, href: str) -> bool:
|
||||||
|
path = self._resolve(href)
|
||||||
|
if not path.exists() or not path.is_file():
|
||||||
|
return False
|
||||||
|
path.unlink(missing_ok=True)
|
||||||
|
parent = path.parent
|
||||||
|
while parent != self.root:
|
||||||
|
try:
|
||||||
|
parent.rmdir()
|
||||||
|
except OSError:
|
||||||
|
break
|
||||||
|
parent = parent.parent
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
storage = NasContentStorage(settings.nas_content_root)
|
storage = NasContentStorage(settings.nas_content_root)
|
||||||
|
|||||||
+1
-19
@@ -23,7 +23,7 @@ services:
|
|||||||
retries: 5
|
retries: 5
|
||||||
start_period: 20s
|
start_period: 20s
|
||||||
|
|
||||||
# Local mode API: binds to local Postgres/Mongo containers.
|
# Local mode API: binds to local Postgres container.
|
||||||
api-local:
|
api-local:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
@@ -35,7 +35,6 @@ services:
|
|||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: postgresql://reader:reader@postgres:5432/reader
|
DATABASE_URL: postgresql://reader:reader@postgres:5432/reader
|
||||||
MONGODB_URI: mongodb://mongo:27017/reader
|
|
||||||
NAS_CONTENT_ROOT: ${NAS_CONTENT_ROOT:-/data/content}
|
NAS_CONTENT_ROOT: ${NAS_CONTENT_ROOT:-/data/content}
|
||||||
EPUB_SOURCE_ROOT: ${EPUB_SOURCE_ROOT:-/data/epub-source}
|
EPUB_SOURCE_ROOT: ${EPUB_SOURCE_ROOT:-/data/epub-source}
|
||||||
ports:
|
ports:
|
||||||
@@ -53,8 +52,6 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
mongo:
|
|
||||||
condition: service_healthy
|
|
||||||
|
|
||||||
web:
|
web:
|
||||||
build:
|
build:
|
||||||
@@ -97,23 +94,8 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 10
|
retries: 10
|
||||||
|
|
||||||
mongo:
|
|
||||||
image: mongo:7
|
|
||||||
container_name: reader-api-mongo
|
|
||||||
profiles: ["localdb"]
|
|
||||||
ports:
|
|
||||||
- "27017:27017"
|
|
||||||
volumes:
|
|
||||||
- mongo_data:/data/db
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 10
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
web_uploads:
|
web_uploads:
|
||||||
postgres_data:
|
postgres_data:
|
||||||
mongo_data:
|
|
||||||
nas_chapter_content:
|
nas_chapter_content:
|
||||||
nas_epub_source:
|
nas_epub_source:
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS "ChapterMeta" (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
"novelId" TEXT NOT NULL,
|
||||||
|
number INT NOT NULL,
|
||||||
|
title TEXT,
|
||||||
|
views INT NOT NULL DEFAULT 0,
|
||||||
|
"createdAt" TIMESTAMPTZ,
|
||||||
|
UNIQUE("novelId", number)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS "ChapterMeta_novel_number_idx" ON "ChapterMeta"("novelId", number);
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN insufficient_privilege THEN NULL;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
ALTER TABLE "SourceAsset"
|
||||||
|
ADD COLUMN IF NOT EXISTS search_name TEXT,
|
||||||
|
ADD COLUMN IF NOT EXISTS size_bytes BIGINT,
|
||||||
|
ADD COLUMN IF NOT EXISTS mtime_epoch BIGINT,
|
||||||
|
ADD COLUMN IF NOT EXISTS "lastScannedAt" TIMESTAMPTZ,
|
||||||
|
ADD COLUMN IF NOT EXISTS review_status TEXT NOT NULL DEFAULT 'discovered',
|
||||||
|
ADD COLUMN IF NOT EXISTS review_payload JSONB;
|
||||||
|
|
||||||
|
UPDATE "SourceAsset"
|
||||||
|
SET search_name = lower(regexp_replace(path, '[^a-zA-Z0-9\s]', ' ', 'g'))
|
||||||
|
WHERE search_name IS NULL;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS "SourceAsset_search_name_idx" ON "SourceAsset"(search_name);
|
||||||
|
CREATE INDEX IF NOT EXISTS "SourceAsset_search_name_trgm_idx" ON "SourceAsset" USING GIN (search_name gin_trgm_ops);
|
||||||
|
CREATE INDEX IF NOT EXISTS "SourceAsset_status_updatedAt_idx" ON "SourceAsset"(status, "updatedAt" DESC);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "ImportSession" (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
"sourceAssetId" TEXT NOT NULL REFERENCES "SourceAsset"(id) ON DELETE CASCADE,
|
||||||
|
"novelId" TEXT,
|
||||||
|
status TEXT NOT NULL DEFAULT 'pending',
|
||||||
|
phase TEXT NOT NULL DEFAULT 'prepare',
|
||||||
|
"progressPct" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||||
|
log TEXT,
|
||||||
|
"resultJson" JSONB,
|
||||||
|
"createdBy" TEXT,
|
||||||
|
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
"updatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS "ImportSession_asset_status_idx" ON "ImportSession"("sourceAssetId", status, "updatedAt" DESC);
|
||||||
@@ -10,7 +10,6 @@ dependencies = [
|
|||||||
"sqlalchemy[asyncio]>=2.0.43",
|
"sqlalchemy[asyncio]>=2.0.43",
|
||||||
"greenlet>=3.0.0",
|
"greenlet>=3.0.0",
|
||||||
"asyncpg>=0.30.0",
|
"asyncpg>=0.30.0",
|
||||||
"motor>=3.7.1",
|
|
||||||
"python-jose[cryptography]>=3.5.0",
|
"python-jose[cryptography]>=3.5.0",
|
||||||
"google-auth>=2.40.3",
|
"google-auth>=2.40.3",
|
||||||
"requests>=2.32.5",
|
"requests>=2.32.5",
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ dependencies = [
|
|||||||
{ name = "jmespath" },
|
{ name = "jmespath" },
|
||||||
{ name = "s3transfer" },
|
{ name = "s3transfer" },
|
||||||
]
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/74/ec/636ab2aa7ad9e6bf6e297240ac2d44dba63cc6611e2d5038db318436d449/boto3-1.42.74.tar.gz", hash = "sha256:dbacd808cf2a3dadbf35f3dbd8de97b94dc9f78b1ebd439f38f552e0f9753577", size = 112739, upload-time = "2026-03-23T19:34:09.815Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/ad/16/a264b4da2af99f4a12609b93fea941cce5ec41da14b33ed3fef77a910f0c/boto3-1.42.74-py3-none-any.whl", hash = "sha256:4bf89c044d618fe4435af854ab820f09dd43569c0df15d7beb0398f50b9aa970", size = 140557, upload-time = "2026-03-23T19:34:07.084Z" },
|
{ url = "https://files.pythonhosted.org/packages/ad/16/a264b4da2af99f4a12609b93fea941cce5ec41da14b33ed3fef77a910f0c/boto3-1.42.74-py3-none-any.whl", hash = "sha256:4bf89c044d618fe4435af854ab820f09dd43569c0df15d7beb0398f50b9aa970", size = 140557, upload-time = "2026-03-23T19:34:07.084Z" },
|
||||||
]
|
]
|
||||||
@@ -356,15 +357,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/bc/58/6b3d24e6b9bc474a2dcdee65dfd1f008867015408a271562e4b690561a4d/cryptography-46.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7", size = 3407605, upload-time = "2026-02-10T19:18:29.233Z" },
|
{ url = "https://files.pythonhosted.org/packages/bc/58/6b3d24e6b9bc474a2dcdee65dfd1f008867015408a271562e4b690561a4d/cryptography-46.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7", size = 3407605, upload-time = "2026-02-10T19:18:29.233Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dnspython"
|
|
||||||
version = "2.8.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ebooklib"
|
name = "ebooklib"
|
||||||
version = "0.20"
|
version = "0.20"
|
||||||
@@ -673,18 +665,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/6c/77/d7f491cbc05303ac6801651aabeb262d43f319288c1ea96c66b1d2692ff3/lxml-6.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:27220da5be049e936c3aca06f174e8827ca6445a4353a1995584311487fc4e3e", size = 3518768, upload-time = "2025-09-22T04:04:57.097Z" },
|
{ url = "https://files.pythonhosted.org/packages/6c/77/d7f491cbc05303ac6801651aabeb262d43f319288c1ea96c66b1d2692ff3/lxml-6.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:27220da5be049e936c3aca06f174e8827ca6445a4353a1995584311487fc4e3e", size = 3518768, upload-time = "2025-09-22T04:04:57.097Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "motor"
|
|
||||||
version = "3.7.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "pymongo" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/93/ae/96b88362d6a84cb372f7977750ac2a8aed7b2053eed260615df08d5c84f4/motor-3.7.1.tar.gz", hash = "sha256:27b4d46625c87928f331a6ca9d7c51c2f518ba0e270939d395bc1ddc89d64526", size = 280997, upload-time = "2025-05-14T18:56:33.653Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/01/9a/35e053d4f442addf751ed20e0e922476508ee580786546d699b0567c4c67/motor-3.7.1-py3-none-any.whl", hash = "sha256:8a63b9049e38eeeb56b4fdd57c3312a6d1f25d01db717fe7d82222393c410298", size = 74996, upload-time = "2025-05-14T18:56:31.665Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyasn1"
|
name = "pyasn1"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
@@ -841,67 +821,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/00/4b/ccc026168948fec4f7555b9164c724cf4125eac006e176541483d2c959be/pydantic_settings-2.13.1-py3-none-any.whl", hash = "sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237", size = 58929, upload-time = "2026-02-19T13:45:06.034Z" },
|
{ url = "https://files.pythonhosted.org/packages/00/4b/ccc026168948fec4f7555b9164c724cf4125eac006e176541483d2c959be/pydantic_settings-2.13.1-py3-none-any.whl", hash = "sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237", size = 58929, upload-time = "2026-02-19T13:45:06.034Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pymongo"
|
|
||||||
version = "4.16.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "dnspython" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/65/9c/a4895c4b785fc9865a84a56e14b5bd21ca75aadc3dab79c14187cdca189b/pymongo-4.16.0.tar.gz", hash = "sha256:8ba8405065f6e258a6f872fe62d797a28f383a12178c7153c01ed04e845c600c", size = 2495323, upload-time = "2026-01-07T18:05:48.107Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e6/3a/907414a763c4270b581ad6d960d0c6221b74a70eda216a1fdd8fa82ba89f/pymongo-4.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6f2077ec24e2f1248f9cac7b9a2dfb894e50cc7939fcebfb1759f99304caabef", size = 862561, upload-time = "2026-01-07T18:04:00.628Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8c/58/787d8225dd65cb2383c447346ea5e200ecfde89962d531111521e3b53018/pymongo-4.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d4f7ba040f72a9f43a44059872af5a8c8c660aa5d7f90d5344f2ed1c3c02721", size = 862923, upload-time = "2026-01-07T18:04:02.213Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5d/a7/cc2865aae32bc77ade7b35f957a58df52680d7f8506f93c6edbf458e5738/pymongo-4.16.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8a0f73af1ea56c422b2dcfc0437459148a799ef4231c6aee189d2d4c59d6728f", size = 1426779, upload-time = "2026-01-07T18:04:03.942Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/81/25/3e96eb7998eec05382174da2fefc58d28613f46bbdf821045539d0ed60ab/pymongo-4.16.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa30cd16ddd2f216d07ba01d9635c873e97ddb041c61cf0847254edc37d1c60e", size = 1454207, upload-time = "2026-01-07T18:04:05.387Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/86/7b/8e817a7df8c5d565d39dd4ca417a5e0ef46cc5cc19aea9405f403fec6449/pymongo-4.16.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1d638b0b1b294d95d0fdc73688a3b61e05cc4188872818cd240d51460ccabcb5", size = 1511654, upload-time = "2026-01-07T18:04:08.458Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/7a/50c4d075ccefcd281cdcfccc5494caa5665b096b85e65a5d6afabb80e09e/pymongo-4.16.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:21d02cc10a158daa20cb040985e280e7e439832fc6b7857bff3d53ef6914ad50", size = 1496794, upload-time = "2026-01-07T18:04:10.355Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0f/cd/ebdc1aaca5deeaf47310c369ef4083e8550e04e7bf7e3752cfb7d95fcdb8/pymongo-4.16.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fbb8d3552c2ad99d9e236003c0b5f96d5f05e29386ba7abae73949bfebc13dd", size = 1448371, upload-time = "2026-01-07T18:04:11.76Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3d/c9/50fdd78c37f68ea49d590c027c96919fbccfd98f3a4cb39f84f79970bd37/pymongo-4.16.0-cp311-cp311-win32.whl", hash = "sha256:be1099a8295b1a722d03fb7b48be895d30f4301419a583dcf50e9045968a041c", size = 841024, upload-time = "2026-01-07T18:04:13.522Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4a/dd/a3aa1ade0cf9980744db703570afac70a62c85b432c391dea0577f6da7bb/pymongo-4.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:61567f712bda04c7545a037e3284b4367cad8d29b3dec84b4bf3b2147020a75b", size = 855838, upload-time = "2026-01-07T18:04:14.923Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/bf/10/9ad82593ccb895e8722e4884bad4c5ce5e8ff6683b740d7823a6c2bcfacf/pymongo-4.16.0-cp311-cp311-win_arm64.whl", hash = "sha256:c53338613043038005bf2e41a2fafa08d29cdbc0ce80891b5366c819456c1ae9", size = 845007, upload-time = "2026-01-07T18:04:17.099Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/6a/03/6dd7c53cbde98de469a3e6fb893af896dca644c476beb0f0c6342bcc368b/pymongo-4.16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bd4911c40a43a821dfd93038ac824b756b6e703e26e951718522d29f6eb166a8", size = 917619, upload-time = "2026-01-07T18:04:19.173Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/73/e1/328915f2734ea1f355dc9b0e98505ff670f5fab8be5e951d6ed70971c6aa/pymongo-4.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25a6b03a68f9907ea6ec8bc7cf4c58a1b51a18e23394f962a6402f8e46d41211", size = 917364, upload-time = "2026-01-07T18:04:20.861Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/41/fe/4769874dd9812a1bc2880a9785e61eba5340da966af888dd430392790ae0/pymongo-4.16.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:91ac0cb0fe2bf17616c2039dac88d7c9a5088f5cb5829b27c9d250e053664d31", size = 1686901, upload-time = "2026-01-07T18:04:22.219Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fa/8d/15707b9669fdc517bbc552ac60da7124dafe7ac1552819b51e97ed4038b4/pymongo-4.16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cf0ec79e8ca7077f455d14d915d629385153b6a11abc0b93283ed73a8013e376", size = 1723034, upload-time = "2026-01-07T18:04:24.055Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/af/3d5d16ff11d447d40c1472da1b366a31c7380d7ea2922a449c7f7f495567/pymongo-4.16.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2d0082631a7510318befc2b4fdab140481eb4b9dd62d9245e042157085da2a70", size = 1797161, upload-time = "2026-01-07T18:04:25.964Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fb/04/725ab8664eeec73ec125b5a873448d80f5d8cf2750aaaf804cbc538a50a5/pymongo-4.16.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85dc2f3444c346ea019a371e321ac868a4fab513b7a55fe368f0cc78de8177cc", size = 1780938, upload-time = "2026-01-07T18:04:28.745Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/22/50/dd7e9095e1ca35f93c3c844c92eb6eb0bc491caeb2c9bff3b32fe3c9b18f/pymongo-4.16.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dabbf3c14de75a20cc3c30bf0c6527157224a93dfb605838eabb1a2ee3be008d", size = 1714342, upload-time = "2026-01-07T18:04:30.331Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/03/c9/542776987d5c31ae8e93e92680ea2b6e5a2295f398b25756234cabf38a39/pymongo-4.16.0-cp312-cp312-win32.whl", hash = "sha256:60307bb91e0ab44e560fe3a211087748b2b5f3e31f403baf41f5b7b0a70bd104", size = 887868, upload-time = "2026-01-07T18:04:32.124Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2e/d4/b4045a7ccc5680fb496d01edf749c7a9367cc8762fbdf7516cf807ef679b/pymongo-4.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:f513b2c6c0d5c491f478422f6b5b5c27ac1af06a54c93ef8631806f7231bd92e", size = 907554, upload-time = "2026-01-07T18:04:33.685Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/60/4c/33f75713d50d5247f2258405142c0318ff32c6f8976171c4fcae87a9dbdf/pymongo-4.16.0-cp312-cp312-win_arm64.whl", hash = "sha256:dfc320f08ea9a7ec5b2403dc4e8150636f0d6150f4b9792faaae539c88e7db3b", size = 892971, upload-time = "2026-01-07T18:04:35.594Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/84/148d8b5da8260f4679d6665196ae04ab14ffdf06f5fe670b0ab11942951f/pymongo-4.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d15f060bc6d0964a8bb70aba8f0cb6d11ae99715438f640cff11bbcf172eb0e8", size = 972009, upload-time = "2026-01-07T18:04:38.303Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1e/5e/9f3a8daf583d0adaaa033a3e3e58194d2282737dc164014ff33c7a081103/pymongo-4.16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a19ea46a0fe71248965305a020bc076a163311aefbaa1d83e47d06fa30ac747", size = 971784, upload-time = "2026-01-07T18:04:39.669Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ad/f2/b6c24361fcde24946198573c0176406bfd5f7b8538335f3d939487055322/pymongo-4.16.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:311d4549d6bf1f8c61d025965aebb5ba29d1481dc6471693ab91610aaffbc0eb", size = 1947174, upload-time = "2026-01-07T18:04:41.368Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/1a/8634192f98cf740b3d174e1018dd0350018607d5bd8ac35a666dc49c732b/pymongo-4.16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46ffb728d92dd5b09fc034ed91acf5595657c7ca17d4cf3751322cd554153c17", size = 1991727, upload-time = "2026-01-07T18:04:42.965Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5a/2f/0c47ac84572b28e23028a23a3798a1f725e1c23b0cf1c1424678d16aff42/pymongo-4.16.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:acda193f440dd88c2023cb00aa8bd7b93a9df59978306d14d87a8b12fe426b05", size = 2082497, upload-time = "2026-01-07T18:04:44.652Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ba/57/9f46ef9c862b2f0cf5ce798f3541c201c574128d31ded407ba4b3918d7b6/pymongo-4.16.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5d9fdb386cf958e6ef6ff537d6149be7edb76c3268cd6833e6c36aa447e4443f", size = 2064947, upload-time = "2026-01-07T18:04:46.228Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/56/5421c0998f38e32288100a07f6cb2f5f9f352522157c901910cb2927e211/pymongo-4.16.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:91899dd7fb9a8c50f09c3c1cf0cb73bfbe2737f511f641f19b9650deb61c00ca", size = 1980478, upload-time = "2026-01-07T18:04:48.017Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/92/93/bfc448d025e12313a937d6e1e0101b50cc9751636b4b170e600fe3203063/pymongo-4.16.0-cp313-cp313-win32.whl", hash = "sha256:2cd60cd1e05de7f01927f8e25ca26b3ea2c09de8723241e5d3bcfdc70eaff76b", size = 934672, upload-time = "2026-01-07T18:04:49.538Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/96/10/12710a5e01218d50c3dd165fd72c5ed2699285f77348a3b1a119a191d826/pymongo-4.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:3ead8a0050c53eaa55935895d6919d393d0328ec24b2b9115bdbe881aa222673", size = 959237, upload-time = "2026-01-07T18:04:51.382Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0c/56/d288bcd1d05bc17ec69df1d0b1d67bc710c7c5dbef86033a5a4d2e2b08e6/pymongo-4.16.0-cp313-cp313-win_arm64.whl", hash = "sha256:dbbc5b254c36c37d10abb50e899bc3939bbb7ab1e7c659614409af99bd3e7675", size = 940909, upload-time = "2026-01-07T18:04:52.904Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/9e/4d343f8d0512002fce17915a89477b9f916bda1205729e042d8f23acf194/pymongo-4.16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:8a254d49a9ffe9d7f888e3c677eed3729b14ce85abb08cd74732cead6ccc3c66", size = 1026634, upload-time = "2026-01-07T18:04:54.359Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c3/e3/341f88c5535df40c0450fda915f582757bb7d988cdfc92990a5e27c4c324/pymongo-4.16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a1bf44e13cf2d44d2ea2e928a8140d5d667304abe1a61c4d55b4906f389fbe64", size = 1026252, upload-time = "2026-01-07T18:04:56.642Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/64/9471b22eb98f0a2ca0b8e09393de048502111b2b5b14ab1bd9e39708aab5/pymongo-4.16.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f1c5f1f818b669875d191323a48912d3fcd2e4906410e8297bb09ac50c4d5ccc", size = 2207399, upload-time = "2026-01-07T18:04:58.255Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/87/ac/47c4d50b25a02f21764f140295a2efaa583ee7f17992a5e5fa542b3a690f/pymongo-4.16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77cfd37a43a53b02b7bd930457c7994c924ad8bbe8dff91817904bcbf291b371", size = 2260595, upload-time = "2026-01-07T18:04:59.788Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ee/1b/0ce1ce9dd036417646b2fe6f63b58127acff3cf96eeb630c34ec9cd675ff/pymongo-4.16.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:36ef2fee50eee669587d742fb456e349634b4fcf8926208766078b089054b24b", size = 2366958, upload-time = "2026-01-07T18:05:01.942Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/3c/a5a17c0d413aa9d6c17bc35c2b472e9e79cda8068ba8e93433b5f43028e9/pymongo-4.16.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55f8d5a6fe2fa0b823674db2293f92d74cd5f970bc0360f409a1fc21003862d3", size = 2346081, upload-time = "2026-01-07T18:05:03.576Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/65/19/f815533d1a88fb8a3b6c6e895bb085ffdae68ccb1e6ed7102202a307f8e2/pymongo-4.16.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9caacac0dd105e2555521002e2d17afc08665187017b466b5753e84c016628e6", size = 2246053, upload-time = "2026-01-07T18:05:05.459Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c6/88/4be3ec78828dc64b212c123114bd6ae8db5b7676085a7b43cc75d0131bd2/pymongo-4.16.0-cp314-cp314-win32.whl", hash = "sha256:c789236366525c3ee3cd6e4e450a9ff629a7d1f4d88b8e18a0aea0615fd7ecf8", size = 989461, upload-time = "2026-01-07T18:05:07.018Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/5a/ab8d5af76421b34db483c9c8ebc3a2199fb80ae63dc7e18f4cf1df46306a/pymongo-4.16.0-cp314-cp314-win_amd64.whl", hash = "sha256:2b0714d7764efb29bf9d3c51c964aed7c4c7237b341f9346f15ceaf8321fdb35", size = 1017803, upload-time = "2026-01-07T18:05:08.499Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f6/f4/98d68020728ac6423cf02d17cfd8226bf6cce5690b163d30d3f705e8297e/pymongo-4.16.0-cp314-cp314-win_arm64.whl", hash = "sha256:12762e7cc0f8374a8cae3b9f9ed8dabb5d438c7b33329232dd9b7de783454033", size = 997184, upload-time = "2026-01-07T18:05:09.944Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/50/00/dc3a271daf06401825b9c1f4f76f018182c7738281ea54b9762aea0560c1/pymongo-4.16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1c01e8a7cd0ea66baf64a118005535ab5bf9f9eb63a1b50ac3935dccf9a54abe", size = 1083303, upload-time = "2026-01-07T18:05:11.702Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/4b/b5375ee21d12eababe46215011ebc63801c0d2c5ffdf203849d0d79f9852/pymongo-4.16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4c4872299ebe315a79f7f922051061634a64fda95b6b17677ba57ef00b2ba2a4", size = 1083233, upload-time = "2026-01-07T18:05:13.182Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ee/e3/52efa3ca900622c7dcb56c5e70f15c906816d98905c22d2ee1f84d9a7b60/pymongo-4.16.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:78037d02389745e247fe5ab0bcad5d1ab30726eaac3ad79219c7d6bbb07eec53", size = 2527438, upload-time = "2026-01-07T18:05:14.981Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/96/43b1be151c734e7766c725444bcbfa1de6b60cc66bfb406203746839dd25/pymongo-4.16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c126fb72be2518395cc0465d4bae03125119136462e1945aea19840e45d89cfc", size = 2600399, upload-time = "2026-01-07T18:05:16.794Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e7/62/fa64a5045dfe3a1cd9217232c848256e7bc0136cffb7da4735c5e0d30e40/pymongo-4.16.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f3867dc225d9423c245a51eaac2cfcd53dde8e0a8d8090bb6aed6e31bd6c2d4f", size = 2720960, upload-time = "2026-01-07T18:05:18.498Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/54/7b/01577eb97e605502821273a5bc16ce0fb0be5c978fe03acdbff471471202/pymongo-4.16.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f25001a955073b80510c0c3db0e043dbbc36904fd69e511c74e3d8640b8a5111", size = 2699344, upload-time = "2026-01-07T18:05:20.073Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/55/68/6ef6372d516f703479c3b6cbbc45a5afd307173b1cbaccd724e23919bb1a/pymongo-4.16.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d9885aad05f82fd7ea0c9ca505d60939746b39263fa273d0125170da8f59098", size = 2577133, upload-time = "2026-01-07T18:05:22.052Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/15/c7/b5337093bb01da852f945802328665f85f8109dbe91d81ea2afe5ff059b9/pymongo-4.16.0-cp314-cp314t-win32.whl", hash = "sha256:948152b30eddeae8355495f9943a3bf66b708295c0b9b6f467de1c620f215487", size = 1040560, upload-time = "2026-01-07T18:05:23.888Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/96/8c/5b448cd1b103f3889d5713dda37304c81020ff88e38a826e8a75ddff4610/pymongo-4.16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f6e42c1bc985d9beee884780ae6048790eb4cd565c46251932906bdb1630034a", size = 1075081, upload-time = "2026-01-07T18:05:26.874Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/32/cd/ddc794cdc8500f6f28c119c624252fb6dfb19481c6d7ed150f13cf468a6d/pymongo-4.16.0-cp314-cp314t-win_arm64.whl", hash = "sha256:6b2a20edb5452ac8daa395890eeb076c570790dfce6b7a44d788af74c2f8cf96", size = 1047725, upload-time = "2026-01-07T18:05:28.47Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-dateutil"
|
name = "python-dateutil"
|
||||||
version = "2.9.0.post0"
|
version = "2.9.0.post0"
|
||||||
@@ -1031,7 +950,6 @@ dependencies = [
|
|||||||
{ name = "greenlet" },
|
{ name = "greenlet" },
|
||||||
{ name = "html2text" },
|
{ name = "html2text" },
|
||||||
{ name = "httpx" },
|
{ name = "httpx" },
|
||||||
{ name = "motor" },
|
|
||||||
{ name = "pydantic-settings" },
|
{ name = "pydantic-settings" },
|
||||||
{ name = "python-jose", extra = ["cryptography"] },
|
{ name = "python-jose", extra = ["cryptography"] },
|
||||||
{ name = "python-multipart" },
|
{ name = "python-multipart" },
|
||||||
@@ -1056,7 +974,6 @@ requires-dist = [
|
|||||||
{ name = "greenlet", specifier = ">=3.0.0" },
|
{ name = "greenlet", specifier = ">=3.0.0" },
|
||||||
{ name = "html2text", specifier = ">=2024.2.26" },
|
{ name = "html2text", specifier = ">=2024.2.26" },
|
||||||
{ name = "httpx", specifier = ">=0.27.0" },
|
{ name = "httpx", specifier = ">=0.27.0" },
|
||||||
{ name = "motor", specifier = ">=3.7.1" },
|
|
||||||
{ name = "pydantic-settings", specifier = ">=2.10.1" },
|
{ name = "pydantic-settings", specifier = ">=2.10.1" },
|
||||||
{ name = "python-jose", extras = ["cryptography"], specifier = ">=3.5.0" },
|
{ name = "python-jose", extras = ["cryptography"], specifier = ">=3.5.0" },
|
||||||
{ name = "python-multipart", specifier = ">=0.0.9" },
|
{ name = "python-multipart", specifier = ">=0.0.9" },
|
||||||
|
|||||||
Reference in New Issue
Block a user