sql-assistant 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. sql_assistant/__init__.py +3 -0
  2. sql_assistant/api/__init__.py +1 -0
  3. sql_assistant/api/backup.py +116 -0
  4. sql_assistant/api/config.py +183 -0
  5. sql_assistant/api/conversation.py +71 -0
  6. sql_assistant/api/dependencies.py +22 -0
  7. sql_assistant/api/history.py +61 -0
  8. sql_assistant/api/models.py +221 -0
  9. sql_assistant/api/query.py +275 -0
  10. sql_assistant/api/routes.py +19 -0
  11. sql_assistant/api/schema.py +21 -0
  12. sql_assistant/config.py +144 -0
  13. sql_assistant/database/__init__.py +1 -0
  14. sql_assistant/database/backup.py +568 -0
  15. sql_assistant/database/connectors/__init__.py +1 -0
  16. sql_assistant/database/connectors/base.py +185 -0
  17. sql_assistant/database/connectors/exceptions.py +88 -0
  18. sql_assistant/database/connectors/mongodb.py +194 -0
  19. sql_assistant/database/connectors/mysql.py +110 -0
  20. sql_assistant/database/connectors/postgresql.py +133 -0
  21. sql_assistant/database/connectors/redis.py +132 -0
  22. sql_assistant/database/connectors/sqlserver.py +140 -0
  23. sql_assistant/database/history.py +290 -0
  24. sql_assistant/database/manager.py +178 -0
  25. sql_assistant/database/security.py +230 -0
  26. sql_assistant/llm/__init__.py +1 -0
  27. sql_assistant/llm/base.py +28 -0
  28. sql_assistant/llm/exceptions.py +96 -0
  29. sql_assistant/llm/manager.py +82 -0
  30. sql_assistant/llm/prompts.py +29 -0
  31. sql_assistant/llm/providers/__init__.py +1 -0
  32. sql_assistant/llm/providers/claude.py +132 -0
  33. sql_assistant/llm/providers/gemini.py +127 -0
  34. sql_assistant/llm/providers/openai_compatible.py +103 -0
  35. sql_assistant/llm/retry.py +88 -0
  36. sql_assistant/main.py +94 -0
  37. sql_assistant/settings.py +219 -0
  38. sql_assistant/web/__init__.py +1 -0
  39. sql_assistant/web/static/css/base.css +25 -0
  40. sql_assistant/web/static/css/components/backup.css +146 -0
  41. sql_assistant/web/static/css/components/chat.css +465 -0
  42. sql_assistant/web/static/css/components/modal.css +143 -0
  43. sql_assistant/web/static/css/components/settings.css +358 -0
  44. sql_assistant/web/static/css/components/sidebar.css +235 -0
  45. sql_assistant/web/static/css/components/toast.css +30 -0
  46. sql_assistant/web/static/css/style.css +10 -0
  47. sql_assistant/web/static/css/theme.css +200 -0
  48. sql_assistant/web/static/js/api.js +38 -0
  49. sql_assistant/web/static/js/app.js +161 -0
  50. sql_assistant/web/static/js/backup.js +216 -0
  51. sql_assistant/web/static/js/chat.js +238 -0
  52. sql_assistant/web/static/js/color-theme-manager.js +121 -0
  53. sql_assistant/web/static/js/confirm.js +95 -0
  54. sql_assistant/web/static/js/conversations.js +182 -0
  55. sql_assistant/web/static/js/settings.js +425 -0
  56. sql_assistant/web/static/js/state.js +43 -0
  57. sql_assistant/web/static/js/theme-manager.js +64 -0
  58. sql_assistant/web/static/js/ui.js +53 -0
  59. sql_assistant/web/templates/index.html +373 -0
  60. sql_assistant-1.0.0.dist-info/METADATA +24 -0
  61. sql_assistant-1.0.0.dist-info/RECORD +64 -0
  62. sql_assistant-1.0.0.dist-info/WHEEL +4 -0
  63. sql_assistant-1.0.0.dist-info/entry_points.txt +2 -0
  64. sql_assistant-1.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,219 @@
