diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 80acc27..aeeb5c1 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -28,10 +28,10 @@ jobs: run: | pip3 install -r requirements.txt ruff -# - name: Run ruff linter -# shell: sh -# run: | -# ruff check SPARC/ tests/ + - name: Run ruff linter + shell: sh + run: | + ruff check SPARC/ tests/ - name: Install Node.js and check TypeScript types shell: sh @@ -47,16 +47,17 @@ jobs: fi npx tsc --noEmit -# - name: Run pytest -# shell: sh -# env: -# DATABASE_URL: "sqlite://" -# API_KEY: "test-key" -# OPENROUTER_API_KEY: "test-key" -# JWT_SECRET: "test-secret-for-ci" -# APP_ENV: "development" -# run: | -# python3 -m pytest tests/ -v --tb=short -x + - name: Run pytest + shell: sh + env: + DATABASE_URL: "sqlite://" + API_KEY: "test-key" + OPENROUTER_API_KEY: "test-key" + JWT_SECRET: "test-secret-for-ci" + APP_ENV: "development" + run: | + pip3 install pytest + python3 -m pytest tests/ -v --tb=short -x build-api: needs: test diff --git a/SPARC/analyzer.py b/SPARC/analyzer.py index 31ad7f1..1ebceaf 100644 --- a/SPARC/analyzer.py +++ b/SPARC/analyzer.py @@ -10,13 +10,13 @@ from concurrent.futures import ThreadPoolExecutor, as_completed from typing import Callable from SPARC import config - -logger = logging.getLogger(__name__) from SPARC.database import DatabaseClient from SPARC.llm import LLMAnalyzer from SPARC.serp_api import SERP from SPARC.types import BatchAnalysisResult, CompanyAnalysisResult, Patent, Patents +logger = logging.getLogger(__name__) + class CompanyAnalyzer: """Orchestrates end-to-end company performance analysis via patents.""" diff --git a/SPARC/api.py b/SPARC/api.py index 3a28033..a42ddd7 100644 --- a/SPARC/api.py +++ b/SPARC/api.py @@ -3,9 +3,14 @@ Provides REST API endpoints for analyzing company patent portfolios. """ +from __future__ import annotations + from contextlib import asynccontextmanager from datetime import datetime -from typing import Annotated, List +from typing import TYPE_CHECKING, Annotated, List + +if TYPE_CHECKING: + from SPARC.database import DatabaseClient from fastapi import BackgroundTasks, Depends, FastAPI, HTTPException, Query, Request from fastapi.middleware.cors import CORSMiddleware @@ -653,7 +658,6 @@ async def export_company_pdf( PDF file download """ import io - import textwrap from reportlab.lib import colors from reportlab.lib.pagesizes import letter diff --git a/tests/test_auth.py b/tests/test_auth.py index de79259..bb4378a 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -175,6 +175,7 @@ class TestGetMe: from datetime import timedelta import jwt as pyjwt + from SPARC.auth import JWT_ALGORITHM, JWT_SECRET payload = { diff --git a/tests/test_rate_limit.py b/tests/test_rate_limit.py index f9f06af..8d0adf0 100644 --- a/tests/test_rate_limit.py +++ b/tests/test_rate_limit.py @@ -1,7 +1,8 @@ """Tests for rate limiting on auth endpoints.""" +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import Mock, patch, MagicMock from fastapi.testclient import TestClient from SPARC.api import app diff --git a/tests/test_security.py b/tests/test_security.py index b6e4be1..b34deec 100644 --- a/tests/test_security.py +++ b/tests/test_security.py @@ -14,6 +14,7 @@ class TestJWTSecretStartupCheck: with patch.dict(os.environ, {"APP_ENV": "production"}): # Reload config to pick up the new APP_ENV import importlib + import SPARC.config importlib.reload(SPARC.config) @@ -31,6 +32,7 @@ class TestJWTSecretStartupCheck: """Starting with default secret and APP_ENV=development must not raise.""" with patch.dict(os.environ, {"APP_ENV": "development"}): import importlib + import SPARC.config importlib.reload(SPARC.config) @@ -46,6 +48,7 @@ class TestJWTSecretStartupCheck: """Starting with a custom secret in production must not raise.""" with patch.dict(os.environ, {"APP_ENV": "production"}): import importlib + import SPARC.config importlib.reload(SPARC.config) @@ -65,6 +68,7 @@ class TestJWTSecretStartupCheck: env.pop("APP_ENV", None) with patch.dict(os.environ, env, clear=True): import importlib + import SPARC.config importlib.reload(SPARC.config) @@ -84,6 +88,7 @@ class TestCORSConfig: """When CORS_ORIGINS is unset, defaults to localhost origins.""" with patch.dict(os.environ, {"CORS_ORIGINS": ""}): import importlib + import SPARC.config importlib.reload(SPARC.config) assert SPARC.config.cors_origins == [ @@ -95,6 +100,7 @@ class TestCORSConfig: """Setting CORS_ORIGINS configures allowed origins.""" with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com,https://app.example.com"}): import importlib + import SPARC.config importlib.reload(SPARC.config) assert SPARC.config.cors_origins == [ @@ -109,6 +115,7 @@ class TestCORSConfig: """A single origin without comma works correctly.""" with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com"}): import importlib + import SPARC.config importlib.reload(SPARC.config) assert SPARC.config.cors_origins == ["https://sparc.example.com"]