pipecatcloud 0.0.10__tar.gz → 0.1.0__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 (47) hide show
  1. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/.github/workflows/publish-pypi.yml +1 -1
  2. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/.github/workflows/publish-test.yml +1 -1
  3. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/.github/workflows/python-publish.yml +0 -37
  4. pipecatcloud-0.1.0/CHANGELOG.md +86 -0
  5. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/PKG-INFO +1 -1
  6. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/pyproject.toml +1 -1
  7. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/__init__.py +6 -0
  8. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/__main__.py +6 -0
  9. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/__version__.py +6 -0
  10. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/async_utils.py +6 -0
  11. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/auth_utils.py +7 -0
  12. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/console_utils.py +43 -26
  13. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/deploy_utils.py +13 -15
  14. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/local_runner.py +6 -5
  15. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/api.py +31 -11
  16. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/__init__.py +7 -1
  17. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/api.py +6 -0
  18. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/agent.py +110 -111
  19. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/auth.py +57 -22
  20. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/deploy.py +113 -95
  21. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/init.py +24 -11
  22. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/organizations.py +72 -42
  23. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/run.py +7 -0
  24. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/secrets.py +134 -108
  25. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/config.py +17 -7
  26. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/entry_point.py +10 -2
  27. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/config.py +12 -2
  28. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/exception.py +17 -11
  29. pipecatcloud-0.1.0/src/pipecatcloud/session.py +104 -0
  30. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/PKG-INFO +1 -1
  31. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/SOURCES.txt +0 -2
  32. pipecatcloud-0.0.10/CHANGELOG.md +0 -103
  33. pipecatcloud-0.0.10/publish-pypi.yml +0 -59
  34. pipecatcloud-0.0.10/publish-test.yml +0 -59
  35. pipecatcloud-0.0.10/src/pipecatcloud/session.py +0 -68
  36. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/.gitignore +0 -0
  37. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/LICENSE +0 -0
  38. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/README.md +0 -0
  39. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/dev-requirements.txt +0 -0
  40. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/pipecat-cloud.png +0 -0
  41. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/setup.cfg +0 -0
  42. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/__init__.py +0 -0
  43. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/__init__.py +0 -0
  44. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
  45. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
  46. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/requires.txt +0 -0
  47. {pipecatcloud-0.0.10 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/top_level.txt +0 -0
@@ -39,7 +39,7 @@ jobs:
39
39
  - name: Install dependencies
40
40
  run: |
41
41
  python -m pip install --upgrade pip
42
- pip install -r requirements.txt
42
+ pip install -r dev-requirements.txt
43
43
  pip install build twine
44
44
 
45
45
  - name: Build package
@@ -39,7 +39,7 @@ jobs:
39
39
  - name: Install dependencies
40
40
  run: |
41
41
  python -m pip install --upgrade pip
42
- pip install -r requirements.txt
42
+ pip install -r dev-requirements.txt
43
43
  pip install build twine
44
44
 
45
45
  - name: Build package
@@ -38,40 +38,3 @@ jobs:
38
38
  with:
39
39
  name: release-dists
40
40
  path: dist/
41
-
42
- pypi-publish:
43
- runs-on: ubuntu-latest
44
- needs:
45
- - release-build
46
- permissions:
47
- id-token: write
48
- contents: read
49
-
50
- environment:
51
- name: pypi
52
- url: https://pypi.org/p/pipecat-cloud
53
-
54
- steps:
55
- - uses: actions/checkout@v4
56
-
57
- - name: Retrieve release distributions
58
- uses: actions/download-artifact@v4
59
- with:
60
- name: release-dists
61
- path: dist/
62
-
63
- - name: Publish release distributions to PyPI
64
- uses: pypa/gh-action-pypi-publish@release/v1
65
- with:
66
- packages-dir: dist/
67
-
68
- - name: Create GitHub Release
69
- uses: softprops/action-gh-release@v2
70
- with:
71
- tag_name: ${{ github.ref }}
72
- name: Release ${{ github.ref_name }}
73
- draft: false
74
- prerelease: false
75
- files: |
76
- dist/*.tar.gz
77
- dist/*.whl
@@ -0,0 +1,86 @@
1
+ # Pipecat Cloud Changelog
2
+
3
+ All notable changes to **Pipecat Cloud** will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-03-05
9
+
10
+ - `pipecatcloud.toml` moved to `$HOME/.config/pipecatcloud/pipecatcloud.toml`
11
+
12
+ ### Added
13
+
14
+ - `pcc auth whoami` now shows the namespace Daily API key for convenience
15
+
16
+ ## [0.0.11] - 2025-03-04
17
+
18
+ ### Changed
19
+
20
+ - `session.py` now returns the response body from the `start()` method.
21
+
22
+ ### Fixed
23
+
24
+ - Fixed an issue in `session.py` where a bot wouldn't start due to malformed
25
+ `data`.
26
+
27
+ ## [0.0.10] - 2025-03-04
28
+
29
+ ### Added
30
+
31
+ - `init` convenience command will now populate the working directory with files
32
+ from the starter project.
33
+
34
+ - `agent log` allows for optional severity level filtering.
35
+
36
+ ### Changed
37
+
38
+ - `agent status` and `deploy` no longer show superfluous data.
39
+
40
+ - `session.py` now correctly handles errors when starting agents.
41
+
42
+ - `secrets set` no longer prompts twice for confirmation if the secret set does
43
+ not exist.
44
+
45
+ ### Removed
46
+
47
+ - `errors.py` removed as redundant (error message and code returned via API).
48
+
49
+ - `agent_utils.py` removed as redundant (error message and code returned via
50
+ API).
51
+
52
+ ## [0.0.9] - 2025-02-27
53
+
54
+ ### Added
55
+
56
+ - `agent status [agent-name]` now shows deployment info and scaling
57
+ configuration.
58
+
59
+ - `agent sessions [agent-name]` lists active session count for an agent (will
60
+ list session details in future).
61
+
62
+ - `agent start [agent-name] -D` now shows the Daily room URL (and token) to
63
+ join in the terminal output.
64
+
65
+ ### Changed
66
+
67
+ - Changed CLI command from `pipecat` to `pipecatcloud` or `pcc`.
68
+
69
+ - `agent delete` prompts the user for confirmation first.
70
+
71
+ - `agent start` now checks the target deployment first to ensure it exists and
72
+ is in a healthy state.
73
+
74
+ - Changed the information order of `agent status` so the health badge is
75
+ clearly visible in terminal.
76
+
77
+ - `agent deploy` now defaults to "Y" for the confirmation prompts.
78
+
79
+ ### Fixed
80
+
81
+ - Fixed lint error with payload data in `agent start`.
82
+
83
+ - Fixed a bug where `pcc-deploy.toml` files were required to be present.
84
+
85
+ - `deploy` command now correctly passes the secret set to the deployment from
86
+ the `pcc-deploy.toml` file.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pipecatcloud
3
- Version: 0.0.10
3
+ Version: 0.1.0
4
4
  Summary: Cloud hosting for Pipecat AI applications
5
5
  License: BSD 2-Clause License
6
6
  Project-URL: Website, https://docs.pipecat.daily.co/
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pipecatcloud"
7
- version = "0.0.10"
7
+ version = "0.1.0"
8
8
  requires-python = ">=3.10"
9
9
  description = "Cloud hosting for Pipecat AI applications"
10
10
  license = { text = "BSD 2-Clause License" }
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  import os
2
8
  import sys
3
9
 
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  from pipecatcloud.cli.entry_point import entrypoint_cli
2
8
 
3
9
 
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  from pathlib import Path
2
8
 
3
9
  import toml
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  import inspect
2
8
  from typing import (
3
9
  TypeVar,
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  import functools
2
8
 
3
9
  from pipecatcloud._utils.console_utils import console
@@ -16,4 +22,5 @@ def requires_login(func):
16
22
  )
17
23
  return
18
24
  return func(*args, **kwargs)
25
+
19
26
  return wrapper
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  from typing import Optional, Union
2
8
 
3
9
  from rich.console import Console
@@ -8,12 +14,12 @@ from pipecatcloud.cli import PANEL_TITLE_ERROR, PANEL_TITLE_SUCCESS, PIPECAT_CLI
8
14
 
9
15
  class PipecatConsole(Console):
10
16
  def success(
11
- self,
12
- message,
13
- title: Optional[str] = None,
14
- title_extra: Optional[str] = None,
15
- subtitle: Optional[str] = None):
16
-
17
+ self,
18
+ message,
19
+ title: Optional[str] = None,
20
+ title_extra: Optional[str] = None,
21
+ subtitle: Optional[str] = None,
22
+ ):
17
23
  if not title:
18
24
  title = f"{PANEL_TITLE_SUCCESS}{f' - {title_extra}' if title_extra is not None else ''}"
19
25
 
@@ -24,15 +30,17 @@ class PipecatConsole(Console):
24
30
  subtitle=subtitle,
25
31
  title_align="left",
26
32
  subtitle_align="left",
27
- border_style="green"))
33
+ border_style="green",
34
+ )
35
+ )
28
36
 
29
37
  def error(
30
- self,
31
- message,
32
- title: Optional[str] = None,
33
- title_extra: Optional[str] = None,
34
- subtitle: Optional[str] = None):
35
-
38
+ self,
39
+ message,
40
+ title: Optional[str] = None,
41
+ title_extra: Optional[str] = None,
42
+ subtitle: Optional[str] = None,
43
+ ):
36
44
  if not title:
37
45
  title = f"{PANEL_TITLE_ERROR}{f' - {title_extra}' if title_extra is not None else ''}"
38
46
 
@@ -43,7 +51,9 @@ class PipecatConsole(Console):
43
51
  subtitle=subtitle,
44
52
  title_align="left",
45
53
  subtitle_align="left",
46
- border_style="red"))
54
+ border_style="red",
55
+ )
56
+ )
47
57
 
48
58
  def cancel(self):
49
59
  self.print("[yellow]Cancelled by user[/yellow]")
@@ -56,13 +66,16 @@ class PipecatConsole(Console):
56
66
  subtitle="",
57
67
  title_align="left",
58
68
  subtitle_align="left",
59
- border_style="red"))
69
+ border_style="red",
70
+ )
71
+ )
60
72
 
61
73
  def api_error(
62
- self,
63
- error_code: Optional[Union[str, dict]] = None,
64
- title: Optional[str] = "API Error",
65
- hide_subtitle: bool = False):
74
+ self,
75
+ error_code: Optional[Union[str, dict]] = None,
76
+ title: Optional[str] = "API Error",
77
+ hide_subtitle: bool = False,
78
+ ):
66
79
  DEFAULT_ERROR_MESSAGE = "Unknown error. Please contact support."
67
80
 
68
81
  if isinstance(error_code, dict):
@@ -77,13 +90,16 @@ class PipecatConsole(Console):
77
90
 
78
91
  self.print(
79
92
  Panel(
80
- f"[red]{title}[/red]\n\n"
81
- f"[dim]Error message:[/dim]\n{error_message}",
93
+ f"[red]{title}[/red]\n\n" f"[dim]Error message:[/dim]\n{error_message}",
82
94
  title=f"[bold red]{PANEL_TITLE_ERROR}{f' - {code}' if code else ''}[/bold red]",
83
- subtitle=f"[dim]Docs: https://docs.pipecat.daily.co/agents/error-codes#{code}[/dim]" if not hide_subtitle and code else None,
95
+ subtitle=f"[dim]Docs: https://docs.pipecat.daily.co/agents/error-codes#{code}[/dim]"
96
+ if not hide_subtitle and code
97
+ else None,
84
98
  title_align="left",
85
99
  subtitle_align="left",
86
- border_style="red"))
100
+ border_style="red",
101
+ )
102
+ )
87
103
 
88
104
 
89
105
  console = PipecatConsole()
@@ -113,10 +129,11 @@ def format_timestamp(timestamp: str) -> str:
113
129
  parts = timestamp.split(".")
114
130
  if len(parts) == 2 and parts[1].endswith("Z"):
115
131
  # Truncate microseconds to 6 digits
116
- microseconds = parts[1][:-1][:6].ljust(6, '0')
132
+ microseconds = parts[1][:-1][:6].ljust(6, "0")
117
133
  normalized = f"{parts[0]}.{microseconds}Z"
118
- return datetime.strptime(normalized,
119
- "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S")
134
+ return datetime.strptime(normalized, "%Y-%m-%dT%H:%M:%S.%fZ").strftime(
135
+ "%Y-%m-%d %H:%M:%S"
136
+ )
120
137
  except (ValueError, IndexError):
121
138
  pass
122
139
 
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  import os
2
8
  from typing import Optional
3
9
 
@@ -10,7 +16,7 @@ from pipecatcloud.exception import ConfigFileError
10
16
  DEPLOY_STATUS_MAP = {
11
17
  "Unknown": "[dim]Waiting[/dim]",
12
18
  "True": "[green]Ready[/green]",
13
- "False": "[yellow]Creating[/yellow]"
19
+ "False": "[yellow]Creating[/yellow]",
14
20
  }
15
21
 
16
22
 
@@ -32,14 +38,11 @@ class ScalingParams:
32
38
  raise ValueError("max_instances must be greater than or equal to min_instances")
33
39
 
34
40
  def to_dict(self):
35
- return {
36
- "min_instances": self.min_instances,
37
- "max_instances": self.max_instances
38
- }
41
+ return {"min_instances": self.min_instances, "max_instances": self.max_instances}
39
42
 
40
43
 
41
44
  @dataclass
42
- class DeployConfigParams():
45
+ class DeployConfigParams:
43
46
  agent_name: Optional[str] = None
44
47
  image: Optional[str] = None
45
48
  image_credentials: Optional[str] = None
@@ -56,7 +59,7 @@ class DeployConfigParams():
56
59
  "image": self.image,
57
60
  "image_credentials": self.image_credentials,
58
61
  "secret_set": self.secret_set,
59
- "scaling": self.scaling.to_dict() if self.scaling else None
62
+ "scaling": self.scaling.to_dict() if self.scaling else None,
60
63
  }
61
64
 
62
65
 
@@ -69,12 +72,12 @@ def load_deploy_config_file() -> Optional[DeployConfigParams]:
69
72
  try:
70
73
  with open(deploy_config_path, "r") as f:
71
74
  config_data = toml.load(f)
72
- except Exception as e:
75
+ except Exception:
73
76
  return None
74
77
 
75
78
  try:
76
79
  # Extract scaling parameters if present
77
- scaling_data = config_data.pop('scaling', {})
80
+ scaling_data = config_data.pop("scaling", {})
78
81
  scaling_params = ScalingParams(**scaling_data)
79
82
 
80
83
  # Create DeployConfigParams with validated data
@@ -84,12 +87,7 @@ def load_deploy_config_file() -> Optional[DeployConfigParams]:
84
87
  )
85
88
 
86
89
  # Check for unexpected keys
87
- expected_keys = {
88
- 'agent_name',
89
- 'image',
90
- 'image_credentials',
91
- 'secret_set',
92
- 'scaling'}
90
+ expected_keys = {"agent_name", "image", "image_credentials", "secret_set", "scaling"}
93
91
  unexpected_keys = set(config_data.keys()) - expected_keys
94
92
  if unexpected_keys:
95
93
  raise ConfigFileError(f"Unexpected keys in config file: {unexpected_keys}")
@@ -1,3 +1,8 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
1
6
 
2
7
  import fastapi
3
8
  import uvicorn
@@ -11,11 +16,7 @@ async def start_server(entrypoint: str, host: str = "0.0.0.0", port: int = 8000)
11
16
  entrypoint (str): The entry point identifier
12
17
  """
13
18
  logger.debug(f"Starting local bot runner for {entrypoint}")
14
- app = fastapi.FastAPI(
15
- openapi_url=None,
16
- docs_url=None,
17
- redoc_url=None
18
- )
19
+ app = fastapi.FastAPI(openapi_url=None, docs_url=None, redoc_url=None)
19
20
 
20
21
  # @TODO dynamically load entrypoint
21
22
 
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  from functools import wraps
2
8
  from typing import Callable, List, Optional
3
9
 
@@ -18,10 +24,11 @@ def api_method(func):
18
24
  if live:
19
25
  live.stop()
20
26
  raise e
27
+
21
28
  return wrapper
22
29
 
23
30
 
24
- class _API():
31
+ class _API:
25
32
  def __init__(self, token: Optional[str] = None):
26
33
  self.token = token
27
34
  self.error = None
@@ -49,7 +56,7 @@ class _API():
49
56
  params: Optional[dict] = None,
50
57
  json: Optional[dict] = None,
51
58
  not_found_is_empty: bool = False,
52
- override_token: Optional[str] = None
59
+ override_token: Optional[str] = None,
53
60
  ) -> Optional[dict]:
54
61
  async with aiohttp.ClientSession() as session:
55
62
  response = await session.request(
@@ -57,7 +64,7 @@ class _API():
57
64
  url=url,
58
65
  headers=self._configure_headers(override_token),
59
66
  params=params,
60
- json=json
67
+ json=json,
61
68
  )
62
69
  if not response.ok:
63
70
  if not_found_is_empty and response.status == 404:
@@ -68,7 +75,7 @@ class _API():
68
75
  try:
69
76
  error_data = await response.json()
70
77
  self.error = error_data
71
- except Exception as e:
78
+ except Exception:
72
79
  # Fallback structure matching API format
73
80
  self.error = {"error": "Bad Request", "code": str(response.status)}
74
81
  else:
@@ -80,6 +87,7 @@ class _API():
80
87
 
81
88
  def create_api_method(self, method_func: Callable) -> Callable:
82
89
  """Factory method that wraps API methods with error handling and live context"""
90
+
83
91
  @wraps(method_func)
84
92
  async def wrapper(*args, live=None, **kwargs):
85
93
  self.error = None
@@ -97,6 +105,7 @@ class _API():
97
105
 
98
106
  self.bubble_next = False
99
107
  return None, self.error
108
+
100
109
  return wrapper
101
110
 
102
111
  def print_error(self):
@@ -159,6 +168,16 @@ class _API():
159
168
  def organizations(self):
160
169
  return self.create_api_method(self._organizations)
161
170
 
171
+ # Daily API Key
172
+
173
+ async def _organizations_daily_key(self, org) -> dict:
174
+ url = self.construct_api_url("daily_key_path").format(org=org)
175
+ return await self._base_request("GET", url) or {}
176
+
177
+ @property
178
+ def organizations_daily_key(self):
179
+ return self.create_api_method(self._organizations_daily_key)
180
+
162
181
  # API Keys
163
182
 
164
183
  async def _api_keys(self, org) -> dict:
@@ -175,7 +194,10 @@ class _API():
175
194
 
176
195
  async def _api_key_create(self, api_key_name: str, org: str) -> dict:
177
196
  url = self.construct_api_url("api_keys_path").format(org=org)
178
- return await self._base_request("POST", url, json={"name": api_key_name, "type": "public"}) or {}
197
+ return (
198
+ await self._base_request("POST", url, json={"name": api_key_name, "type": "public"})
199
+ or {}
200
+ )
179
201
 
180
202
  @property
181
203
  def api_key_create(self):
@@ -271,10 +293,8 @@ class _API():
271
293
  # Deploy
272
294
 
273
295
  async def _deploy(
274
- self,
275
- deploy_config: DeployConfigParams,
276
- org: str,
277
- update: bool = False) -> dict | None:
296
+ self, deploy_config: DeployConfigParams, org: str, update: bool = False
297
+ ) -> dict | None:
278
298
  url = f"{self.construct_api_url('services_path').format(org=org)}"
279
299
 
280
300
  # Create base payload and filter out None values
@@ -285,8 +305,8 @@ class _API():
285
305
  "secretSet": deploy_config.secret_set,
286
306
  "autoScaling": {
287
307
  "minReplicas": deploy_config.scaling.min_instances,
288
- "maxReplicas": deploy_config.scaling.max_instances
289
- }
308
+ "maxReplicas": deploy_config.scaling.max_instances,
309
+ },
290
310
  }
291
311
 
292
312
  # Remove None values recursively
@@ -1,5 +1,11 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  PIPECAT_CLI_NAME = "pcc"
2
- PIPECAT_CREDENTIALS_PATH = "~/.pipecatcloud.toml"
8
+ PIPECAT_CREDENTIALS_PATH = "~/.config/pipecatcloud/pipecatcloud.toml"
3
9
  PIPECAT_DEPLOY_CONFIG_PATH = "pcc-deploy.toml"
4
10
 
5
11
  PANEL_TITLE_ERROR = "ᓚᘏᗢ Error"
@@ -1,3 +1,9 @@
1
+ #
2
+ # Copyright (c) 2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+
1
7
  from pipecatcloud.api import _API
2
8
  from pipecatcloud.cli.config import config
3
9