From a687b770ef048f587b147b3777fd650bb056c52b Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 11 Aug 2026 17:04:58 +0200 Subject: [PATCH] fix: clear ruff so the pre-push gate passes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 105 findings to zero. Most were mechanical — 67 unused imports, and assorted f-strings without placeholders. Three groups needed a decision. The 15 F821 "undefined name" were forward references, not runtime errors. Each annotation is quoted — `-> "WikiService"`, `Optional["IngestionService"]` — with the real import inside the function body to break an import cycle. A quoted annotation is never evaluated, so the code ran; the names were simply unresolvable to any checker. They now have a TYPE_CHECKING block, which costs nothing at import time and keeps the cycle broken. The 6 E402 split two ways. `import secrets`, `Security`, `Request` and `HTTPBearer` in dependencies.py had drifted below several hundred lines of factory functions for no reason — stdlib and fastapi, no cycle to avoid — and moved up. The other three are deliberate and now say so: the VectorService and GraphService aliases import back into dependencies.py, and main.py's routers expect a configured app, so both must stay put. Bare `except:` narrowed to `except Exception:` in three places, which stops them swallowing KeyboardInterrupt and SystemExit. The 5 unused locals were all genuinely dead. One is worth naming rather than fixing: qdrant_client.delete()'s return value was bound and never read, so a failed delete is indistinguishable from a successful one — the assignment is gone, but nothing checks the status either way and that has not changed here. `timing = {}` in _retrieve_parallel looked like it might mean the reported per-leg timings were always zero; traced, and they come from output["timing"], so the local was only vestigial. 426 passed, 29 skipped, unchanged. The app imports and the service aliases still resolve, which is the check that mattered after moving imports in dependencies.py. The gate still prints "not gated here yet: test (T-56)" — lint is green, tests remain unwired, and that is left visible rather than silently absent. Co-Authored-By: Claude --- src/apis/news.py | 1 - src/clients/neo4j_client.py | 2 +- src/clients/qdrant_client.py | 2 +- src/core/dependencies.py | 34 ++++++++++++++++++-------- src/main.py | 5 ++-- src/models/consolidation.py | 2 +- src/models/graph.py | 1 - src/models/ingestion.py | 2 +- src/models/wiki.py | 1 - src/routers/documents.py | 2 +- src/routers/entity_linking.py | 2 +- src/routers/graph.py | 2 +- src/routers/vector.py | 8 ++---- src/routers/volatile.py | 1 - src/routers/webhooks.py | 10 +++----- src/routers/wiki.py | 4 --- src/services/consolidation_service.py | 13 ++++++++-- src/services/entity_linking_utils.py | 18 +++++++++----- src/services/graph_service.py | 4 +-- src/services/hybrid_rag_service.py | 4 +-- src/services/ingestion_service.py | 3 --- src/services/rag_search_service.py | 1 - src/services/vector_service.py | 5 ++-- src/services/volatile_fetch_service.py | 6 ----- src/services/wiki_change_listener.py | 1 - src/services/wiki_service.py | 10 +++++++- tests/test_consolidation.py | 7 ++---- tests/test_entity_linking.py | 2 +- tests/test_graph_service.py | 4 +-- tests/test_hybrid_rag.py | 14 +++++------ tests/test_ingestion.py | 8 ++---- tests/test_maintenance.py | 6 ++--- tests/test_rag_search.py | 2 +- tests/test_smart_create.py | 2 -- tests/test_volatile.py | 2 +- tests/test_wiki_change_listener.py | 3 +-- 36 files changed, 95 insertions(+), 99 deletions(-) diff --git a/src/apis/news.py b/src/apis/news.py index 9491cf9..ba7e19b 100644 --- a/src/apis/news.py +++ b/src/apis/news.py @@ -8,7 +8,6 @@ Source selection is driven by user preferences in the settings database. import asyncio import logging from datetime import datetime, timezone -from typing import Optional from .base import NewsProvider, NewsItem, NewsFeed from .nos import NOSProvider diff --git a/src/clients/neo4j_client.py b/src/clients/neo4j_client.py index c990148..efe18e5 100644 --- a/src/clients/neo4j_client.py +++ b/src/clients/neo4j_client.py @@ -8,7 +8,7 @@ Provides async Neo4j operations with: - Automatic retry on transient failures """ -from neo4j import AsyncGraphDatabase, AsyncDriver, AsyncSession, READ_ACCESS +from neo4j import AsyncGraphDatabase, AsyncDriver, READ_ACCESS from typing import Optional, List, Dict, Any import logging diff --git a/src/clients/qdrant_client.py b/src/clients/qdrant_client.py index e17e579..d9af6f1 100644 --- a/src/clients/qdrant_client.py +++ b/src/clients/qdrant_client.py @@ -529,7 +529,7 @@ class QdrantClientWrapper: query_filter = Filter(must=conditions) # Delete points - result = await self.client.delete( + await self.client.delete( collection_name=collection_name, points_selector=query_filter ) diff --git a/src/core/dependencies.py b/src/core/dependencies.py index 0103631..7e3a76e 100644 --- a/src/core/dependencies.py +++ b/src/core/dependencies.py @@ -9,12 +9,17 @@ Provides FastAPI dependencies for service clients with: """ from functools import lru_cache -from typing import Annotated +from typing import TYPE_CHECKING, Annotated from fastapi import Depends, HTTPException, Query import logging import redis.asyncio as aioredis +import secrets + +from fastapi import Request, Security +from fastapi.security import HTTPBearer + from src.config import Settings, get_settings from src.clients.neo4j_client import Neo4jClient from src.clients.qdrant_client import QdrantClientWrapper @@ -764,11 +769,6 @@ def get_volatile_cache_service() -> "VolatileCacheService": ) -# Authentication -import secrets -from fastapi import Security, HTTPException, Request -from fastapi.security import HTTPBearer - security = HTTPBearer() @@ -833,10 +833,24 @@ async def verify_browser_request( raise HTTPException(status_code=401, detail="Unauthenticated") -# Service type aliases for FastAPI endpoint dependencies -# These are defined after the factory functions -from src.services.vector_service import VectorService -from src.services.graph_service import GraphService +# Service type aliases for FastAPI endpoint dependencies. +# Deliberately imported here rather than at the top: these modules import back +# into this one, so a module-level import would cycle. The factory functions +# above must exist before they are pulled in. +from src.services.vector_service import VectorService # noqa: E402 +from src.services.graph_service import GraphService # noqa: E402 + +# Imported for annotations only. The real imports live inside the functions +# that use them, to break an import cycle; a quoted annotation is never +# evaluated at runtime, so the names were unresolvable to any checker. This +# block costs nothing at import time and makes them resolvable again. +if TYPE_CHECKING: + from src.services.consolidation_service import ConsolidationService + from src.services.hybrid_rag_service import HybridRAGService + from src.services.ingestion_service import IngestionService + from src.services.rag_search_service import RAGSearchService + from src.services.volatile_service import VolatileCacheService + from src.services.wiki_service import WikiService VectorServiceDep = Annotated[VectorService, Depends(get_vector_service)] GraphServiceDep = Annotated[GraphService, Depends(get_graph_service)] diff --git a/src/main.py b/src/main.py index 67a1826..17f7ad9 100644 --- a/src/main.py +++ b/src/main.py @@ -55,8 +55,9 @@ app.add_middleware( allow_headers=["*"], ) -# Register routers -from src.routers import ( +# Register routers. Imported after the app and middleware exist, because the +# routers import dependencies that expect a configured app. +from src.routers import ( # noqa: E402 wiki, tools, graph, vector, hybrid_rag, consolidation, ingestion, entity_linking, webhooks, rag_search, content, maintenance, volatile, documents diff --git a/src/models/consolidation.py b/src/models/consolidation.py index b18a0f9..1ccf5b9 100644 --- a/src/models/consolidation.py +++ b/src/models/consolidation.py @@ -5,7 +5,7 @@ Used by the consolidation endpoint to process SearchQuery nodes and consolidate knowledge into wiki pages. """ from pydantic import BaseModel, Field -from typing import List, Optional, Dict, Any +from typing import List, Optional class ConsolidationRequest(BaseModel): diff --git a/src/models/graph.py b/src/models/graph.py index 6503a6d..84d46b0 100644 --- a/src/models/graph.py +++ b/src/models/graph.py @@ -6,7 +6,6 @@ Provides models for knowledge graph nodes, relationships, and queries. from pydantic import BaseModel, Field from typing import List, Dict, Any, Optional -from datetime import datetime from src.core.multi_tenancy import RequiredUser diff --git a/src/models/ingestion.py b/src/models/ingestion.py index 7445a3e..3c62bbd 100644 --- a/src/models/ingestion.py +++ b/src/models/ingestion.py @@ -2,7 +2,7 @@ Pydantic models for Document Ingestion system. """ from pydantic import BaseModel, Field -from typing import Optional, List, Dict, Any +from typing import Optional, List from datetime import datetime from src.core.multi_tenancy import RequiredUser diff --git a/src/models/wiki.py b/src/models/wiki.py index 7ff0468..6ff22c7 100644 --- a/src/models/wiki.py +++ b/src/models/wiki.py @@ -9,7 +9,6 @@ Models for: from pydantic import BaseModel, Field, field_validator from typing import Optional, List, Dict, Any -from datetime import datetime from src.core.multi_tenancy import RequiredUser diff --git a/src/routers/documents.py b/src/routers/documents.py index f733be4..28ac2dc 100644 --- a/src/routers/documents.py +++ b/src/routers/documents.py @@ -140,7 +140,7 @@ async def capture_webhook(request: Request): # Try to parse as JSON try: capture["body_json"] = json.loads(body) - except: + except Exception: capture["body_json"] = None # Write to file diff --git a/src/routers/entity_linking.py b/src/routers/entity_linking.py index 1156776..bd0cd90 100644 --- a/src/routers/entity_linking.py +++ b/src/routers/entity_linking.py @@ -9,7 +9,7 @@ Creates both: import logging from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel -from typing import List, Dict, Any, Optional, Tuple +from typing import List, Dict, Any, Tuple import re from src.config import get_settings diff --git a/src/routers/graph.py b/src/routers/graph.py index 08a4d7e..afdbc7a 100644 --- a/src/routers/graph.py +++ b/src/routers/graph.py @@ -10,7 +10,7 @@ import logging from src.models.graph import ( CypherQueryRequest, CypherQueryResponse, - UpdateFromPageRequest, GraphUpdateSummary, + GraphUpdateSummary, NodeListResponse, GraphNodeDetail, MindMapResponse ) diff --git a/src/routers/vector.py b/src/routers/vector.py index 2083538..3c20a51 100644 --- a/src/routers/vector.py +++ b/src/routers/vector.py @@ -5,19 +5,15 @@ Endpoints for semantic search and vector operations. """ from fastapi import APIRouter, HTTPException, Depends, Query -from typing import Optional import logging from src.models.vector import ( SearchRequest, SearchResponse, - VectorUpdateRequest, VectorUpdateSummary, + VectorUpdateSummary, CollectionListResponse, - DeletePageChunksRequest, DeletePageChunksResponse + DeletePageChunksResponse ) from src.services.vector_service import VectorService -from src.clients.qdrant_client import QdrantClientWrapper -from src.clients.wikijs_client import WikiJSClient -from src.clients.ollama_client import OllamaClient from src.core.dependencies import ( QdrantDep, WikiJSDep, OllamaDep, verify_api_key, RequiredUserQuery ) diff --git a/src/routers/volatile.py b/src/routers/volatile.py index be0e93f..d2cf4e9 100644 --- a/src/routers/volatile.py +++ b/src/routers/volatile.py @@ -11,7 +11,6 @@ import logging from src.models.volatile import ( VolatileRecordCreate, VolatileRecordResponse, - VolatileListResponse, VolatileScheduledResponse, VolatileStatsResponse, VolatileDeleteResponse, diff --git a/src/routers/webhooks.py b/src/routers/webhooks.py index 4c4c67e..ff07c93 100644 --- a/src/routers/webhooks.py +++ b/src/routers/webhooks.py @@ -5,14 +5,12 @@ Receives webhook events from Wiki.js for page CRUD operations and processes them identically to AI-generated content. """ import logging -from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks +from fastapi import APIRouter, Depends, BackgroundTasks from pydantic import BaseModel from typing import Optional, Literal from src.core.dependencies import ( get_ingestion_service, - get_wiki_service, - get_graph_service, verify_api_key ) from src.services.ingestion_service import IngestionService @@ -373,7 +371,7 @@ async def process_page_rename( logger.error(f"Failed to apply entity linking: {e}") elif path_changed: - logger.info(f"Path changed only (move), no re-processing needed") + logger.info("Path changed only (move), no re-processing needed") logger.info(f"Rename processing complete for page {page_id}") @@ -470,9 +468,9 @@ async def cleanup_deleted_page( logger.error(f"Failed to delete orphaned entity {entity_name}: {e}") # STEP 5: Clean up broken SearchQuery relationships - cleanup_search_query = f""" + cleanup_search_query = """ MATCH (sq:SearchQuery)-[r:FOUND]->(d:Document) - WHERE NOT EXISTS {{(d)}} + WHERE NOT EXISTS {(d)} DELETE r RETURN count(r) as cleaned_count """ diff --git a/src/routers/wiki.py b/src/routers/wiki.py index 4167e53..98b0def 100644 --- a/src/routers/wiki.py +++ b/src/routers/wiki.py @@ -18,10 +18,6 @@ from src.models.wiki import ( from src.services.wiki_service import WikiService from src.services.graph_service import GraphService from src.services.vector_service import VectorService -from src.clients.wikijs_client import WikiJSClient -from src.clients.neo4j_client import Neo4jClient -from src.clients.qdrant_client import QdrantClientWrapper -from src.clients.ollama_client import OllamaClient from src.core.dependencies import ( WikiJSDep, Neo4jDep, QdrantDep, OllamaDep, verify_api_key, get_settings, get_hybrid_rag_service, get_ingestion_service, diff --git a/src/services/consolidation_service.py b/src/services/consolidation_service.py index bad8d44..e6a021c 100644 --- a/src/services/consolidation_service.py +++ b/src/services/consolidation_service.py @@ -15,14 +15,13 @@ import logging import json import time from datetime import datetime, timedelta, timezone -from typing import List, Dict, Any, Optional +from typing import TYPE_CHECKING, List, Dict, Any, Optional from src.clients.neo4j_client import Neo4jClient from src.clients.ollama_client import OllamaClient from src.clients.wikijs_client import WikiJSClient from src.services.wiki_page_writer import WikiPageWriter from src.models.consolidation import ( - SearchQueryInfo, ConsolidationResult, ConsolidationResponse, MemoryRouteClassification, @@ -30,6 +29,16 @@ from src.models.consolidation import ( ) from src.config import Settings +# Imported for annotations only. The real imports live inside the functions +# that use them, to break an import cycle; a quoted annotation is never +# evaluated at runtime, so the names were unresolvable to any checker. This +# block costs nothing at import time and makes them resolvable again. +if TYPE_CHECKING: + from src.clients.scheduler_client import SchedulerClient + from src.clients.settings_client import SettingsClient + from src.services.ingestion_service import IngestionService + from src.services.volatile_service import VolatileCacheService + logger = logging.getLogger(__name__) diff --git a/src/services/entity_linking_utils.py b/src/services/entity_linking_utils.py index b29c149..394f1bf 100644 --- a/src/services/entity_linking_utils.py +++ b/src/services/entity_linking_utils.py @@ -7,10 +7,19 @@ Provides bidirectional entity linking functionality that can be used by: - Any other service that creates wiki pages """ import logging -from typing import Dict, Any, Optional +from typing import TYPE_CHECKING, Dict, Optional from src.core.multi_tenancy import get_neo4j_user_base_label +# Imported for annotations only. The real imports live inside the functions +# that use them, to break an import cycle; a quoted annotation is never +# evaluated at runtime, so the names were unresolvable to any checker. This +# block costs nothing at import time and makes them resolvable again. +if TYPE_CHECKING: + from src.clients.neo4j_client import Neo4jClient + from src.services.ingestion_service import IngestionService + from src.services.wiki_service import WikiService + logger = logging.getLogger(__name__) @@ -49,12 +58,9 @@ async def apply_bidirectional_entity_linking( """ from src.routers.entity_linking import ( link_entities_in_page, - EntityLinkingRequest, - get_entities_with_paths, - add_entity_links_to_content + EntityLinkingRequest ) - from src.core.dependencies import get_graph_service, get_wiki_service, get_ingestion_service - from src.models.wiki import WikiPageUpdate + from src.core.dependencies import get_graph_service, get_ingestion_service forward_links = 0 backward_links = 0 diff --git a/src/services/graph_service.py b/src/services/graph_service.py index 2546a6c..89e7627 100644 --- a/src/services/graph_service.py +++ b/src/services/graph_service.py @@ -879,7 +879,7 @@ Feel free to expand it with more details! { "name": r["name"], # Get the entity type label (not the user label) - "type": [l for l in r["labels"] if l not in [user_base_label, "Document"]][0] + "type": [line for line in r["labels"] if line not in [user_base_label, "Document"]][0] if r["labels"] else "Entity", "path": r.get("path") # Include path if it exists (for entity stub pages) } @@ -1524,7 +1524,7 @@ Feel free to expand it with more details! for r in results: labels = r.get("labels", []) entity_type = next( - (l for l in labels if l != user_base_label), + (line for line in labels if line != user_base_label), "Unknown" ) orphans.append({ diff --git a/src/services/hybrid_rag_service.py b/src/services/hybrid_rag_service.py index 4f6f057..49023bd 100644 --- a/src/services/hybrid_rag_service.py +++ b/src/services/hybrid_rag_service.py @@ -26,7 +26,7 @@ from src.clients.ollama_client import OllamaClient from src.clients.content_extractor import ContentExtractor from src.config import Settings from src.models.hybrid_rag import ( - HybridRAGConfig, HybridRAGRequest, HybridRAGResponse, + HybridRAGConfig, HybridRAGResponse, HybridRAGResult, TimingBreakdown, KeywordExtraction, RelatedDossier ) @@ -123,7 +123,6 @@ class HybridRAGService: timing["query_enhancement_ms"] = (time.time() - phase0_start) * 1000 # Phase 1: Parallel Retrieval - phase1_start = time.time() raw_results = await self._retrieve_parallel(query, user, config, keywords_data) timing["vector_ms"] = raw_results.get("timing", {}).get("vector_ms", 0) timing["graph_ms"] = raw_results.get("timing", {}).get("graph_ms", 0) @@ -357,7 +356,6 @@ JSON:""" "source_status" ('ok', 'failed', or 'disabled') """ tasks = {} - timing = {} # Vector search if config.enable_vector: diff --git a/src/services/ingestion_service.py b/src/services/ingestion_service.py index bc51cc3..02eb574 100644 --- a/src/services/ingestion_service.py +++ b/src/services/ingestion_service.py @@ -14,16 +14,13 @@ This service is called by: import logging import asyncio from typing import List, Optional -from datetime import datetime import time from src.services.vector_service import VectorService from src.services.graph_service import GraphService from src.clients.wikijs_client import WikiJSClient from src.models.ingestion import ( - IngestionRequest, IngestionResult, - BatchIngestionRequest, BatchIngestionResult ) diff --git a/src/services/rag_search_service.py b/src/services/rag_search_service.py index 4d8dc98..7412c77 100644 --- a/src/services/rag_search_service.py +++ b/src/services/rag_search_service.py @@ -21,7 +21,6 @@ from src.clients.content_extractor import ContentExtractor from src.config import Settings from src.models.rag_search import ( SearchType, - RAGSearchRequest, RAGSearchResult, RAGSearchResponse, ) diff --git a/src/services/vector_service.py b/src/services/vector_service.py index 6d55184..f6f91a9 100644 --- a/src/services/vector_service.py +++ b/src/services/vector_service.py @@ -6,9 +6,8 @@ Handles semantic search, document chunking, and embeddings. import re import time -import hashlib import uuid -from typing import List, Dict, Any, Optional +from typing import List, Dict, Any import logging from src.clients.qdrant_client import QdrantClientWrapper @@ -17,7 +16,7 @@ from src.clients.ollama_client import OllamaClient from src.core.multi_tenancy import get_qdrant_collection_name, is_path_in_user_namespace from src.models.vector import ( SearchResult, SearchResponse, VectorUpdateSummary, - DocumentChunk, CollectionInfo, CollectionListResponse + CollectionInfo, CollectionListResponse ) logger = logging.getLogger(__name__) diff --git a/src/services/volatile_fetch_service.py b/src/services/volatile_fetch_service.py index 32085d5..b35e8aa 100644 --- a/src/services/volatile_fetch_service.py +++ b/src/services/volatile_fetch_service.py @@ -14,12 +14,6 @@ from src.apis import ( OpenMeteoProvider, AggregatedNewsProvider, AlphaVantageProvider, - CurrentWeather, - WeatherForecast, - SunTimes, - AirQuality, - NewsFeed, - StockQuote, ) from src.services.volatile_service import VolatileCacheService from src.models.volatile import VolatileRecordResponse, VolatileNamespace diff --git a/src/services/wiki_change_listener.py b/src/services/wiki_change_listener.py index 2382712..8546038 100644 --- a/src/services/wiki_change_listener.py +++ b/src/services/wiki_change_listener.py @@ -14,7 +14,6 @@ from datetime import datetime from src.config import get_settings from src.core.dependencies import get_ingestion_service -from src.services.consolidation_service import ConsolidationService logger = logging.getLogger(__name__) diff --git a/src/services/wiki_service.py b/src/services/wiki_service.py index 98b3bb1..16bc5a0 100644 --- a/src/services/wiki_service.py +++ b/src/services/wiki_service.py @@ -8,7 +8,7 @@ Handles business logic for wiki operations with: - Search functionality """ -from typing import List, Optional, Dict, Any +from typing import TYPE_CHECKING, List, Optional, Dict, Any import logging from src.clients.wikijs_client import WikiJSClient @@ -19,6 +19,14 @@ from src.models.wiki import ( DossierInfo, DossierList ) +# Imported for annotations only. The real imports live inside the functions +# that use them, to break an import cycle; a quoted annotation is never +# evaluated at runtime, so the names were unresolvable to any checker. This +# block costs nothing at import time and makes them resolvable again. +if TYPE_CHECKING: + from src.services.hybrid_rag_service import HybridRAGService + from src.services.wiki_page_writer import WikiPageWriter + logger = logging.getLogger(__name__) diff --git a/tests/test_consolidation.py b/tests/test_consolidation.py index a20d0fa..fabbb79 100644 --- a/tests/test_consolidation.py +++ b/tests/test_consolidation.py @@ -12,9 +12,7 @@ Run with: pytest tests/test_consolidation.py -v -s """ import pytest -import pytest_asyncio -from unittest.mock import AsyncMock, MagicMock, patch -from typing import AsyncGenerator +from unittest.mock import AsyncMock, MagicMock from datetime import datetime import json @@ -22,8 +20,7 @@ from src.services.consolidation_service import ConsolidationService from src.models.consolidation import ( ConsolidationRequest, ConsolidationResponse, - ConsolidationResult, - SearchQueryInfo + ConsolidationResult ) # Test constants diff --git a/tests/test_entity_linking.py b/tests/test_entity_linking.py index b620180..406c646 100644 --- a/tests/test_entity_linking.py +++ b/tests/test_entity_linking.py @@ -480,4 +480,4 @@ async def test_cleanup_entity_linking_test_data(neo4j_client): """ await neo4j_client.execute_query(cleanup_query) - print(f"\n✓ Cleaned up entity linking test data") + print("\n✓ Cleaned up entity linking test data") diff --git a/tests/test_graph_service.py b/tests/test_graph_service.py index a19f8fe..a38373e 100644 --- a/tests/test_graph_service.py +++ b/tests/test_graph_service.py @@ -10,9 +10,7 @@ Run with: pytest tests/test_graph_service.py -v -s """ import pytest -import pytest_asyncio -from unittest.mock import AsyncMock, MagicMock, patch -from typing import AsyncGenerator +from unittest.mock import AsyncMock from src.services.graph_service import GraphService diff --git a/tests/test_hybrid_rag.py b/tests/test_hybrid_rag.py index da46f54..5f6eb5f 100644 --- a/tests/test_hybrid_rag.py +++ b/tests/test_hybrid_rag.py @@ -29,7 +29,7 @@ from src.clients.content_extractor import ContentExtractor from src.services.hybrid_rag_service import HybridRAGService from src.services.vector_service import VectorService from src.services.graph_service import GraphService -from src.models.hybrid_rag import HybridRAGConfig, HybridRAGRequest +from src.models.hybrid_rag import HybridRAGConfig from src.config import get_settings # Test user to isolate test data @@ -176,7 +176,7 @@ We deploy microservices using Helm charts and manage them with kubectl. # Cleanup try: await wiki_client.delete_page(page["id"]) - except: + except Exception: pass except Exception as e: pytest.skip(f"Could not create test page: {e}") @@ -531,7 +531,7 @@ class TestPhase6_Persistence: result = await neo4j_client.execute_query(query, {"search_id": search_id}) assert len(result) == 1 assert result[0]["query"] == "test query" - assert result[0]["processed"] == False + assert not result[0]["processed"] # Cleanup cleanup_query = f""" @@ -614,7 +614,7 @@ class TestHybridRAG_EndToEnd: assert len(response.context) > 0 # Log results for inspection - print(f"\n=== HybridRAG E2E Test Results ===") + print("\n=== HybridRAG E2E Test Results ===") print(f"Query: {response.query}") print(f"Total Results: {response.total_results}") print(f"Source Counts: {response.source_counts}") @@ -623,7 +623,7 @@ class TestHybridRAG_EndToEnd: print(f"Search ID: {response.search_id}") if response.results: - print(f"\nTop Result:") + print("\nTop Result:") top = response.results[0] print(f" Title: {top.title}") print(f" Source: {top.source_type}") @@ -674,7 +674,7 @@ class TestHybridRAG_EndToEnd: config = HybridRAGConfig() start = time.time() - response = await hybrid_rag_service.search( + await hybrid_rag_service.search( query="kubernetes orchestration", user=TEST_USER, config=config @@ -722,7 +722,7 @@ async def test_cleanup_test_data(neo4j_client, qdrant_client): collection_name = get_qdrant_collection_name(TEST_USER) try: await qdrant_client.delete_collection(collection_name) - except: + except Exception: pass print(f"\n✓ Cleaned up test data for user: {TEST_USER}") diff --git a/tests/test_ingestion.py b/tests/test_ingestion.py index d70f1b3..884c20c 100644 --- a/tests/test_ingestion.py +++ b/tests/test_ingestion.py @@ -11,16 +11,12 @@ Run with: pytest tests/test_ingestion.py -v -s """ import pytest -import pytest_asyncio -from unittest.mock import AsyncMock, MagicMock, patch -from typing import AsyncGenerator +from unittest.mock import AsyncMock, MagicMock from src.services.ingestion_service import IngestionService from src.models.ingestion import ( IngestionRequest, - IngestionResult, - BatchIngestionRequest, - BatchIngestionResult + BatchIngestionRequest ) diff --git a/tests/test_maintenance.py b/tests/test_maintenance.py index 95cac07..260ed59 100644 --- a/tests/test_maintenance.py +++ b/tests/test_maintenance.py @@ -8,7 +8,7 @@ Tests cleanup of: """ import pytest -from unittest.mock import AsyncMock, MagicMock, patch +from unittest.mock import AsyncMock, MagicMock from src.routers.maintenance import ( cleanup_vectors, cleanup_graph, @@ -18,9 +18,7 @@ from src.routers.maintenance import ( CleanupResult, VectorCleanupResponse, GraphCleanupResponse, - FullCleanupResponse, - HealthCheckResponse, - ReindexResponse + HealthCheckResponse ) diff --git a/tests/test_rag_search.py b/tests/test_rag_search.py index b70cce6..d2e0ef5 100644 --- a/tests/test_rag_search.py +++ b/tests/test_rag_search.py @@ -1,7 +1,7 @@ """Tests for RAG search service and endpoints.""" import pytest -from unittest.mock import AsyncMock, MagicMock, patch +from unittest.mock import AsyncMock, MagicMock from src.models.rag_search import ( SearchType, diff --git a/tests/test_smart_create.py b/tests/test_smart_create.py index 03cc1c9..56b9637 100644 --- a/tests/test_smart_create.py +++ b/tests/test_smart_create.py @@ -538,8 +538,6 @@ class TestSmartCreateEndpoint: @pytest.mark.asyncio async def test_endpoint_returns_201(self, mock_clients): """Test that successful creation returns 201 status.""" - from fastapi.testclient import TestClient - from unittest.mock import patch # This test would require more setup with FastAPI TestClient # For now, we test the model validation diff --git a/tests/test_volatile.py b/tests/test_volatile.py index 3162d11..7f9bb0e 100644 --- a/tests/test_volatile.py +++ b/tests/test_volatile.py @@ -539,7 +539,7 @@ class TestVolatileCleanupEndpoint: @pytest.mark.asyncio async def test_cleanup_volatile(self): """Test volatile cleanup endpoint.""" - from src.routers.maintenance import cleanup_volatile, VolatileCleanupResponse + from src.routers.maintenance import cleanup_volatile mock_qdrant = AsyncMock() mock_qdrant.get_volatile_collections = AsyncMock(return_value=[ diff --git a/tests/test_wiki_change_listener.py b/tests/test_wiki_change_listener.py index 669f062..3568812 100644 --- a/tests/test_wiki_change_listener.py +++ b/tests/test_wiki_change_listener.py @@ -10,7 +10,6 @@ Tests the PostgreSQL NOTIFY/LISTEN change detection system including: """ import pytest -import asyncio from unittest.mock import AsyncMock, MagicMock, patch from datetime import datetime, timedelta @@ -238,7 +237,7 @@ class TestWikiChangeListener: async def test_process_page_delete_calls_cleanup(self, listener): """Test that DELETE events call cleanup_deleted_page.""" with patch('src.routers.webhooks.cleanup_deleted_page', new_callable=AsyncMock) as mock_cleanup, \ - patch('src.services.wiki_change_listener.get_ingestion_service') as mock_service: + patch('src.services.wiki_change_listener.get_ingestion_service'): await listener._process_page_change( page_id=123,