docs: add comprehensive README and project scaffolding

- README completo con istruzioni di installazione, configurazione e utilizzo
- API Swagger/OpenAPI documentata
- File env.example con variabili di configurazione
- Dockerfile multi-stage ottimizzato
- Docker Compose con Ollama e LLM Monitor
- Struttura completa dell'app FastAPI (main.py, config, api routes)
- Servizio client Ollama reusabile
- Dashboard web HTML con TailwindCSS
- Test suite con pytest
- Makefile per comandi comuni
- CONTRIBUTING.md per i contributori
- LICENSE MIT
- .editorconfig e .dockerignore
- requirements.txt e requirements-dev.txt
This commit is contained in:
Luca Sacchi Ricciardi
2026-04-24 19:11:58 +02:00
commit 4b782ffdc8
28 changed files with 2087 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
"""
Test Ollama client service
"""
import pytest
from unittest.mock import patch, MagicMock
from app.services.ollama import OllamaClient
@pytest.fixture
def ollama_client():
"""Create OllamaClient instance"""
return OllamaClient(host="http://localhost:11434", timeout=30)
def test_get_models(ollama_client):
"""Test getting models from Ollama"""
mock_data = {
"models": [
{"name": "llama2", "digest": "abc123", "size": 3825922048},
{"name": "mistral", "digest": "def456", "size": 4096000000}
]
}
with patch("requests.get") as mock_get:
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = mock_data
mock_get.return_value = mock_response
models = ollama_client.get_models()
assert len(models) == 2
assert models[0]["name"] == "llama2"
def test_get_models_error(ollama_client):
"""Test get models when error occurs"""
with patch("requests.get") as mock_get:
mock_get.side_effect = Exception("Connection error")
models = ollama_client.get_models()
assert models == []
def test_get_model(ollama_client):
"""Test getting specific model"""
mock_data = {
"models": [
{"name": "llama2", "digest": "abc123", "size": 3825922048}
]
}
with patch("requests.get") as mock_get:
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = mock_data
mock_get.return_value = mock_response
model = ollama_client.get_model("llama2")
assert model is not None
assert model["name"] == "llama2"
def test_get_nonexistent_model(ollama_client):
"""Test getting nonexistent model"""
mock_data = {"models": []}
with patch("requests.get") as mock_get:
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = mock_data
mock_get.return_value = mock_response
model = ollama_client.get_model("nonexistent")
assert model is None
def test_is_available(ollama_client):
"""Test checking if Ollama is available"""
with patch("requests.get") as mock_get:
mock_response = MagicMock()
mock_response.status_code = 200
mock_get.return_value = mock_response
assert ollama_client.is_available() is True
def test_is_available_offline(ollama_client):
"""Test checking if Ollama is available when offline"""
with patch("requests.get") as mock_get:
mock_get.side_effect = Exception("Connection refused")
assert ollama_client.is_available() is False
def test_pull_model(ollama_client):
"""Test pulling a model"""
with patch("requests.post") as mock_post:
mock_response = MagicMock()
mock_response.status_code = 200
mock_post.return_value = mock_response
result = ollama_client.pull_model("llama2")
assert result is True
def test_pull_model_error(ollama_client):
"""Test pull model when error occurs"""
with patch("requests.post") as mock_post:
mock_post.side_effect = Exception("Error")
result = ollama_client.pull_model("llama2")
assert result is False
def test_delete_model(ollama_client):
"""Test deleting a model"""
with patch("requests.delete") as mock_delete:
mock_response = MagicMock()
mock_response.status_code = 204
mock_delete.return_value = mock_response
result = ollama_client.delete_model("llama2")
assert result is True
def test_delete_model_error(ollama_client):
"""Test delete model when error occurs"""
with patch("requests.delete") as mock_delete:
mock_delete.side_effect = Exception("Error")
result = ollama_client.delete_model("llama2")
assert result is False