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,