coze-coding-dev-sdk 0.5.18__tar.gz → 0.5.20__tar.gz
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.
Potentially problematic release.
This version of coze-coding-dev-sdk might be problematic. Click here for more details.
- {coze_coding_dev_sdk-0.5.18/coze_coding_dev_sdk.egg-info → coze_coding_dev_sdk-0.5.20}/PKG-INFO +7 -2
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/README.md +1 -1
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/cli/db.py +96 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/cli/supabase.py +139 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/core/__init__.py +12 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/core/client.py +37 -31
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/core/config.py +97 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/core/desktop_credential.py +37 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/core/developer_credential.py +46 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/core/endpoints.py +8 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/core/integration_request.py +51 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/core/project_env.py +109 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/core/runtime.py +207 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/core/runtime_resource_cache.py +61 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/database/__init__.py +2 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/database/client.py +35 -26
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/database/environment.py +45 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/database/migration.py +24 -17
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/database/setup.py +45 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/fetch/client.py +4 -3
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/llm/client.py +3 -2
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/client.py +14 -18
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/s3/__init__.py +2 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/s3/client.py +116 -72
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/s3/environment.py +57 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/s3/setup.py +36 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/supabase/__init__.py +31 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/supabase/client.py +164 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/supabase/models.py +96 -0
- coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk/supabase/setup.py +47 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/video/client.py +4 -4
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/video/models.py +1 -1
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20/coze_coding_dev_sdk.egg-info}/PKG-INFO +7 -2
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk.egg-info/SOURCES.txt +12 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk.egg-info/requires.txt +5 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/pyproject.toml +6 -1
- coze_coding_dev_sdk-0.5.18/coze_coding_dev_sdk/cli/db.py +0 -156
- coze_coding_dev_sdk-0.5.18/coze_coding_dev_sdk/cli/supabase.py +0 -727
- coze_coding_dev_sdk-0.5.18/coze_coding_dev_sdk/core/config.py +0 -58
- coze_coding_dev_sdk-0.5.18/coze_coding_dev_sdk/supabase/__init__.py +0 -57
- coze_coding_dev_sdk-0.5.18/coze_coding_dev_sdk/supabase/client.py +0 -494
- coze_coding_dev_sdk-0.5.18/coze_coding_dev_sdk/supabase/models.py +0 -244
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/CHANGELOG.md +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/LICENSE +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/MANIFEST.in +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/chat.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/cli.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/constants.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/document.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/embedding.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/image.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/knowledge.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/search.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/storage.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/utils.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/video.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/video_edit.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/cli/voice.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/core/exceptions.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/core/url_utils.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/document/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/document/client.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/document/docx_generator.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/document/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/document/pdf_generator.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/document/pptx_generator.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/document/xlsx_generator.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/embedding/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/embedding/client.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/embedding/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/fetch/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/fetch/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/image/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/image/client.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/image/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/knowledge/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/knowledge/client.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/knowledge/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/llm/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/llm/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/memory/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/memory/client.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/buffer.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/interceptors/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/interceptors/boto3_hook.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/interceptors/httpx_transport.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/singleton.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/report/utils.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/s3/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/search/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/search/client.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/search/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/video/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/video_edit/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/video_edit/examples.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/video_edit/frame_extractor.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/video_edit/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/video_edit/video_edit.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/voice/__init__.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/voice/asr.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/voice/models.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/voice/tts.py +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk.egg-info/dependency_links.txt +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk.egg-info/entry_points.txt +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk.egg-info/top_level.txt +0 -0
- {coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/setup.cfg +0 -0
{coze_coding_dev_sdk-0.5.18/coze_coding_dev_sdk.egg-info → coze_coding_dev_sdk-0.5.20}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coze-coding-dev-sdk
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.20
|
|
4
4
|
Summary: Coze Coding Dev SDK - 优雅的多功能 AI SDK,支持图片生成、视频生成、语音合成、语音识别、大语言模型、联网搜索和文本/多模态 Embedding。包含命令行工具 coze-coding-ai,支持 Context 上下文追踪
|
|
5
5
|
Author-email: Coze Coding Integration Team <support@coze.com>
|
|
6
6
|
Maintainer-email: Coze Coding Integration Team <support@coze.com>
|
|
@@ -44,8 +44,13 @@ Requires-Dist: click>=8.0.0
|
|
|
44
44
|
Requires-Dist: rich>=13.0.0
|
|
45
45
|
Requires-Dist: supabase==2.27.3
|
|
46
46
|
Requires-Dist: httpx==0.28.1
|
|
47
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
47
48
|
Requires-Dist: markdown>=3.0.0
|
|
49
|
+
Requires-Dist: numpy>=1.26.0
|
|
50
|
+
Requires-Dist: openpyxl>=3.1.0
|
|
51
|
+
Requires-Dist: Pillow>=10.0.0
|
|
48
52
|
Requires-Dist: python-docx>=1.0.0
|
|
53
|
+
Requires-Dist: python-pptx>=1.0.0
|
|
49
54
|
Requires-Dist: reportlab>=4.0.0
|
|
50
55
|
Requires-Dist: cssutils>=2.0.0
|
|
51
56
|
Provides-Extra: dev
|
|
@@ -107,7 +112,7 @@ pip install -e ".[dev]"
|
|
|
107
112
|
#### 必需配置
|
|
108
113
|
|
|
109
114
|
```bash
|
|
110
|
-
export
|
|
115
|
+
export COZE_API_TOKEN="your_user_token"
|
|
111
116
|
export COZE_INTEGRATION_BASE_URL="https://api.coze.com"
|
|
112
117
|
export COZE_INTEGRATION_MODEL_BASE_URL="https://model.coze.com"
|
|
113
118
|
```
|
|
@@ -50,7 +50,7 @@ pip install -e ".[dev]"
|
|
|
50
50
|
#### 必需配置
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
export
|
|
53
|
+
export COZE_API_TOKEN="your_user_token"
|
|
54
54
|
export COZE_INTEGRATION_BASE_URL="https://api.coze.com"
|
|
55
55
|
export COZE_INTEGRATION_MODEL_BASE_URL="https://model.coze.com"
|
|
56
56
|
```
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
数据库 CLI 命令
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
# 默认路径
|
|
11
|
+
DEFAULT_MODEL_OUTPUT = "src/storage/database/shared/model.py"
|
|
12
|
+
DEFAULT_MODEL_IMPORT_PATH = "storage.database.shared.model"
|
|
13
|
+
DEFAULT_MODEL_PATH = "src"
|
|
14
|
+
|
|
15
|
+
console = Console()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _get_workspace_path() -> str:
|
|
19
|
+
"""获取工程根目录:`.env` 的 PROJECT_PATH 优先,其次环境变量 WORKSPACE_PATH。
|
|
20
|
+
|
|
21
|
+
两者都读不到即明确报错(不静默退回 cwd,避免把文件写到错误目录)。
|
|
22
|
+
"""
|
|
23
|
+
from coze_coding_dev_sdk.core.runtime import resolve_workspace_path
|
|
24
|
+
|
|
25
|
+
workspace = resolve_workspace_path()
|
|
26
|
+
if not workspace:
|
|
27
|
+
console.print(
|
|
28
|
+
"[red]未能确定工程根目录:请在当前目录 .env 中设置 PROJECT_PATH"
|
|
29
|
+
"(或由运行时注入 WORKSPACE_PATH)。[/red]"
|
|
30
|
+
)
|
|
31
|
+
raise SystemExit(1)
|
|
32
|
+
return workspace
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@click.group()
|
|
36
|
+
def db():
|
|
37
|
+
"""Database management commands."""
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@db.command()
|
|
42
|
+
@click.argument("output_path", required=False, default=None)
|
|
43
|
+
@click.option("--verbose", "-v", is_flag=True, help="Verbose output")
|
|
44
|
+
def generate_models(output_path: str, verbose: bool):
|
|
45
|
+
"""
|
|
46
|
+
Generate ORM models from database.
|
|
47
|
+
|
|
48
|
+
OUTPUT_PATH: Path to output model file (default: src/storage/database/shared/model.py)
|
|
49
|
+
"""
|
|
50
|
+
from coze_coding_dev_sdk.database import generate_models as _generate_models
|
|
51
|
+
|
|
52
|
+
if output_path is None:
|
|
53
|
+
workspace = _get_workspace_path()
|
|
54
|
+
output_path = os.path.join(workspace, DEFAULT_MODEL_OUTPUT)
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
_generate_models(output_path, verbose=verbose)
|
|
58
|
+
click.echo(f"Models generated at {output_path}")
|
|
59
|
+
except Exception as e:
|
|
60
|
+
click.echo(f"Error: {e}", err=True)
|
|
61
|
+
raise SystemExit(1)
|
|
62
|
+
|
|
63
|
+
@db.command()
|
|
64
|
+
@click.option(
|
|
65
|
+
"--model-import-path",
|
|
66
|
+
default=DEFAULT_MODEL_IMPORT_PATH,
|
|
67
|
+
help=f"Model import path (default: {DEFAULT_MODEL_IMPORT_PATH})",
|
|
68
|
+
)
|
|
69
|
+
@click.option(
|
|
70
|
+
"--model-path",
|
|
71
|
+
default=None,
|
|
72
|
+
help=f"Path to add to sys.path for model import (default: $WORKSPACE_PATH/{DEFAULT_MODEL_PATH})",
|
|
73
|
+
)
|
|
74
|
+
@click.option("--verbose", "-v", is_flag=True, help="Verbose output")
|
|
75
|
+
def upgrade(model_import_path: str, model_path: str, verbose: bool):
|
|
76
|
+
"""
|
|
77
|
+
Run database migrations.
|
|
78
|
+
|
|
79
|
+
Automatically generates migration and upgrades to head.
|
|
80
|
+
"""
|
|
81
|
+
from coze_coding_dev_sdk.database import upgrade as _upgrade
|
|
82
|
+
|
|
83
|
+
if model_path is None:
|
|
84
|
+
workspace = _get_workspace_path()
|
|
85
|
+
model_path = os.path.join(workspace, DEFAULT_MODEL_PATH)
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
_upgrade(
|
|
89
|
+
model_import_path=model_import_path,
|
|
90
|
+
model_path=model_path,
|
|
91
|
+
verbose=verbose,
|
|
92
|
+
)
|
|
93
|
+
click.echo("Database upgraded successfully")
|
|
94
|
+
except Exception as e:
|
|
95
|
+
click.echo(f"Error: {e}", err=True)
|
|
96
|
+
raise SystemExit(1)
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""Supabase Edge Function and Auth CLI; Storage CRUD uses the dedicated S3 command."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
from ..core.config import Config
|
|
10
|
+
from ..supabase import SupabaseClient
|
|
11
|
+
from .utils import parse_headers
|
|
12
|
+
|
|
13
|
+
console = Console()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@click.group()
|
|
17
|
+
def supabase():
|
|
18
|
+
"""Supabase Edge Functions 与 Auth 配置管理命令。"""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@supabase.group("functions")
|
|
22
|
+
def functions():
|
|
23
|
+
"""Edge Functions 管理命令。"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@functions.command("list")
|
|
27
|
+
@click.option("--header", "-H", multiple=True, help="自定义 HTTP 请求头")
|
|
28
|
+
def functions_list(header: tuple):
|
|
29
|
+
"""列出 Edge Functions。"""
|
|
30
|
+
response = SupabaseClient(Config(), custom_headers=parse_headers(header) or {}).list_functions()
|
|
31
|
+
if response.code != 0:
|
|
32
|
+
raise click.ClickException(response.msg)
|
|
33
|
+
console.print_json(json.dumps([item.__dict__ for item in response.functions], ensure_ascii=False))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@functions.command("get")
|
|
37
|
+
@click.argument("slug")
|
|
38
|
+
@click.option("--header", "-H", multiple=True, help="自定义 HTTP 请求头")
|
|
39
|
+
def functions_get(slug: str, header: tuple):
|
|
40
|
+
"""获取 Edge Function 详情和源码。"""
|
|
41
|
+
response = SupabaseClient(Config(), custom_headers=parse_headers(header) or {}).get_function(slug)
|
|
42
|
+
if response.code != 0:
|
|
43
|
+
raise click.ClickException(response.msg)
|
|
44
|
+
console.print_json(json.dumps({"function": response.function.__dict__ if response.function else None, "files": [item.__dict__ for item in response.files]}, ensure_ascii=False))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@functions.command("deploy")
|
|
48
|
+
@click.argument("slug")
|
|
49
|
+
@click.option("--code", help="单文件函数源码")
|
|
50
|
+
@click.option("--file", "files", multiple=True, nargs=2, help="多文件函数的名称和内容对,可重复传入")
|
|
51
|
+
@click.option("--name")
|
|
52
|
+
@click.option("--entrypoint")
|
|
53
|
+
@click.option("--verify-jwt/--no-verify-jwt", default=None)
|
|
54
|
+
@click.option("--header", "-H", multiple=True, help="自定义 HTTP 请求头")
|
|
55
|
+
def functions_deploy(slug: str, code: Optional[str], files: tuple, name: Optional[str], entrypoint: Optional[str], verify_jwt: Optional[bool], header: tuple):
|
|
56
|
+
"""部署或更新 Edge Function。"""
|
|
57
|
+
if not code and not files:
|
|
58
|
+
raise click.UsageError("必须提供 --code 或 --file")
|
|
59
|
+
options = {"code": code, "files": [{"name": item[0], "content": item[1]} for item in files] or None, "name": name, "entrypoint": entrypoint, "verify_jwt": verify_jwt}
|
|
60
|
+
response = SupabaseClient(Config(), custom_headers=parse_headers(header) or {}).deploy_function(slug, **{key: value for key, value in options.items() if value is not None})
|
|
61
|
+
if response.code != 0 or not response.success:
|
|
62
|
+
raise click.ClickException(response.msg or "Edge Function deployment failed")
|
|
63
|
+
console.print_json(json.dumps(response.__dict__, ensure_ascii=False))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@functions.command("delete")
|
|
67
|
+
@click.argument("slug")
|
|
68
|
+
@click.option("--header", "-H", multiple=True, help="自定义 HTTP 请求头")
|
|
69
|
+
def functions_delete(slug: str, header: tuple):
|
|
70
|
+
"""删除 Edge Function。"""
|
|
71
|
+
response = SupabaseClient(Config(), custom_headers=parse_headers(header) or {}).delete_function(slug)
|
|
72
|
+
if response.code != 0 or not response.success:
|
|
73
|
+
raise click.ClickException(response.msg or "Edge Function deletion failed")
|
|
74
|
+
console.print_json(json.dumps(response.__dict__, ensure_ascii=False))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@supabase.group("auth")
|
|
78
|
+
def auth():
|
|
79
|
+
"""Auth(认证配置)管理命令。"""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@auth.command("get-config-v2")
|
|
83
|
+
@click.option("--mock", is_flag=True, help="使用 mock 模式(测试运行,不会真正执行操作)")
|
|
84
|
+
@click.option("--header", "-H", multiple=True, help="自定义 HTTP 请求头")
|
|
85
|
+
def auth_get_config(mock: bool, header: tuple):
|
|
86
|
+
"""获取 Auth 认证配置。"""
|
|
87
|
+
if mock:
|
|
88
|
+
console.print_json(json.dumps({"config": {}, "mock": True}))
|
|
89
|
+
return
|
|
90
|
+
response = SupabaseClient(Config(), custom_headers=parse_headers(header) or {}).get_auth_config_v2()
|
|
91
|
+
if response.code != 0 or response.status != 3:
|
|
92
|
+
raise click.ClickException(response.msg or f"Auth status={response.status}")
|
|
93
|
+
config = response.config
|
|
94
|
+
console.print_json(json.dumps({"status": response.status, "config": {
|
|
95
|
+
"project_id": config.project_id,
|
|
96
|
+
"icon_url": config.icon_url,
|
|
97
|
+
"name": config.name,
|
|
98
|
+
"email_config": config.email_config.__dict__ if config.email_config else None,
|
|
99
|
+
"phone_config": config.phone_config.__dict__ if config.phone_config else None,
|
|
100
|
+
}} if config else None, ensure_ascii=False))
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@auth.command("update-config-v2")
|
|
104
|
+
@click.option("--name")
|
|
105
|
+
@click.option("--site-url")
|
|
106
|
+
@click.option("--disable-signup/--enable-signup", default=None)
|
|
107
|
+
@click.option("--external-email-enabled/--external-email-disabled", default=None)
|
|
108
|
+
@click.option("--external-phone-enabled/--external-phone-disabled", default=None)
|
|
109
|
+
@click.option("--mock", is_flag=True, help="使用 mock 模式(测试运行,不会真正执行操作)")
|
|
110
|
+
@click.option("--header", "-H", multiple=True, help="自定义 HTTP 请求头")
|
|
111
|
+
def auth_update_config(
|
|
112
|
+
name: Optional[str], site_url: Optional[str], disable_signup: Optional[bool],
|
|
113
|
+
external_email_enabled: Optional[bool], external_phone_enabled: Optional[bool],
|
|
114
|
+
mock: bool, header: tuple,
|
|
115
|
+
):
|
|
116
|
+
"""更新 Auth 认证配置(V2)。"""
|
|
117
|
+
payload = {}
|
|
118
|
+
if name is not None:
|
|
119
|
+
payload["app_name"] = name
|
|
120
|
+
email_config = {}
|
|
121
|
+
if site_url is not None:
|
|
122
|
+
email_config["site_url"] = site_url
|
|
123
|
+
if disable_signup is not None:
|
|
124
|
+
email_config["disable_signup"] = disable_signup
|
|
125
|
+
if external_email_enabled is not None:
|
|
126
|
+
email_config["external_email_enabled"] = external_email_enabled
|
|
127
|
+
if email_config:
|
|
128
|
+
payload["email_config"] = email_config
|
|
129
|
+
if external_phone_enabled is not None:
|
|
130
|
+
payload["phone_config"] = {"external_phone_enabled": external_phone_enabled}
|
|
131
|
+
if not payload:
|
|
132
|
+
raise click.UsageError("至少需要提供一个配置项")
|
|
133
|
+
if mock:
|
|
134
|
+
console.print_json(json.dumps({"success": True, "should_update_ui": False, "mock": True}))
|
|
135
|
+
return
|
|
136
|
+
response = SupabaseClient(Config(), custom_headers=parse_headers(header) or {}).update_auth_config_v2(payload)
|
|
137
|
+
if response.code != 0:
|
|
138
|
+
raise click.ClickException(response.msg)
|
|
139
|
+
console.print_json(json.dumps({"success": response.success, "should_update_ui": response.should_update_ui}))
|
{coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/core/__init__.py
RENAMED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
from .client import BaseClient
|
|
2
2
|
from .config import Config
|
|
3
|
+
from .endpoints import (
|
|
4
|
+
IDE_API_BASE_URL,
|
|
5
|
+
INTEGRATION_BASE_URL,
|
|
6
|
+
INTEGRATION_MODEL_BASE_URL,
|
|
7
|
+
S3_PROXY_ENDPOINT_URL,
|
|
8
|
+
)
|
|
3
9
|
from .exceptions import (
|
|
4
10
|
CozeSDKError,
|
|
5
11
|
ConfigurationError,
|
|
@@ -8,6 +14,7 @@ from .exceptions import (
|
|
|
8
14
|
ValidationError
|
|
9
15
|
)
|
|
10
16
|
from .url_utils import validate_url, URLValidationError
|
|
17
|
+
from .runtime import runtime_platform
|
|
11
18
|
|
|
12
19
|
try:
|
|
13
20
|
from .. import __version__
|
|
@@ -17,10 +24,15 @@ except ImportError:
|
|
|
17
24
|
__all__ = [
|
|
18
25
|
"BaseClient",
|
|
19
26
|
"Config",
|
|
27
|
+
"INTEGRATION_BASE_URL",
|
|
28
|
+
"INTEGRATION_MODEL_BASE_URL",
|
|
29
|
+
"IDE_API_BASE_URL",
|
|
30
|
+
"S3_PROXY_ENDPOINT_URL",
|
|
20
31
|
"CozeSDKError",
|
|
21
32
|
"ConfigurationError",
|
|
22
33
|
"APIError",
|
|
23
34
|
"NetworkError",
|
|
24
35
|
"ValidationError",
|
|
36
|
+
"runtime_platform",
|
|
25
37
|
"__version__",
|
|
26
38
|
]
|
{coze_coding_dev_sdk-0.5.18 → coze_coding_dev_sdk-0.5.20}/coze_coding_dev_sdk/core/client.py
RENAMED
|
@@ -14,6 +14,17 @@ from .exceptions import APIError, NetworkError
|
|
|
14
14
|
console = Console()
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
def sanitize_payload_for_log(value):
|
|
18
|
+
if isinstance(value, dict):
|
|
19
|
+
return {
|
|
20
|
+
key: "[REDACTED]" if key.lower() in {"smtp_pass", "password", "secret"} else sanitize_payload_for_log(item)
|
|
21
|
+
for key, item in value.items()
|
|
22
|
+
}
|
|
23
|
+
if isinstance(value, list):
|
|
24
|
+
return [sanitize_payload_for_log(item) for item in value]
|
|
25
|
+
return value
|
|
26
|
+
|
|
27
|
+
|
|
17
28
|
class BaseClient:
|
|
18
29
|
def __init__(
|
|
19
30
|
self,
|
|
@@ -41,8 +52,9 @@ class BaseClient:
|
|
|
41
52
|
if self.custom_headers:
|
|
42
53
|
request_headers.update(self.custom_headers)
|
|
43
54
|
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
if headers:
|
|
56
|
+
request_headers.update(headers)
|
|
57
|
+
request_headers = self.config.get_headers(request_headers)
|
|
46
58
|
|
|
47
59
|
response = self._make_request(
|
|
48
60
|
method=method, url=url, headers=request_headers, **kwargs
|
|
@@ -61,8 +73,9 @@ class BaseClient:
|
|
|
61
73
|
if self.custom_headers:
|
|
62
74
|
request_headers.update(self.custom_headers)
|
|
63
75
|
|
|
64
|
-
|
|
65
|
-
|
|
76
|
+
if headers:
|
|
77
|
+
request_headers.update(headers)
|
|
78
|
+
request_headers = self.config.get_headers(request_headers)
|
|
66
79
|
|
|
67
80
|
response = self._make_request(
|
|
68
81
|
method=method, url=url, headers=request_headers, **kwargs
|
|
@@ -81,8 +94,9 @@ class BaseClient:
|
|
|
81
94
|
if self.custom_headers:
|
|
82
95
|
request_headers.update(self.custom_headers)
|
|
83
96
|
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
if headers:
|
|
98
|
+
request_headers.update(headers)
|
|
99
|
+
request_headers = self.config.get_headers(request_headers)
|
|
86
100
|
|
|
87
101
|
kwargs["stream"] = True
|
|
88
102
|
return self._make_request(
|
|
@@ -91,14 +105,14 @@ class BaseClient:
|
|
|
91
105
|
|
|
92
106
|
def _sanitize_headers(self, headers: Dict[str, str]) -> Dict[str, str]:
|
|
93
107
|
sanitized = headers.copy()
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
108
|
+
for key in list(sanitized):
|
|
109
|
+
if key.lower() not in {"authorization", "x-coze-token", "x-storage-token"}:
|
|
110
|
+
continue
|
|
111
|
+
token = str(sanitized[key])
|
|
112
|
+
if key.lower() == "authorization" and token.startswith("Bearer "):
|
|
113
|
+
sanitized[key] = "Bearer ****"
|
|
114
|
+
else:
|
|
115
|
+
sanitized[key] = "****"
|
|
102
116
|
return sanitized
|
|
103
117
|
|
|
104
118
|
def _log_request(self, method: str, url: str, **kwargs):
|
|
@@ -119,7 +133,7 @@ class BaseClient:
|
|
|
119
133
|
if "json" in kwargs and kwargs["json"]:
|
|
120
134
|
parts.append("[bold]Body:[/bold]")
|
|
121
135
|
try:
|
|
122
|
-
json_str = json.dumps(kwargs["json"], ensure_ascii=False, indent=2)
|
|
136
|
+
json_str = json.dumps(sanitize_payload_for_log(kwargs["json"]), ensure_ascii=False, indent=2)
|
|
123
137
|
parts.append("")
|
|
124
138
|
except Exception:
|
|
125
139
|
json_str = str(kwargs["json"])
|
|
@@ -136,7 +150,7 @@ class BaseClient:
|
|
|
136
150
|
|
|
137
151
|
if "json" in kwargs and kwargs["json"]:
|
|
138
152
|
try:
|
|
139
|
-
json_str = json.dumps(kwargs["json"], ensure_ascii=False, indent=2)
|
|
153
|
+
json_str = json.dumps(sanitize_payload_for_log(kwargs["json"]), ensure_ascii=False, indent=2)
|
|
140
154
|
console.print(
|
|
141
155
|
Syntax(json_str, "json", theme="monokai", line_numbers=False)
|
|
142
156
|
)
|
|
@@ -184,16 +198,10 @@ class BaseClient:
|
|
|
184
198
|
)
|
|
185
199
|
|
|
186
200
|
try:
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if len(json_str) > 2000:
|
|
190
|
-
json_str = json_str[:2000] + "\n... (truncated)"
|
|
191
|
-
console.print(Syntax(json_str, "json", theme="monokai", line_numbers=False))
|
|
201
|
+
response.json()
|
|
202
|
+
console.print(" [response body redacted]")
|
|
192
203
|
except Exception:
|
|
193
|
-
|
|
194
|
-
if len(response.text) > 500:
|
|
195
|
-
body_text += "... (truncated)"
|
|
196
|
-
console.print(f" {body_text}")
|
|
204
|
+
console.print(" [non-JSON response body redacted]")
|
|
197
205
|
|
|
198
206
|
console.print()
|
|
199
207
|
|
|
@@ -226,10 +234,10 @@ class BaseClient:
|
|
|
226
234
|
def _handle_response(self, response: requests.Response) -> dict:
|
|
227
235
|
try:
|
|
228
236
|
data = response.json()
|
|
229
|
-
except Exception
|
|
237
|
+
except Exception:
|
|
230
238
|
logid = response.headers.get("X-Tt-Logid")
|
|
231
239
|
raise APIError(
|
|
232
|
-
f"响应解析失败: {
|
|
240
|
+
f"响应解析失败: status={response.status_code}, logid: {logid}",
|
|
233
241
|
status_code=response.status_code,
|
|
234
242
|
)
|
|
235
243
|
|
|
@@ -237,11 +245,9 @@ class BaseClient:
|
|
|
237
245
|
response.raise_for_status()
|
|
238
246
|
except requests.exceptions.HTTPError as e:
|
|
239
247
|
logid = response.headers.get("X-Tt-Logid")
|
|
240
|
-
error_msg = f"HTTP 错误: {
|
|
241
|
-
if data:
|
|
242
|
-
error_msg += f", 响应数据: {data}"
|
|
248
|
+
error_msg = f"HTTP 错误: status={response.status_code}, logid: {logid}"
|
|
243
249
|
raise APIError(
|
|
244
|
-
error_msg, status_code=response.status_code
|
|
250
|
+
error_msg, status_code=response.status_code
|
|
245
251
|
)
|
|
246
252
|
|
|
247
253
|
return data
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from . import runtime
|
|
5
|
+
from .desktop_credential import desktop_pat_token
|
|
6
|
+
from .endpoints import INTEGRATION_BASE_URL, INTEGRATION_MODEL_BASE_URL
|
|
7
|
+
from .exceptions import ConfigurationError
|
|
8
|
+
|
|
9
|
+
class Config:
|
|
10
|
+
DEFAULT_RETRY_TIMES = 1
|
|
11
|
+
DEFAULT_RETRY_DELAY = 1.0
|
|
12
|
+
DEFAULT_TIMEOUT = 900
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
api_key: Optional[str] = None,
|
|
17
|
+
base_url: Optional[str] = None,
|
|
18
|
+
base_model_url: Optional[str] = None,
|
|
19
|
+
retry_times: int = DEFAULT_RETRY_TIMES,
|
|
20
|
+
retry_delay: float = DEFAULT_RETRY_DELAY,
|
|
21
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
22
|
+
):
|
|
23
|
+
# 确保「当前目录 .env 优先、环境变量兜底」的加载已完成,再读取任何配置。
|
|
24
|
+
runtime.ensure_env_loaded()
|
|
25
|
+
|
|
26
|
+
project_runtime_auth = runtime.uses_project_runtime_auth()
|
|
27
|
+
project_id_from_runtime = runtime.get_project_id()
|
|
28
|
+
api_token = runtime.get_api_token()
|
|
29
|
+
desktop_token = desktop_pat_token()
|
|
30
|
+
|
|
31
|
+
self._explicit_api_key = api_key is not None
|
|
32
|
+
self.api_key = desktop_token or (
|
|
33
|
+
api_token if project_runtime_auth else api_key or api_token or runtime.get_legacy_workload_token()
|
|
34
|
+
)
|
|
35
|
+
self._uses_user_access_token = project_runtime_auth and bool(desktop_token or api_token)
|
|
36
|
+
|
|
37
|
+
# 本地/云端由运行环境决定,不根据 token 来源猜测:COZE_DEVBOX_ENV
|
|
38
|
+
# 非空表示云端 Devbox,空或未设置表示本地。
|
|
39
|
+
self.runtime_platform = runtime.runtime_platform()
|
|
40
|
+
self.base_url = (
|
|
41
|
+
base_url or os.getenv("COZE_INTEGRATION_BASE_URL") or INTEGRATION_BASE_URL
|
|
42
|
+
)
|
|
43
|
+
self.base_model_url = base_model_url or os.getenv(
|
|
44
|
+
"COZE_INTEGRATION_MODEL_BASE_URL"
|
|
45
|
+
) or INTEGRATION_MODEL_BASE_URL
|
|
46
|
+
# 项目 scope 只能来自项目根目录 .coze,不能由环境变量或调用参数覆盖。
|
|
47
|
+
self.project_id = str(project_id_from_runtime) if project_id_from_runtime else None
|
|
48
|
+
self.app_id = runtime.get_app_id() if project_runtime_auth else None
|
|
49
|
+
|
|
50
|
+
self.retry_times = retry_times
|
|
51
|
+
self.retry_delay = retry_delay
|
|
52
|
+
self.timeout = timeout
|
|
53
|
+
|
|
54
|
+
self._validate()
|
|
55
|
+
|
|
56
|
+
def _validate(self):
|
|
57
|
+
if not self.api_key:
|
|
58
|
+
raise ConfigurationError(
|
|
59
|
+
"API Key 未配置:请设置 COZE_API_TOKEN 或提供 api_key"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def get_headers(self, ctx_headers: Optional[dict] = None) -> dict:
|
|
63
|
+
try:
|
|
64
|
+
from .. import __version__
|
|
65
|
+
except ImportError:
|
|
66
|
+
__version__ = "0.0.0"
|
|
67
|
+
|
|
68
|
+
headers = {}
|
|
69
|
+
if ctx_headers:
|
|
70
|
+
headers.update(ctx_headers)
|
|
71
|
+
for key, value in runtime.ppe_headers().items():
|
|
72
|
+
if not any(existing_key.lower() == key.lower() for existing_key in headers):
|
|
73
|
+
headers[key] = value
|
|
74
|
+
headers.setdefault("Content-Type", "application/json")
|
|
75
|
+
if self._uses_user_access_token:
|
|
76
|
+
headers["Authorization"] = f"Bearer {self.api_key}"
|
|
77
|
+
else:
|
|
78
|
+
headers.setdefault("Authorization", f"Bearer {self.api_key}")
|
|
79
|
+
headers.setdefault("X-Client-Sdk", f"coze-coding-dev-sdk-python/{__version__}")
|
|
80
|
+
if runtime.project_resource_env() != runtime.PROJECT_ENV_PROD:
|
|
81
|
+
for key in list(headers):
|
|
82
|
+
if key.lower() == runtime.APP_ID_HEADER.lower():
|
|
83
|
+
del headers[key]
|
|
84
|
+
if self.uses_user_runtime_auth():
|
|
85
|
+
for key in list(headers):
|
|
86
|
+
if key.lower() == runtime.APP_ID_HEADER.lower():
|
|
87
|
+
del headers[key]
|
|
88
|
+
if key.lower() == runtime.PROJECT_ID_HEADER.lower():
|
|
89
|
+
del headers[key]
|
|
90
|
+
headers.update(runtime.request_headers())
|
|
91
|
+
return headers
|
|
92
|
+
|
|
93
|
+
def uses_user_runtime_auth(self) -> bool:
|
|
94
|
+
return (
|
|
95
|
+
runtime.uses_project_runtime_auth()
|
|
96
|
+
and self._uses_user_access_token
|
|
97
|
+
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Developer credential published by the Coze Desktop runtime files."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import time
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
# Coze Desktop writes the beta lane first; either file may be absent or omit
|
|
9
|
+
# patToken entirely, so both are optional candidates.
|
|
10
|
+
RUNTIME_FILES = ("runtime.beta.json", "runtime.json")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _read_pat_token(path: Path) -> Optional[str]:
|
|
14
|
+
try:
|
|
15
|
+
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
16
|
+
except (OSError, ValueError):
|
|
17
|
+
return None
|
|
18
|
+
pat_token = payload.get("patToken") if isinstance(payload, dict) else None
|
|
19
|
+
if not isinstance(pat_token, dict):
|
|
20
|
+
return None
|
|
21
|
+
access_token = pat_token.get("accessToken")
|
|
22
|
+
if not isinstance(access_token, str) or not access_token.strip():
|
|
23
|
+
return None
|
|
24
|
+
expires_in = pat_token.get("expiresIn")
|
|
25
|
+
# expiresIn is an absolute Unix second rather than a duration. A non-numeric
|
|
26
|
+
# value carries no expiry information, so the token stays usable.
|
|
27
|
+
if isinstance(expires_in, (int, float)) and expires_in <= time.time():
|
|
28
|
+
return None
|
|
29
|
+
return access_token.strip()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def desktop_pat_token() -> Optional[str]:
|
|
33
|
+
for name in RUNTIME_FILES:
|
|
34
|
+
token = _read_pat_token(Path.home() / ".coze" / "desktop" / name)
|
|
35
|
+
if token:
|
|
36
|
+
return token
|
|
37
|
+
return None
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Callable, Optional
|
|
4
|
+
|
|
5
|
+
from .desktop_credential import desktop_pat_token
|
|
6
|
+
from .exceptions import ConfigurationError
|
|
7
|
+
from .runtime import get_api_token, uses_project_runtime_auth
|
|
8
|
+
|
|
9
|
+
_provider: Optional[Callable[[], str]] = None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def set_developer_credential_provider(provider: Optional[Callable[[], str]]) -> None:
|
|
13
|
+
global _provider
|
|
14
|
+
_provider = provider
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def resolve_developer_credential() -> str:
|
|
18
|
+
desktop_token = desktop_pat_token()
|
|
19
|
+
if desktop_token:
|
|
20
|
+
return desktop_token
|
|
21
|
+
if uses_project_runtime_auth():
|
|
22
|
+
api_token = (get_api_token() or "").strip()
|
|
23
|
+
if api_token:
|
|
24
|
+
return api_token
|
|
25
|
+
raise ConfigurationError("项目必须设置 COZE_API_TOKEN")
|
|
26
|
+
if _provider:
|
|
27
|
+
value = (_provider() or "").strip()
|
|
28
|
+
if value:
|
|
29
|
+
return value
|
|
30
|
+
api_token = (get_api_token() or "").strip()
|
|
31
|
+
if api_token:
|
|
32
|
+
return api_token
|
|
33
|
+
bridge = Path.home() / ".coze" / "bridge" / "pat-token"
|
|
34
|
+
if bridge.exists():
|
|
35
|
+
value = bridge.read_text(encoding="utf-8").strip()
|
|
36
|
+
if value:
|
|
37
|
+
return value
|
|
38
|
+
config = Path.home() / ".coze" / "cli" / "config.json"
|
|
39
|
+
if config.exists():
|
|
40
|
+
try:
|
|
41
|
+
value = str(json.loads(config.read_text(encoding="utf-8")).get("accessToken") or "").strip()
|
|
42
|
+
except (OSError, ValueError, TypeError):
|
|
43
|
+
value = ""
|
|
44
|
+
if value:
|
|
45
|
+
return value
|
|
46
|
+
raise ConfigurationError("开发者凭证不可用,请先登录 Coze CLI")
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Public online endpoint defaults for the Coze Coding Integration SDK."""
|
|
2
|
+
|
|
3
|
+
INTEGRATION_BASE_URL = "https://integration.coze.cn"
|
|
4
|
+
INTEGRATION_MODEL_BASE_URL = f"{INTEGRATION_BASE_URL}/api/v3"
|
|
5
|
+
# Integration control-plane APIs share the public Integration gateway. The
|
|
6
|
+
# API path is part of each endpoint declaration, so this base has no suffix.
|
|
7
|
+
IDE_API_BASE_URL = INTEGRATION_BASE_URL
|
|
8
|
+
S3_PROXY_ENDPOINT_URL = f"{INTEGRATION_BASE_URL}/coze-coding-s3proxy/v1"
|