pipecatcloud 0.0.11__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 (46) hide show
  1. pipecatcloud-0.1.0/CHANGELOG.md +86 -0
  2. {pipecatcloud-0.0.11/src/pipecatcloud.egg-info → pipecatcloud-0.1.0}/PKG-INFO +1 -1
  3. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/pyproject.toml +1 -1
  4. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/api.py +10 -0
  5. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/__init__.py +1 -1
  6. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/agent.py +9 -25
  7. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/auth.py +23 -10
  8. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/deploy.py +62 -82
  9. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/init.py +2 -1
  10. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/secrets.py +1 -1
  11. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/config.py +4 -3
  12. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/config.py +1 -0
  13. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0/src/pipecatcloud.egg-info}/PKG-INFO +1 -1
  14. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/SOURCES.txt +0 -2
  15. pipecatcloud-0.0.11/CHANGELOG.md +0 -188
  16. pipecatcloud-0.0.11/publish-pypi.yml +0 -59
  17. pipecatcloud-0.0.11/publish-test.yml +0 -59
  18. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/.github/workflows/publish-pypi.yml +0 -0
  19. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/.github/workflows/publish-test.yml +0 -0
  20. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/.github/workflows/python-publish.yml +0 -0
  21. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/.gitignore +0 -0
  22. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/LICENSE +0 -0
  23. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/README.md +0 -0
  24. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/dev-requirements.txt +0 -0
  25. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/pipecat-cloud.png +0 -0
  26. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/setup.cfg +0 -0
  27. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/__init__.py +0 -0
  28. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/__main__.py +0 -0
  29. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/__version__.py +0 -0
  30. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/__init__.py +0 -0
  31. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/async_utils.py +0 -0
  32. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/auth_utils.py +0 -0
  33. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/console_utils.py +0 -0
  34. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/deploy_utils.py +0 -0
  35. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/_utils/local_runner.py +0 -0
  36. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/api.py +0 -0
  37. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/__init__.py +0 -0
  38. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/organizations.py +0 -0
  39. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/commands/run.py +0 -0
  40. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/cli/entry_point.py +0 -0
  41. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/exception.py +0 -0
  42. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud/session.py +0 -0
  43. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
  44. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
  45. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/requires.txt +0 -0
  46. {pipecatcloud-0.0.11 → pipecatcloud-0.1.0}/src/pipecatcloud.egg-info/top_level.txt +0 -0
@@ -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.11
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.11"
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" }
@@ -168,6 +168,16 @@ class _API:
168
168
  def organizations(self):
169
169
  return self.create_api_method(self._organizations)
170
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
+
171
181
  # API Keys
172
182
 
173
183
  async def _api_keys(self, org) -> dict:
@@ -5,7 +5,7 @@
5
5
  #
6
6
 
7
7
  PIPECAT_CLI_NAME = "pcc"
8
- PIPECAT_CREDENTIALS_PATH = "~/.pipecatcloud.toml"
8
+ PIPECAT_CREDENTIALS_PATH = "~/.config/pipecatcloud/pipecatcloud.toml"
9
9
  PIPECAT_DEPLOY_CONFIG_PATH = "pcc-deploy.toml"
10
10
 
11
11
  PANEL_TITLE_ERROR = "ᓚᘏᗢ Error"
@@ -41,18 +41,16 @@ async def list(
41
41
  ):
42
42
  org = organization or config.get("org")
43
43
 
44
- with console.status(f"Fetching agents for organization: [bold]'{org}'[/bold]", spinner="dots"):
44
+ with console.status(f"[dim]Fetching agents for organization: [bold]'{org}'[/bold][/dim]", spinner="dots"):
45
45
  data, error = await API.agents(org=org)
46
46
 
47
- print(data)
48
47
  if error:
49
48
  typer.Exit()
50
49
 
51
50
  if not data or len(data) == 0:
52
51
  console.error(
53
52
  f"[red]No agents found for namespace / organization '{org}'[/red]\n\n"
54
- f"[dim]Please deploy an agent first using[/dim] [bold cyan]{PIPECAT_CLI_NAME} deploy[/bold cyan]"
55
- )
53
+ f"[dim]Please deploy an agent first using[/dim] [bold cyan]{PIPECAT_CLI_NAME} deploy[/bold cyan]")
56
54
  return typer.Exit(1)
