Repository Analysis

Kludex/starlette

The little ASGI framework that shines. 🌟

17.1 Moderate AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of Kludex/starlette, a Python project with 12,474 GitHub stars. SynthScan v2.0 examined 24,316 lines of code across 110 source files, recording 419 pattern matches distributed across 13 syntactic categories. The overall adjusted score of 17.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).

17.1
Adjusted Score
17.1
Raw Score
100%
Time Factor
2026-07-04
Last Push
12.5K
Stars
Python
Language
24.3K
Lines of Code
110
Files
419
Pattern Hits
2026-07-14
Scan Date
0.02
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

This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.

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 0HIGH 2MEDIUM 5LOW 412

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 419 distinct pattern matches across 13 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 Identifiers322 hits · 303 pts
SeverityFileLineSnippetContext
LOWstarlette/responses.py154 def _wrap_websocket_denial_send(self, send: Send) -> Send:CODE
LOWstarlette/routing.py540def _wrap_gen_lifespan_context(CODE
LOWstarlette/_exception_handler.py16def _lookup_exception_handler(exc_handlers: ExceptionHandlers, exc: Exception) -> ExceptionHandler | None:CODE
LOWstarlette/_exception_handler.py23def wrap_app_handling_exceptions(app: ASGIApp, conn: Request | WebSocket) -> ASGIApp:CODE
LOWstarlette/_utils.py83async def create_collapsing_task_group() -> AsyncGenerator[anyio.abc.TaskGroup, None]:CODE
LOWtests/test_datastructures.py184def test_url_from_scope_with_invalid_host(host: bytes) -> None:CODE
LOWtests/test_datastructures.py209def test_url_from_scope_with_authority_in_path(path: str, expected_path: str, with_host_header: bool) -> None:CODE
LOWtests/test_datastructures.py269def test_mutable_headers_merge() -> None:CODE
LOWtests/test_datastructures.py278def test_mutable_headers_merge_dict() -> None:CODE
LOWtests/test_datastructures.py287def test_mutable_headers_update() -> None:CODE
LOWtests/test_datastructures.py296def test_mutable_headers_update_dict() -> None:CODE
LOWtests/test_datastructures.py305def test_mutable_headers_merge_not_mapping() -> None:CODE
LOWtests/test_datastructures.py321def test_mutable_headers_from_scope() -> None:CODE
LOWtests/test_datastructures.py373async def test_upload_file_file_input() -> None:CODE
LOWtests/test_datastructures.py387async def test_upload_file_without_size() -> None:CODE
LOWtests/test_datastructures.py457async def test_upload_file_repr_headers() -> None:CODE
LOWtests/test_concurrency.py16async def test_run_until_first_complete() -> None:CODE
LOWtests/test_concurrency.py33def test_accessing_context_from_threaded_sync_endpoint(CODE
LOWtests/test_concurrency.py50async def test_iterate_in_threadpool() -> None:CODE
LOWtests/test_templates.py37def test_templates_autoescape(tmp_path: Path) -> None:CODE
LOWtests/test_templates.py49def test_calls_context_processors(tmp_path: Path, test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_templates.py77def test_template_with_middleware(tmpdir: Path, test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_templates.py103def test_templates_with_directories(tmp_path: Path, test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_templates.py138def test_templates_require_directory_or_environment() -> None:CODE
LOWtests/test_templates.py143def test_templates_require_directory_or_environment_not_both() -> None:CODE
LOWtests/test_templates.py148def test_templates_with_directory(tmpdir: Path) -> None:CODE
LOWtests/test_templates.py158def test_templates_with_environment(tmpdir: Path, test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_endpoints.py37def test_http_endpoint_route_path_params(client: TestClient) -> None:CODE
LOWtests/test_endpoints.py43def test_http_endpoint_route_method(client: TestClient) -> None:CODE
LOWtests/test_endpoints.py50def test_http_endpoint_does_not_dispatch_non_verb_method(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_endpoints.py67def test_websocket_endpoint_on_connect(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_endpoints.py78def test_websocket_endpoint_on_receive_bytes(CODE
LOWtests/test_endpoints.py98def test_websocket_endpoint_on_receive_json(CODE
LOWtests/test_endpoints.py118def test_websocket_endpoint_on_receive_json_binary(CODE
LOWtests/test_endpoints.py134def test_websocket_endpoint_on_receive_text(CODE
LOWtests/test_endpoints.py154def test_websocket_endpoint_on_default(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_endpoints.py168def test_websocket_endpoint_on_disconnect(CODE
LOWtests/test_convertors.py63def test_default_float_convertor(test_client_factory: TestClientFactory, param: str, status_code: int) -> None:CODE
LOWtests/test_convertors.py86def test_default_uuid_convertor(test_client_factory: TestClientFactory, param: str, status_code: int) -> None:CODE
LOWtests/test_exceptions.py108def test_websockets_should_raise(client: TestClient) -> None:CODE
LOWtests/test_exceptions.py114def test_handled_exc_after_response(test_client_factory: TestClientFactory, client: TestClient) -> None:CODE
LOWtests/test_exceptions.py185def test_request_in_app_and_handler_is_the_same_object(client: TestClient) -> None:CODE
LOWtests/test_exceptions.py191def test_http_exception_does_not_use_threadpool(client: TestClient, monkeypatch: MonkeyPatch) -> None:CODE
LOWtests/test_exceptions.py210def test_handlers_annotations() -> None:CODE
LOWtests/test_testclient.py50def test_use_testclient_in_endpoint(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py70def test_testclient_headers_behavior() -> None:CODE
LOWtests/test_testclient.py89def test_use_testclient_as_contextmanager(test_client_factory: TestClientFactory, anyio_backend_name: str) -> None:CODE
LOWtests/test_testclient.py180def test_exception_in_middleware(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py233def test_websocket_blocking_receive(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py258def test_websocket_not_block_on_close(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py293def test_client_custom_client(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py335def test_domain_restricted_cookies(test_client_factory: TestClientFactory, domain: str, ok: bool) -> None:CODE
LOWtests/test_testclient.py361def test_forward_follow_redirects(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py374def test_forward_nofollow_redirects(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py384def test_with_duplicate_headers(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py404def test_raw_path_with_querystring(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test_testclient.py414def test_websocket_raw_path_without_params(test_client_factory: TestClientFactory) -> None:CODE
LOWtests/test__utils.py58def test_async_partial_object_call() -> None:CODE
LOWtests/test__utils.py80def test_async_nested_partial() -> None:CODE
LOWtests/test__utils.py91def test_async_mocked_async_function() -> None:CODE
262 more matches not shown…
Unused Imports45 hits · 43 pts
SeverityFileLineSnippetContext
LOWstarlette/responses.py1CODE
LOWstarlette/config.py1CODE
LOWstarlette/templating.py1CODE
LOWstarlette/websockets.py1CODE
LOWstarlette/applications.py1CODE
LOWstarlette/concurrency.py1CODE
LOWstarlette/background.py1CODE
LOWstarlette/types.py6CODE
LOWstarlette/types.py7CODE
LOWstarlette/types.py8CODE
LOWstarlette/convertors.py1CODE
LOWstarlette/staticfiles.py1CODE
LOWstarlette/schemas.py1CODE
LOWstarlette/routing.py1CODE
LOWstarlette/authentication.py1CODE
LOWstarlette/testclient.py1CODE
LOWstarlette/_exception_handler.py1CODE
LOWstarlette/exceptions.py1CODE
LOWstarlette/requests.py1CODE
LOWstarlette/datastructures.py1CODE
LOWstarlette/endpoints.py1CODE
LOWstarlette/formparsers.py1CODE
LOWstarlette/_utils.py1CODE
LOWstarlette/status.py9CODE
LOWstarlette/middleware/sessions.py1CODE
LOWstarlette/middleware/cors.py1CODE
LOWstarlette/middleware/__init__.py1CODE
LOWstarlette/middleware/trustedhost.py1CODE
LOWstarlette/middleware/authentication.py1CODE
LOWstarlette/middleware/exceptions.py1CODE
LOWstarlette/middleware/errors.py1CODE
LOWstarlette/middleware/base.py1CODE
LOWstarlette/middleware/wsgi.py1CODE
LOWtests/conftest.py1CODE
LOWtests/test_templates.py1CODE
LOWtests/test_testclient.py1CODE
LOWtests/types.py1CODE
LOWtests/test_authentication.py1CODE
LOWtests/test_routing.py1CODE
LOWtests/test_applications.py1CODE
LOWtests/test_requests.py1CODE
LOWtests/test_responses.py1CODE
LOWtests/test_formparsers.py1CODE
LOWtests/middleware/test_gzip.py1CODE
LOWtests/middleware/test_base.py1CODE
Deep Nesting17 hits · 17 pts
SeverityFileLineSnippetContext
LOWstarlette/websockets.py59CODE
LOWstarlette/staticfiles.py109CODE
LOWstarlette/schemas.py40CODE
LOWstarlette/routing.py420CODE
LOWstarlette/routing.py486CODE
LOWstarlette/authentication.py25CODE
LOWstarlette/authentication.py32CODE
LOWstarlette/testclient.py150CODE
LOWstarlette/testclient.py225CODE
LOWstarlette/testclient.py300CODE
LOWstarlette/requests.py268CODE
LOWstarlette/endpoints.py70CODE
LOWstarlette/endpoints.py91CODE
LOWstarlette/formparsers.py105CODE
LOWstarlette/middleware/gzip.py48CODE
LOWstarlette/middleware/cors.py107CODE
LOWstarlette/middleware/errors.py149CODE
Cross-Language Confusion2 hits · 10 pts
SeverityFileLineSnippetContext
HIGHstarlette/config.py90 default: Any = undefined,CODE
HIGHstarlette/config.py98 default: Any = undefined,CODE
Self-Referential Comments3 hits · 9 pts
SeverityFileLineSnippetContext
MEDIUMstarlette/requests.py193 # Create a state instance with a reference to the dict in which it shouldCOMMENT
MEDIUMstarlette/formparsers.py115 # Create the parser.COMMENT
MEDIUMstarlette/formparsers.py271 # Create the parser.COMMENT
AI Structural Patterns10 hits · 8 pts
SeverityFileLineSnippetContext
LOWstarlette/responses.py89CODE
LOWstarlette/testclient.py381CODE
LOWstarlette/testclient.py429CODE
LOWstarlette/testclient.py539CODE
LOWstarlette/testclient.py570CODE
LOWstarlette/testclient.py601CODE
LOWstarlette/middleware/cors.py16CODE
LOWtests/test_staticfiles.py56CODE
LOWtests/middleware/test_base.py137CODE
LOWtests/middleware/test_base.py957CODE
Excessive Try-Catch Wrapping7 hits · 8 pts
SeverityFileLineSnippetContext
LOWstarlette/_exception_handler.py43 except Exception as exc:CODE
LOWstarlette/endpoints.py85 except Exception as exc:CODE
LOWstarlette/middleware/errors.py165 except Exception as exc:STRING
LOWstarlette/middleware/base.py145 except Exception as exc:CODE
LOWtests/middleware/test_base.py1277 except Exception:CODE
LOWtests/middleware/test_base.py1283 except Exception as e:CODE
LOWdocs/middleware.md642 except Exception as exc:CODE
Dead Code2 hits · 4 pts
SeverityFileLineSnippetContext
MEDIUMtests/test_testclient.py171CODE
MEDIUMtests/test_routing.py697CODE
Modern Structural Boilerplate3 hits · 3 pts
SeverityFileLineSnippetContext
LOWstarlette/responses.py330 def set_stat_headers(self, stat_result: os.stat_result) -> None:CODE
LOWstarlette/templating.py101 def _setup_env_defaults(self, env: jinja2.Environment) -> None:CODE
LOWstarlette/status.py15__all__ = [CODE
Redundant / Tautological Comments2 hits · 3 pts
SeverityFileLineSnippetContext
LOWstarlette/staticfiles.py136 # Check if we have 'index.html' file to serve.COMMENT
LOWstarlette/formparsers.py277 # Write file data, it needs to use await with the UploadFile methodsCOMMENT
AI Slop Vocabulary2 hits · 3 pts
SeverityFileLineSnippetContext
LOWstarlette/routing.py614 # returning the response. For plain ASGI apps, just return the response.COMMENT
LOWstarlette/endpoints.py51 # returning the response. For plain ASGI apps, just return the response.COMMENT
Overly Generic Function Names2 hits · 2 pts
SeverityFileLineSnippetContext
LOWstarlette/testclient.py225 def handle_request(self, request: httpx.Request) -> httpx.Response:CODE
LOWtests/test_routing.py769 async def my_method(self, request: Request) -> None: ... # pragma: no coverCODE
Fake / Example Data2 hits · 2 pts
SeverityFileLineSnippetContext
LOWdocs/applications.md27 username = "John Doe"CODE
LOWdocs/applications.md65app.state.ADMIN_EMAIL = 'admin@example.org'CODE