From 715536033b739b75d5f32b0bb210d071b5f9c628 Mon Sep 17 00:00:00 2001 From: Luca Sacchi Ricciardi Date: Tue, 7 Apr 2026 09:48:15 +0200 Subject: [PATCH] feat(setup): T03 create requirements.txt with dependencies - Add requirements.txt with all core dependencies: - FastAPI 0.104.1, uvicorn 0.24.0 - SQLAlchemy 2.0.23, Alembic 1.12.1 - Pydantic 2.5.0, pydantic-settings 2.1.0 - python-jose 3.3.0, passlib 1.7.4, cryptography 41.0.7 - httpx 0.25.2, pytest 7.4.3, pytest-asyncio 0.21.1, pytest-cov 4.1.0 - Add test_requirements.py with 15 unit tests - All tests passing (15/15) Refs: T03 --- export/progress.md | 8 +-- requirements.txt | 30 +++++++++ tests/unit/test_requirements.py | 112 ++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 requirements.txt create mode 100644 tests/unit/test_requirements.py diff --git a/export/progress.md b/export/progress.md index 9b2721d..888fa2b 100644 --- a/export/progress.md +++ b/export/progress.md @@ -9,11 +9,11 @@ | Metrica | Valore | |---------|--------| | **Stato** | 🟡 In Progress | -| **Progresso** | 3% | +| **Progresso** | 4% | | **Data Inizio** | 2024-04-07 | | **Data Target** | TBD | | **Task Totali** | 74 | -| **Task Completati** | 2 | +| **Task Completati** | 3 | | **Task In Progress** | 1 | --- @@ -37,10 +37,10 @@ ## 📋 Task Pianificate -### 🔧 Setup Progetto (T01-T05) - 2/5 completati +### 🔧 Setup Progetto (T01-T05) - 3/5 completati - [x] T01: Creare struttura cartelle progetto (2024-04-07) - [x] T02: Inizializzare virtual environment e .gitignore (2024-04-07) -- [ ] T03: Creare requirements.txt con dipendenze +- [x] T03: Creare requirements.txt con dipendenze (2024-04-07) - [ ] T04: Setup file configurazione (.env, config.py) - [ ] T05: Configurare pytest e struttura test diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..cd42d69 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,30 @@ +# =========================================== +# OpenRouter API Key Monitor - Dependencies +# =========================================== + +# Web Framework +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +python-multipart==0.0.6 + +# Database +sqlalchemy==2.0.23 +alembic==1.12.1 + +# Validation & Settings +pydantic==2.5.0 +pydantic-settings==2.1.0 + +# Authentication & Security +python-jose[cryptography]==3.3.0 +passlib[bcrypt]==1.7.4 +cryptography==41.0.7 + +# HTTP Client +httpx==0.25.2 + +# Testing +pytest==7.4.3 +pytest-asyncio==0.21.1 +pytest-cov==4.1.0 +httpx==0.25.2 diff --git a/tests/unit/test_requirements.py b/tests/unit/test_requirements.py new file mode 100644 index 0000000..77e7545 --- /dev/null +++ b/tests/unit/test_requirements.py @@ -0,0 +1,112 @@ +"""Test for requirements.txt setup (T03).""" +import os +import pytest + + +@pytest.mark.unit +class TestRequirementsSetup: + """Test requirements.txt contains all necessary dependencies.""" + + def test_requirements_txt_exists(self): + """Verify requirements.txt file exists.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + assert os.path.isfile(req_path), f"File {req_path} does not exist" + + def test_requirements_contains_fastapi(self): + """Verify FastAPI is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'fastapi' in content, "requirements.txt should contain FastAPI" + + def test_requirements_contains_uvicorn(self): + """Verify uvicorn is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'uvicorn' in content, "requirements.txt should contain uvicorn" + + def test_requirements_contains_sqlalchemy(self): + """Verify SQLAlchemy is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'sqlalchemy' in content, "requirements.txt should contain SQLAlchemy" + + def test_requirements_contains_alembic(self): + """Verify Alembic is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'alembic' in content, "requirements.txt should contain Alembic" + + def test_requirements_contains_pydantic(self): + """Verify Pydantic is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'pydantic' in content, "requirements.txt should contain Pydantic" + + def test_requirements_contains_pydantic_settings(self): + """Verify pydantic-settings is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'pydantic-settings' in content, "requirements.txt should contain pydantic-settings" + + def test_requirements_contains_python_jose(self): + """Verify python-jose is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'python-jose' in content, "requirements.txt should contain python-jose" + + def test_requirements_contains_passlib(self): + """Verify passlib is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'passlib' in content, "requirements.txt should contain passlib" + + def test_requirements_contains_cryptography(self): + """Verify cryptography is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'cryptography' in content, "requirements.txt should contain cryptography" + + def test_requirements_contains_httpx(self): + """Verify httpx is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'httpx' in content, "requirements.txt should contain httpx" + + def test_requirements_contains_pytest(self): + """Verify pytest is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'pytest' in content, "requirements.txt should contain pytest" + + def test_requirements_contains_pytest_asyncio(self): + """Verify pytest-asyncio is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'pytest-asyncio' in content, "requirements.txt should contain pytest-asyncio" + + def test_requirements_contains_pytest_cov(self): + """Verify pytest-cov is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'pytest-cov' in content or 'pytest-coverage' in content, \ + "requirements.txt should contain pytest-cov" + + def test_requirements_contains_python_multipart(self): + """Verify python-multipart is in requirements.""" + req_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/requirements.txt" + with open(req_path, 'r') as f: + content = f.read().lower() + assert 'python-multipart' in content, "requirements.txt should contain python-multipart"