57
55
 
58
56
  else:
@@ -441,8 +439,7 @@ async def start(
441
439
  title="Public API Key Required",
442
440
  title_align="left",
443
441
  border_style="yellow",
444
- )
445
- )
442
+ ))
446
443
 
447
444
  return typer.Exit(1)
448
445
 
@@ -457,8 +454,7 @@ async def start(
457
454
  title=f"[bold]Start Request for agent: {agent_name}[/bold]",
458
455
  title_align="left",
459
456
  border_style="yellow",
460
- )
461
- )
457
+ ))
462
458
  if not await questionary.confirm(
463
459
  "Are you sure you want to start an active session for this agent?"
464
460
  ).ask_async():
@@ -472,7 +468,7 @@ async def start(
472
468
  if not health_data or not health_data["ready"]:
473
469
  live.stop()
474
470
  console.error(
475
- f"Agent '{agent_name}' does not exist or is not in a health state. Please check the agent status with [bold cyan]{PIPECAT_CLI_NAME} agent status {agent_name}[/bold cyan]"
471
+ f"Agent '{agent_name}' does not exist or is not in a healthy state. Please check the agent status with [bold cyan]{PIPECAT_CLI_NAME} agent status {agent_name}[/bold cyan]"
476
472
  )
477
473
  return typer.Exit(1)
478
474
 
@@ -494,25 +490,13 @@ async def start(
494
490
  if error:
495
491
  return typer.Exit(1)
496
492
 
497
- if not data:
498
- live.stop()
499
- console.error(
500
- f"Agent '{agent_name}' not found. Have you deployed the agent?",
501
- subtitle=f"[white dim]Deploy an agent with[/white dim] [bold cyan]{PIPECAT_CLI_NAME} deploy[/bold cyan]",
502
- )
503
- return typer.Exit(1)
504
-
505
493
  live.stop()
506
494
 
507
- message = f"Agent '{agent_name}' started successfully"
495
+ console.success(f"Agent '{agent_name}' started successfully")
508
496
  if use_daily and isinstance(data, dict):
509
497
  daily_room = data.get("dailyRoom")
510
498
  daily_token = data.get("dailyToken")
511
499
  if daily_room:
512
- message += f"\n\nDaily room: [link={daily_room}?t={daily_token}]{daily_room}?t={daily_token}[/link]\n"
513
- return console.success(
514
- message,
515
- subtitle=f"[white dim]Join the session:[/white dim] [link={daily_room}?t={daily_token}]click here[/link]",
516
- )
517
-
518
- console.success(message)
500
+ url = f"{daily_room}?t={daily_token}"
501
+ console.print("\nJoin your session by visiting the link below:")
502
+ console.print(f"[link='{url}']{url}[/link]")
@@ -13,6 +13,7 @@ from typing import AsyncGenerator, Optional, Tuple
13
13
  import aiohttp
14
14
  import typer
15
15
  from loguru import logger
16
+ from rich.columns import Columns
16
17
  from rich.live import Live
17
18
  from rich.panel import Panel
18
19
 
@@ -151,10 +152,7 @@ async def login():
151
152
  Panel(
152
153
  "The web browser should have opened for you to authenticate with Pipecat Cloud.\n"
153
154
  "If it didn't, please copy this URL into your web browser manually:\n\n"
154
- f"[blue][link={web_url}]{web_url}[/link][/blue]\n",
155
- )
156
- )
157
- )
155
+ f"[blue][link={web_url}]{web_url}[/link][/blue]\n", )))
158
156
  else:
159
157
  # For headless use-cases, just print the URL
160
158
  live.stop()
@@ -222,7 +220,7 @@ async def logout():
222
220
  )
223
221
 
224
222
 
225
- @auth_cli.command(name="whoami", help="Display data about the current user.")
223
+ @auth_cli.command(name="whoami", help="Display data about the current user. Also show Daily API key.")
226
224
  @synchronizer.create_blocking
