forked from claw/flaskpaste
fix: add comprehensive type annotations for mypy
- database.py: add type hints for Path, Flask, Any, BaseException - pki.py: add assertions to narrow Optional types after has_ca() checks - routes.py: annotate config values to avoid Any return types - api/__init__.py: use float for cleanup timestamps (time.time()) - __init__.py: remove unused return from setup_rate_limiting
This commit is contained in:
@@ -1,13 +1,19 @@
|
||||
"""Database connection and schema management."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import secrets
|
||||
import sqlite3
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from flask import current_app, g
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from flask import Flask
|
||||
|
||||
SCHEMA = """
|
||||
CREATE TABLE IF NOT EXISTS pastes (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -74,7 +80,7 @@ _HASH_ITERATIONS = 600000 # OWASP 2023 recommendation for PBKDF2-SHA256
|
||||
_SALT_LENGTH = 32
|
||||
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
def hash_password(password: str) -> str | None:
|
||||
"""Hash password using PBKDF2-HMAC-SHA256.
|
||||
|
||||
Returns format: $pbkdf2-sha256$iterations$salt$hash
|
||||
@@ -119,7 +125,7 @@ def verify_password(password: str, password_hash: str) -> bool:
|
||||
_memory_db_holder = None
|
||||
|
||||
|
||||
def _get_connection_string(db_path) -> tuple[str, dict]:
|
||||
def _get_connection_string(db_path: str | Path) -> tuple[str, dict[str, Any]]:
|
||||
"""Get connection string and kwargs for sqlite3.connect."""
|
||||
if isinstance(db_path, Path):
|
||||
db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
@@ -129,7 +135,7 @@ def _get_connection_string(db_path) -> tuple[str, dict]:
|
||||
return db_path, {}
|
||||
|
||||
|
||||
def _is_file_database(db_path) -> bool:
|
||||
def _is_file_database(db_path: str | Path) -> bool:
|
||||
"""Check if database path refers to a file (not in-memory)."""
|
||||
if isinstance(db_path, Path):
|
||||
return True
|
||||
@@ -150,10 +156,11 @@ def get_db() -> sqlite3.Connection:
|
||||
# WAL mode set in init_db; these optimize per-connection behavior
|
||||
g.db.execute("PRAGMA busy_timeout = 5000")
|
||||
g.db.execute("PRAGMA synchronous = NORMAL")
|
||||
return g.db
|
||||
conn: sqlite3.Connection = g.db
|
||||
return conn
|
||||
|
||||
|
||||
def close_db(exception=None) -> None:
|
||||
def close_db(exception: BaseException | None = None) -> None:
|
||||
"""Close database connection at end of request."""
|
||||
db = g.pop("db", None)
|
||||
if db is not None:
|
||||
@@ -280,7 +287,7 @@ def check_content_hash(content_hash: str) -> tuple[bool, int]:
|
||||
return True, current_count
|
||||
|
||||
|
||||
def init_app(app) -> None:
|
||||
def init_app(app: Flask) -> None:
|
||||
"""Register database functions with Flask app."""
|
||||
app.teardown_appcontext(close_db)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user