Compare commits

..

1 Commits

Author SHA1 Message Date
agent-company b32eebff8a ci: enable ruff linting and pytest in CI pipeline
Uncomment the ruff check and pytest steps in the Gitea Actions build
workflow so that linting violations and test failures block image builds.
Fix all pre-existing ruff violations (E402 import ordering in analyzer.py,
F821 undefined name in api.py, I001 unsorted imports in test files, F401
unused import in test_rate_limit.py).

Closes leeworks-agents/SPARC#1559
Closes leeworks-agents/SPARC#1560

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 20:06:10 +00:00
6 changed files with 33 additions and 19 deletions
+15 -14
View File
@@ -28,10 +28,10 @@ jobs:
run: | run: |
pip3 install -r requirements.txt ruff pip3 install -r requirements.txt ruff
# - name: Run ruff linter - name: Run ruff linter
# shell: sh shell: sh
# run: | run: |
# ruff check SPARC/ tests/ ruff check SPARC/ tests/
- name: Install Node.js and check TypeScript types - name: Install Node.js and check TypeScript types
shell: sh shell: sh
@@ -47,16 +47,17 @@ jobs:
fi fi
npx tsc --noEmit npx tsc --noEmit
# - name: Run pytest - name: Run pytest
# shell: sh shell: sh
# env: env:
# DATABASE_URL: "sqlite://" DATABASE_URL: "sqlite://"
# API_KEY: "test-key" API_KEY: "test-key"
# OPENROUTER_API_KEY: "test-key" OPENROUTER_API_KEY: "test-key"
# JWT_SECRET: "test-secret-for-ci" JWT_SECRET: "test-secret-for-ci"
# APP_ENV: "development" APP_ENV: "development"
# run: | run: |
# python3 -m pytest tests/ -v --tb=short -x pip3 install pytest
python3 -m pytest tests/ -v --tb=short -x
build-api: build-api:
needs: test needs: test
+2 -2
View File
@@ -10,13 +10,13 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Callable from typing import Callable
from SPARC import config from SPARC import config
logger = logging.getLogger(__name__)
from SPARC.database import DatabaseClient from SPARC.database import DatabaseClient
from SPARC.llm import LLMAnalyzer from SPARC.llm import LLMAnalyzer
from SPARC.serp_api import SERP from SPARC.serp_api import SERP
from SPARC.types import BatchAnalysisResult, CompanyAnalysisResult, Patent, Patents from SPARC.types import BatchAnalysisResult, CompanyAnalysisResult, Patent, Patents
logger = logging.getLogger(__name__)
class CompanyAnalyzer: class CompanyAnalyzer:
"""Orchestrates end-to-end company performance analysis via patents.""" """Orchestrates end-to-end company performance analysis via patents."""
+6 -2
View File
@@ -3,9 +3,14 @@
Provides REST API endpoints for analyzing company patent portfolios. Provides REST API endpoints for analyzing company patent portfolios.
""" """
from __future__ import annotations
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from datetime import datetime 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 import BackgroundTasks, Depends, FastAPI, HTTPException, Query, Request
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
@@ -653,7 +658,6 @@ async def export_company_pdf(
PDF file download PDF file download
""" """
import io import io
import textwrap
from reportlab.lib import colors from reportlab.lib import colors
from reportlab.lib.pagesizes import letter from reportlab.lib.pagesizes import letter
+1
View File
@@ -175,6 +175,7 @@ class TestGetMe:
from datetime import timedelta from datetime import timedelta
import jwt as pyjwt import jwt as pyjwt
from SPARC.auth import JWT_ALGORITHM, JWT_SECRET from SPARC.auth import JWT_ALGORITHM, JWT_SECRET
payload = { payload = {
+2 -1
View File
@@ -1,7 +1,8 @@
"""Tests for rate limiting on auth endpoints.""" """Tests for rate limiting on auth endpoints."""
from unittest.mock import MagicMock, patch
import pytest import pytest
from unittest.mock import Mock, patch, MagicMock
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from SPARC.api import app from SPARC.api import app
+7
View File
@@ -14,6 +14,7 @@ class TestJWTSecretStartupCheck:
with patch.dict(os.environ, {"APP_ENV": "production"}): with patch.dict(os.environ, {"APP_ENV": "production"}):
# Reload config to pick up the new APP_ENV # Reload config to pick up the new APP_ENV
import importlib import importlib
import SPARC.config import SPARC.config
importlib.reload(SPARC.config) importlib.reload(SPARC.config)
@@ -31,6 +32,7 @@ class TestJWTSecretStartupCheck:
"""Starting with default secret and APP_ENV=development must not raise.""" """Starting with default secret and APP_ENV=development must not raise."""
with patch.dict(os.environ, {"APP_ENV": "development"}): with patch.dict(os.environ, {"APP_ENV": "development"}):
import importlib import importlib
import SPARC.config import SPARC.config
importlib.reload(SPARC.config) importlib.reload(SPARC.config)
@@ -46,6 +48,7 @@ class TestJWTSecretStartupCheck:
"""Starting with a custom secret in production must not raise.""" """Starting with a custom secret in production must not raise."""
with patch.dict(os.environ, {"APP_ENV": "production"}): with patch.dict(os.environ, {"APP_ENV": "production"}):
import importlib import importlib
import SPARC.config import SPARC.config
importlib.reload(SPARC.config) importlib.reload(SPARC.config)
@@ -65,6 +68,7 @@ class TestJWTSecretStartupCheck:
env.pop("APP_ENV", None) env.pop("APP_ENV", None)
with patch.dict(os.environ, env, clear=True): with patch.dict(os.environ, env, clear=True):
import importlib import importlib
import SPARC.config import SPARC.config
importlib.reload(SPARC.config) importlib.reload(SPARC.config)
@@ -84,6 +88,7 @@ class TestCORSConfig:
"""When CORS_ORIGINS is unset, defaults to localhost origins.""" """When CORS_ORIGINS is unset, defaults to localhost origins."""
with patch.dict(os.environ, {"CORS_ORIGINS": ""}): with patch.dict(os.environ, {"CORS_ORIGINS": ""}):
import importlib import importlib
import SPARC.config import SPARC.config
importlib.reload(SPARC.config) importlib.reload(SPARC.config)
assert SPARC.config.cors_origins == [ assert SPARC.config.cors_origins == [
@@ -95,6 +100,7 @@ class TestCORSConfig:
"""Setting CORS_ORIGINS configures allowed origins.""" """Setting CORS_ORIGINS configures allowed origins."""
with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com,https://app.example.com"}): with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com,https://app.example.com"}):
import importlib import importlib
import SPARC.config import SPARC.config
importlib.reload(SPARC.config) importlib.reload(SPARC.config)
assert SPARC.config.cors_origins == [ assert SPARC.config.cors_origins == [
@@ -109,6 +115,7 @@ class TestCORSConfig:
"""A single origin without comma works correctly.""" """A single origin without comma works correctly."""
with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com"}): with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com"}):
import importlib import importlib
import SPARC.config import SPARC.config
importlib.reload(SPARC.config) importlib.reload(SPARC.config)
assert SPARC.config.cors_origins == ["https://sparc.example.com"] assert SPARC.config.cors_origins == ["https://sparc.example.com"]