ChatCoolify 0.2.0__tar.gz → 0.2.1__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 (28) hide show
  1. {chatcoolify-0.2.0/src/ChatCoolify.egg-info → chatcoolify-0.2.1}/PKG-INFO +8 -2
  2. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/README.md +2 -0
  3. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/pyproject.toml +5 -2
  4. {chatcoolify-0.2.0 → chatcoolify-0.2.1/src/ChatCoolify.egg-info}/PKG-INFO +8 -2
  5. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/src/ChatCoolify.egg-info/SOURCES.txt +9 -0
  6. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/src/ChatCoolify.egg-info/requires.txt +6 -1
  7. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/src/chatcoolify/__init__.py +10 -1
  8. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/src/chatcoolify/cli.py +6 -27
  9. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/src/chatcoolify/client.py +4 -1
  10. chatcoolify-0.2.1/src/chatcoolify/config.py +81 -0
  11. chatcoolify-0.2.1/src/chatcoolify/platform.py +670 -0
  12. chatcoolify-0.2.1/src/chatcoolify/platform_artifact.py +113 -0
  13. chatcoolify-0.2.1/src/chatcoolify/platform_backend.py +103 -0
  14. chatcoolify-0.2.1/src/chatcoolify/platform_cli.py +258 -0
  15. chatcoolify-0.2.1/src/chatcoolify/platform_client.py +105 -0
  16. chatcoolify-0.2.1/src/chatcoolify/platform_runtime.py +207 -0
  17. chatcoolify-0.2.1/src/chatcoolify/platform_source.py +86 -0
  18. chatcoolify-0.2.1/src/chatcoolify/platform_web.py +214 -0
  19. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/tests/test_cli.py +4 -2
  20. chatcoolify-0.2.1/tests/test_platform.py +293 -0
  21. chatcoolify-0.2.0/src/chatcoolify/config.py +0 -48
  22. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/LICENSE +0 -0
  23. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/setup.cfg +0 -0
  24. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/src/ChatCoolify.egg-info/dependency_links.txt +0 -0
  25. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/src/ChatCoolify.egg-info/entry_points.txt +0 -0
  26. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/src/ChatCoolify.egg-info/top_level.txt +0 -0
  27. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/tests/test_client.py +0 -0
  28. {chatcoolify-0.2.0 → chatcoolify-0.2.1}/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.1
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.0; 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
  ```
@@ -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
  ```
@@ -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.1"
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.0,<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.1
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.0; 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
  ```
@@ -11,6 +11,15 @@ src/chatcoolify/__init__.py
11
11
  src/chatcoolify/cli.py
12
12
  src/chatcoolify/client.py
13
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
14
22
  tests/test_cli.py
15
23
  tests/test_client.py
24
+ tests/test_platform.py
16
25
  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.0
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.1"
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,81 @@
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_INTERNAL_URL = EnvField('CHATCOOLIFY_INTERNAL_URL',desc='Private platform origin for frontend authorization')
70
+ CHATCOOLIFY_SERVER_UUID = EnvField('CHATCOOLIFY_SERVER_UUID',desc='Operator-approved native server')
71
+ CHATCOOLIFY_TEAM_ID = EnvField('CHATCOOLIFY_TEAM_ID',desc='Native service Team ID')
72
+ CHATCOOLIFY_SOURCE_URL = EnvField('CHATCOOLIFY_SOURCE_URL',desc='Private read-only Git source base URL')
73
+ CHATCOOLIFY_SOURCE_KEY_UUID = EnvField('CHATCOOLIFY_SOURCE_KEY_UUID',desc='Native key resource for restricted source clone')
74
+ CHATCOOLIFY_EXTERNAL_TLS = EnvField('CHATCOOLIFY_EXTERNAL_TLS',default='false',desc='Existing external edge terminates HTTPS; native routing remains HTTP')
75
+
76
+ @classmethod
77
+ def test(cls):
78
+ print('Platform server schema loaded; credentials stay server-side.')
79
+
80
+
81
+ __all__ = ["CoolifyConfig", "PlatformConfig", "PlatformServerConfig"]