Add ruff and mypy to dev dependencies with configuration in pyproject.toml. Add a lint CI job that runs ruff check, ruff format --check, and mypy. Auto-fix import sorting and formatting across the codebase. Exclude alembic/versions from linting (auto-generated migrations). Ignore B008 (FastAPI Depends pattern) and RUF001 (unicode in user-facing strings). 21 ruff lint errors and 50 mypy errors remain for manual review. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
56 lines
2.3 KiB
Python
56 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
SCHOLAR_ID_PATTERN = re.compile(r"^[a-zA-Z0-9_-]{12}$")
|
|
MAX_IMAGE_URL_LENGTH = 2048
|
|
MAX_AUTHOR_SEARCH_LIMIT = 25
|
|
|
|
DEFAULT_AUTHOR_SEARCH_CACHE_MAX_ENTRIES = 512
|
|
DEFAULT_AUTHOR_SEARCH_BLOCKED_CACHE_TTL_SECONDS = 300
|
|
DEFAULT_AUTHOR_SEARCH_COOLDOWN_BLOCK_THRESHOLD = 1
|
|
DEFAULT_AUTHOR_SEARCH_COOLDOWN_SECONDS = 1800
|
|
DEFAULT_AUTHOR_SEARCH_MIN_INTERVAL_SECONDS = 3.0
|
|
DEFAULT_AUTHOR_SEARCH_INTERVAL_JITTER_SECONDS = 1.0
|
|
DEFAULT_AUTHOR_SEARCH_RETRY_ALERT_THRESHOLD = 2
|
|
DEFAULT_AUTHOR_SEARCH_COOLDOWN_REJECTION_ALERT_THRESHOLD = 3
|
|
|
|
AUTHOR_SEARCH_RUNTIME_STATE_KEY = "global"
|
|
AUTHOR_SEARCH_LOCK_NAMESPACE = 3901
|
|
AUTHOR_SEARCH_LOCK_KEY = 1
|
|
|
|
ALLOWED_IMAGE_UPLOAD_CONTENT_TYPES = {
|
|
"image/jpeg": ".jpg",
|
|
"image/png": ".png",
|
|
"image/webp": ".webp",
|
|
"image/gif": ".gif",
|
|
}
|
|
|
|
SEARCH_DISABLED_REASON = "search_disabled_by_configuration"
|
|
SEARCH_COOLDOWN_REASON = "search_temporarily_disabled_due_to_repeated_blocks"
|
|
SEARCH_CACHED_BLOCK_REASON = "search_temporarily_disabled_from_cached_blocked_response"
|
|
|
|
STATE_REASON_HINTS: dict[str, str] = {
|
|
SEARCH_DISABLED_REASON: (
|
|
"Scholar name search is currently disabled by service policy. Add scholars by profile URL or Scholar ID."
|
|
),
|
|
SEARCH_COOLDOWN_REASON: (
|
|
"Scholar name search is temporarily paused after repeated block responses. "
|
|
"Use Scholar URL/ID adds until cooldown expires."
|
|
),
|
|
SEARCH_CACHED_BLOCK_REASON: (
|
|
"A recent blocked response was cached to reduce traffic. Retry later or add by Scholar URL/ID."
|
|
),
|
|
"network_dns_resolution_failed": (
|
|
"DNS resolution failed while reaching scholar.google.com. Verify container DNS/network and retry."
|
|
),
|
|
"network_timeout": ("Request timed out before Google Scholar responded. Increase delay/backoff and retry."),
|
|
"network_tls_error": ("TLS handshake/certificate validation failed. Verify outbound TLS/network configuration."),
|
|
"blocked_http_429_rate_limited": ("Google Scholar rate-limited the request. Slow request cadence and retry later."),
|
|
"blocked_unusual_traffic_detected": (
|
|
"Google Scholar flagged traffic as unusual. Increase delay/jitter and reduce concurrent scraping."
|
|
),
|
|
"blocked_accounts_redirect": (
|
|
"Request was redirected to Google Account sign-in. Treat as access block and retry later."
|
|
),
|
|
}
|