227
225
  @requires_login
228
226
  async def whomai():
@@ -251,11 +249,26 @@ async def whomai():
251
249
  if not account["name"] or not account["verbose_name"]:
252
250
  raise
253
251
 
254
- live.stop()
252
+ # Retrieve user Daily API key
253
+ # Note: we don't raise an error if this fails, as it's not required for
254
+ # the CLI to function
255
+ live.update(console.status("[dim]Fetching Daily API key...[/dim]", spinner="dots"))
255
256
 
256
- console.success(
257
- f"[bold]User ID:[/bold] {user_data['user']['userId']}\n"
258
- f"[bold]Active Organization:[/bold] {account['verbose_name']} [dim]({account['name']})[/dim]",
259
- )
257
+ daily_api_key = None
258
+ try:
259
+ daily_api_key, error = await API.organizations_daily_key(org=org, live=live)
260
+ except Exception:
261
+ pass
262
+
263
+ live.stop()
264
+ message = Columns([
265
+ "[bold]User ID[/bold]\n"
266
+ "[bold]Active Organization[/bold]\n"
267
+ "[bold]Daily API Key[/bold]",
268
+ f"{user_data['user']['userId']}\n"
269
+ f"{account['verbose_name']} [dim]({account['name']})[/dim]\n"
270
+ f"{daily_api_key.get('apiKey', '[dim]N/A[/dim]') if daily_api_key else '[dim]N/A[/dim]'}",
271
+ ])
272
+ console.success(message)
260
273
  except Exception:
261
274
  console.error("Unable to obtain user data. Please contact support")
@@ -9,7 +9,6 @@ import asyncio
9
9
  import typer
10
10
  from rich.console import Group
11
11
  from rich.live import Live
12
- from rich.padding import Padding
13
12
  from rich.panel import Panel
14
13
  from rich.table import Table
15
14
  from rich.text import Text
@@ -26,7 +25,7 @@ from pipecatcloud.cli import PIPECAT_CLI_NAME
26
25
  from pipecatcloud.cli.api import API
27
26
  from pipecatcloud.cli.config import config
28
27
 
29
- MAX_ALIVE_CHECKS = 10
28
+ MAX_ALIVE_CHECKS = 30
30
29
  ALIVE_CHECK_SLEEP = 5
31
30
 
32
31
  # ----- Command
@@ -37,7 +36,7 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
37
36
 
38
37
  # Check for an existing deployment with this agent name
39
38
  with Live(
40
- console.status("[dim]Checking for existing agent deployment...[/dim]", spinner="dots")
39
+ console.status("[dim]Checking for existing agent deployment...[/dim]", spinner="dots"), transient=True
41
40
  ) as live:
42
41
  data, error = await API.agent(agent_name=params.agent_name, org=org, live=live)
43
42
 
@@ -108,7 +107,7 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
108
107
 
109
108
  live.update(
110
109
  console.status(
111
- f"[dim]{'Updating' if existing_agent else 'Pushing'} agent manifest...[/dim]"
110
+ f"[dim]{'Updating' if existing_agent else 'Pushing'} agent manifest for[/dim] [cyan]'{params.agent_name}'[/cyan]"
112
111
  )
113
112
  )
114
113
 
@@ -124,85 +123,73 @@ async def _deploy(params: DeployConfigParams, org, force: bool = False):
124
123
  console.error("A problem occured during deployment. Please contact support.")
125
124
  return typer.Exit()
126
125
 
