refactor: migrate to uv + pyproject.toml dependency management

BREAKING CHANGE: Removed pip-style requirements files

Migration Details:
- Removed core_requirements.{in,txt} and dev_requirements.in
- Consolidated all dependencies into pyproject.toml
- Added platform markers for Windows-specific packages:
  - pywin32>=311 (sys_platform == 'win32')
  - win32-setctime>=1.2.0 (sys_platform == 'win32')
  - hypercorn (Windows ASGI server)
  - gunicorn (Unix WSGI server)

CI/CD Changes:
- Updated .github/workflows/test.yml to use 'uv sync --group test'
- Simplified installation: no more manual pip install steps
- Uses 'uv run pytest' for test execution with PYTHONPATH

Benefits:
-  Fixes pywin32 installation failure on Ubuntu CI runners
-  Single source of truth for dependencies (pyproject.toml)
-  Faster resolution with uv lockfile
-  Modern Python packaging (PEP 621)
-  Proper dependency groups (dev, test)
-  Platform-aware installation

New Workflow:
- Production: uv sync
- With tests: uv sync --group test
- With dev tools: uv sync --group dev
- All groups: uv sync --all-groups

Added MIGRATION_UV.md with full migration guide for developers.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-04 16:07:14 -05:00
parent 6745b3c870
commit a11e0c65fe
7 changed files with 475 additions and 1352 deletions

View File

@ -28,15 +28,13 @@ jobs:
- name: Install dependencies
run: |
uv venv
source .venv/bin/activate
uv pip install -r core_requirements.txt
uv pip install pytest pytest-cov pytest-asyncio httpx
uv sync --group test
- name: Run tests
run: |
source .venv/bin/activate
pytest --cov=src --cov-report=xml --cov-report=term
uv run pytest --cov=src --cov-report=xml --cov-report=term
env:
PYTHONPATH: src
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4

99
MIGRATION_UV.md Normal file
View File

@ -0,0 +1,99 @@
# Migration to uv + pyproject.toml
**Date**: 2026-02-04
**Status**: ✅ Completed
## What Changed
Migrated from pip-style `requirements.txt`/`requirements.in` files to modern `uv` + `pyproject.toml` dependency management.
## Old Approach (Deprecated)
```bash
# Old way - DO NOT USE
uv pip install -r core_requirements.txt
uv pip install -r dev_requirements.txt
```
## New Approach (Current)
```bash
# Production dependencies
uv sync
# With test dependencies
uv sync --group test
# With development dependencies
uv sync --group dev
# All groups
uv sync --all-groups
```
## Files Removed
-`core_requirements.in`
-`core_requirements.txt`
-`dev_requirements.in`
## Files Updated
-`pyproject.toml` - All dependencies now defined here
-`.github/workflows/test.yml` - CI uses `uv sync --group test`
## Platform-Specific Dependencies
The following dependencies are now properly marked with platform markers:
### Windows Only
- `pywin32>=311` (sys_platform == 'win32')
- `win32-setctime>=1.2.0` (sys_platform == 'win32')
- `hypercorn>=0.18.0` (sys_platform == 'win32')
### Unix Only
- `gunicorn>=25.0.1` (sys_platform != 'win32')
This fixes the CI installation failure where `pywin32` was being installed on Ubuntu runners.
## Benefits
1. **Single source of truth**: All dependencies in `pyproject.toml`
2. **Platform awareness**: Proper platform markers prevent installation failures
3. **Faster resolution**: `uv` lockfile (`uv.lock`) ensures reproducible installs
4. **Modern tooling**: Aligned with Python packaging standards (PEP 621)
5. **Dependency groups**: Separate dev/test dependencies cleanly
## For Developers
### First Time Setup
```bash
# Install uv if not already installed
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone and setup
git clone <repo>
cd strategiq
uv sync --all-groups
```
### Running Tests
```bash
uv run pytest
```
### Adding Dependencies
```bash
# Add to [project] dependencies in pyproject.toml
# Then sync
uv sync
```
## CI/CD
GitHub Actions now uses:
```yaml
- name: Install dependencies
run: uv sync --group test
- name: Run tests
run: uv run pytest --cov=src
```
No more manual pip install steps!

View File

