Sentry file, and header linting hints

This commit is contained in:
Zeecka
2025-12-31 04:02:00 +01:00
parent 5ccb47b6b1
commit d3a3617815
22 changed files with 120 additions and 56 deletions
+3
View File
@@ -0,0 +1,3 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
+3
View File
@@ -0,0 +1,3 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Binwalk Analyzer for Image Submissions.""" """Binwalk Analyzer for Image Submissions."""
import shutil import shutil
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Bits Decomposer Analyzer for Image Submissions.""" """Bits Decomposer Analyzer for Image Submissions."""
from pathlib import Path from pathlib import Path
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Exiftool Analyzer for Image Submissions.""" """Exiftool Analyzer for Image Submissions."""
import subprocess import subprocess
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Foremost Analyzer for Image Submissions.""" """Foremost Analyzer for Image Submissions."""
import shutil import shutil
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Image size bruteforcer for common PNG sizes.""" """Image size bruteforcer for common PNG sizes."""
from pathlib import Path from pathlib import Path
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""OpenStego Analyzer for Image Submissions.""" """OpenStego Analyzer for Image Submissions."""
import shutil import shutil
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Outguess Analyzer for Image Submissions.""" """Outguess Analyzer for Image Submissions."""
import shutil import shutil
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Pngcheck Analyzer for Image Submissions.""" """Pngcheck Analyzer for Image Submissions."""
import subprocess import subprocess
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Steghide Analyzer for Image Submissions.""" """Steghide Analyzer for Image Submissions."""
import re import re
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Strings Analyzer for Image Submissions.""" """Strings Analyzer for Image Submissions."""
import subprocess import subprocess
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Custom Analyzer for Image Submissions.""" """Custom Analyzer for Image Submissions."""
import shutil import shutil
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Utility functions for analyzers modules.""" """Utility functions for analyzers modules."""
import fcntl import fcntl
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Zsteg Analyzer for Image Submissions.""" """Zsteg Analyzer for Image Submissions."""
import subprocess import subprocess
+7 -32
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Aperi'Solve Flask application.""" """Aperi'Solve Flask application."""
import hashlib import hashlib
@@ -9,46 +12,18 @@ from pathlib import Path
from typing import Any, Optional from typing import Any, Optional
import sentry_sdk import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from sentry_sdk.integrations.rq import RqIntegration
from sentry_sdk.integrations.threading import ThreadingIntegration
from flask import Flask, Response, abort, jsonify, render_template, request, send_file from flask import Flask, Response, abort, jsonify, render_template, request, send_file
from redis import Redis from redis import Redis
from rq import Queue from rq import Queue
from .sentry import initialize_sentry
initialize_sentry()
from .cleanup import cleanup_old_entries from .cleanup import cleanup_old_entries
from .config import IMAGE_EXTENSIONS, RESULT_FOLDER, WORKER_FILES from .config import IMAGE_EXTENSIONS, RESULT_FOLDER, WORKER_FILES
from .models import Image, Submission, db, init_db from .models import Image, Submission, db, init_db
SENTRY_DSN = os.environ.get("SENTRY_DSN")
ENVIRONMENT = os.environ.get("ENVIRONMENT", "development")
if SENTRY_DSN:
sentry_sdk.init(
dsn=SENTRY_DSN,
integrations=[
FlaskIntegration(),
SqlalchemyIntegration(),
RqIntegration(),
ThreadingIntegration(propagate_hub=True),
],
# Set traces_sample_rate to 1.0 to capture 100% of transactions for performance monitoring.
# Adjust this value in production (e.g., 0.1 for 10%)
traces_sample_rate=float(os.environ.get("SENTRY_TRACES_SAMPLE_RATE", "0.1")),
# Set profiles_sample_rate to 1.0 to profile 100% of sampled transactions.
profiles_sample_rate=float(os.environ.get("SENTRY_PROFILES_SAMPLE_RATE", "0.1")),
# Environment tag (production, staging, development)
environment=ENVIRONMENT,
# Release version (use git commit hash or version number)
release=os.environ.get("SENTRY_RELEASE", "1.0.0"),
# Send default PII (user IPs, etc.) - set to False for privacy
send_default_pii=False,
# Enable automatic breadcrumb tracking
enable_tracing=True,
)
app: Flask = Flask(__name__) app: Flask = Flask(__name__)
app.json.sort_keys = False # type: ignore app.json.sort_keys = False # type: ignore
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DB_URI") app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DB_URI")
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Cleanup old entries in the database and file system.""" """Cleanup old entries in the database and file system."""
import shutil import shutil
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Aperi'Solve configuration variables.""" """Aperi'Solve configuration variables."""
from pathlib import Path from pathlib import Path
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""This module defines the database models for the Aperi'Solve application.""" """This module defines the database models for the Aperi'Solve application."""
import itertools import itertools
+46
View File
@@ -0,0 +1,46 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Sentry initialization for Aperisolve."""
import os
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.rq import RqIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from sentry_sdk.integrations.threading import ThreadingIntegration
SENTRY_DSN = os.environ.get("SENTRY_DSN")
ENVIRONMENT = os.environ.get("ENVIRONMENT", "development")
def initialize_sentry() -> None:
"""Initialize Sentry SDK once, safely."""
# No DSN → do nothing
dsn = os.environ.get("SENTRY_DSN")
if not dsn:
return
# Prevent double initialization (Flask + RQ, CLI, tests, etc.)
if sentry_sdk.Hub.current.client is not None:
return
sentry_sdk.init(
dsn=dsn,
integrations=[
FlaskIntegration(),
SqlalchemyIntegration(),
RqIntegration(),
ThreadingIntegration(propagate_hub=True),
],
traces_sample_rate=float(os.environ.get("SENTRY_TRACES_SAMPLE_RATE", "0.1")),
profiles_sample_rate=float(
os.environ.get("SENTRY_PROFILES_SAMPLE_RATE", "0.1")
),
environment=os.environ.get("ENVIRONMENT", "development"),
release=os.environ.get("SENTRY_RELEASE", "1.0.0"),
send_default_pii=False,
enable_tracing=True,
)
+10 -24
View File
@@ -1,32 +1,19 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Asynchronous worker for analyzing image submissions.""" """Asynchronous worker for analyzing image submissions."""
import os
import threading import threading
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
import sentry_sdk import sentry_sdk
from sentry_sdk.integrations.rq import RqIntegration
from sentry_sdk.integrations.threading import ThreadingIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
# Initialize Sentry for workers (separate process from Flask app) from .sentry import initialize_sentry
SENTRY_DSN = os.environ.get("SENTRY_DSN")
if SENTRY_DSN:
sentry_sdk.init(
dsn=SENTRY_DSN,
integrations=[
RqIntegration(),
ThreadingIntegration(propagate_hub=True), # Capture exceptions in threads
SqlalchemyIntegration(),
],
traces_sample_rate=float(os.environ.get("SENTRY_TRACES_SAMPLE_RATE", "0.1")),
environment=os.environ.get("ENVIRONMENT", "development"),
release=os.environ.get("SENTRY_RELEASE", "1.0.0"),
send_default_pii=False,
)
from .analyzers.binwalk import analyze_binwalk initialize_sentry()
from .analyzers.binwalk import analyze_binwalk # pylint: disable=C0413
from .analyzers.decomposer import analyze_decomposer from .analyzers.decomposer import analyze_decomposer
from .analyzers.exiftool import analyze_exiftool from .analyzers.exiftool import analyze_exiftool
from .analyzers.foremost import analyze_foremost from .analyzers.foremost import analyze_foremost
@@ -74,8 +61,7 @@ def analyze_image(submission_hash: str) -> None:
if not submission or not image: # No submission found if not submission or not image: # No submission found
sentry_sdk.capture_message( sentry_sdk.capture_message(
f"Submission or image not found: {submission_hash}", f"Submission or image not found: {submission_hash}", level="warning"
level="warning"
) )
return return
@@ -127,10 +113,10 @@ def analyze_image(submission_hash: str) -> None:
for thread in threads: for thread in threads:
thread.join() thread.join()
submission.status = "completed" submission.status = "completed" # type: ignore
except Exception as e: except Exception as e:
sentry_sdk.capture_exception(e) sentry_sdk.capture_exception(e)
submission.status = "error" submission.status = "error" # type: ignore
finally: finally:
db.session.commit() # pylint: disable=no-member db.session.commit() # pylint: disable=no-member
# Flush Sentry events - wait up to 5 seconds for events to be sent # Flush Sentry events - wait up to 5 seconds for events to be sent
+3
View File
@@ -1,3 +1,6 @@
# flake8: noqa: E203,E501,W503
# pylint: disable=C0413,W0718,R0903,R0801
# mypy: disable-error-code=unused-awaitable
"""Aperi'Solve WSGI runner.""" """Aperi'Solve WSGI runner."""
from .app import app as application from .app import app as application