127
- """
128
- # 3. Poll status until healthy
129
- """
130
- attempts = 0
131
- active_deployment_id = None
132
- has_failed = False
133
- is_ready = False
134
-
135
- while attempts < MAX_ALIVE_CHECKS:
136
- status_render_group = Panel.fit(
137
- Group(
138
- Padding(
139
- console.status(
140
- f"[dim]Watching for deployment status (attempt: {attempts + 1})[dim]"
141
- if not active_deployment_id
142
- else f"Waiting for deployment to enter ready state [dim](attempt: {attempts + 1})[/dim]",
143
- spinner="bouncingBar",
144
- ),
145
- (1, 0),
146
- )
147
- ),
148
- title=f"[bold]{'Deploying' if not existing_agent else 'Updating'} agent[/bold]",
149
- border_style="dim" if not active_deployment_id else "white",
150
- subtitle=f"[dim]ID: {'Waiting...' if not active_deployment_id else active_deployment_id}[/dim]",
151
- )
152
- try:
153
- await asyncio.sleep(ALIVE_CHECK_SLEEP)
154
-
155
- live.update(status_render_group)
156
-
157
- if has_failed:
158
- break
126
+ # Close the live display before starting the new polling phase
127
+ live.stop()
159
128
 
160
- status, error = await API.agent(agent_name=params.agent_name, org=org, live=live)
129
+ """
130
+ # 3. Poll status until healthy
131
+ """
132
+ active_deployment_id = None
133
+ has_failed = False
134
+ is_ready = False
135
+ checks_performed = 0
136
+
137
+ # Create a simple spinner for the polling phase
138
+ with console.status(
139
+ "[dim]Waiting for deployment to become ready...[/dim]", spinner="bouncingBar"
140
+ ) as status:
141
+ try:
142
+ while checks_performed < MAX_ALIVE_CHECKS:
143
+ # Get deployment status
144
+ agent_status, error = await API.agent(
145
+ agent_name=params.agent_name, org=org, live=None
146
+ )
161
147
 
162
148
  if error:
149
+ status.stop()
150
+ console.error("Error checking deployment status")
163
151
  return typer.Exit()
164
152
 
165
- if not active_deployment_id and status["activeDeploymentId"]:
166
- # Reset attempts when deployment is assigned an ID
167
- attempts = 0
168
- active_deployment_id = status["activeDeploymentId"]
153
+ # Update deployment ID if received (silently)
154
+ if not active_deployment_id and agent_status.get("activeDeploymentId"):
155
+ active_deployment_id = agent_status["activeDeploymentId"]
169
156
 
170
- # Deployment is ready
171
- if status["ready"]:
172
- live.update("")
157
+ # Check if deployment is ready
158
+ if agent_status.get("ready"):
173
159
  is_ready = True
174
160
  break
175
161
 
176
- except KeyboardInterrupt:
177
- live.stop()
178
- console.print(
179
- "\n[yellow]Deployment monitoring interrupted. The deployment may still be in progress.[/yellow]"
180
- )
181
- return typer.Exit()
182
-
183
- attempts += 1
184
-
185
- live.stop()
186
-
187
- if has_failed:
188
- console.print(has_failed["message"])
189
- console.error("Deployment failed with the above error")
190
- return typer.Exit()
162
+ # Wait before checking again
163
+ await asyncio.sleep(ALIVE_CHECK_SLEEP)
164
+ checks_performed += 1
191
165
 
