Repository Analysis

vitalik/django-ninja

💨 Fast, Async-ready, Openapi, type hints based framework for building APIs

15.1 Moderate AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of vitalik/django-ninja, a Python project with 9,179 GitHub stars. SynthScan v2.0 examined 32,738 lines of code across 271 source files, recording 467 pattern matches distributed across 14 syntactic categories. The overall adjusted score of 15.1 places this repository in the Moderate AI signal band.

The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).

15.1
Adjusted Score
15.1
Raw Score
100%
Time Factor
2026-08-24
Last Push
9.2K
Stars
Python
Language
32.7K
Lines of Code
271
Files
467
Pattern Hits
2026-08-29
Scan Date
0.00
HC Hit Rate

What These Metrics Mean

Adjusted Score
Primary synthetic code indicator. Raw score normalised per 1,000 lines of code and multiplied by the temporal discount factor. This is the definitive comparative metric — use it to rank repositories by AI authorship density.
Raw Score
The unmodified sum of all severity-weighted, context-multiplied pattern match scores before temporal discounting. Reflects the absolute signal strength independent of when the repository was last active.
Time Factor
The temporal discount multiplier (0–100%) applied to the raw score. Repositories last updated before ChatGPT's launch (Nov 2022) receive a 5% factor. Full signal is only assigned to repositories active in the post-adoption era (Jan 2024+).
Pattern Hits
Total count of individual pattern matches across all files and categories. A high hit count with a low score may indicate a very large codebase with isolated AI snippets; a low count with a high score indicates dense, concentrated AI signatures.
HC Hit Rate
High+Critical pattern hits per file, averaged across the repository. This orthogonal signal catches repositories where a few files are densely packed with high-severity AI tells — a strong indicator even when the normalised score appears moderate due to codebase size.
Lines of Code / Files
Total lines and files analysed. The scanner examines 94 file extensions. These denominators are used to normalise the score, enabling fair comparison between repositories of vastly different sizes.

Score History

Longitudinal tracking requires multiple scan runs. Once this repository is re-scanned after new commits land, this chart will visualise how the synthetic code signal evolves over time — enabling you to detect whether AI authorship is growing, stabilising, or being actively corrected by human engineers.

No multi-scan history yet — run the scanner again to build trend data.

Severity Breakdown

Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.

CRITICAL 1HIGH 0MEDIUM 7LOW 459

Directory Score Breakdown

This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.

Pattern Findings

The scanner identified 467 distinct pattern matches across 14 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.

