decompose application.py into enrichment, scholar processing, run completion

This commit is contained in:
Justin Visser 2026-02-27 14:19:39 +01:00
parent 9a7fa5004e
commit 6379c97e90
28 changed files with 2982 additions and 2576 deletions

View file

@ -391,6 +391,61 @@ async def test_api_admin_user_management_endpoints(db_session: AsyncSession) ->
assert created_exists.scalar_one() == 1
@pytest.mark.integration
@pytest.mark.db
@pytest.mark.asyncio
async def test_api_admin_scholar_http_settings_endpoints(db_session: AsyncSession) -> None:
await insert_user(
db_session,
email="api-admin-http@example.com",
password="admin-password",
is_admin=True,
)
await insert_user(
db_session,
email="api-member-http@example.com",
password="member-password",
is_admin=False,
)
previous_user_agent = settings.scholar_http_user_agent
previous_rotate = settings.scholar_http_rotate_user_agent
previous_accept_language = settings.scholar_http_accept_language
previous_cookie = settings.scholar_http_cookie
try:
client = TestClient(app)
login_user(client, email="api-admin-http@example.com", password="admin-password")
headers = _api_csrf_headers(client)
read_response = client.get("/api/v1/admin/settings/scholar-http")
assert read_response.status_code == 200
update_response = client.put(
"/api/v1/admin/settings/scholar-http",
json={
"user_agent": "Mozilla/5.0 Test Runner",
"rotate_user_agent": False,
"accept_language": "en-US,en;q=0.8",
"cookie": "SID=test-cookie",
},
headers=headers,
)
assert update_response.status_code == 200
payload = update_response.json()["data"]
assert payload["user_agent"] == "Mozilla/5.0 Test Runner"
assert payload["cookie"] == "SID=test-cookie"
assert settings.scholar_http_user_agent == "Mozilla/5.0 Test Runner"
client.post("/api/v1/auth/logout", headers=headers)
login_user(client, email="api-member-http@example.com", password="member-password")
forbidden_response = client.get("/api/v1/admin/settings/scholar-http")
assert forbidden_response.status_code == 403
finally:
object.__setattr__(settings, "scholar_http_user_agent", previous_user_agent)
object.__setattr__(settings, "scholar_http_rotate_user_agent", previous_rotate)
object.__setattr__(settings, "scholar_http_accept_language", previous_accept_language)
object.__setattr__(settings, "scholar_http_cookie", previous_cookie)
@pytest.mark.integration
@pytest.mark.db
@pytest.mark.asyncio

View file

@ -8,7 +8,7 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.db.models import CrawlRun, Publication, RunStatus, RunTriggerType, ScholarProfile, ScholarPublication
from app.services.ingestion.application import ScholarIngestionService
from app.services.ingestion.enrichment import EnrichmentRunner
from app.services.openalex.types import OpenAlexWork
from tests.integration.helpers import insert_user
@ -79,8 +79,7 @@ async def test_deferred_enrichment_sweeps_previous_runs(db_session: AsyncSession
oa_url="http://example.com/grover.pdf",
)
mock_source = MagicMock()
service = ScholarIngestionService(source=mock_source)
runner = EnrichmentRunner()
# We patch the client at its source, and also mock arXiv to avoid real HTTP calls
with (
@ -93,7 +92,7 @@ async def test_deferred_enrichment_sweeps_previous_runs(db_session: AsyncSession
mock_instance.get_works_by_filter = AsyncMock(return_value=[mock_work])
# 5. Execute the enrichment pass for the NEW run
await service._enrich_pending_publications(db_session, run_id=new_run.id)
await runner.enrich_pending_publications(db_session, run_id=new_run.id)
await db_session.commit()
# 6. Verification: The publication from the FAILED run should now be enriched