F401 `app.dataset.load_documents` imported but unused; consider removing, adding to `__all__`, or using a redundant alias --> app\__init__.py:1:25 | 1 | from app.dataset import load_documents | ^^^^^^^^^^^^^^ 2 | from app.cache import SemanticCache | help: Use an explicit re-export: `load_documents as load_documents` F401 `app.cache.SemanticCache` imported but unused; consider removing, adding to `__all__`, or using a redundant alias --> app\__init__.py:2:23 | 1 | from app.dataset import load_documents 2 | from app.cache import SemanticCache | ^^^^^^^^^^^^^ | help: Use an explicit re-export: `SemanticCache as SemanticCache` E402 Module level import not at top of file --> app\api.py:13:1 | 11 | # ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ 12 | 13 | from app.rate_limit import limiter | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 14 | from app.logger import get_logger 15 | import time | E402 Module level import not at top of file --> app\api.py:14:1 | 13 | from app.rate_limit import limiter 14 | from app.logger import get_logger | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 15 | import time 16 | from app.analytics import log_query, get_analytics_stats | E402 Module level import not at top of file --> app\api.py:15:1 | 13 | from app.rate_limit import limiter 14 | from app.logger import get_logger 15 | import time | ^^^^^^^^^^^ 16 | from app.analytics import log_query, get_analytics_stats | E402 Module level import not at top of file --> app\api.py:16:1 | 14 | from app.logger import get_logger 15 | import time 16 | from app.analytics import log_query, get_analytics_stats | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 17 | 18 | logger = get_logger("api") | E402 Module level import not at top of file --> app\api.py:133:1 | 131 | # Endpoints 132 | # ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ 133 | from app.auth import require_role, Role | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 134 | 135 | @router.post("/query", response_model=QueryResponse, dependencies=[Depends(require_role(Role.USER))]) | F811 Redefinition of unused `store` from line 274 --> app\cache.py:305:9 | 303 | The newly created CacheEntry 304 | """ 305 | def store(self, query: str, embedding: np.ndarray, result: str, | ^^^^^ `store` redefined here 306 | dominant_cluster: int, cluster_probs: np.ndarray | None = None, 307 | generated_answer: str | None = None, | ::: app\cache.py:274:9 | 272 | # ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ 273 | 274 | def store( | ----- previous definition of `store` here 275 | self, 276 | query: str, | help: Remove definition: `store` E402 Module level import not at top of file --> app\main.py:10:1 | 8 | load_dotenv() 9 | 10 | from app.api import router | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 11 | from app.dataset import load_documents 12 | from app.embeddings import get_model, embed_documents, save_embeddings, load_embeddings | E402 Module level import not at top of file --> app\main.py:11:1 | 10 | from app.api import router 11 | from app.dataset import load_documents | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | from app.embeddings import get_model, embed_documents, save_embeddings, load_embeddings 13 | from app.vector_store import build_index, save_index, load_index | E402 Module level import not at top of file --> app\main.py:12:1 | 10 | from app.api import router 11 | from app.dataset import load_documents 12 | from app.embeddings import get_model, embed_documents, save_embeddings, load_embeddings | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 13 | from app.vector_store import build_index, save_index, load_index 14 | from app.clustering import ( | E402 Module level import not at top of file --> app\main.py:13:1 | 11 | from app.dataset import load_documents 12 | from app.embeddings import get_model, embed_documents, save_embeddings, load_embeddings 13 | from app.vector_store import build_index, save_index, load_index | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 14 | from app.clustering import ( 15 | reduce_dimensions, fit_gmm, get_cluster_distributions, | E402 Module level import not at top of file --> app\main.py:14:1 | 12 | from app.embeddings import get_model, embed_documents, save_embeddings, load_embeddings 13 | from app.vector_store import build_index, save_index, load_index 14 | / from app.clustering import ( 15 | | reduce_dimensions, fit_gmm, get_cluster_distributions, 16 | | get_dominant_cluster, save_clustering, load_clustering, 17 | | analyze_clusters 18 | | ) | |_^ 19 | from app.cache import SemanticCache 20 | from app.hybrid_search import BM25Index, HybridSearcher, save_bm25, load_bm25 | E402 Module level import not at top of file --> app\main.py:19:1 | 17 | analyze_clusters 18 | ) 19 | from app.cache import SemanticCache | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 20 | from app.hybrid_search import BM25Index, HybridSearcher, save_bm25, load_bm25 21 | from app.logger import setup_logging, get_logger | E402 Module level import not at top of file --> app\main.py:20:1 | 18 | ) 19 | from app.cache import SemanticCache 20 | from app.hybrid_search import BM25Index, HybridSearcher, save_bm25, load_bm25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 21 | from app.logger import setup_logging, get_logger 22 | from app.rate_limit import setup_rate_limiting | E402 Module level import not at top of file --> app\main.py:21:1 | 19 | from app.cache import SemanticCache 20 | from app.hybrid_search import BM25Index, HybridSearcher, save_bm25, load_bm25 21 | from app.logger import setup_logging, get_logger | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 22 | from app.rate_limit import setup_rate_limiting 23 | from app.analytics import init_db | E402 Module level import not at top of file --> app\main.py:22:1 | 20 | from app.hybrid_search import BM25Index, HybridSearcher, save_bm25, load_bm25 21 | from app.logger import setup_logging, get_logger 22 | from app.rate_limit import setup_rate_limiting | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 23 | from app.analytics import init_db | E402 Module level import not at top of file --> app\main.py:23:1 | 21 | from app.logger import setup_logging, get_logger 22 | from app.rate_limit import setup_rate_limiting 23 | from app.analytics import init_db | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 24 | 25 | # Setup structured logging | E402 Module level import not at top of file --> app\main.py:112:1 | 110 | # ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ 111 | 112 | from fastapi.middleware.cors import CORSMiddleware | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 113 | 114 | app = FastAPI( | E701 Multiple statements on one line (colon) --> experiments\benchmark_expansion.py:113:24 | 111 | pool = set() 112 | for idx in dense_indices: 113 | if idx >= 0: pool.add(int(idx)) | ^ 114 | for idx in bm25_indices: 115 | if idx >= 0: pool.add(int(idx)) | E701 Multiple statements on one line (colon) --> experiments\benchmark_expansion.py:115:24 | 113 | if idx >= 0: pool.add(int(idx)) 114 | for idx in bm25_indices: 115 | if idx >= 0: pool.add(int(idx)) | ^ 116 | for idx in hybrid_indices: 117 | if idx >= 0: pool.add(int(idx)) | E701 Multiple statements on one line (colon) --> experiments\benchmark_expansion.py:117:24 | 115 | if idx >= 0: pool.add(int(idx)) 116 | for idx in hybrid_indices: 117 | if idx >= 0: pool.add(int(idx)) | ^ 118 | 119 | candidates_to_judge = [doc_id for doc_id in pool if doc_id != baseline_id] | E701 Multiple statements on one line (colon) --> experiments\chunking_comparison.py:89:50 | 87 | q_text = item["query"] 88 | expected_cat_name = item["category"] 89 | if expected_cat_name not in cat_to_id: continue | ^ 90 | 91 | expected_cat_id = cat_to_id[expected_cat_name] | E701 Multiple statements on one line (colon) --> experiments\chunking_comparison.py:94:33 | 92 | # Ground truth is documents that match the category 93 | relevant_docs = [i for i, lbl in enumerate(labels) if lbl == expected_cat_id] 94 | if not relevant_docs: continue | ^ 95 | 96 | q_emb = model.encode([q_text], convert_to_numpy=True, normalize_embeddings=True)[0] | E701 Multiple statements on one line (colon) --> experiments\chunking_comparison.py:104:33 | 102 | seen = set() 103 | for chunk_idx in retrieved_chunk_indices: 104 | if chunk_idx < 0: continue | ^ 105 | doc_idx = chunk_to_doc[int(chunk_idx)] 106 | if doc_idx not in seen: | F841 Local variable `cat_to_id` is assigned to but never used --> experiments\error_analysis.py:57:5 | 55 | error_report = [] 56 | 57 | cat_to_id = {name: i for i, name in enumerate(label_names)} | ^^^^^^^^^ 58 | for item in benchmark_queries: 59 | q_text = item["query"] | help: Remove assignment to unused variable `cat_to_id` F821 Undefined name `expected_cat_name` --> experiments\error_analysis.py:105:51 | 103 | reason = "Reranker pushed irrelevant documents above the relevant ones found by hybrid." 104 | elif not hybrid_hit and not reranked_hit: 105 | if set(retrieved_cats_hybrid) == set([expected_cat_name]): | ^^^^^^^^^^^^^^^^^ 106 | failure_type = "DATASET_LABEL_ISSUE" 107 | reason = "Retrieved documents look perfectly relevant but ground truth labels don't match." | F821 Undefined name `expected_cat_name` --> experiments\error_analysis.py:110:32 | 108 | else: 109 | # Check if the query is ambiguous between two categories 110 | if "cs.LG" in expected_cat_name and any("cs." in c for c in retrieved_cats_hybrid): | ^^^^^^^^^^^^^^^^^ 111 | failure_type = "BOUNDARY_CASE" 112 | reason = f"Query is ambiguous between {expected_cat_name} and {set(retrieved_cats_hybrid)}." | F821 Undefined name `expected_cat_name` --> experiments\error_analysis.py:112:61 | 110 | if "cs.LG" in expected_cat_name and any("cs." in c for c in retrieved_cats_hybrid): 111 | failure_type = "BOUNDARY_CASE" 112 | reason = f"Query is ambiguous between {expected_cat_name} and {set(retrieved_cats_hybrid)}." | ^^^^^^^^^^^^^^^^^ 113 | else: 114 | failure_type = "RETRIEVAL_FAILURE" | F821 Undefined name `expected_cat_name` --> experiments\error_analysis.py:119:34 | 117 | error_report.append({ 118 | "query": q_text, 119 | "expected_category": expected_cat_name, | ^^^^^^^^^^^^^^^^^ 120 | "hybrid_retrieved_categories": retrieved_cats_hybrid, 121 | "reranked_retrieved_categories": retrieved_cats_reranked, | E722 Do not use bare `except` --> experiments\evaluate_rag.py:66:5 | 64 | if matches: 65 | return float(matches[0]) 66 | except: | ^^^^^^ 67 | pass 68 | return 0.0 | F841 Local variable `cat_to_id` is assigned to but never used --> experiments\evaluate_search.py:62:5 | 60 | } 61 | 62 | cat_to_id = {name: i for i, name in enumerate(label_names)} | ^^^^^^^^^ 63 | 64 | for item in benchmark_queries: | help: Remove assignment to unused variable `cat_to_id` E701 Multiple statements on one line (colon) --> experiments\kaggle_bge_benchmark.ipynb:cell 3:15:25 | 13 | def mrr(relevant, retrieved): 14 | for rank, d in enumerate(retrieved, 1): 15 | if d in relevant: return 1.0 / rank | ^ 16 | return 0.0 | E701 Multiple statements on one line (colon) --> experiments\kaggle_bge_benchmark.ipynb:cell 3:27:20 | 26 | def recall_at_k(relevant, retrieved, k): 27 | if not relevant: return 0.0 | ^ 28 | hits = len(set(retrieved[:k]).intersection(set(relevant))) 29 | return hits / len(relevant) | E701 Multiple statements on one line (colon) --> experiments\kaggle_bge_benchmark.ipynb:cell 3:32:20 | 31 | def average_precision(relevant, retrieved): 32 | if not relevant: return 0.0 | ^ 33 | hits = 0 34 | sum_prec = 0.0 | E701 Multiple statements on one line (colon) --> experiments\kaggle_bge_benchmark.ipynb:cell 4:32:36 | 30 | scores = np.zeros(self.n_docs, dtype=np.float64) 31 | for term in tokens: 32 | if term not in self.idf: continue | ^ 33 | idf = self.idf[term] 34 | for doc_idx in range(self.n_docs): | E701 Multiple statements on one line (colon) --> experiments\kaggle_bge_benchmark.ipynb:cell 4:36:27 | 34 | for doc_idx in range(self.n_docs): 35 | tf = self.doc_term_freqs[doc_idx].get(term, 0) 36 | if tf == 0: continue | ^ 37 | doc_len = self.doc_lengths[doc_idx] 38 | num = tf * (self.k1 + 1) | E402 Module level import not at top of cell --> experiments\kaggle_bge_benchmark.ipynb:cell 5:11:1 | 10 | qrels = load_dataset("mteb/scifact", "default", split="test") 11 | from collections import defaultdict | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | benchmark = defaultdict(list) 13 | for item in qrels: | E402 Module level import not at top of file --> tests\conftest.py:19:1 | 18 | # Inject the mock 19 | import sentence_transformers | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 20 | sentence_transformers.SentenceTransformer = MockSentenceTransformer | E402 Module level import not at top of file --> tests\conftest.py:23:1 | 22 | # Now import the app safely 23 | from app.main import app | ^^^^^^^^^^^^^^^^^^^^^^^^ 24 | 25 | @pytest.fixture | F841 Local variable `score_jumps` is assigned to but never used --> tests\unit\test_bm25.py:41:5 | 39 | # "the" is in 2 docs, "jumps" is in 1 doc. 40 | # We don't have direct access to vocab mapping, but we can score single terms 41 | score_jumps = bm25.score("jumps")[0] | ^^^^^^^^^^^ 42 | score_the = bm25.score("the")[0] 43 | # Because jumps is rarer, its IDF is higher, and the doc is longer, but usually IDF dominates | help: Remove assignment to unused variable `score_jumps` F841 Local variable `score_the` is assigned to but never used --> tests\unit\test_bm25.py:42:5 | 40 | # We don't have direct access to vocab mapping, but we can score single terms 41 | score_jumps = bm25.score("jumps")[0] 42 | score_the = bm25.score("the")[0] | ^^^^^^^^^ 43 | # Because jumps is rarer, its IDF is higher, and the doc is longer, but usually IDF dominates 44 | # Let's just check that IDF values are positive | help: Remove assignment to unused variable `score_the` Found 42 errors. No fixes available (4 hidden fixes can be enabled with the `--unsafe-fixes` option).