192
- if is_ready:
193
- console.success(
194
- f"Agent deployment [bold]'{params.agent_name}'[/bold] is ready\n\n"
195
- f"[dim]Start a session with your new agent by running:\n[/dim]"
196
- f"[bold]`{PIPECAT_CLI_NAME} agent start {params.agent_name}`[/bold]",
197
- title_extra=f"{'Update'if existing_agent else 'Deployment'} complete",
198
- )
199
- else:
200
- console.error(
201
- f"Deployment did not enter ready state. Please check logs `{PIPECAT_CLI_NAME} agent logs {params.agent_name}`"
166
+ except KeyboardInterrupt:
167
+ status.stop()
168
+ console.print(
169
+ "\n[yellow]Deployment monitoring interrupted. The deployment may still be in progress.[/yellow]"
202
170
  )
171
+ return typer.Exit()
203
172
 
173
+ # Final result handling
174
+ if has_failed:
175
+ console.print(has_failed["message"])
176
+ console.error("Deployment failed with the above error")
204
177
  return typer.Exit()
205
178
 
179
+ if is_ready:
180
+ console.success(
181
+ f"Agent deployment [bold]'{params.agent_name}'[/bold] is ready\n\n"
182
+ f"[dim]Start a session with your new agent by running:\n[/dim]"
183
+ f"[bold]`{PIPECAT_CLI_NAME} agent start {params.agent_name}`[/bold]",
184
+ title_extra=f"{'Update' if existing_agent else 'Deployment'} complete",
185
+ )
186
+ else:
187
+ console.error(
188
+ f"Deployment did not enter ready state within {MAX_ALIVE_CHECKS * ALIVE_CHECK_SLEEP} seconds. "
189
+ f"Please check logs with `{PIPECAT_CLI_NAME} agent logs {params.agent_name}`")
190
+
191
+ return typer.Exit()
192
+
206
193
 
207
194
  def create_deploy_command(app: typer.Typer):
208
195
  @app.command(name="deploy", help="Deploy agent to Pipecat Cloud")
@@ -312,24 +299,17 @@ def create_deploy_command(app: typer.Typer):
312
299
  (f"[bold white]Agent name:[/bold white] [green]{partial_config.agent_name}[/green]"),
313
300
  (f"[bold white]Image:[/bold white] [green]{partial_config.image}[/green]"),
314
301
  (f"[bold white]Organization:[/bold white] [green]{org}[/green]"),
315
- (
316
- f"[bold white]Secret set:[/bold white] {'[dim]None[/dim]' if not partial_config.secret_set else '[green] '+ partial_config.secret_set + '[/green]'}"
317
- ),
318
- (
319
- f"[bold white]Image pull secret:[/bold white] {'[dim]None[/dim]' if not partial_config.image_credentials else '[green]' + partial_config.image_credentials + '[/green]'}"
320
- ),
302
+ (f"[bold white]Secret set:[/bold white] {'[dim]None[/dim]' if not partial_config.secret_set else '[green] '+ partial_config.secret_set + '[/green]'}"),
303
+ (f"[bold white]Image pull secret:[/bold white] {'[dim]None[/dim]' if not partial_config.image_credentials else '[green]' + partial_config.image_credentials + '[/green]'}"),
321
304
  "\n[dim]Scaling configuration:[/dim]",
322
305
  table,
323
- *(
324
- []
325
- if partial_config.scaling.min_instances
326
- else [
306
+ *
307
+ (
308
+ [] if partial_config.scaling.min_instances else [
327
309
  Text(
328
310
  "Note: Deploying with 0 minimum instances may result in cold starts",
329
311
  style="red",
330
- )
331
- ]
332
- ),
312
+ )]),
333
313
  )
334
314
 
