ChatCoolify 0.2.0__tar.gz → 0.2.2__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.
Files changed (32) hide show
  1. {chatcoolify-0.2.0/src/ChatCoolify.egg-info → chatcoolify-0.2.2}/PKG-INFO +11 -3
  2. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/README.md +5 -1
  3. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/pyproject.toml +5 -2
  4. {chatcoolify-0.2.0 → chatcoolify-0.2.2/src/ChatCoolify.egg-info}/PKG-INFO +11 -3
  5. chatcoolify-0.2.2/src/ChatCoolify.egg-info/SOURCES.txt +28 -0
  6. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/src/ChatCoolify.egg-info/requires.txt +6 -1
  7. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/src/chatcoolify/__init__.py +10 -1
  8. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/src/chatcoolify/cli.py +6 -27
  9. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/src/chatcoolify/client.py +4 -1
  10. chatcoolify-0.2.2/src/chatcoolify/config.py +83 -0
  11. chatcoolify-0.2.2/src/chatcoolify/platform.py +1057 -0
  12. chatcoolify-0.2.2/src/chatcoolify/platform_artifact.py +113 -0
  13. chatcoolify-0.2.2/src/chatcoolify/platform_backend.py +144 -0
  14. chatcoolify-0.2.2/src/chatcoolify/platform_cli.py +308 -0
  15. chatcoolify-0.2.2/src/chatcoolify/platform_client.py +133 -0
  16. chatcoolify-0.2.2/src/chatcoolify/platform_runtime.py +250 -0
  17. chatcoolify-0.2.2/src/chatcoolify/platform_source.py +86 -0
  18. chatcoolify-0.2.2/src/chatcoolify/platform_web.py +292 -0
  19. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/tests/test_cli.py +32 -2
  20. chatcoolify-0.2.2/tests/test_platform.py +375 -0
  21. chatcoolify-0.2.2/tests/test_platform_domains.py +290 -0
  22. chatcoolify-0.2.2/tests/test_platform_management.py +358 -0
  23. chatcoolify-0.2.2/tests/test_platform_public.py +216 -0
  24. chatcoolify-0.2.0/src/ChatCoolify.egg-info/SOURCES.txt +0 -16
  25. chatcoolify-0.2.0/src/chatcoolify/config.py +0 -48
  26. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/LICENSE +0 -0
  27. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/setup.cfg +0 -0
  28. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/src/ChatCoolify.egg-info/dependency_links.txt +0 -0
  29. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/src/ChatCoolify.egg-info/entry_points.txt +0 -0
  30. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/src/ChatCoolify.egg-info/top_level.txt +0 -0
  31. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/tests/test_client.py +0 -0
  32. {chatcoolify-0.2.0 → chatcoolify-0.2.2}/tests/test_release_contract.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ChatCoolify
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: AI-safe Python client and CLI for the official Coolify API
5
5
  Author-email: ChatArch <1073853456@qq.com>
6
6
  License-Expression: MIT
@@ -19,8 +19,12 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Requires-Python: >=3.10
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
- Requires-Dist: chatenv<0.3.0,>=0.2.9
22
+ Requires-Dist: chatenv<0.3.0,>=0.2.10
23
+ Requires-Dist: chatstyle<0.3.0,>=0.2.0
24
+ Requires-Dist: chatlogin<0.3.0,>=0.2.1
23
25
  Requires-Dist: click<9.0,>=8.1
26
+ Provides-Extra: comments
27
+ Requires-Dist: ChatComment<0.3.0,>=0.2.2; extra == "comments"
24
28
  Provides-Extra: dev
25
29
  Requires-Dist: build<2.0,>=1.2; extra == "dev"
26
30
  Requires-Dist: pytest<10.0,>=8.0; extra == "dev"
@@ -64,6 +68,8 @@ coolify --tree
64
68
 
65
69
  ## 最快开始
66
70
 
