deslop 0.2.0

A static analyzer that spots low-context and AI-assisted code patterns across naming, concurrency, security, performance, and test quality.
Documentation
from django.db import models
from django.http import JsonResponse
from django.shortcuts import render
from flask import Flask, request, jsonify
from fastapi import FastAPI, Depends, BackgroundTasks
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
import requests
import re
import json


# --- Django ORM rules ---

class Product(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=10, decimal_places=2)


@app.route("/products")
def product_list_view(request):
    """Triggers django_queryset_evaluated_multiple_times, django_queryset_len_instead_of_count."""
    qs = Product.objects.filter(active=True)
    count = len(qs)
    items = list(qs)
    return JsonResponse({"count": count, "items": [i.name for i in items]})


@app.route("/count")
def product_count_view(request):
    """Triggers django_queryset_count_then_exists."""
    qs = Product.objects.filter(active=True)
    if qs.count() > 0:
        return JsonResponse({"exists": True})
    return JsonResponse({"exists": False})


@app.route("/random")
def random_product_view(request):
    """Triggers django_queryset_order_by_random."""
    product = Product.objects.order_by("?").first()
    return JsonResponse({"name": product.name})


@app.route("/all")
def all_products_view(request):
    """Triggers django_all_without_limit_in_view."""
    products = Product.objects.all()
    return JsonResponse({"products": [p.name for p in products]})


@app.route("/related")
def related_view(request):
    """Triggers django_n_plus_one_no_select_related."""
    orders = Order.objects.all()
    for order in orders:
        print(order.customer.name)


@app.route("/bulk-create")
def bulk_create_view(request):
    """Triggers django_create_single_in_loop, django_save_full_model_in_loop."""
    for name in request.POST.getlist("names"):
        Product.objects.create(name=name, price=10)
        p = Product(name=name)
        p.save()


@app.route("/delete-old")
def delete_old_view(request):
    """Triggers django_delete_single_in_loop, django_raw_sql_in_loop."""
    old = Product.objects.filter(active=False)
    for p in old:
        p.delete()
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("DELETE FROM audit WHERE id=%s", [p.id])


@app.route("/partial")
def partial_update_view(request):
    """Triggers django_values_vs_full_model_in_loop + django_update_single_in_loop."""
    for item in Product.objects.filter(active=True).objects.all():
        item.price = 0
    for p in Product.objects.filter(price=0):
        Product.objects.filter(id=p.id).objects.filter(id=p.id).update(price=99)


@app.route("/migrate")
def migration_in_view(request):
    """Triggers django_migration_code_in_view."""
    from django.db import schema_editor
    return JsonResponse({"ok": True})


# --- Flask rules ---

app = Flask(__name__)


@app.route("/parse", methods=["POST"])
def flask_parse_view():
    """Triggers flask_request_body_parsed_multiple_times."""
    data1 = request.get_json()
    data2 = request.get_json()
    return jsonify(data1, data2)


@app.route("/db")
def flask_db_view():
    """Triggers flask_global_db_connection_per_request."""
    import sqlite3
    conn = sqlite3.connect("db.sqlite3")
    cursor = conn.cursor()
    return jsonify({"ok": True})


@app.route("/config")
def flask_config_view():
    """Triggers flask_app_config_read_per_request."""
    db_host = app.config["DB_HOST"]
    db_port = app.config["DB_PORT"]
    return jsonify({"host": db_host, "port": db_port})


@app.route("/file")
def flask_file_view():
    """Triggers flask_file_read_per_request."""
    with open("data.json") as f:
        data = json.load(f)
    return jsonify(data)


@app.route("/template")
def flask_template_view():
    """Triggers flask_template_rendered_from_string_in_view."""
    return render_template_string("<h1>{{ name }}</h1>", name="test")


@app.route("/debug")
def flask_debug_view():
    """Triggers flask_debug_mode_in_production_code."""
    app.run(debug=True)
    return "ok"


@app.route("/encoder")
def flask_encoder_view():
    """Triggers flask_json_encoder_per_request."""
    encoder = json.JSONEncoder()
    return encoder.encode({"key": "value"})


@app.route("/large")
def flask_large_view():
    """Triggers flask_no_streaming_for_large_response."""
    data = open("huge_file.csv").read()
    return data


# --- FastAPI rules ---

fastapi_app = FastAPI()


@app.get("/sync")
def fastapi_sync_view():
    """Triggers fastapi_sync_def_with_blocking_io."""
    import time
    time.sleep(1)
    data = open("data.txt").read()
    return {"data": data}


@app.get("/dep")
def fastapi_dep_view():
    """Triggers fastapi_dependency_creates_client_per_request."""
    client = requests.Session()
    return {"ok": True}


@app.post("/bg")
def fastapi_bg_view(bg: BackgroundTasks):
    """Triggers fastapi_background_task_exception_silent."""
    bg.add_task(lambda: do_work())
    return {"queued": True}


# --- SQLAlchemy rules ---

def sqlalchemy_session_bad():
    """Triggers sqlalchemy_session_not_closed, sqlalchemy_create_engine_per_request."""
    engine = create_engine("sqlite:///db.sqlite3")
    session = Session(engine)
    session.query(Product).all()


def sqlalchemy_loop_bad():
    """Triggers sqlalchemy_query_in_loop, sqlalchemy_commit_per_row_in_loop."""
    session = Session()
    for name in ["a", "b", "c"]:
        session.query(Product).filter_by(name=name).first()
        session.add(Product(name=name))
        session.commit()


def sqlalchemy_n_plus_one():
    """Triggers sqlalchemy_n_plus_one_lazy_load."""
    session = Session()
    orders = session.query(Order).all()
    for order in orders:
        print(order.items)


def sqlalchemy_async_bad():
    """Triggers sqlalchemy_expire_on_commit_default_in_async."""
    from sqlalchemy.ext.asyncio import AsyncSession
    async_session = AsyncSession()


# --- Middleware rules ---

class BadMiddleware:
    def process_request(self, request):
        """Triggers middleware_creates_http_client_per_request, middleware_compiles_regex_per_request, middleware_loads_config_file_per_request."""
        client = requests.Session()
        pattern = re.compile(r"^/api/.*$")
        with open("middleware_config.yaml") as f:
            config = json.load(f)


# --- Handler fanout rules ---

@app.route("/fanout")
def fanout_handler(request):
    """Triggers upstream_http_call_per_item_in_handler, upstream_call_without_timeout_in_handler, upstream_response_not_checked_before_decode."""
    items = request.get_json()
    for item in items:
        resp = requests.get("https://api.example.com/" + str(item["id"]))
        data = resp.json()


# --- Template/Response rules ---

@app.route("/templates")
def template_loop_handler(request):
    """Triggers template_render_in_loop."""
    for item in items:
        html = render_template_string("<li>{{ name }}</li>", name=item)


@app.route("/double")
def response_double_handler(request):
    """Triggers response_json_dumps_then_response_object."""
    data = json.dumps({"key": "value"})
    return Response(data, mimetype="application/json")


# --- Wave 5 Plan 2 additions ---

@app.route("/large-dict")
def large_response_handler(request):
    """Triggers large_dict_literal_response_in_handler."""
    return jsonify({
        "field1": "value1",
        "field2": "value2",
        "field3": "value3",
        "field4": "value4",
        "field5": "value5",
        "field6": "value6",
        "field7": "value7",
        "field8": "value8",
        "field9": "value9",
    })


class OrmModel:
    pass


def fastapi_orm_handler():
    """Triggers fastapi_response_model_without_orm_mode."""
    response_model = OrmModel
    obj = OrmModel.from_orm(db_obj)
    return obj