335
315
  console.print(
@@ -24,7 +24,8 @@ FILES_TO_EXTRACT = {
24
24
  "pipecat-cloud-starter-main/requirements.txt",
25
25
  "pipecat-cloud-starter-main/pcc-deploy.toml",
26
26
  "pipecat-cloud-starter-main/README.md",
27
- "pipecat-cloud-starter-main/pipecat-cloud-starter-main/.gitignore",
27
+ "pipecat-cloud-starter-main/.gitignore",
28
+ "pipecat-cloud-starter-main/env.example",
28
29
  "pipecat-cloud-starter-main/local_runner.py",
29
30
  }
30
31
 
@@ -247,7 +247,7 @@ async def set(
247
247
  action = "created" if not existing_set else "modified"
248
248
  message = f"Secret set [bold green]'{name}'[/bold green] {action} successfully"
249
249
  if action == "modified":
250
- message += "\n[dim]You must re-deploy any agents using this secret set for changes to take effect[/dim]"
250
+ message += "\n[bold white]You must re-deploy any agents using this secret set for changes to take effect[/bold white]"
251
251
  else:
252
252
  message += f"\n[dim]Deploy your agent with {PIPECAT_CLI_NAME} deploy agent-name --secrets {name}[/dim]"
253
253
  console.success(message)
@@ -7,6 +7,8 @@
7
7
  import os
8
8
  from typing import Optional
9
9
 
10
+ import toml
11
+
10
12
  from pipecatcloud.cli import PIPECAT_CREDENTIALS_PATH, PIPECAT_DEPLOY_CONFIG_PATH
11
13
  from pipecatcloud.config import _SETTINGS, Config, _Setting
12
14
  from pipecatcloud.exception import ConfigError
@@ -26,8 +28,6 @@ deploy_config_path: str = os.environ.get("PIPECAT_DEPLOY_CONFIG_PATH") or os.pat
26
28
  def _read_user_config():
27
29
  config_data = {}
28
30
  if os.path.exists(user_config_path):
29
- import toml
30
-
31
31
  try:
32
32
  with open(user_config_path) as f:
33
33
  config_data = toml.load(f)
@@ -53,7 +53,8 @@ user_config = _read_user_config()
53
53
 
54
54
 
55
55
  def _write_user_config(new_config):
56
- import toml
56
+ dir_path = os.path.dirname(user_config_path)
57
+ os.makedirs(dir_path, exist_ok=True)
57
58
 
58
59
  with open(user_config_path, "w") as f:
59
60
  toml.dump(new_config, f)
@@ -26,6 +26,7 @@ _SETTINGS = {
26
26
  "login_status_path": _Setting("/auth/status"),
27
27
  "whoami_path": _Setting("/v1/users"),
28
28
  "organization_path": _Setting("/v1/organizations"),
29
+ "daily_key_path": _Setting("/v1/organizations/{org}/daily"),
29
30
  "services_path": _Setting("/v1/organizations/{org}/services"),
30
31
  "services_logs_path": _Setting("/v1/organizations/{org}/services/{service}/logs"),
31
32
  "services_deployments_path": _Setting("/v1/organizations/{org}/services/{service}/deployments"),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pipecatcloud
3
- Version: 0.0.11
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,8 +4,6 @@ LICENSE
4
4
  README.md
5
5
  dev-requirements.txt
6
6
  pipecat-cloud.png
7
- publish-pypi.yml
8
- publish-test.yml
9
7
  pyproject.toml
10
8
  .github/workflows/publish-pypi.yml
11
9
  .github/workflows/publish-test.yml
@@ -1,188 +0,0 @@
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.0.11] - 2025-03-04
9
-
10
- ### Changed
11
-
12
- - `session.py` now returns the response body from the `start()` method.
13
-
14
- ### Fixed
15
-
16
- - Fixed an issue in `session.py` where a bot wouldn't start due to malformed
17
- `data`.
18
-
19
- ## [0.0.10] - 2025-03-04
20
-
21
- ### Added
22
-
23
- - `init` convenience command will now populate the working directory with files
24
- from the starter project.
25
-
26
- - `agent log` allows for optional severity level filtering.
27
-
28
- ### Changed
29
-
30
- - `agent status` and `deploy` no longer show superfluous data.
31
-
32
- - `session.py` now correctly handles errors when starting agents.
33
-
34
- - `secrets set` no longer prompts twice for confirmation if the secret set does
35
- not exist.
36
-
37
- ### Removed
38
-
39
- - `errors.py` removed as redundant (error message and code returned via API).
40
-
41
- - `agent_utils.py` removed as redundant (error message and code returned via
42
- API).
43
-
44
- ## [0.0.9] - 2025-02-27
45
-
46
- ### Added
47
-
48
- - `agent status [agent-name]` now shows deployment info and scaling
49
- configuration.
50
-
51
- - `agent sessions [agent-name]` lists active session count for an agent (will
52
- list session details in future).
53
-
54
- - `agent start [agent-name] -D` now shows the Daily room URL (and token) to
55
- join in the terminal output.
56
-
57
- ### Changed
58
-
59
- - Changed CLI command from `pipecat` to `pipecatcloud` or `pcc`.
60
-
61
- - `agent delete` prompts the user for confirmation first.
62
-
63
- - `agent start` now checks the target deployment first to ensure it exists and
64
- is in a healthy state.
65
-
66
- - Changed the information order of `agent status` so the health badge is
67
- clearly visible in terminal.
68
-
69
- - `agent deploy` now defaults to "Y" for the confirmation prompts.
70
-
71
- ### Fixed
72
-
73
- - Fixed lint error with payload data in `agent start`.
74
-
75
- - Fixed a bug where `pcc-deploy.toml` files were required to be present.
76
-
77
- - `deploy` command now correctly passes the secret set to the deployment from
78
- the `pcc-deploy.toml` file.
79
-
80
- ## [0.0.8] - 2025-02-03
81
-
82
- ### Added
83
-
84
- - `secrets set [set-name] --file` allowing you to create a secret set from .env
85
- file.
86
-
87
- - `agent scale` to modify agent configuration without pushing a new image.
88
-
89
- - `run` command for running bot.py files locally via FastAPI. This initial
90
- implementation is very basic and will be expanded in the future.
91
-
92
- - `organizations select` allows passing an `--org / -o` option to bypass
93
- prompt.
94
-
95
- ### Fixed
96
-
97
- - All commands use the correct shorthand flag syntax (`-` vs. `--`).
98
-
99
- - CLI config extends from module config to avoid loading config TOML with
100
- package imports.
101
-
102
- - `secrets list` now correctly lists all secrets vs. just a single entry.
103
-
104
- - `deploy` command displays live status to prevent skewed terminal output.
105
-
106
- - `deploy` command no longer allows pushing images without a tag.
107
-
108
- - `agent logs` paginate / filter / sort and tidy up display for logs.
109
-
110
- - `start` command correctly clears the live terminal text.
111
-
112
- - `pcc-deploy.toml` files now work as intended with `deploy` command.
113
-
114
- - `deploy` method now passes configuration parameters correctly.
115
-
116
- - Switching organizations will fully remove any default API tokens from the
117
- previously selected organization.
118
-
119
- ### Changed
120
-
121
- - Local config now retains default keys when switching between organizations.
122
-
123
- - Local config now retains defaukt keys when logging in again.
124
-
125
- - `deploy` will check passed secret set exists before deployment.
126
-
127
- - `secrets list` now takes an optional `--sets / -s` parameter that filters by
128
- secret sets or image pull secrets.
129
-
130
- - `organizations keys create` now prompts you to set the newly created key as
131
- the default after creation (if active org matches).
132
-
133
- - `organizations keys delete` not prompts to confirm if selected key is
134
- currently your local config default.
135
-
136
- - `Agent` module import has been renamed to `Session` to better reflect API.
137
-
138
- ## [0.0.7] - 2025-02-01
139
-
140
- ### Added
141
-
142
- - `run` command for running an agent locally. This initial implementation is
143
- very basic and will be expanded in the future.
144
-
145
- ### Changed
146
-
147
- - `start_agent` method no longer requires an organization. If not provided, it
148
- will assume the namespace of the API token owner.
149
-
150
- - `start` command no longer looks up the agent before starting (health check is
151
- handled by the proxy route).
152
-
153
- ## [0.0.6] - 2025-02-01
154
-
155
- ### Added
156
-
157
- - `pipecatcloud.agent` module for working with agents via Python scripts.
158
-
159
- - `start_agent` method for starting an agent.
160
-
161
- ### Backlog
162
-
163
- - `deploy` make image pull secrets non-optional, but allow for bypassing.
164
-
165
- - Fix: update docs to assert that the bot method must be async.
166
-
167
- - Fix: Secrets are not upserting (overriding each time, which may be.
168
- preferable?).
169
-
170
- - Fix: deployment process needs better output.
171
-
172
- - `organizations keys create` should ask if you'd like to set the created key
173
- as default after creation (if org matches).
174
-
175
- - Sense check image parameter of the deploy command (does it have a tag, etc).
176
-
177
- - `agent logs` paginate / filter / sort and tidy up display for logs.
178
-
179
- - Fix: start command should clear the live text.
180
-
181
- - Secrets from .env method.
182
-
183
- - Fix: .pcc-deploy.toml should read correctly.
184
-
185
- - New convenience method to add account associated Daily API Key to a secret
186
- set.
187
-
188
- - Add: concurrency support for agent deployments.
@@ -1,59 +0,0 @@
1
- name: Publish to PyPI
2
-
3
- on:
4
- workflow_dispatch:
5
- inputs:
6
- version:
7
- description: 'Version to publish (must match pyproject.toml, e.g. 0.0.4)'
8
- required: true
9
- type: string
10
-
11
- jobs:
12
- build-and-publish:
13
- runs-on: ubuntu-latest
14
- environment:
15
- name: pypi
16
- url: https://pypi.org/p/pipecat-cloud
17
- permissions:
18
- id-token: write # IMPORTANT: this permission is needed for trusted publishing
19
- contents: write # Needed for tagging
20
-
21
- steps:
22
- - name: Checkout code
23
- uses: actions/checkout@v4
24
-
25
- - name: Set up Python
26
- uses: actions/setup-python@v4
27
- with:
28
- python-version: '3.10'
29
-
30
- - name: Verify version matches
31
- run: |
32
- pip install tomli
33
- PROJECT_VERSION=$(python -c "import tomli; print(tomli.load(open('pyproject.toml', 'rb'))['project']['version'])")
34
- if [ "$PROJECT_VERSION" != "${{ github.event.inputs.version }}" ]; then
35
- echo "Error: Input version (${{ github.event.inputs.version }}) does not match pyproject.toml version ($PROJECT_VERSION)"
36
- exit 1
37
- fi
38
-
39
- - name: Install dependencies
40
- run: |
41
- python -m pip install --upgrade pip
42
- pip install -r requirements.txt
43
- pip install build twine
44
-
45
- - name: Build package
46
- run: python -m build
47
-
48
- - name: Create release tag
49
- run: |
50
- git config --local user.email "action@github.com"
51
- git config --local user.name "GitHub Action"
52
- git tag -a "v${{ github.event.inputs.version }}" -m "Version ${{ github.event.inputs.version }}"
53
- git push origin "v${{ github.event.inputs.version }}"
54
-
55
- - name: Publish to PyPI
56
- uses: pypa/gh-action-pypi-publish@release/v1
57
- with:
58
- verbose: true
59
- print-hash: true
@@ -1,59 +0,0 @@
1
- name: Publish to TEST PyPI
2
-
3
- on:
4
- workflow_dispatch:
5
- inputs:
6
- version:
7
- description: 'Version to publish (must match pyproject.toml, e.g. 0.0.4)'
8
- required: true
9
- type: string
10
-
11
- jobs:
12
- build-and-publish:
13
- runs-on: ubuntu-latest
14
- environment:
15
- name: pypi
16
- url: https://test.pypi.org/project/pipecat-cloud
17
- permissions:
18
- id-token: write # IMPORTANT: this permission is needed for trusted publishing
19
- contents: write # Needed for tagging
20
-
21
- steps:
22
- - name: Checkout code
23
- uses: actions/checkout@v4
24
-
25
- - name: Set up Python
26
- uses: actions/setup-python@v4
27
- with:
28
- python-version: '3.10'
29
-
30
- - name: Verify version matches
31
- run: |
32
- pip install tomli
33
- PROJECT_VERSION=$(python -c "import tomli; print(tomli.load(open('pyproject.toml', 'rb'))['project']['version'])")
34
- if [ "$PROJECT_VERSION" != "${{ github.event.inputs.version }}" ]; then
35
- echo "Error: Input version (${{ github.event.inputs.version }}) does not match pyproject.toml version ($PROJECT_VERSION)"
36
- exit 1
37
- fi
38
-
39
- - name: Install dependencies
40
- run: |
41
- python -m pip install --upgrade pip
42
- pip install -r requirements.txt
43
- pip install build twine
44
-
45
- - name: Build package
46
- run: python -m build
47
-
48
- - name: Create release tag
49
- run: |
50
- git config --local user.email "action@github.com"
51
- git config --local user.name "GitHub Action"
52
- git tag -a "v${{ github.event.inputs.version }}" -m "Version ${{ github.event.inputs.version }}"
53
- git push origin "v${{ github.event.inputs.version }}"
54
-
55
- - name: Publish to PyPI
56
- uses: pypa/gh-action-pypi-publish@release/v1
57
- with:
58
- verbose: true
59
- print-hash: true
File without changes
File without changes
File without changes
File without changes