Hyper-Verbose Identifiers286 hits · 294 pts
SeverityFileLineSnippetContext
LOWtests/test_csrf.py71def obtain_csrf_token_get_no_auth_route(request):CODE
LOWtests/test_csrf.py78def obtain_csrf_token_post_no_auth_route(request):CODE
LOWtests/test_csrf.py145def test_csrf_cookies_can_be_obtained():CODE
LOWtests/test_filter_schema.py33def test_annotated_without_filter_lookup():CODE
LOWtests/test_filter_schema.py44def test_improperly_configured_deprecated():CODE
LOWtests/test_filter_schema.py55def test_improperly_configured_annotated():CODE
LOWtests/test_filter_schema.py66def test_empty_q_when_none_ignored_deprecated():CODE
LOWtests/test_filter_schema.py78def test_empty_q_when_none_ignored_annotated():CODE
LOWtests/test_filter_schema.py149def test_q_is_a_list_deprecated(implicit_field_name):CODE
LOWtests/test_filter_schema.py168def test_q_is_a_list_annotated(implicit_field_name):CODE
LOWtests/test_filter_schema.py188def test_field_level_expression_connector_deprecated():CODE
LOWtests/test_filter_schema.py205def test_field_level_expression_connector_annotated():CODE
LOWtests/test_filter_schema.py225def test_class_level_expression_connector_deprecated():CODE
LOWtests/test_filter_schema.py239def test_class_level_expression_connector_annotated():CODE
LOWtests/test_filter_schema.py253def test_class_level_and_field_level_expression_connector_deprecated():CODE
LOWtests/test_filter_schema.py272def test_class_level_and_field_level_expression_connector_annotated():CODE
LOWtests/test_filter_schema.py294def test_ignore_none_deprecated():CODE
LOWtests/test_filter_schema.py305def test_ignore_none_annotated():CODE
LOWtests/test_filter_schema.py316def test_ignore_none_class_level_deprecated():CODE
LOWtests/test_filter_schema.py330def test_ignore_none_class_level_annotated():CODE
LOWtests/test_filter_schema.py344def test_field_level_custom_expression():CODE
LOWtests/test_filter_schema.py367def test_class_level_custom_expression():CODE
LOWtests/test_filter_schema.py393def test_multiple_filter_lookup_instances_error():CODE
LOWtests/test_filter_schema.py406def test_pydantic_field_with_extra_warns():CODE
LOWtests/test_export_openapi_schema.py50def test_export_default_without_api_endpoint(mock):CODE
LOWtests/test_inheritance_routers.py86def test_inheritance_responses(path, expected_status, expected_response):CODE
LOWtests/test_utils.py18def test_replace_path_param_notation(input, expected_output):CODE
LOWtests/test_utils.py22def test_contribute_operation_args():CODE
LOWtests/test_pagination.py620def test_limit_offset_per_endpoint_max_limit():CODE
LOWtests/test_pagination.py667def test_pagination_works_with_unnamed_classes():CODE
LOWtests/test_pagination.py680def test_no_pagination_without_query_params():CODE
LOWtests/test_pagination.py707def test_find_collection_response_skips_none_and_not_set():CODE
LOWtests/test_pagination.py730def test_find_collection_response_raises_when_no_collection():CODE
LOWtests/test_body.py59def test_body_validation_error():CODE
LOWtests/test_body.py75def test_incorrect_annotation():CODE
LOWtests/test_body.py90 def validation_error_from_error_contexts(CODE
LOWtests/test_body.py118def test_body_custom_validation_error():CODE
LOWtests/test_response.py202def test_pydantic_httpurl_schema():CODE
LOWtests/test_annotations_py314.py38def test_paginated_route_with_deferred_annotations():CODE
LOWtests/test_annotations_py314.py56def test_schema_with_self_referencing_resolver_annotation():CODE
LOWtests/test_compatibility.py14def test_modelschema_custom_annotation():CODE
LOWtests/test_compatibility.py34def test_modelschema_fk_schema_annotation():CODE
LOWtests/test_openapi_schema.py165def method_union_payload_and_simple(request, data: Union[int, TypeB]):CODE
LOWtests/test_openapi_schema.py183def method_test_title_description(CODE
LOWtests/test_openapi_schema.py193def method_test_deprecated_example_examples(CODE
LOWtests/test_openapi_schema.py698def test_schema_title_description(schema):CODE
LOWtests/test_openapi_schema.py758def test_schema_deprecated_example_examples(schema):CODE
LOWtests/test_openapi_schema.py836def test_union_payload_simple(schema):CODE
LOWtests/test_openapi_schema.py860def test_new_union_payload_type(schema):CODE
LOWtests/test_openapi_schema.py895def test_unique_operation_ids(capsys):CODE
LOWtests/test_openapi_schema.py982def test_all_paths_typed_params_rendered():CODE
LOWtests/test_openapi_schema.py1012def test_no_default_for_custom_items_attribute():CODE
LOWtests/test_openapi_schema.py1047def test_by_alias_uses_serialization_alias_simple():CODE
LOWtests/test_openapi_schema.py1072def test_by_alias_uses_validation_alias_simple():CODE
LOWtests/test_openapi_schema.py1098def test_by_alias_uses_serialization_alias_model():CODE
LOWtests/test_forms_and_files.py71def test_empty_multipart_body_field():CODE
LOWtests/test_pydantic_migrate.py23def test_optional_pydantic_model():CODE
LOWtests/test_orm_schemas.py376def test_textfield_max_length_validates_input_only():CODE
LOWtests/test_orm_schemas.py405def test_textfield_max_length_api_flow():CODE
LOWtests/test_orm_schemas.py603def test_duplicate_schema_names():CODE
226 more matches not shown…
Unused Imports75 hits · 70 pts
SeverityFileLineSnippetContext
LOWtests/test_docs/test_body.py11CODE
LOWtests/test_docs/test_body.py12CODE
LOWtests/test_docs/test_body.py13CODE
LOWtests/test_docs/test_auth.py30CODE
LOWtests/test_docs/test_auth.py31CODE
LOWtests/test_docs/test_auth.py32CODE
LOWtests/test_docs/test_auth.py33CODE
LOWtests/test_docs/test_auth.py34CODE
LOWtests/test_docs/test_auth.py35CODE
LOWtests/test_docs/test_auth.py36CODE
LOWtests/test_docs/test_auth.py37CODE
LOWtests/test_docs/test_auth.py38CODE
LOWtests/test_docs/test_form.py14CODE
LOWtests/test_docs/test_form.py15CODE
LOWtests/test_docs/test_form.py47CODE
LOWtests/test_docs/test_query.py11CODE
LOWtests/test_docs/test_query.py12CODE
LOWtests/test_docs/test_query.py13CODE
LOWtests/test_docs/test_query.py14CODE
LOWtests/test_docs/test_path.py11CODE
LOWtests/test_docs/test_path.py21CODE
LOWtests/test_docs/test_path.py22CODE
LOWdocs/src/tutorial/query/code010.py1CODE
LOWninja/__init__.py5CODE
LOWninja/__init__.py7CODE
LOWninja/__init__.py8CODE
LOWninja/__init__.py8CODE
LOWninja/__init__.py8CODE
LOWninja/__init__.py9CODE
LOWninja/__init__.py10CODE
LOWninja/__init__.py10CODE
LOWninja/__init__.py11CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py12CODE
LOWninja/__init__.py29CODE
LOWninja/__init__.py30CODE
LOWninja/__init__.py31CODE
LOWninja/__init__.py32CODE
LOWninja/__init__.py33CODE
LOWninja/__init__.py33CODE
LOWninja/errors.py13CODE
LOWninja/errors.py14CODE
LOWninja/router.py28CODE
LOWninja/main.py38CODE
LOWninja/signature/__init__.py1CODE
LOWninja/signature/__init__.py2CODE
LOWninja/security/__init__.py1CODE
15 more matches not shown…
Modern Structural Boilerplate34 hits · 34 pts
SeverityFileLineSnippetContext
LOWninja/files.py6__all__ = ["UploadedFile"]CODE
LOWninja/responses.py10__all__ = [CODE
LOWninja/constants.py3__all__ = ["NOT_SET"]CODE
LOWninja/__init__.py35__all__ = [CODE
LOWninja/renderers.py8__all__ = ["BaseRenderer", "JSONRenderer"]CODE
LOWninja/types.py3__all__ = ["DictStrAny", "TCallable"]CODE
LOWninja/operation.py51__all__ = ["Operation", "PathView", "ResponseObject"]CODE
LOWninja/parser.py9__all__ = ["Parser"]CODE
LOWninja/utils.py7__all__ = [CODE
LOWninja/errors.py16__all__ = [CODE
LOWninja/errors.py87def set_default_exc_handlers(api: "NinjaAPI") -> None:CODE
LOWninja/router.py31__all__ = ["Router", "RouterMount", "BoundRouter"]CODE
LOWninja/streaming.py8__all__ = ["StreamFormat", "SSE", "JSONL"]CODE
LOWninja/main.py40__all__ = ["NinjaAPI"]CODE
LOWninja/main.py610 def set_default_exception_handlers(self) -> None:CODE
LOWninja/schema.py48__all__ = ["BaseModel", "Field", "DjangoGetter", "Schema"]CODE
LOWninja/compatibility/util.py4__all__ = ["UNION_TYPES", "get_annotations_from_namespace"]CODE
LOWninja/signature/__init__.py4__all__ = ["ViewSignature", "is_async"]CODE
LOWninja/signature/details.py30__all__ = [CODE
LOWninja/signature/utils.py13__all__ = [CODE
LOWninja/security/session.py8__all__ = ["SessionAuth", "SessionAuthSuperUser", "SessionAuthIsStaff"]CODE
LOWninja/security/__init__.py5__all__ = [CODE
LOWninja/security/http.py12__all__ = ["HttpAuthBase", "HttpBearer", "DecodeError", "HttpBasicAuth"]CODE
LOWninja/security/apikey.py10__all__ = ["APIKeyBase", "APIKeyQuery", "APIKeyCookie", "APIKeyHeader"]CODE
LOWninja/security/base.py9__all__ = ["SecuritySchema", "AuthBase"]CODE
LOWninja/openapi/__init__.py3__all__ = ["get_schema"]CODE
LOWninja/openapi/urls.py11__all__ = ["get_openapi_urls", "get_root_url"]CODE
LOWninja/testing/__init__.py3__all__ = ["TestClient", "TestAsyncClient"]CODE
LOWninja/params/models.py26__all__ = [CODE
LOWninja/params/__init__.py7__all__ = [CODE
LOWninja/orm/fields.py17__all__ = ["create_m2m_link_type", "get_schema_field", "get_related_field_schema"]CODE
LOWninja/orm/shortcuts.py6__all__ = ["S", "L"]CODE
LOWninja/orm/__init__.py5__all__ = ["create_schema", "register_field", "ModelSchema"]CODE
LOWninja/orm/factory.py25__all__ = ["SchemaFactory", "factory", "create_schema"]CODE
AI Structural Patterns25 hits · 25 pts
SeverityFileLineSnippetContext
LOWninja/operation.py55CODE
LOWninja/operation.py574CODE
LOWninja/router.py231CODE
LOWninja/router.py271CODE
LOWninja/router.py311CODE
LOWninja/router.py351CODE
LOWninja/router.py391CODE
LOWninja/router.py431CODE
LOWninja/router.py477CODE
LOWninja/main.py52CODE
LOWninja/main.py123CODE
LOWninja/main.py166CODE
LOWninja/main.py209CODE
LOWninja/main.py252CODE
LOWninja/main.py295CODE
LOWninja/main.py338CODE
LOWninja/params/functions.py11CODE
LOWninja/params/functions.py50CODE
LOWninja/params/functions.py89CODE
LOWninja/params/functions.py128CODE
LOWninja/params/functions.py167CODE
LOWninja/params/functions.py206CODE
LOWninja/params/functions.py245CODE
LOWninja/params/models.py198CODE
LOWninja/params/__init__.py77CODE
Deep Nesting18 hits · 18 pts
SeverityFileLineSnippetContext
LOWninja/filter_schema.py155CODE
LOWninja/operation.py312CODE
LOWninja/operation.py548CODE
LOWninja/router.py116CODE
LOWninja/router.py170CODE
LOWninja/router.py685CODE
LOWninja/main.py468CODE
LOWninja/schema.py61CODE
LOWninja/signature/details.py356CODE
LOWninja/signature/details.py126CODE
LOWninja/signature/details.py187CODE
LOWninja/signature/details.py221CODE
LOWninja/management/utils.py7CODE
LOWninja/openapi/schema.py345CODE
LOWninja/openapi/schema.py63CODE
LOWninja/openapi/schema.py158CODE
LOWninja/testing/client.py144CODE
LOWninja/orm/metaclass.py68CODE
Self-Referential Comments4 hits · 12 pts
SeverityFileLineSnippetContext
MEDIUMtests/test_csrf_async.py75 # Define the async function and manually set csrf_exempt attributeCOMMENT
MEDIUMninja/operation.py647 # Create a unique view function for this PathViewCOMMENT
MEDIUMninja/operation.py650 # Create a wrapper for async viewCOMMENT
MEDIUMninja/operation.py662 # Create a wrapper for sync viewCOMMENT
AI Slop Vocabulary4 hits · 10 pts
SeverityFileLineSnippetContext
LOWninja/signature/details.py275 # 1) if type of the param is defined as one of the Param's subclasses - we just use that definitionCOMMENT
MEDIUMninja/static/ninja/redoc.standalone.js2!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):"function"==typeof deCODE
MEDIUMninja/static/ninja/redoc.standalone.js2!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):"function"==typeof deCODE
MEDIUMninja/static/ninja/redoc.standalone.js2!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):"function"==typeof deCODE
Hallucination Indicators1 hit · 10 pts
SeverityFileLineSnippetContext
CRITICALninja/static/ninja/redoc.standalone.js41`;class As extends n.PureComponent{render(){return n.createElement("div",{style:{textAlign:"center"}},n.createElement(_sCODE
Over-Commented Block8 hits · 8 pts
SeverityFileLineSnippetContext
LOWtests/test_forms.py81# username: strCOMMENT
LOWtests/test_union.py1# This is no longer the case in pydantic 2COMMENT
LOWtests/test_union.py21# assert client.get("/test?value=today").json() == ["today", "str"]COMMENT
LOW…/docs/guides/response/django-pydantic-create-schema.md61# username: strCOMMENT
LOWdocs/docs/guides/response/django-pydantic.md61 model = UserCOMMENT
LOWninja/schema.py141COMMENT
LOWninja/static/ninja/swagger-ui-init.js21// configObject.requestInterceptor = (req) => {COMMENT
LOWninja/static/ninja/swagger-ui-init.js41// req.headers['X-CSRFToken'] = swaggerUi.dataset.csrfTokenCOMMENT
Excessive Try-Catch Wrapping7 hits · 7 pts
SeverityFileLineSnippetContext
LOWtests/test_app.py98 except Exception:CODE
LOWninja/operation.py221 except Exception as e:CODE
LOWninja/operation.py321 except Exception as exc:CODE
LOWninja/operation.py500 except Exception as e:CODE
LOWninja/operation.py559 except Exception as exc:CODE
LOWninja/security/http.py85 except Exception as e: # dear contributors please do not change to valueerror - here can be multiple exceptionsCODE
LOWninja/params/models.py137 except Exception as e:CODE
Fake / Example Data2 hits · 2 pts
SeverityFileLineSnippetContext
LOWninja/static/ninja/redoc.standalone.js41`;class As extends n.PureComponent{render(){return n.createElement("div",{style:{textAlign:"center"}},n.createElement(_sCODE
LOWninja/static/ninja/redoc.standalone.js752`;var Bd=Object.defineProperty,Ud=Object.defineProperties,qd=Object.getOwnPropertyDescriptors,Vd=Object.getOwnPropertySyCODE
Slop Phrases1 hit · 2 pts
SeverityFileLineSnippetContext
LOWtests/test_app.py16# make sure to check how this will work with versioningCOMMENT
Redundant / Tautological Comments1 hit · 2 pts
SeverityFileLineSnippetContext
LOWninja/pagination.py619 # Check if Input schema has any fieldsCOMMENT
Overly Generic Function Names1 hit · 1 pts
SeverityFileLineSnippetContext
LOWtests/test_auth.py349 async def handle_request(request):CODE