71
+ 已有平台账号可通过 `coolify platform` 完成本地目录上传、原生预览、显式发布及回退;平台按项目授权,普通用户不持有原生 Team token。见[本地项目平台](docs/platform.md)。以下保留原生 Coolify 客户端用法,其写操作仍需 `--allow-write`。
72
+
67
73
  ```bash
68
74
  coolify --base-url https://<coolify-url> health
69
75
  ```
@@ -89,6 +95,8 @@ coolify website-plan \
89
95
 
90
96
  省略 `--domain` 时,计划会请求 Coolify 从已配置的泛域名池自动分配唯一 tenant URL;需要自定义域名时才显式传入 `--domain`。查看完整的 [真实 Git 到 HTTPS 演示](https://arch.gh.wzhecnu.cn/ChatCoolify/self-service-demo/)。
91
97
 
98
+ 以上为直接原生 API 的低层命令。面向普通协作者的 `coolify platform` 使用项目名分配可读的正式/预览子域名,owner 可在“我的网站”管理页或通过 `domains set` 自定义受管前缀,并用 `domains apply` 应用到已发布网站。新项目默认公开阅读,管理登录与访客留言分离;登录、项目列表、目录上传与明确发布流程见[本地项目平台](https://arch.gh.wzhecnu.cn/ChatCoolify/platform/)。
99
+
92
100
  该命令只输出官方 API payload。真正创建资源需要同时具备 `write` Token 和显式写门:
93
101
 
94
102
  ```bash
@@ -105,7 +113,7 @@ coolify --allow-write website-create ...
105
113
  ## 开发
106
114
 
107
115
  ```bash
108
- python -m pip install -e '.[dev,docs]'
116
+ python -m pip install -e '.[dev,docs,comments]'
109
117
  python -m pytest -q
110
118
  python -m mkdocs build --strict
111
119
  python -m build
@@ -29,6 +29,8 @@ coolify --tree
29
29
 
30
30
  ## 最快开始
31
31
 
32
+ 已有平台账号可通过 `coolify platform` 完成本地目录上传、原生预览、显式发布及回退;平台按项目授权,普通用户不持有原生 Team token。见[本地项目平台](docs/platform.md)。以下保留原生 Coolify 客户端用法,其写操作仍需 `--allow-write`。
33
+
32
34
  ```bash
33
35
  coolify --base-url https://<coolify-url> health
34
36
  ```
@@ -54,6 +56,8 @@ coolify website-plan \
54
56
 
55
57
  省略 `--domain` 时,计划会请求 Coolify 从已配置的泛域名池自动分配唯一 tenant URL;需要自定义域名时才显式传入 `--domain`。查看完整的 [真实 Git 到 HTTPS 演示](https://arch.gh.wzhecnu.cn/ChatCoolify/self-service-demo/)。
56
58
 
59
+ 以上为直接原生 API 的低层命令。面向普通协作者的 `coolify platform` 使用项目名分配可读的正式/预览子域名,owner 可在“我的网站”管理页或通过 `domains set` 自定义受管前缀,并用 `domains apply` 应用到已发布网站。新项目默认公开阅读,管理登录与访客留言分离;登录、项目列表、目录上传与明确发布流程见[本地项目平台](https://arch.gh.wzhecnu.cn/ChatCoolify/platform/)。
60
+
57
61
  该命令只输出官方 API payload。真正创建资源需要同时具备 `write` Token 和显式写门:
58
62
 
59
63
  ```bash
@@ -70,7 +74,7 @@ coolify --allow-write website-create ...
70
74
  ## 开发
71
75
 
72
76
  ```bash
73
- python -m pip install -e '.[dev,docs]'
77
+ python -m pip install -e '.[dev,docs,comments]'
74
78
  python -m pytest -q
75
79
  python -m mkdocs build --strict
76
80
  python -m build
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ChatCoolify"
7
- version = "0.2.0"
7
+ version = "0.2.2"
8
8
  description = "AI-safe Python client and CLI for the official Coolify API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -21,7 +21,9 @@ classifiers = [
21
21
  "Programming Language :: Python :: 3.12",
22
22
  ]
23
23
  dependencies = [
24
- "chatenv>=0.2.9,<0.3.0",
24
+ "chatenv>=0.2.10,<0.3.0",
25
+ "chatstyle>=0.2.0,<0.3.0",
26
+ "chatlogin>=0.2.1,<0.3.0",
25
27
  "click>=8.1,<9.0",
26
28
  ]
27
29
 
@@ -38,6 +40,7 @@ coolify = "chatcoolify.cli:main"
38
40
  chatcoolify = "chatcoolify.config"
39
41
 
40
42
  [project.optional-dependencies]
43
+ comments = ["ChatComment>=0.2.2,<0.3.0"]
41
44
  dev = [
42
45
  "build>=1.2,<2.0",
43
46
  "pytest>=8.0,<10.0",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ChatCoolify
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: AI-safe Python client and CLI for the official Coolify API
5
5
  Author-email: ChatArch <1073853456@qq.com>
6
6
  License-Expression: MIT
@@ -19,8 +19,12 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Requires-Python: >=3.10
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
- Requires-Dist: chatenv<0.3.0,>=0.2.9
22
+ Requires-Dist: chatenv<0.3.0,>=0.2.10
23
+ Requires-Dist: chatstyle<0.3.0,>=0.2.0
24
+ Requires-Dist: chatlogin<0.3.0,>=0.2.1
23
25
  Requires-Dist: click<9.0,>=8.1
26
+ Provides-Extra: comments
27
+ Requires-Dist: ChatComment<0.3.0,>=0.2.2; extra == "comments"
24
28
  Provides-Extra: dev
25
29
  Requires-Dist: build<2.0,>=1.2; extra == "dev"
26
30
  Requires-Dist: pytest<10.0,>=8.0; extra == "dev"
@@ -64,6 +68,8 @@ coolify --tree
64
68
 
65
69
  ## 最快开始
66
70
 
71
+ 已有平台账号可通过 `coolify platform` 完成本地目录上传、原生预览、显式发布及回退;平台按项目授权,普通用户不持有原生 Team token。见[本地项目平台](docs/platform.md)。以下保留原生 Coolify 客户端用法,其写操作仍需 `--allow-write`。
72
+
67
73
  ```bash
68
74
  coolify --base-url https://<coolify-url> health
69
75
  ```
@@ -89,6 +95,8 @@ coolify website-plan \
89
95
 
90
96
  省略 `--domain` 时,计划会请求 Coolify 从已配置的泛域名池自动分配唯一 tenant URL;需要自定义域名时才显式传入 `--domain`。查看完整的 [真实 Git 到 HTTPS 演示](https://arch.gh.wzhecnu.cn/ChatCoolify/self-service-demo/)。
91
97
 
98
+ 以上为直接原生 API 的低层命令。面向普通协作者的 `coolify platform` 使用项目名分配可读的正式/预览子域名,owner 可在“我的网站”管理页或通过 `domains set` 自定义受管前缀,并用 `domains apply` 应用到已发布网站。新项目默认公开阅读,管理登录与访客留言分离;登录、项目列表、目录上传与明确发布流程见[本地项目平台](https://arch.gh.wzhecnu.cn/ChatCoolify/platform/)。
99
+
92
100
  该命令只输出官方 API payload。真正创建资源需要同时具备 `write` Token 和显式写门:
93
101
 
94
102
  ```bash
@@ -105,7 +113,7 @@ coolify --allow-write website-create ...
105
113
  ## 开发
106
114
 
107
115
  ```bash
108
- python -m pip install -e '.[dev,docs]'
116
+ python -m pip install -e '.[dev,docs,comments]'
109
117
  python -m pytest -q
110
118
  python -m mkdocs build --strict
111
119
  python -m build
@@ -0,0 +1,28 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/ChatCoolify.egg-info/PKG-INFO
5
+ src/ChatCoolify.egg-info/SOURCES.txt
6
+ src/ChatCoolify.egg-info/dependency_links.txt
7
+ src/ChatCoolify.egg-info/entry_points.txt
8
+ src/ChatCoolify.egg-info/requires.txt
9
+ src/ChatCoolify.egg-info/top_level.txt
10
+ src/chatcoolify/__init__.py
11
+ src/chatcoolify/cli.py
12
+ src/chatcoolify/client.py
13
+ src/chatcoolify/config.py
14
+ src/chatcoolify/platform.py
15
+ src/chatcoolify/platform_artifact.py
16
+ src/chatcoolify/platform_backend.py
17
+ src/chatcoolify/platform_cli.py
18
+ src/chatcoolify/platform_client.py
19
+ src/chatcoolify/platform_runtime.py
20
+ src/chatcoolify/platform_source.py
21
+ src/chatcoolify/platform_web.py
22
+ tests/test_cli.py
23
+ tests/test_client.py
24
+ tests/test_platform.py
25
+ tests/test_platform_domains.py
26
+ tests/test_platform_management.py
27
+ tests/test_platform_public.py
28
+ tests/test_release_contract.py
@@ -1,6 +1,11 @@
1
- chatenv<0.3.0,>=0.2.9
1
+ chatenv<0.3.0,>=0.2.10
2
+ chatstyle<0.3.0,>=0.2.0
3
+ chatlogin<0.3.0,>=0.2.1
2
4
  click<9.0,>=8.1
3
5
 
6
+ [comments]
7
+ ChatComment<0.3.0,>=0.2.2
8
+
4
9
  [dev]
5
10
  build<2.0,>=1.2
6
11
  pytest<10.0,>=8.0
@@ -10,7 +10,12 @@ from .client import (
10
10
  PublicApplicationSpec,
11
11
  )
12
12
 
13
- __version__ = "0.2.0"
13
+ __version__ = "0.2.2"
14
+
15
+ from .platform import PlatformService
16
+ from .platform_client import PlatformClient
17
+ from .platform_artifact import PlatformError
18
+ from .platform_backend import CoolifyBackend
14
19
 
15
20
  __all__ = [
16
21
  "DEFAULT_BASE_URL",
@@ -20,5 +25,9 @@ __all__ = [
20
25
  "CoolifyError",
21
26
  "CoolifyPermissionError",
22
27
  "PublicApplicationSpec",
28
+ "PlatformService",
29
+ "PlatformClient",
30
+ "PlatformError",
31
+ "CoolifyBackend",
23
32
  "__version__",
24
33
  ]
@@ -6,6 +6,7 @@ import json
6
6
  from typing import Any
7
7
 
8
8
  import click
9
+ from chatstyle import add_tree_option
9
10
 
10
11
  from . import __version__
11
12
  from .client import DEFAULT_BASE_URL, CoolifyClient, CoolifyError, PublicApplicationSpec
@@ -26,35 +27,9 @@ def _handle_error(error: CoolifyError) -> None:
26
27
  raise click.ClickException(str(error)) from error
27
28
 
28
29
 
29
- def _render_tree(command: click.Group, *, brief: bool) -> str:
30
- """Render the registered CLI surface instead of maintaining docs by hand."""
31
-
32
- options = ["--help", "--version", "--tree", "--tree-brief", "--base-url", "--allow-write"]
33
- lines = [command.name or "coolify"]
34
- for option in options:
35
- lines.append(f"|- {option}")
36
- commands = sorted(command.commands.values(), key=lambda item: item.name)
37
- for index, subcommand in enumerate(commands):
38
- connector = "`-" if index == len(commands) - 1 else "|-"
39
- suffix = "" if brief else f" # {subcommand.help or subcommand.short_help or ''}".rstrip()
40
- lines.append(f"{connector} {subcommand.name}{suffix}")
41
- return "\n".join(lines)
42
-
43
-
44
- def _tree_callback(brief: bool):
45
- def callback(ctx: click.Context, _param: click.Parameter, value: bool) -> None:
46
- if not value or ctx.resilient_parsing:
47
- return
48
- click.echo(_render_tree(ctx.command, brief=brief))
49
- ctx.exit()
50
-
51
- return callback
52
-
53
-
54
30
  @click.group(name="coolify", context_settings=CONTEXT_SETTINGS)
55
31
  @click.version_option(__version__, prog_name="coolify")
56
- @click.option("--tree", is_flag=True, is_eager=True, expose_value=False, callback=_tree_callback(False), help="Print the registered command tree.")
57
- @click.option("--tree-brief", is_flag=True, is_eager=True, expose_value=False, callback=_tree_callback(True), help="Print the registered command tree without descriptions.")
32
+ @add_tree_option()
58
33
  @click.option(
59
34
  "--base-url",
60
35
  envvar="COOLIFY_BASE_URL",
@@ -311,5 +286,9 @@ def deploy(ctx: click.Context, application_uuid: str, force: bool) -> None:
311
286
  _handle_error(error)
312
287
 
313
288
 
289
+ from .platform_cli import platform
290
+ main.add_command(platform)
291
+
292
+
314
293
  if __name__ == "__main__": # pragma: no cover
315
294
  main()
@@ -371,7 +371,10 @@ def _error_message(error: HTTPError, token: str | None) -> str:
371
371
  raw = error.read().decode("utf-8", errors="replace")
372
372
  parsed = json.loads(raw)
373
373
  if isinstance(parsed, Mapping) and isinstance(parsed.get("message"), str):
374
- return _redact_sensitive_text(parsed["message"], token)[:500]
374
+ fields = parsed.get('errors', {})
375
+ safe_fields = [key for key in fields if isinstance(key,str) and re.fullmatch(r'[A-Za-z0-9_.]{1,80}',key)] if isinstance(fields,Mapping) else []
376
+ suffix = ' (fields: ' + ', '.join(safe_fields[:20]) + ')' if safe_fields else ''
377
+ return _redact_sensitive_text(parsed["message"], token)[:500] + suffix
375
378
  except (OSError, UnicodeDecodeError, json.JSONDecodeError):
376
379
  pass
377
380
  return _redact_sensitive_text(str(error.reason or "request failed"), token)
@@ -0,0 +1,83 @@
1
+ """ChatEnv schema for ChatCoolify credentials and API endpoint."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ from chatenv import BaseEnvConfig, EnvField, EnvStore, get_paths
8
+
9
+
10
+ class CoolifyConfig(BaseEnvConfig):
11
+ """Typed configuration for the existing Coolify control plane."""
12
+
13
+ _title = "Coolify Configuration"
14
+ _aliases = ["coolify", "chatcoolify"]
15
+ _storage_dir = "Coolify"
16
+
17
+ COOLIFY_BASE_URL = EnvField(
18
+ "COOLIFY_BASE_URL",
19
+ default="https://coolify.example.com",
20
+ desc="Public HTTPS URL of the Coolify control plane",
21
+ )
22
+ COOLIFY_API_TOKEN = EnvField(
23
+ "COOLIFY_API_TOKEN",
24
+ desc="Team-scoped Coolify API token; use the minimum required permissions and expiration",
25
+ is_sensitive=True,
26
+ )
27
+
28
+ @classmethod
29
+ def test(cls) -> None:
30
+ """Validate a configured endpoint, while keeping unconfigured schemas offline."""
31
+
32
+ from .client import DEFAULT_BASE_URL, CoolifyClient, CoolifyError
33
+
34
+ profile_values = EnvStore(get_paths().envs_dir).load_active(cls)
35
+ base_url = os.getenv("COOLIFY_BASE_URL") or profile_values.get("COOLIFY_BASE_URL") or DEFAULT_BASE_URL
36
+ if base_url == DEFAULT_BASE_URL:
37
+ print("ChatCoolify schema loaded; configure COOLIFY_BASE_URL to run a health check.")
38
+ return
39
+ try:
40
+ result = CoolifyClient(base_url).health()
41
+ except CoolifyError as error:
42
+ raise RuntimeError(f"Coolify health check failed: {error}") from error
43
+ if not result.get("ok"):
44
+ raise RuntimeError("Coolify health check did not report OK")
45
+ print(f"Coolify health check passed for {base_url}.")
46
+
47
+
48
+ class PlatformConfig(BaseEnvConfig):
49
+ """A user's platform endpoint; opaque sessions live in TokenStore."""
50
+ _title = 'ChatCoolify Platform'
51
+ _aliases = ['coolify-platform']
52
+ _storage_dir = 'CoolifyPlatform'
53
+ CHATCOOLIFY_PLATFORM_URL = EnvField('CHATCOOLIFY_PLATFORM_URL',desc='HTTPS origin of the project platform')
54
+
55
+ @classmethod
56
+ def test(cls):
57
+ print('Platform endpoint schema loaded; login sessions use the private TokenStore.')
58
+
59
+
60
+ class PlatformServerConfig(BaseEnvConfig):
61
+ """Operator-only configuration, never returned by the public platform API."""
62
+ _title = 'ChatCoolify Platform Server'
63
+ _aliases = ['coolify-platform-server']
64
+ _storage_dir = 'CoolifyPlatformServer'
65
+ COOLIFY_BASE_URL = EnvField('COOLIFY_BASE_URL',desc='Existing native control origin')
66
+ COOLIFY_API_TOKEN = EnvField('COOLIFY_API_TOKEN',is_sensitive=True,desc='Server-only native Team service token')
67
+ CHATCOOLIFY_PLATFORM_DATA = EnvField('CHATCOOLIFY_PLATFORM_DATA',default='/data',desc='Persistent platform root')
68
+ CHATCOOLIFY_CONTROL_URL = EnvField('CHATCOOLIFY_CONTROL_URL',desc='Public platform HTTPS origin')
69
+ CHATCOOLIFY_DOMAIN_SUFFIX = EnvField('CHATCOOLIFY_DOMAIN_SUFFIX',desc='Operator-managed wildcard DNS suffix; defaults to the parent of platform.<suffix>')
70
+ CHATCOOLIFY_RESERVED_HOSTS = EnvField('CHATCOOLIFY_RESERVED_HOSTS',desc='Comma-separated additional operator-reserved public hostnames outside native Team inventory')
71
+ CHATCOOLIFY_INTERNAL_URL = EnvField('CHATCOOLIFY_INTERNAL_URL',desc='Private platform origin for frontend authorization')
72
+ CHATCOOLIFY_SERVER_UUID = EnvField('CHATCOOLIFY_SERVER_UUID',desc='Operator-approved native server')
73
+ CHATCOOLIFY_TEAM_ID = EnvField('CHATCOOLIFY_TEAM_ID',desc='Native service Team ID')
74
+ CHATCOOLIFY_SOURCE_URL = EnvField('CHATCOOLIFY_SOURCE_URL',desc='Private read-only Git source base URL')
75
+ CHATCOOLIFY_SOURCE_KEY_UUID = EnvField('CHATCOOLIFY_SOURCE_KEY_UUID',desc='Native key resource for restricted source clone')
76
+ CHATCOOLIFY_EXTERNAL_TLS = EnvField('CHATCOOLIFY_EXTERNAL_TLS',default='false',desc='Existing external edge terminates HTTPS; native routing remains HTTP')
77
+
78
+ @classmethod
79
+ def test(cls):
80
+ print('Platform server schema loaded; credentials stay server-side.')
81
+
82
+
83
+ __all__ = ["CoolifyConfig", "PlatformConfig", "PlatformServerConfig"]