1
+ """配置数据模型"""
2
+
3
+ from pydantic import BaseModel, Field
4
+ from typing import Optional, Literal
5
+
6
+
7
+ # 默认 Base URL 映射
8
+ DEFAULT_BASE_URLS: dict[str, str] = {
9
+ "deepseek": "https://api.deepseek.com/v1",
10
+ "doubao": "https://ark.cn-beijing.volces.com/api/v3",
11
+ "kimi": "https://api.moonshot.cn/v1",
12
+ "qwen": "https://dashscope.aliyuncs.com/compatible-mode/v1",
13
+ "openai": "https://api.openai.com/v1",
14
+ "gemini": "https://generativelanguage.googleapis.com/v1beta",
15
+ "claude": "https://api.anthropic.com/v1",
16
+ "glm": "https://open.bigmodel.cn/api/paas/v4",
17
+ "minimax": "https://api.minimaxi.com/anthropic/v1",
18
+ "siliconflow": "https://api.siliconflow.cn/v1",
19
+ "openrouter": "https://openrouter.ai/api/v1",
20
+ "grok": "https://api.x.ai/v1",
21
+ "tencent": "https://tokenhub.tencentmaas.com/v1",
22
+ "mimo": "https://api.xiaomimimo.com/v1",
23
+ "ollama": "http://localhost:11434/v1",
24
+ }
25
+
26
+ # 默认模型映射(2025-2026最新版本)
27
+ DEFAULT_MODELS: dict[str, str] = {
28
+ "deepseek": "deepseek-v4-pro",
29
+ "doubao": "doubao-seed-2-0-pro-260215",
30
+ "kimi": "kimi-k2.6",
31
+ "qwen": "qwen3.6-max-preview",
32
+ "openai": "gpt-5.5",
33
+ "gemini": "gemini-3.1-pro-preview",
34
+ "claude": "claude-opus-4-7",
35
+ "glm": "glm-5.1",
36
+ "minimax": "MiniMax-M2.7",
37
+ "siliconflow": "deepseek-ai/DeepSeek-V3.2",
38
+ "openrouter": "deepseek/deepseek-v4-pro",
39
+ "grok": "grok-4.20-reasoning",
40
+ "tencent": "hy3-preview",
41
+ "mimo": "mimo-v2.5-pro",
42
+ "ollama": "llama3.3",
43
+ }
44
+
45
+ # 各提供商支持的模型列表(2025-2026最新)
46
+ PROVIDER_MODELS: dict[str, list[str]] = {
47
+ # === 已支持的提供商 ===
48
+ "deepseek": [
49
+ "deepseek-v4-pro",
50
+ "deepseek-v4-flash",
51
+ ],
52
+ "doubao": [
53
+ "doubao-seed-2-0-pro-260215",
54
+ "doubao-seed-2-0-lite-260215",
55
+ "doubao-seed-2-0-mini-260215",
56
+ "doubao-seed-1-8-251228",
57
+ ],
58
+ "kimi": [
59
+ "kimi-k2.6",
60
+ "kimi-k2.5",
61
+ "kimi-k2-thinking",
62
+ ],
63
+ "qwen": [
64
+ "qwen3.6-max-preview",
65
+ "qwen3.6-plus",
66
+ "qwen3.6-plus-2026-04-02",
67
+ "qwen3.6-flash",
68
+ "qwen3.6-flash-2026-04-16",
69
+ "qwen3.6-35b-a3b",
70
+ "qwen3.5-flash",
71
+ "qwen3.5-plus",
72
+ "qwen3-max",
73
+ "qwen3-vl-plus",
74
+ ],
75
+ "openai": [
76
+ "gpt-5.5",
77
+ "gpt-5.4-pro",
78
+ "gpt-5.4-mini",
79
+ "gpt-5.4-nano",
80
+ "gpt-4o",
81
+ "gpt-4o-mini",
82
+ "gpt-4-turbo",
83
+ "gpt-4.1",
84
+ "gpt-4.1-mini",
85
+ "gpt-4",
86
+ "gpt-3.5-turbo",
87
+ "gpt-3.5-turbo-16k",
88
+ "o1-preview",
89
+ "o1-mini",
90
+ ],
91
+ "gemini": [
92
+ "gemini-3.1-pro-preview",
93
+ "gemini-3-flash-preview",
94
+ "gemini-2.5-flash",
95
+ "gemini-2.5-flash-lite",
96
+ "gemini-2.5-pro",
97
+ "gemini-1.5-flash",
98
+ "gemini-1.5-pro",
99
+ "gemini-1.0-pro",
100
+ ],
101
+ "claude": [
102
+ "claude-opus-4-7",
103
+ "claude-opus-4-6",
104
+ "claude-sonnet-4-6",
105
+ "claude-sonnet-4-5",
106
+ "claude-haiku-4-5",
107
+ "claude-3-sonnet",
108
+ "claude-3-opus",
109
+ "claude-3-haiku",
110
+ "claude-2.1",
111
+ "claude-2",
112
+ ],
113
+ # === 尚未支持的提供商(待扩展)===
114
+ "glm": [
115
+ "glm-5.1",
116
+ "glm-5v-turbo",
117
+ "glm-5",
118
+ "glm-4.7",
119
+ "glm-4.7-flashx",
120
+ "glm-4.7-flash",
121
+ "glm-4.6",
122
+ "glm-4.6v",
123
+ "glm-4.6v-flash",
124
+ ],
125
+ "minimax": [
126
+ "MiniMax-M2.7",
127
+ ],
128
+ "siliconflow": [
129
+ "deepseek-ai/DeepSeek-V3.2",
130
+ "deepseek-ai/DeepSeek-R1",
131
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B",
132
+ "Qwen/Qwen3-VL-32B-Instruct",
133
+ "Pro/moonshotai/Kimi-K2.5",
134
+ "THUDM/GLM-4.1V-9B-Thinking",
135
+ "THUDM/GLM-Z1-Rumination-32B-0414",
136
+ ],
137
+ "openrouter": [
138
+ "deepseek/deepseek-v4-pro",
139
+ "deepseek/deepseek-v4-flash",
140
+ ],
141
+ "grok": [
142
+ "grok-4.20-reasoning",
143
+ "grok-4.20",
144
+ "grok-4.20-multi-agent",
145
+ "grok-4-1-fast-reasoning",
146
+ "grok-4-1-fast-non-reasoning",
147
+ "grok-code-fast-1",
148
+ ],
149
+ "tencent": [
150
+ "hy3-preview",
151
+ ],
152
+ "mimo": [
153
+ "mimo-v2.5-pro",
154
+ "mimo-v2.5",
155
+ ],
156
+ "ollama": [
157
+ "llama3.3",
158
+ "gemma3",
159
+ "deepseek-r1",
160
+ ],
161
+ }
162
+
163
+
164
+ class LLMProviderConfig(BaseModel):
165
+ """LLM 提供商配置"""
166
+ name: str = Field(description="配置名称,如 '我的DeepSeek'")
167
+ provider: Literal[
168
+ "deepseek", "doubao", "kimi", "qwen", "gemini", "claude", "openai",
169
+ "glm", "minimax", "siliconflow", "openrouter", "grok", "tencent", "mimo", "ollama"
170
+ ] = Field(description="LLM 提供商类型")
171
+ api_key: str = Field(default="", description="API Key")
172
+ base_url: str = Field(default="", description="API 基础URL(OpenAI兼容接口自动填充,可覆盖)")
173
+ model: str = Field(default="", description="模型名称")
174
+ enabled: bool = Field(default=True, description="是否启用")
175
+
176
+ def get_base_url(self) -> str:
177
+ return self.base_url or DEFAULT_BASE_URLS.get(self.provider, "")
178
+
179
+ def get_model(self) -> str:
180
+ return self.model or DEFAULT_MODELS.get(self.provider, "")
181
+
182
+ def is_openai_compatible(self) -> bool:
183
+ """除 Claude、Gemini 和 MiniMax 外都是 OpenAI 兼容接口"""
184
+ return self.provider not in ("claude", "gemini", "minimax")
185
+
186
+
187
+ class DatabaseConfig(BaseModel):
188
+ """数据库连接配置"""
189
+ name: str = Field(description="连接名称,如 '生产MySQL'")
190
+ db_type: Literal["mysql", "sqlserver", "postgresql", "redis", "mongodb"] = Field(
191
+ description="数据库类型"
192
+ )
193
+ host: str = Field(default="localhost", description="主机地址")
194
+ port: int = Field(default=0, description="端口")
195
+ user: str = Field(default="", description="用户名")
196
+ password: str = Field(default="", description="密码")
197
+ database: str = Field(default="", description="数据库名")
198
+ enabled: bool = Field(default=True, description="是否启用")
199
+
200
+ DEFAULT_PORTS: dict[str, int] = {
201
+ "mysql": 3306,
202
+ "sqlserver": 1433,
203
+ "postgresql": 5432,
204
+ "redis": 6379,
205
+ "mongodb": 27017,
206
+ }
207
+
208
+ def get_port(self) -> int:
209
+ return self.port or self.DEFAULT_PORTS.get(self.db_type, 0)
210
+
211
+
212
+ class AppSettings(BaseModel):
213
+ """应用全局设置"""
214
+ llm_providers: list[LLMProviderConfig] = Field(default_factory=list)
215
+ databases: list[DatabaseConfig] = Field(default_factory=list)
216
+ active_llm: str = Field(default="", description="当前激活的 LLM 配置名称")
217
+ active_database: str = Field(default="", description="当前激活的数据库配置名称")
218
+ max_history_rows: int = Field(default=1000, description="最大历史记录数")
219
+ theme: Literal["light", "dark", "auto"] = Field(default="auto")
@@ -0,0 +1 @@
1
+ """Web 界面模块"""
@@ -0,0 +1,25 @@
1
+ /* === Reset & Base Styles === */
2
+ /* 主题变量已移动到 theme.css */
3
+
4
+ * { margin: 0; padding: 0; box-sizing: border-box; }
5
+
6
+ body {
7
+ font-family: var(--font-sans);
8
+ background: var(--bg-primary);
9
+ color: var(--text-primary);
10
+ line-height: 1.5;
11
+ overflow: hidden;
12
+ height: 100vh;
13
+ }
14
+
15
+ /* === Layout === */
16
+ .app-container {
17
+ display: flex;
18
+ height: 100vh;
19
+ }
20
+
21
+ /* Scrollbar */
22
+ ::-webkit-scrollbar { width: 6px; }
23
+ ::-webkit-scrollbar-track { background: transparent; }
24
+ ::-webkit-scrollbar-thumb { background: var(--bg-hover); border-radius: 3px; }
25
+ ::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
@@ -0,0 +1,146 @@
1
+ /* === Backup Section === */
2
+ .backup-section {
3
+ display: flex;
4
+ gap: 24px;
5
+ height: calc(100% - 20px);
6
+ }
7
+
8
+ .backup-form {
9
+ flex: 1;
10
+ padding: 16px;
11
+ background: var(--bg-secondary);
12
+ border: 1px solid var(--border-color);
13
+ border-radius: var(--radius);
14
+ }
15
+
16
+ .backup-form h4 {
17
+ font-size: 14px;
18
+ margin-bottom: 16px;
19
+ color: var(--text-primary);
20
+ }
21
+
22
+ .backup-list-section {
23
+ flex: 1;
24
+ display: flex;
25
+ flex-direction: column;
26
+ }
27
+
28
+ .backup-list-section h4 {
29
+ font-size: 14px;
30
+ margin-bottom: 12px;
31
+ color: var(--text-primary);
32
+ }
33
+
34
+ .backup-list {
35
+ flex: 1;
36
+ overflow-y: auto;
37
+ background: var(--bg-secondary);
38
+ border: 1px solid var(--border-color);
39
+ border-radius: var(--radius);
40
+ padding: 8px;
41
+ }
42
+
43
+ .backup-item {
44
+ padding: 12px;
45
+ margin-bottom: 8px;
46
+ background: var(--bg-tertiary);
47
+ border-radius: var(--radius-sm);
48
+ border: 1px solid var(--border-color);
49
+ }
50
+
51
+ .backup-item:last-child {
52
+ margin-bottom: 0;
53
+ }
54
+
55
+ .backup-item-header {
56
+ display: flex;
57
+ justify-content: space-between;
58
+ align-items: center;
59
+ margin-bottom: 8px;
60
+ gap: 12px;
61
+ }
62
+
63
+ .backup-item-id {
64
+ font-size: 13px;
65
+ font-weight: 600;
66
+ color: var(--text-primary);
67
+ white-space: nowrap;
68
+ overflow: hidden;
69
+ text-overflow: ellipsis;
70
+ flex: 1;
71
+ }
72
+
73
+ .backup-item-type {
74
+ font-size: 11px;
75
+ padding: 2px 8px;
76
+ border-radius: 10px;
77
+ background: var(--accent);
78
+ color: white;
79
+ white-space: nowrap;
80
+ flex-shrink: 0;
81
+ }
82
+
83
+ .backup-item-type.incremental {
84
+ background: var(--accent);
85
+ }
86
+
87
+ .backup-item-info {
88
+ font-size: 12px;
89
+ color: var(--text-secondary);
90
+ margin-bottom: 4px;
91
+ }
92
+
93
+ .backup-item-meta {
94
+ display: flex;
95
+ gap: 12px;
96
+ font-size: 11px;
97
+ color: var(--text-muted);
98
+ }
99
+
100
+ .backup-item-actions {
101
+ display: flex;
102
+ gap: 4px;
103
+ margin-top: 8px;
104
+ }
105
+
106
+ .backup-item-actions button {
107
+ font-size: 11px;
108
+ padding: 4px 10px;
109
+ background: var(--bg-hover);
110
+ border: 1px solid var(--border-color);
111
+ color: var(--text-secondary);
112
+ cursor: pointer;
113
+ border-radius: var(--radius-sm);
114
+ transition: all var(--transition);
115
+ }
116
+
117
+ .backup-item-actions button:hover {
118
+ background: var(--bg-primary);
119
+ color: var(--text-primary);
120
+ }
121
+
122
+ .backup-item-actions button.danger {
123
+ color: var(--danger);
124
+ }
125
+
126
+ .empty-state {
127
+ text-align: center;
128
+ color: var(--text-muted);
129
+ font-size: 13px;
130
+ padding: 24px;
131
+ }
132
+
133
+ #backup-tables {
134
+ width: 100%;
135
+ padding: 4px;
136
+ background: var(--bg-tertiary);
137
+ border: 1px solid var(--border-color);
138
+ border-radius: var(--radius-sm);
139
+ color: var(--text-primary);
140
+ font-size: 13px;
141
+ outline: none;
142
+ }
143
+
144
+ #backup-tables:focus {
145
+ border-color: var(--accent);
146
+ }