Repository Analysis

Kanaries/pygwalker

PyGWalker: Turn your dataframe into an interactive UI for visual analysis

20.5 Moderate AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of Kanaries/pygwalker, a Python project with 15,902 GitHub stars. SynthScan v2.0 examined 24,261 lines of code across 220 source files, recording 465 pattern matches distributed across 11 syntactic categories. The overall adjusted score of 20.5 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).

20.5
Adjusted Score
20.5
Raw Score
100%
Time Factor
2026-07-01
Last Push
15.9K
Stars
Python
Language
24.3K
Lines of Code
220
Files
465
Pattern Hits
2026-07-14
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

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 1HIGH 0MEDIUM 11LOW 453

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 465 distinct pattern matches across 11 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 Identifiers349 hits · 346 pts
SeverityFileLineSnippetContext
LOWapp/src/dataSource/index.tsx171export function getDatasFromKernelByPayload(comm: ICommunication | null) {CODE
LOWapp/src/tools/saveTool.tsx18function DocumentTextIconWithRedPoint(iconProps) {CODE
LOWtests/test_dsl_transform.py15def test_dsl_to_workflow_returns_valid_workflow():CODE
LOWtests/test_dsl_transform.py22def test_dsl_to_workflow_with_fields():CODE
LOWtests/test_dsl_transform.py34def test_vega_to_dsl_returns_expected_keys():CODE
LOWtests/test_dsl_transform.py52def test_import_error_when_no_js_runtime():CODE
LOWtests/test_dsl_transform.py66def test_runtime_initialized_only_once():CODE
LOWtests/test_dsl_transform.py82def test_reset_runtime_closes_existing_contexts():CODE
LOWtests/test_frontend_contracts.py192def test_frontend_props_interface_covers_python_props_builder():CODE
LOWtests/test_frontend_contracts.py198def test_python_props_builder_stringifies_frontend_id():CODE
LOWtests/test_frontend_contracts.py205def test_frontend_comm_maps_cover_python_comm_handler_endpoints():CODE
LOWtests/test_frontend_contracts.py215def test_frontend_comm_request_map_uses_types_matching_python_request_models():CODE
LOWtests/test_frontend_contracts.py225def test_frontend_protocol_interfaces_match_pydantic_aliases():CODE
LOWtests/test_frontend_contracts.py232def test_generated_frontend_protocol_types_are_fresh():CODE
LOWtests/test_frontend_contracts.py239def test_comm_handler_register_uses_typed_request_models():CODE
LOWtests/test_frontend_contracts.py258def test_frontend_dev_typescript_source_maps_are_enabled():CODE
LOWtests/test_frontend_contracts.py266def test_frontend_tracker_loads_segment_only_after_events_opt_in():CODE
LOWtests/test_frontend_contracts.py276def test_frontend_http_integrations_initialize_communication():CODE
LOWtests/test_frontend_contracts.py107def _comm_handler_request_models(repo_root: Path) -> dict[str, str]:CODE
LOWtests/test_frontend_contracts.py133def _comm_handler_register_calls(repo_root: Path) -> list[ast.Call]:CODE
LOWtests/test_frontend_contracts.py146def _typescript_interface_keys(repo_root: Path, interface_name: str) -> set[str]:CODE
LOWtests/test_frontend_contracts.py287def test_streamlit_entrypoint_refreshes_props_on_reruns():CODE
LOWtests/test_frontend_contracts.py302def test_frontend_component_state_refreshes_when_props_change():CODE
LOWtests/test_frontend_contracts.py310def test_frontend_pure_renderer_uses_local_data_without_kernel_computation():CODE
LOWtests/test_frontend_contracts.py327def test_frontend_modals_are_lazy_loaded_from_entrypoint():CODE
LOWtests/test_frontend_contracts.py346def test_frontend_save_payload_strips_graphic_walker_export_fields():CODE
LOWtests/test_frontend_assets.py16def test_read_frontend_asset_reads_from_templates_dist(monkeypatch, tmp_path):CODE
LOWtests/test_frontend_assets.py25def test_read_frontend_asset_reports_compile_command(monkeypatch, tmp_path):CODE
LOWtests/test_frontend_assets.py36def test_read_frontend_asset_report_uses_stable_posix_path_with_windows_paths(monkeypatch, tmp_path):CODE
LOWtests/test_readme_api_reference.py19def _read_walk_api_table_rows() -> list[dict[str, str]]:CODE
LOWtests/test_readme_api_reference.py47def _read_walk_api_table_params() -> list[str]:CODE
LOWtests/test_readme_api_reference.py51def _format_signature_default(parameter: inspect.Parameter) -> str:CODE
LOWtests/test_readme_api_reference.py82def test_readme_walk_api_table_matches_jupyter_walk_signature():CODE
LOWtests/test_readme_api_reference.py93def test_readme_walk_api_table_defaults_match_jupyter_walk_signature():CODE
LOWtests/test_readme_api_reference.py103def test_readme_walk_api_table_documents_reusable_walker_input():CODE
LOWtests/test_readme_api_reference.py136def test_public_api_docstrings_document_current_dataset_inputs(relative_path, qualified_name, expected_fragments):CODE
LOWtests/test_readme_api_reference.py144def test_readme_walk_api_table_marks_legacy_jupyter_envs_deprecated():CODE
LOWtests/test_readme_api_reference.py176def test_translated_readmes_defer_api_reference_to_english_readme():CODE
LOWtests/test_readme_api_reference.py185def test_translated_readmes_do_not_repeat_stale_api_parameters():CODE
LOWtests/test_preview_image.py4def test_preview_image_tool_renders_on_daemon_thread(monkeypatch):CODE
LOWtests/test_preview_image.py34def test_preview_image_tool_keeps_worker_alive_after_render_error(monkeypatch):CODE
LOWtests/test_pygwalker_core.py1746def test_to_html_rejects_live_computation_modes(kwargs):CODE
LOWtests/test_pygwalker_core.py1751def test_to_html_rejects_invalid_computation_mode():CODE
LOWtests/test_pygwalker_core.py1756def test_to_html_allows_disabled_computation_kwargs(monkeypatch):CODE
LOWtests/test_pygwalker_core.py29def _expected_legacy_computation_warning(kwargs):CODE
LOWtests/test_pygwalker_core.py71def _patch_cloud_computation_parser(monkeypatch):CODE
LOWtests/test_pygwalker_core.py103 def fake_create_cloud_dataset(self, data_parser, name, is_public, temporary):CODE
LOWtests/test_pygwalker_core.py139def test_pygwalker_props_expose_browser_data_path(monkeypatch):CODE
LOWtests/test_pygwalker_core.py158def test_pygwalker_props_expose_kernel_data_path(monkeypatch):CODE
LOWtests/test_pygwalker_core.py169def test_pygwalker_get_props_falls_back_without_props_builder(monkeypatch):CODE
LOWtests/test_pygwalker_core.py211def test_props_tracker_tracks_expected_invocation_fields():CODE
LOWtests/test_pygwalker_core.py267def test_render_manager_preview_handles_parser_exception_and_manual_gid(monkeypatch):CODE
LOWtests/test_pygwalker_core.py312def test_render_manager_chart_preview_uses_chart_indexed_workflow(monkeypatch):CODE
LOWtests/test_pygwalker_core.py325 def fake_render_chart_preview(**kwargs):CODE
LOWtests/test_pygwalker_core.py357def test_render_manager_chart_preview_returns_empty_for_mismatched_workflow_list():CODE
LOWtests/test_pygwalker_core.py375def test_jupyter_display_manager_convert_html_displays_iframe():CODE
LOWtests/test_pygwalker_core.py387def test_jupyter_display_manager_uploads_large_classic_jupyter_data(monkeypatch):CODE
LOWtests/test_pygwalker_core.py426def test_chart_export_manager_exports_png(monkeypatch):CODE
LOWtests/test_pygwalker_core.py445def test_chart_export_manager_exports_svg_variants():CODE
LOWtests/test_pygwalker_core.py465def test_chart_export_manager_display_chart_uses_chart_name_as_default_title():CODE
289 more matches not shown…
Excessive Try-Catch Wrapping34 hits · 42 pts
SeverityFileLineSnippetContext
LOWpygwalker/data_parsers/base.py186 except Exception:CODE
LOWpygwalker/data_parsers/base.py230 except Exception:CODE
LOWpygwalker/utils/encode.py23 except Exception:CODE
LOWpygwalker/utils/runtime_env.py12 except Exception:CODE
MEDIUMpygwalker/utils/runtime_env.py4def _is_jupyter() -> bool:CODE
LOWpygwalker/api/webserver.py170 except Exception:CODE
LOWpygwalker/services/preview_image.py118 except Exception:CODE
LOWpygwalker/services/preview_image.py130 except Exception:CODE
LOWpygwalker/services/preview_image.py143 except Exception:CODE
MEDIUMpygwalker/services/preview_image.py140def _safe_render_next_preview(self):CODE
LOWpygwalker/services/config.py76 except Exception:STRING
LOWpygwalker/services/config.py151 except Exception:CODE
LOWpygwalker/services/track.py70 except Exception:CODE
LOWpygwalker/services/check_update.py109 except Exception as exc:CODE
LOWpygwalker/services/kaggle.py16 except Exception:CODE
LOWpygwalker/services/kaggle.py32 except Exception:CODE
LOWpygwalker/services/data_bridge.py84 except Exception:CODE
MEDIUMpygwalker/services/data_bridge.py81def warm_kernel_table(self) -> None:CODE
LOWpygwalker/services/format_invoke_walk_code.py68 except Exception:CODE
LOWpygwalker/services/cloud_service.py80 except Exception as e:CODE
LOWpygwalker/communications/reflex_comm.py37 except Exception as e:CODE
LOWpygwalker/communications/reflex_comm.py77 except Exception as e:CODE
LOWpygwalker/communications/streamlit_comm.py97 except Exception:CODE
LOWpygwalker/communications/streamlit_comm.py151 except Exception:CODE
LOWpygwalker/communications/base.py15 except Exception:CODE
LOWpygwalker/communications/base.py50 except Exception as e:CODE
LOWpygwalker/communications/base.py66 except Exception as e:CODE
LOWexamples/reflex_demo/app/app.py34except Exception as e:CODE
LOWexamples/reflex_demo/app/app.py83 except Exception as e:CODE
MEDIUMexamples/reflex_demo/app/app.py84 print(f"Error in pygwalker_demo: {e}")CODE
LOWexamples/reflex_demo/app/app.py162 except Exception as e:CODE
LOWexamples/reflex_demo/app/app.py174except Exception as e:CODE
LOWscripts/test-init.py17except Exception as e:CODE
MEDIUMscripts/test-init.py18 print(f"Error: could not download the file\n{e}", file=sys.stderr)CODE
Unused Imports24 hits · 24 pts
SeverityFileLineSnippetContext
LOWpygwalker/__init__.py16CODE
LOWpygwalker/__init__.py16CODE
LOWpygwalker/__init__.py16CODE
LOWpygwalker/__init__.py17CODE
LOWpygwalker/__init__.py18CODE
LOWpygwalker/__init__.py19CODE
LOWpygwalker/__init__.py20CODE
LOWpygwalker/__init__.py21CODE
LOWpygwalker/api/streamlit.py31CODE
LOWpygwalker/api/webserver.py30CODE
LOWpygwalker/api/adapter.py13CODE
LOWpygwalker/api/marimo.py24CODE
LOWpygwalker/api/anywidget.py23CODE
LOWpygwalker/api/jupyter.py25CODE
LOWpygwalker/services/data_upload_communication.py7CODE
LOWpygwalker/services/data_communication.py17CODE
LOWpygwalker/services/desktop_communication.py7CODE
LOWpygwalker/services/comm_handler.py34CODE
LOWpygwalker/services/spec_communication.py15CODE
LOWpygwalker/services/cloud_communication.py21CODE
LOWscripts/generate_comm_protocol_ts.py1CODE
LOWscripts/local_ci.py3CODE
LOWpygwalker_tools/metrics/__init__.py1CODE
LOWpygwalker_tools/metrics/__init__.py1CODE
AI Structural Patterns21 hits · 21 pts
SeverityFileLineSnippetContext
LOWpygwalker/data_parsers/database_parser.py212CODE
LOWpygwalker/data_parsers/database_parser.py221CODE
LOWpygwalker/data_parsers/cloud_dataset_parser.py70CODE
LOWpygwalker/api/streamlit.py356CODE
LOWpygwalker/api/streamlit.py104CODE
LOWpygwalker/api/reflex.py22CODE
LOWpygwalker/api/webserver.py214CODE
LOWpygwalker/api/webserver.py314CODE
LOWpygwalker/api/webserver.py376CODE
LOWpygwalker/api/adapter.py16CODE
LOWpygwalker/api/walker.py60CODE
LOWpygwalker/api/html.py25CODE
LOWpygwalker/api/html.py79CODE
LOWpygwalker/api/html.py142CODE
LOWpygwalker/api/marimo.py64CODE
LOWpygwalker/api/component.py426CODE
LOWpygwalker/api/component.py309CODE
LOWpygwalker/api/gradio.py15CODE
LOWpygwalker/api/anywidget.py63CODE
LOWpygwalker/api/jupyter.py119CODE
LOWpygwalker/services/comm_handler.py43CODE
Self-Referential Comments6 hits · 20 pts
SeverityFileLineSnippetContext
MEDIUMpygwalker/communications/reflex_comm.py49# Create a FastAPI sub-application for PyGWalker APICOMMENT
MEDIUMpygwalker/communications/reflex_comm.py85 # Create a sub-application for PyGWalker routesCOMMENT
MEDIUMexamples/reflex_demo/app/app.py66 # Create a PyGWalker componentCOMMENT
MEDIUMexamples/reflex_demo/app/app.py156# Create a Reflex app with the fixed PyGWalker API transformerCOMMENT
MEDIUMscripts/test-init.sh14# Create the directory if it doesn't existCOMMENT
MEDIUMscripts/test-init.py11# Create the directory if it doesn't existCOMMENT
Modern Structural Boilerplate12 hits · 12 pts
SeverityFileLineSnippetContext
LOWpygwalker/__init__.py31__all__ = ["walk", "render", "table", "to_html", "FieldSpec", "GlobalVarManager", "component", "Walker", "spec"]CODE
LOWpygwalker/data_parsers/database_parser.py21logger = logging.getLogger(__name__)CODE
LOWpygwalker/data_parsers/spark_parser.py15logger = logging.getLogger(__name__)CODE
LOWpygwalker/data_parsers/cloud_dataset_parser.py14logger = logging.getLogger(__name__)CODE
LOWpygwalker/utils/check_walker_params.py4logger = logging.getLogger(__name__)CODE
LOWpygwalker/api/html.py22logger = logging.getLogger(__name__)CODE
LOWpygwalker/services/spec_manager.py28 def update_vis_spec(self, vis_spec: List[Dict[str, Any]]) -> None:CODE
LOWpygwalker/services/preview_image.py15logger = logging.getLogger(__name__)CODE
LOWpygwalker/services/check_update.py25logger = logging.getLogger(__name__)CODE
LOWpygwalker/services/format_invoke_walk_code.py12logger = logging.getLogger(__name__)CODE
LOWpygwalker/services/cloud_service.py16logger = logging.getLogger(__name__)CODE
LOWpygwalker_tools/metrics/__init__.py3__all__ = ["get_metrics_datas", "MetricsChart"]CODE
Deep Nesting12 hits · 12 pts
SeverityFileLineSnippetContext
LOWtests/test_frontend_contracts.py55CODE
LOWtests/test_frontend_contracts.py83CODE
LOWtests/test_frontend_contracts.py107CODE
LOWtests/test_readme_api_reference.py59CODE
LOWpygwalker/api/_walker_reuse.py23CODE
LOWpygwalker/api/component.py161CODE
LOWpygwalker/api/component.py309CODE
LOWpygwalker/services/spec.py110CODE
LOWpygwalker/services/spec.py132CODE
LOWpygwalker/communications/gradio_comm.py51CODE
LOWpygwalker/communications/streamlit_comm.py121CODE
LOWpygwalker_tools/metrics/core.py177CODE
Hallucination Indicators1 hit · 10 pts
SeverityFileLineSnippetContext
CRITICALapp/src/utils/communication.tsx232 const domain = window.parent.document.location.host.split(".").slice(-2).join('.');CODE
Structural Annotation Overuse4 hits · 8 pts
SeverityFileLineSnippetContext
LOWdocs/DEVELOPMENT.md65#### Step 1: Start the Vite Dev ServerCOMMENT
LOWdocs/DEVELOPMENT.md74#### Step 2: Start JupyterLab with Server ProxyCOMMENT
LOWdocs/DEVELOPMENT.md83#### Step 3: Configure PyGWalker to Use Dev ServerCOMMENT
LOWdocs/DEVELOPMENT.md100#### Step 4: Disable Dev Server (Return to Bundled Version)COMMENT
Redundant / Tautological Comments1 hit · 2 pts
SeverityFileLineSnippetContext
LOWscripts/test-init.sh37# Check if the file was downloaded successfullyCOMMENT
Fake / Example Data1 hit · 1 pts
SeverityFileLineSnippetContext
LOWapp/src/utils/communication.tsx185 attributeFilter: ["placeholder"],CODE