fix(ci): fix black/ruff failures, add CoC and PR template

- Fix Python formatting (sync no longer strips blank lines from .py files)
- Remove test_community_build.py (tests private sync module)
- Fix ruff warnings in test files
- Add CODE_OF_CONDUCT.md
- Add .github/PULL_REQUEST_TEMPLATE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
airano
2026-02-17 18:19:39 +03:30
parent c9083d86b1
commit c73e39f6e4
135 changed files with 1185 additions and 317 deletions

View File

@@ -5,6 +5,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (6 tools)"""
return [
@@ -112,10 +113,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# Client Functions (6)
# =====================
async def list_clients(client: OpenPanelClient, project_id: str) -> str:
"""List all API clients"""
try:
@@ -132,6 +135,7 @@ async def list_clients(client: OpenPanelClient, project_id: str) -> str:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_client(client: OpenPanelClient, project_id: str, client_id: str) -> str:
"""Get API client details"""
try:
@@ -149,6 +153,7 @@ async def get_client(client: OpenPanelClient, project_id: str, client_id: str) -
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def create_client(
client: OpenPanelClient,
project_id: str,
@@ -181,6 +186,7 @@ async def create_client(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def delete_client(client: OpenPanelClient, project_id: str, client_id: str) -> str:
"""Delete an API client"""
try:
@@ -199,6 +205,7 @@ async def delete_client(client: OpenPanelClient, project_id: str, client_id: str
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def regenerate_client_secret(client: OpenPanelClient, project_id: str, client_id: str) -> str:
"""Regenerate client secret"""
try:
@@ -217,6 +224,7 @@ async def regenerate_client_secret(client: OpenPanelClient, project_id: str, cli
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def update_client_mode(
client: OpenPanelClient,
project_id: str,

View File

@@ -5,6 +5,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (10 tools)"""
return [
@@ -215,10 +216,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# Dashboard Functions (10)
# =====================
async def list_dashboards(client: OpenPanelClient, project_id: str) -> str:
"""List all dashboards"""
try:
@@ -235,6 +238,7 @@ async def list_dashboards(client: OpenPanelClient, project_id: str) -> str:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_dashboard(client: OpenPanelClient, project_id: str, dashboard_id: str) -> str:
"""Get dashboard details"""
try:
@@ -252,6 +256,7 @@ async def get_dashboard(client: OpenPanelClient, project_id: str, dashboard_id:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def create_dashboard(
client: OpenPanelClient, project_id: str, name: str, description: str | None = None
) -> str:
@@ -273,6 +278,7 @@ async def create_dashboard(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def update_dashboard(
client: OpenPanelClient,
project_id: str,
@@ -303,6 +309,7 @@ async def update_dashboard(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def delete_dashboard(client: OpenPanelClient, project_id: str, dashboard_id: str) -> str:
"""Delete a dashboard"""
try:
@@ -320,6 +327,7 @@ async def delete_dashboard(client: OpenPanelClient, project_id: str, dashboard_i
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def add_chart(
client: OpenPanelClient,
project_id: str,
@@ -353,6 +361,7 @@ async def add_chart(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def update_chart(
client: OpenPanelClient,
project_id: str,
@@ -388,6 +397,7 @@ async def update_chart(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def delete_chart(
client: OpenPanelClient, project_id: str, dashboard_id: str, chart_id: str
) -> str:
@@ -408,6 +418,7 @@ async def delete_chart(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def duplicate_dashboard(
client: OpenPanelClient, project_id: str, dashboard_id: str, new_name: str
) -> str:
@@ -428,6 +439,7 @@ async def duplicate_dashboard(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def share_dashboard(
client: OpenPanelClient,
project_id: str,

View File

@@ -5,6 +5,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (10 tools)"""
return [
@@ -302,10 +303,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# Event Tracking Functions (10)
# =====================
async def track_event(
client: OpenPanelClient,
name: str,
@@ -340,6 +343,7 @@ async def track_event(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def track_page_view(
client: OpenPanelClient,
path: str,
@@ -384,6 +388,7 @@ async def track_page_view(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def track_screen_view(
client: OpenPanelClient,
screen_name: str,
@@ -425,6 +430,7 @@ async def track_screen_view(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def identify_user(
client: OpenPanelClient,
profile_id: str,
@@ -461,6 +467,7 @@ async def identify_user(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def set_user_properties(
client: OpenPanelClient, profile_id: str, properties: dict[str, Any]
) -> str:
@@ -482,6 +489,7 @@ async def set_user_properties(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def increment_property(
client: OpenPanelClient, profile_id: str, property_name: str, value: int = 1
) -> str:
@@ -519,6 +527,7 @@ async def increment_property(
ensure_ascii=False,
)
async def decrement_property(
client: OpenPanelClient, profile_id: str, property_name: str, value: int = 1
) -> str:
@@ -556,6 +565,7 @@ async def decrement_property(
ensure_ascii=False,
)
async def alias_user(client: OpenPanelClient, profile_id: str, alias: str) -> str:
"""Create an alias to link two profile IDs"""
try:
@@ -583,6 +593,7 @@ async def alias_user(client: OpenPanelClient, profile_id: str, alias: str) -> st
ensure_ascii=False,
)
async def track_revenue(
client: OpenPanelClient,
amount: float,
@@ -629,6 +640,7 @@ async def track_revenue(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def track_batch(
client: OpenPanelClient,
events: list[dict[str, Any]],

View File

@@ -10,6 +10,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
from plugins.openpanel.handlers.utils import get_project_id as _get_project_id
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (10 tools)"""
return [
@@ -375,10 +376,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# Export Functions (10)
# =====================
async def export_events(
client: OpenPanelClient,
project_id: str | None = None,
@@ -422,6 +425,7 @@ async def export_events(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def export_events_csv(
client: OpenPanelClient,
project_id: str | None = None,
@@ -480,6 +484,7 @@ async def export_events_csv(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def export_chart_data(
client: OpenPanelClient,
events: list[dict[str, Any]],
@@ -517,6 +522,7 @@ async def export_chart_data(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_event_count(
client: OpenPanelClient,
project_id: str | None = None,
@@ -555,6 +561,7 @@ async def get_event_count(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_unique_users(
client: OpenPanelClient, project_id: str | None = None, date_range: str = "30d"
) -> str:
@@ -605,6 +612,7 @@ async def get_unique_users(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_page_views(
client: OpenPanelClient,
project_id: str | None = None,
@@ -660,6 +668,7 @@ async def get_page_views(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_top_pages(
client: OpenPanelClient, project_id: str | None = None, date_range: str = "30d", limit: int = 10
) -> str:
@@ -707,6 +716,7 @@ async def get_top_pages(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_top_referrers(
client: OpenPanelClient, project_id: str | None = None, date_range: str = "30d", limit: int = 10
) -> str:
@@ -764,6 +774,7 @@ async def get_top_referrers(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_geo_data(
client: OpenPanelClient,
project_id: str | None = None,
@@ -827,6 +838,7 @@ async def get_geo_data(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_device_data(
client: OpenPanelClient,
project_id: str | None = None,

View File

@@ -5,6 +5,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (8 tools)"""
return [
@@ -189,10 +190,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# Funnel Functions (8)
# =====================
async def list_funnels(client: OpenPanelClient, project_id: str) -> str:
"""List all funnels for a project"""
try:
@@ -209,6 +212,7 @@ async def list_funnels(client: OpenPanelClient, project_id: str) -> str:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_funnel(
client: OpenPanelClient, project_id: str, funnel_id: str, date_range: str = "30d"
) -> str:
@@ -229,6 +233,7 @@ async def get_funnel(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def create_funnel(
client: OpenPanelClient,
project_id: str,
@@ -262,6 +267,7 @@ async def create_funnel(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def update_funnel(
client: OpenPanelClient,
project_id: str,
@@ -295,6 +301,7 @@ async def update_funnel(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def delete_funnel(client: OpenPanelClient, project_id: str, funnel_id: str) -> str:
"""Delete a funnel"""
try:
@@ -312,6 +319,7 @@ async def delete_funnel(client: OpenPanelClient, project_id: str, funnel_id: str
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_funnel_conversion(
client: OpenPanelClient, project_id: str, funnel_id: str, date_range: str = "30d"
) -> str:
@@ -332,6 +340,7 @@ async def get_funnel_conversion(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_funnel_breakdown(
client: OpenPanelClient,
project_id: str,
@@ -357,6 +366,7 @@ async def get_funnel_breakdown(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def compare_funnels(
client: OpenPanelClient, project_id: str, funnel_ids: list[str], date_range: str = "30d"
) -> str:

View File

@@ -5,6 +5,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (8 tools)"""
return [
@@ -183,10 +184,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# Profile Functions (8)
# =====================
async def list_profiles(
client: OpenPanelClient,
project_id: str,
@@ -210,6 +213,7 @@ async def list_profiles(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_profile(client: OpenPanelClient, project_id: str, profile_id: str) -> str:
"""Get profile details"""
try:
@@ -249,6 +253,7 @@ async def get_profile(client: OpenPanelClient, project_id: str, profile_id: str)
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def search_profiles(
client: OpenPanelClient,
project_id: str,
@@ -278,6 +283,7 @@ async def search_profiles(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_profile_events(
client: OpenPanelClient,
project_id: str,
@@ -308,6 +314,7 @@ async def get_profile_events(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_profile_sessions(
client: OpenPanelClient, project_id: str, profile_id: str, limit: int = 20
) -> str:
@@ -334,6 +341,7 @@ async def get_profile_sessions(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def delete_profile(
client: OpenPanelClient, project_id: str, profile_id: str, confirm: bool = False
) -> str:
@@ -365,6 +373,7 @@ async def delete_profile(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def merge_profiles(
client: OpenPanelClient, project_id: str, primary_profile_id: str, secondary_profile_id: str
) -> str:
@@ -385,6 +394,7 @@ async def merge_profiles(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def export_profile_data(
client: OpenPanelClient, project_id: str, profile_id: str, format: str = "json"
) -> str:

View File

@@ -5,6 +5,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (8 tools)"""
return [
@@ -140,10 +141,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# Project Functions (8)
# =====================
async def list_projects(client: OpenPanelClient) -> str:
"""List all projects"""
try:
@@ -159,6 +162,7 @@ async def list_projects(client: OpenPanelClient) -> str:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_project(client: OpenPanelClient, project_id: str) -> str:
"""Get project details"""
try:
@@ -175,6 +179,7 @@ async def get_project(client: OpenPanelClient, project_id: str) -> str:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def create_project(
client: OpenPanelClient, name: str, domain: str | None = None, timezone: str = "UTC"
) -> str:
@@ -195,6 +200,7 @@ async def create_project(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def update_project(
client: OpenPanelClient,
project_id: str,
@@ -226,6 +232,7 @@ async def update_project(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def delete_project(client: OpenPanelClient, project_id: str, confirm: bool = False) -> str:
"""Delete a project"""
try:
@@ -254,6 +261,7 @@ async def delete_project(client: OpenPanelClient, project_id: str, confirm: bool
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_project_stats(
client: OpenPanelClient, project_id: str, date_range: str = "30d"
) -> str:
@@ -298,6 +306,7 @@ async def get_project_stats(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_project_settings(client: OpenPanelClient, project_id: str) -> str:
"""Get project settings"""
try:
@@ -314,6 +323,7 @@ async def get_project_settings(client: OpenPanelClient, project_id: str) -> str:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def update_project_settings(
client: OpenPanelClient, project_id: str, settings: dict[str, Any]
) -> str:

View File

@@ -9,6 +9,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
from plugins.openpanel.handlers.utils import get_project_id as _get_project_id
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (8 tools)"""
return [
@@ -244,10 +245,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# Report Functions (8)
# =====================
async def get_overview_report(
client: OpenPanelClient, project_id: str | None = None, date_range: str = "30d"
) -> str:
@@ -310,6 +313,7 @@ async def get_overview_report(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_retention_report(
client: OpenPanelClient,
project_id: str | None = None,
@@ -343,6 +347,7 @@ async def get_retention_report(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_cohort_report(
client: OpenPanelClient,
project_id: str | None = None,
@@ -373,6 +378,7 @@ async def get_cohort_report(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_paths_report(
client: OpenPanelClient,
project_id: str | None = None,
@@ -403,6 +409,7 @@ async def get_paths_report(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_realtime_stats(client: OpenPanelClient, project_id: str | None = None) -> str:
"""Get real-time visitor statistics using chart.chart with 30min range"""
try:
@@ -443,6 +450,7 @@ async def get_realtime_stats(client: OpenPanelClient, project_id: str | None = N
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_ab_test_results(
client: OpenPanelClient,
test_name: str,
@@ -469,6 +477,7 @@ async def get_ab_test_results(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def create_scheduled_report(
client: OpenPanelClient,
name: str,
@@ -499,6 +508,7 @@ async def create_scheduled_report(
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def export_report_pdf(
client: OpenPanelClient,
report_type: str,

View File

@@ -5,6 +5,7 @@ from typing import Any
from plugins.openpanel.client import OpenPanelClient
def get_tool_specifications() -> list[dict[str, Any]]:
"""Return tool specifications for ToolGenerator (6 tools)"""
return [
@@ -72,10 +73,12 @@ def get_tool_specifications() -> list[dict[str, Any]]:
},
]
# =====================
# System Functions (6)
# =====================
async def health_check(client: OpenPanelClient) -> str:
"""Check OpenPanel instance health"""
try:
@@ -109,6 +112,7 @@ async def health_check(client: OpenPanelClient) -> str:
ensure_ascii=False,
)
async def get_instance_info(client: OpenPanelClient) -> str:
"""Get OpenPanel instance information"""
try:
@@ -126,6 +130,7 @@ async def get_instance_info(client: OpenPanelClient) -> str:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_usage_stats(client: OpenPanelClient, project_id: str, date_range: str = "30d") -> str:
"""Get usage statistics for a project"""
try:
@@ -173,6 +178,7 @@ async def get_usage_stats(client: OpenPanelClient, project_id: str, date_range:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def get_storage_stats(client: OpenPanelClient, project_id: str) -> str:
"""Get storage usage statistics"""
try:
@@ -199,6 +205,7 @@ async def get_storage_stats(client: OpenPanelClient, project_id: str) -> str:
except Exception as e:
return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
async def test_connection(client: OpenPanelClient) -> str:
"""Test connection to OpenPanel API"""
try:
@@ -232,6 +239,7 @@ async def test_connection(client: OpenPanelClient) -> str:
ensure_ascii=False,
)
async def get_rate_limit_status(client: OpenPanelClient) -> str:
"""Check current rate limit status"""
try:

View File

@@ -2,6 +2,7 @@
from plugins.openpanel.client import OpenPanelClient
def get_project_id(client: OpenPanelClient, project_id: str | None) -> str:
"""
Get effective project_id, using default if not provided.