@ -1,39 +0,0 @@
aiofiles
aiomysql
celery
fastapi
fastapi-restful
fastcrud
flower
greenlet
gunicorn; platform_system != 'Windows'
httpx
httpx[socks]
httpx-html
html5lib
hypercorn; platform_system == 'Windows'
itsdangerous
jinjax
loguru
lxml
lxml[html_clean]
openai
praw
python-dateutil
python-decouple
python-slugify
psycopg
pydantic-ai[examples]
pydantic-settings
pytz
redis
reportlab
simplejson
sqlalchemy_mixins
sqlmodel
sqlmodel-crud-utilities @ git+https://github.com/fsecada01/SQLModel-CRUD-Utilities@v0.0.1a1
tavily-python
typing-inspect
uvicorn
xmljson
xmltodict

View File

@ -1,742 +0,0 @@
# This file was autogenerated by uv via the following command:
# uv pip compile core_requirements.in -o core_requirements.txt
aiofiles==24.1.0
# via
# -r core_requirements.in
# gradio
aiohappyeyeballs==2.6.1
# via aiohttp
aiohttp==3.13.3
# via modal
aiomysql==0.3.2
# via -r core_requirements.in
aiosignal==1.4.0
# via aiohttp
amqp==5.3.1
# via kombu
annotated-doc==0.0.4
# via fastapi
annotated-types==0.7.0
# via
# pydantic
# sqlmodel-crud-utilities
anthropic==0.77.1
# via pydantic-ai-slim
anyio==4.12.1
# via
# anthropic
# google-genai
# gradio
# groq
# httpx
# mcp
# openai
# pydantic-evals
# sse-starlette
# starlette
# watchfiles
appdirs==1.4.4
# via pyppeteer
argcomplete==3.6.3
# via pydantic-ai-slim
asgiref==3.11.1
# via opentelemetry-instrumentation-asgi
asttokens==2.4.1
# via devtools
asyncpg==0.31.0
# via pydantic-ai-examples
attrs==25.4.0
# via
# aiohttp
# jsonschema
# referencing
audioop-lts==0.2.2
# via gradio
beautifulsoup4==4.14.3
# via httpx-html
billiard==4.2.4
# via celery
boto3==1.42.41
# via pydantic-ai-slim
botocore==1.42.41
# via
# boto3
# s3transfer
brotli==1.2.0
# via gradio
cbor2==5.8.0
# via modal
celery==5.6.2
# via
# -r core_requirements.in
# flower
certifi==2026.1.4
# via
# httpcore
# httpx
# modal
# requests
cffi==2.0.0
# via cryptography
charset-normalizer==3.4.4
# via
# reportlab
# requests
click==8.3.1
# via
# celery
# click-didyoumean
# click-plugins
# click-repl
# modal
# typer
# typer-slim
# uvicorn
click-didyoumean==0.3.1
# via celery
click-plugins==1.1.1.2
# via celery
click-repl==0.3.0
# via celery
cohere==5.20.2
# via pydantic-ai-slim
colorama==0.4.6
# via
# click
# griffe
# loguru
# sqlmodel-crud-utilities
# tqdm
cryptography==46.0.4
# via google-auth
cssselect==1.4.0
# via pyquery
devtools==0.12.2
# via pydantic-ai-examples
distro==1.9.0
# via
# anthropic
# google-genai
# groq
# openai
docstring-parser==0.17.0
# via anthropic
eval-type-backport==0.3.1
# via
# mistralai
# pydantic-ai-slim
executing==2.2.1
# via
# devtools
# logfire
fake-useragent==2.2.0
# via httpx-html
fastapi==0.128.1
# via
# -r core_requirements.in
# fastapi-restful
# fastcrud
# gradio
# pydantic-ai-examples
fastapi-restful==0.6.0
# via -r core_requirements.in
fastavro==1.12.1
# via cohere
fastcrud==0.21.0
# via -r core_requirements.in
ffmpy==1.0.0
# via gradio
filelock==3.20.3
# via huggingface-hub
flower==2.0.1
# via -r core_requirements.in
frozenlist==1.8.0
# via
# aiohttp
# aiosignal
fsspec==2026.1.0
# via
# gradio-client
# huggingface-hub
google-auth==2.48.0
# via
# google-genai
# pydantic-ai-slim
google-genai==1.61.0
# via pydantic-ai-slim
googleapis-common-protos==1.72.0
# via opentelemetry-exporter-otlp-proto-http
gradio==6.5.1
# via pydantic-ai-examples
gradio-client==2.0.3
# via gradio
greenlet==3.1.1
# via
# -r core_requirements.in
# sqlalchemy
# sqlmodel-crud-utilities
griffe==1.15.0
# via pydantic-ai-slim
groovy==0.1.2
# via gradio
groq==1.0.0
# via pydantic-ai-slim
grpclib==0.4.9
# via modal
h11==0.16.0
# via
# httpcore
# hypercorn
# uvicorn
# wsproto
h2==4.3.0
# via
# grpclib
# hypercorn
hf-xet==1.2.0
# via huggingface-hub
hpack==4.1.0
# via h2
html5lib==1.1
# via -r core_requirements.in
httpcore==1.0.9
# via httpx
httpx==0.28.1
# via
# -r core_requirements.in
# anthropic
# cohere
# google-genai
# gradio
# gradio-client
# groq
# httpx-html
# huggingface-hub
# mcp
# mistralai
# openai
# pydantic-ai-slim
# pydantic-graph
# safehttpx
# tavily-python
httpx-html==0.11.0.dev0
# via -r core_requirements.in
httpx-sse==0.4.3
# via mcp
huggingface-hub==1.4.0
# via
# gradio
# gradio-client
# pydantic-ai-slim
# tokenizers
humanize==4.15.0
# via flower
hypercorn==0.18.0
# via -r core_requirements.in
hyperframe==6.1.0
# via h2
idna==3.11
# via
# anyio
# httpx
# requests
# yarl
importlib-metadata==8.7.1
# via opentelemetry-api
invoke==2.2.1
# via mistralai
itsdangerous==2.2.0
# via -r core_requirements.in
jinja2==3.1.6
# via
# gradio
# jinjax
jinjax==0.63
# via -r core_requirements.in
jiter==0.13.0
# via
# anthropic
# openai
jmespath==1.1.0
# via
# boto3
# botocore
jsonschema==4.26.0
# via mcp
jsonschema-specifications==2025.9.1
# via jsonschema
kombu==5.6.2
# via celery
logfire==4.22.0
# via pydantic-ai-examples
logfire-api==4.22.0
# via
# pydantic-evals
# pydantic-graph
loguru==0.7.3
# via
# -r core_requirements.in
# sqlmodel-crud-utilities
lxml==6.0.2
# via
# -r core_requirements.in
# lxml-html-clean
# pyquery
lxml-html-clean==0.4.3
# via lxml
markdown-it-py==4.0.0
# via rich
markupsafe==3.0.3
# via
# gradio
# jinja2
# jinjax
mcp==1.12.4
# via
# pydantic-ai-examples
# pydantic-ai-slim
mdurl==0.1.2
# via markdown-it-py
mistralai==1.9.11
# via pydantic-ai-slim
modal==1.3.2
# via pydantic-ai-examples
multidict==6.7.1
# via
# aiohttp
# grpclib
# yarl
mypy-extensions==1.1.0
# via typing-inspect
numpy==2.4.2
# via
# gradio
# pandas
openai==2.16.0
# via
# -r core_requirements.in
# pydantic-ai-slim
opentelemetry-api==1.39.1
# via
# opentelemetry-exporter-otlp-proto-http
# opentelemetry-instrumentation
# opentelemetry-instrumentation-asgi
# opentelemetry-instrumentation-asyncpg
# opentelemetry-instrumentation-dbapi
# opentelemetry-instrumentation-fastapi
# opentelemetry-instrumentation-httpx
# opentelemetry-instrumentation-sqlite3
# opentelemetry-sdk
# opentelemetry-semantic-conventions
# pydantic-ai-slim
opentelemetry-exporter-otlp-proto-common==1.39.1
# via opentelemetry-exporter-otlp-proto-http
opentelemetry-exporter-otlp-proto-http==1.39.1
# via logfire
opentelemetry-instrumentation==0.60b1
# via
# logfire
# opentelemetry-instrumentation-asgi
# opentelemetry-instrumentation-asyncpg
# opentelemetry-instrumentation-dbapi
# opentelemetry-instrumentation-fastapi
# opentelemetry-instrumentation-httpx
# opentelemetry-instrumentation-sqlite3
opentelemetry-instrumentation-asgi==0.60b1
# via opentelemetry-instrumentation-fastapi
opentelemetry-instrumentation-asyncpg==0.60b1
# via logfire
opentelemetry-instrumentation-dbapi==0.60b1
# via opentelemetry-instrumentation-sqlite3
opentelemetry-instrumentation-fastapi==0.60b1
# via logfire
opentelemetry-instrumentation-httpx==0.60b1
# via logfire
opentelemetry-instrumentation-sqlite3==0.60b1
# via logfire
opentelemetry-proto==1.39.1
# via
# opentelemetry-exporter-otlp-proto-common
# opentelemetry-exporter-otlp-proto-http
opentelemetry-sdk==1.39.1
# via
# logfire
# opentelemetry-exporter-otlp-proto-http
opentelemetry-semantic-conventions==0.60b1
# via
# opentelemetry-instrumentation
# opentelemetry-instrumentation-asgi
# opentelemetry-instrumentation-asyncpg
# opentelemetry-instrumentation-dbapi
# opentelemetry-instrumentation-fastapi
# opentelemetry-instrumentation-httpx
# opentelemetry-sdk
opentelemetry-util-http==0.60b1
# via
# opentelemetry-instrumentation-asgi
# opentelemetry-instrumentation-fastapi
# opentelemetry-instrumentation-httpx
orjson==3.11.7
# via gradio
packaging==26.0
# via
# gradio
# gradio-client
# huggingface-hub
# kombu
# opentelemetry-instrumentation
pandas==3.0.0
# via gradio
parse==1.20.2
# via httpx-html
pillow==12.1.0
# via
# gradio
# reportlab
praw==7.8.1
# via -r core_requirements.in
prawcore==2.4.0
# via praw
priority==2.0.0
# via hypercorn
prometheus-client==0.24.1
# via flower
prompt-toolkit==3.0.52
# via
# click-repl
# pydantic-ai-slim
propcache==0.4.1
# via
# aiohttp
# yarl
protobuf==6.33.5
# via
# googleapis-common-protos
# logfire
# modal
# opentelemetry-proto
psutil==5.9.8
# via fastapi-restful
psycopg==3.3.2
# via -r core_requirements.in
pyasn1==0.6.2
# via
# pyasn1-modules
# rsa
pyasn1-modules==0.4.2
# via google-auth
pycparser==3.0
# via cffi
pydantic==2.10.5
# via
# anthropic
# cohere
# fastapi
# fastapi-restful
# fastcrud
# google-genai
# gradio
# groq
# mcp
# mistralai
# openai
# pydantic-ai-slim
# pydantic-evals
# pydantic-graph
# pydantic-settings
# sqlmodel
# sqlmodel-crud-utilities
pydantic-ai==0.4.3
# via -r core_requirements.in
pydantic-ai-examples==0.4.3
# via pydantic-ai
pydantic-ai-slim==0.4.3
# via
# pydantic-ai
# pydantic-ai-examples
# pydantic-evals
pydantic-core==2.27.2
# via
# cohere
# pydantic
# sqlmodel-crud-utilities
pydantic-evals==0.4.3
# via
# pydantic-ai-examples
# pydantic-ai-slim
pydantic-graph==0.4.3
# via pydantic-ai-slim
pydantic-settings==2.12.0
# via
# -r core_requirements.in
# mcp
pydub==0.25.1
# via gradio
pyee==13.0.0
# via pyppeteer
pygments==2.19.2
# via
# devtools
# rich
pymysql==1.1.2
# via aiomysql
pyppeteer==0.0.25
# via httpx-html
pyquery==2.0.1
# via httpx-html
python-dateutil==2.9.0.post0
# via
# -r core_requirements.in
# botocore
# celery
# mistralai
# pandas
# sqlmodel-crud-utilities
python-decouple==3.8
# via -r core_requirements.in
python-dotenv==1.0.1
# via
# mcp
# pydantic-settings
# sqlmodel-crud-utilities
python-multipart==0.0.22
# via
# gradio
# mcp
# pydantic-ai-examples
python-slugify==8.0.4
# via -r core_requirements.in
pytz==2025.2
# via
# -r core_requirements.in
# flower
# gradio
pywin32==311
# via mcp
pyyaml==6.0.3
# via
# gradio
# huggingface-hub
# mistralai
# pydantic-evals
redis==7.1.0
# via -r core_requirements.in
referencing==0.37.0
# via
# jsonschema
# jsonschema-specifications
regex==2026.1.15
# via tiktoken
reportlab==4.4.9
# via -r core_requirements.in
requests==2.32.5
# via
# cohere
# google-auth
# google-genai
# opentelemetry-exporter-otlp-proto-http
# prawcore
# pydantic-ai-slim
# tavily-python
# tiktoken
# update-checker
rich==14.3.2
# via
# logfire
# modal
# pydantic-ai-examples
# pydantic-ai-slim
# pydantic-evals
# typer
rpds-py==0.30.0
# via
# jsonschema
# referencing
rsa==4.9.1
# via google-auth
s3transfer==0.16.0
# via boto3
safehttpx==0.1.7
# via gradio
semantic-version==2.10.0
# via gradio
shellingham==1.5.4
# via
# huggingface-hub
# typer
simplejson==3.20.2
# via -r core_requirements.in
six==1.17.0
# via
# asttokens
# html5lib
# python-dateutil
# sqlalchemy-mixins
# sqlmodel-crud-utilities
sniffio==1.3.1
# via
# anthropic
# google-genai
# groq
# openai
socksio==1.0.0
# via httpx
soupsieve==2.8.3
# via beautifulsoup4
sqlalchemy==2.0.37
# via
# fastcrud
# sqlalchemy-mixins
# sqlalchemy-utils
# sqlmodel
# sqlmodel-crud-utilities
sqlalchemy-mixins==2.0.5
# via -r core_requirements.in
sqlalchemy-utils==0.41.2
# via fastcrud
sqlmodel==0.0.22
# via
# -r core_requirements.in
# sqlmodel-crud-utilities
sqlmodel-crud-utilities @ git+https://github.com/fsecada01/SQLModel-CRUD-Utilities@83e964f6e7b633e339e45ddcaaa49cd8617fa105
# via -r core_requirements.in
sse-starlette==3.2.0
# via mcp
starlette==0.50.0
# via
# fastapi
# gradio
# mcp
# sse-starlette
synchronicity==0.11.1
# via modal
tavily-python==0.7.21
# via -r core_requirements.in
tenacity==9.1.2
# via google-genai
text-unidecode==1.3
# via python-slugify
tiktoken==0.12.0
# via tavily-python
tokenizers==0.22.2
# via cohere
toml==0.10.2
# via modal
tomlkit==0.13.3
# via gradio
tornado==6.5.4
# via flower
tqdm==4.67.3
# via
# huggingface-hub
# openai
# pyppeteer
typer==0.21.1
# via
# gradio
# mcp
# modal
typer-slim==0.21.1
# via huggingface-hub
types-certifi==2021.10.8.3
# via modal
types-requests==2.32.4.20260107
# via cohere
types-toml==0.10.8.20240310
# via modal
typing-extensions==4.12.2
# via
# anthropic
# beautifulsoup4
# cohere
# fastapi
# google-genai
# gradio
# gradio-client
# groq
# huggingface-hub
# logfire
# modal
# openai
# opentelemetry-api
# opentelemetry-exporter-otlp-proto-http
# opentelemetry-sdk
# opentelemetry-semantic-conventions
# pydantic
# pydantic-core
# pyee
# sqlalchemy
# sqlmodel-crud-utilities
# synchronicity
# typer
# typer-slim
# typing-inspect
# typing-inspection
typing-inspect==0.9.0
# via -r core_requirements.in
typing-inspection==0.4.2
# via
# mistralai
# pydantic-ai-slim
# pydantic-graph
# pydantic-settings
tzdata==2025.3
# via
# kombu
# pandas
# psycopg
# tzlocal
tzlocal==5.3.1
# via celery
update-checker==0.18.0
# via praw
urllib3==2.6.3
# via
# botocore
# pyppeteer
# requests
# types-requests
uvicorn==0.40.0
# via
# -r core_requirements.in
# gradio
# mcp
# pydantic-ai-examples
vine==5.1.0
# via
# amqp
# celery
# kombu
w3lib==2.4.0
# via httpx-html
watchfiles==1.1.1
# via modal
wcwidth==0.5.3
# via prompt-toolkit
webencodings==0.5.1
# via html5lib
websocket-client==1.9.0
# via praw
websockets==15.0.1
# via
# google-genai
# pyppeteer
win32-setctime==1.2.0
# via
# loguru
# sqlmodel-crud-utilities
wrapt==1.17.3
# via
# opentelemetry-instrumentation
# opentelemetry-instrumentation-dbapi
# opentelemetry-instrumentation-httpx
wsproto==1.3.2
# via hypercorn
xmljson==0.2.1
# via -r core_requirements.in
xmltodict==1.0.2
# via -r core_requirements.in
yarl==1.22.0
# via aiohttp
zipp==3.23.0
# via importlib-metadata

View File

@ -1,10 +0,0 @@
-c core_requirements.txt
alembic
black
fastapi-debug-toolbar @ git+https://github.com/fsecada01/fastapi-debug-toolbar.git@patch-2
isort
jupyterlab
jupyterlab-code-formatter
pre-commit
ruff

View File

@ -63,7 +63,7 @@ fastapi-debug-toolbar = { git = "https://github.com/fsecada01/fastapi-debug-tool
#force_grid_wrap = 0
[project]
name = "agentic_ai_service"
name = "strategiq"
authors = [
{ name = "Francis Secada", email = "francis.secada@gmail.com" }
]
@ -76,42 +76,80 @@ classifiers = [
version = "1.0.0b0"
requires-python = ">=3.13"
dependencies = [
# Core async I/O
"aiofiles>=24.1.0",
"aiomysql>=0.2.0",
"celery>=5.4.0",
"fastapi>=0.115.7",
"aiomysql>=0.3.2",
# Web framework
"fastapi>=0.128.1",
"fastapi-restful>=0.6.0",
"fastcrud>=0.15.5",
"flower>=2.0.1",
"greenlet>=3.1.1",
"fastcrud>=0.21.0",
"uvicorn>=0.40.0",
# WSGI/ASGI servers (platform-specific)
"gunicorn>=25.0.1 ; sys_platform != 'win32'",
"html5lib>=1.1",
"httpx-html>=0.11.0.dev0",
"httpx[socks]>=0.28.1",
"hypercorn>=0.17.3 ; sys_platform == 'win32'",
"itsdangerous>=2.2.0",
"jinjax>=0.48",
"loguru>=0.7.3",
"lxml[html-clean]>=5.3.0",
"openai>=1.60.0",
"praw>=7.8.1",
"tavily-python>=0.7.0",
"psycopg>=3.2.4",
"pydantic-ai[examples]>=0.0.18",
"pydantic-settings>=2.7.1",
"python-dateutil>=2.9.0.post0",
"python-decouple>=3.8",
"python-slugify>=8.0.4",
"pytz>=2024.2",
"redis>=5.2.1",
"simplejson>=3.19.3",
"hypercorn>=0.18.0 ; sys_platform == 'win32'",
# Task queue
"celery>=5.6.2",
"flower>=2.0.1",
"redis>=7.1.0",
# Database
"psycopg>=3.3.2",
"sqlalchemy>=2.0.37",
"sqlalchemy-mixins>=2.0.5",
"sqlmodel>=0.0.22",
"sqlmodel-crud-utilities",
"greenlet>=3.1.1",
# HTTP clients
"httpx[socks]>=0.28.1",
"httpx-html>=0.11.0.dev0",
# HTML/XML parsing
"html5lib>=1.1",
"lxml[html-clean]>=6.0.2",
"beautifulsoup4>=4.14.3",
# Templating
"jinjax>=0.63",
"jinja2>=3.1.6",
# AI/LLM
"openai>=2.16.0",
"pydantic-ai[examples]>=0.4.3",
"anthropic>=0.77.1",
"tavily-python>=0.7.21",
# Reddit API
"praw>=7.8.1",
# PDF generation
"reportlab>=4.4.9",
# Configuration
"pydantic>=2.10.5",
"pydantic-settings>=2.12.0",
"python-decouple>=3.8",
"python-dotenv>=1.0.1",
# Utilities
"loguru>=0.7.3",
"python-dateutil>=2.9.0.post0",
"python-slugify>=8.0.4",
"pytz>=2025.2",
"itsdangerous>=2.2.0",
"typing-inspect>=0.9.0",
"uvicorn>=0.34.0",
# Serialization
"simplejson>=3.20.2",
"xmljson>=0.2.1",
"xmltodict>=0.14.2",
"xmltodict>=1.0.2",
# Windows-specific dependencies (mark as platform-specific)
"pywin32>=311 ; sys_platform == 'win32'",
"win32-setctime>=1.2.0 ; sys_platform == 'win32'",
]
[dependency-groups]
@ -125,3 +163,10 @@ dev = [
"pre-commit>=4.5.1",
"ruff>=0.14.14",
]
test = [
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=7.0.0",
"httpx>=0.28.1", # For TestClient
]

824
uv.lock generated

File diff suppressed because it is too large Load Diff