pipecatcloud 0.1.5__tar.gz → 0.1.6__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 (44) hide show
  1. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/CHANGELOG.md +6 -0
  2. {pipecatcloud-0.1.5/src/pipecatcloud.egg-info → pipecatcloud-0.1.6}/PKG-INFO +1 -1
  3. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/pyproject.toml +1 -1
  4. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/deploy_utils.py +45 -12
  5. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/api.py +2 -2
  6. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/agent.py +7 -11
  7. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/deploy.py +51 -27
  8. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6/src/pipecatcloud.egg-info}/PKG-INFO +1 -1
  9. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/.github/workflows/publish-pypi.yml +0 -0
  10. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/.github/workflows/publish-test.yml +0 -0
  11. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/.github/workflows/python-publish.yml +0 -0
  12. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/.gitignore +0 -0
  13. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/LICENSE +0 -0
  14. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/README.md +0 -0
  15. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/dev-requirements.txt +0 -0
  16. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/pipecat-cloud.png +0 -0
  17. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/setup.cfg +0 -0
  18. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/__init__.py +0 -0
  19. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/__main__.py +0 -0
  20. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/__version__.py +0 -0
  21. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/__init__.py +0 -0
  22. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/async_utils.py +0 -0
  23. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/auth_utils.py +0 -0
  24. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/console_utils.py +0 -0
  25. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/_utils/local_runner.py +0 -0
  26. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/agent.py +0 -0
  27. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/__init__.py +0 -0
  28. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/api.py +0 -0
  29. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/__init__.py +0 -0
  30. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/auth.py +0 -0
  31. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/init.py +0 -0
  32. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/organizations.py +0 -0
  33. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/run.py +0 -0
  34. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/commands/secrets.py +0 -0
  35. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/config.py +0 -0
  36. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/cli/entry_point.py +0 -0
  37. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/config.py +0 -0
  38. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/exception.py +0 -0
  39. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud/session.py +0 -0
  40. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/SOURCES.txt +0 -0
  41. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
  42. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
  43. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/requires.txt +0 -0
  44. {pipecatcloud-0.1.5 → pipecatcloud-0.1.6}/src/pipecatcloud.egg-info/top_level.txt +0 -0
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.6] - 2025-04-25
11
+
12
+ # Changed
13
+
14
+ - `min-instances` and `max-instances` has been changed to reflect API terminology changes.
15
+
10
16
  ## [0.1.5] - 2025-04-09
11
17
 
12
18
  # Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pipecatcloud
3
- Version: 0.1.5
3
+ Version: 0.1.6
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.1.5"
7
+ version = "0.1.6"
8
8
  requires-python = ">=3.10"
9
9
  description = "Cloud hosting for Pipecat AI applications"
10
10
  license = { text = "BSD 2-Clause License" }
@@ -5,10 +5,11 @@
5
5
  #
6
6
 
7
7
  import os
8
- from typing import Optional
8
+ import functools
9
+ from typing import Optional, Callable, Any
9
10
 
10
11
  import toml
11
- from attr import dataclass
12
+ from attr import dataclass, field
12
13
  from loguru import logger
13
14
 
14
15
  from pipecatcloud.exception import ConfigFileError
@@ -22,23 +23,37 @@ DEPLOY_STATUS_MAP = {
22
23
 
23
24
  @dataclass
24
25
  class ScalingParams:
25
- min_instances: Optional[int] = 0
26
- max_instances: Optional[int] = 10
26
+ min_agents: Optional[int] = 0
27
+ max_agents: Optional[int] = None
28
+ # @deprecated
29
+ min_instances: Optional[int] = field(default=None, metadata={"deprecated": True})
30
+ # @deprecated
31
+ max_instances: Optional[int] = field(default=None, metadata={"deprecated": True})
27
32
 
28
33
  def __attrs_post_init__(self):
34
+ # Handle deprecated fields
29
35
  if self.min_instances is not None:
30
- if self.min_instances < 0:
31
- raise ValueError("min_instances must be greater than or equal to 0")
36
+ logger.warning("min_instances is deprecated, use min_agents instead")
37
+ self.min_agents = self.min_instances
32
38
 
33
39
  if self.max_instances is not None:
34
- if self.max_instances < 1:
35
- raise ValueError("max_instances must be greater than 0")
40
+ logger.warning("max_instances is deprecated, use max_agents instead")
41
+ self.max_agents = self.max_instances
36
42
 
37
- if self.min_instances is not None and self.max_instances < self.min_instances:
38
- raise ValueError("max_instances must be greater than or equal to min_instances")
43
+ # Validation
44
+ if self.min_agents is not None:
45
+ if self.min_agents < 0:
46
+ raise ValueError("min_agents must be greater than or equal to 0")
47
+
48
+ if self.max_agents is not None:
49
+ if self.max_agents < 1:
50
+ raise ValueError("max_agents must be greater than 0")
51
+
52
+ if self.min_agents is not None and self.max_agents < self.min_agents:
53
+ raise ValueError("max_agents must be greater than or equal to min_agents")
39
54
 
40
55
  def to_dict(self):
41
- return {"min_instances": self.min_instances, "max_instances": self.max_instances}
56
+ return {"min_agents": self.min_agents, "max_agents": self.max_agents}
42
57
 
43
58
 
44
59
  @dataclass
@@ -95,7 +110,8 @@ def load_deploy_config_file() -> Optional[DeployConfigParams]:
95
110
  "image_credentials",
96
111
  "secret_set",
97
112
  "scaling",
98
- "enable_krisp"}
113
+ "enable_krisp",
114
+ }
99
115
  unexpected_keys = set(config_data.keys()) - expected_keys
100
116
  if unexpected_keys:
101
117
  raise ConfigFileError(f"Unexpected keys in config file: {unexpected_keys}")
@@ -105,3 +121,20 @@ def load_deploy_config_file() -> Optional[DeployConfigParams]:
105
121
  except Exception as e:
106
122
  logger.debug(e)
107
123
  raise ConfigFileError(str(e))
124
+
125
+
126
+ def with_deploy_config(func: Callable) -> Callable:
127
+ """
128
+ Decorator that loads the deploy config file and injects it into the function.
129
+ If the config file exists, it will be loaded and passed to the function as `deploy_config`.
130
+ """
131
+ @functools.wraps(func)
132
+ def wrapper(*args, **kwargs):
133
+ try:
134
+ deploy_config = load_deploy_config_file()
135
+ kwargs['deploy_config'] = deploy_config
136
+ except Exception as e:
137
+ logger.error(f"Error loading deploy config: {e}")
138
+ raise ConfigFileError(str(e))
139
+ return func(*args, **kwargs)
140
+ return wrapper
@@ -317,8 +317,8 @@ class _API:
317
317
  "imagePullSecretSet": deploy_config.image_credentials,
318
318
  "secretSet": deploy_config.secret_set,
319
319
  "autoScaling": {
320
- "minReplicas": deploy_config.scaling.min_instances,
321
- "maxReplicas": deploy_config.scaling.max_instances,
320
+ "minAgents": deploy_config.scaling.min_agents,
321
+ "maxAgents": deploy_config.scaling.max_agents,
322
322
  },
323
323
  "enableKrisp": deploy_config.enable_krisp,
324
324
  }
@@ -25,7 +25,7 @@ from pipecatcloud._utils.console_utils import console, format_timestamp
25
25
  from pipecatcloud.cli import PIPECAT_CLI_NAME
26
26
  from pipecatcloud.cli.api import API
27
27
  from pipecatcloud.cli.config import config
28
- from pipecatcloud._utils.deploy_utils import load_deploy_config_file, DeployConfigParams
28
+ from pipecatcloud._utils.deploy_utils import with_deploy_config, DeployConfigParams
29
29
 
30
30
  agent_cli = typer.Typer(name="agent", help="Agent management", no_args_is_help=True)
31
31
 
@@ -137,11 +137,11 @@ async def status(
137
137
  if autoscaling_data:
138
138
  scaling_renderables = [
139
139
  Panel(
140
- f"[bold]Minimum Instances[/bold]\n{autoscaling_data.get('minReplicas', 0)}",
140
+ f"[bold]Minimum Agents[/bold]\n{autoscaling_data.get('minAgents', 0)}",
141
141
  expand=True,
142
142
  ),
143
143
  Panel(
144
- f"[bold]Maximum Instances[/bold]\n{autoscaling_data.get('maxReplicas', 0)}",
144
+ f"[bold]Maximum Agents[/bold]\n{autoscaling_data.get('maxAgents', 0)}",
145
145
  expand=True,
146
146
  ),
147
147
  ]
@@ -443,7 +443,9 @@ async def deployments(
443
443
  @agent_cli.command(name="start", help="Start an agent instance")
444
444
  @synchronizer.create_blocking
445
445
  @requires_login
446
+ @with_deploy_config
446
447
  async def start(
448
+ deploy_config=typer.Option(None, hidden=True),
447
449
  agent_name: str = typer.Argument(None, help="Name of the agent to start e.g. 'my-agent'"),
448
450
  force: bool = typer.Option(
449
451
  False,
@@ -495,20 +497,14 @@ async def start(
495
497
  )
496
498
 
497
499
  # Load values from deployment config file (if one exists)
498
- partial_config = DeployConfigParams()
499
- try:
500
- if deploy_config := load_deploy_config_file():
501
- partial_config = deploy_config
502
- except Exception as e:
503
- console.error(str(e))
504
- return typer.Exit()
500
+ partial_config = deploy_config or DeployConfigParams()
505
501
 
506
502
  # Get agent name from pcc-deploy.toml if not provided
507
503
  if not agent_name:
508
504
  default_agent_name = partial_config.agent_name
509
505
 
510
506
  if not default_agent_name:
511
- console.error("No agent name provided and no default agent name found in pcc-deploy.toml")
507
+ console.error("No target agent name provided")
512
508
  return typer.Exit(1)
513
509
 
514
510
  agent_name = default_agent_name
@@ -20,7 +20,7 @@ from pipecatcloud._utils.console_utils import console
20
20
  from pipecatcloud._utils.deploy_utils import (
21
21
  DeployConfigParams,
22
22
  ScalingParams,
23
- load_deploy_config_file,
23
+ with_deploy_config,
24
24
  )
25
25
  from pipecatcloud.cli import PIPECAT_CLI_NAME
26
26
  from pipecatcloud.cli.api import API
@@ -223,26 +223,28 @@ def create_deploy_command(app: typer.Typer):
223
223
  @app.command(name="deploy", help="Deploy agent to Pipecat Cloud")
224
224
  @synchronizer.create_blocking
225
225
  @requires_login
226
+ @with_deploy_config
226
227
  async def deploy(
228
+ deploy_config=typer.Option(None, hidden=True),
227
229
  agent_name: str = typer.Argument(
228
230
  None, help="Name of the agent to deploy e.g. 'my-agent'", show_default=False
229
231
  ),
230
232
  image: str = typer.Argument(
231
233
  None, help="Docker image location e.g. 'my-image:latest'", show_default=False
232
234
  ),
233
- min_instances: int = typer.Option(
235
+ min_agents: int = typer.Option(
234
236
  None,
235
- "--min-instances",
237
+ "--min-agents",
236
238
  "-min",
237
- help="Minimum number of instances to keep warm",
239
+ help="Minimum number of agents to keep warm",
238
240
  rich_help_panel="Deployment Configuration",
239
241
  min=0,
240
242
  ),
241
- max_instances: int = typer.Option(
243
+ max_agents: int = typer.Option(
242
244
  None,
243
- "--max-instances",
245
+ "--max-agents",
244
246
  "-max",
245
- help="Maximum number of allowed instances",
247
+ help="Maximum number of allowed agents",
246
248
  rich_help_panel="Deployment Configuration",
247
249
  min=1,
248
250
  max=50,
@@ -281,7 +283,34 @@ def create_deploy_command(app: typer.Typer):
281
283
  "-f",
282
284
  help="Force deployment / skip confirmation",
283
285
  ),
286
+ # @deprecated
287
+ min_instances: int = typer.Option(
288
+ None,
289
+ "--min-instances",
290
+ help="[Deprecated] Use --min-agents instead",
291
+ hidden=True,
292
+ min=0,
293
+ ),
294
+ # @deprecated
295
+ max_instances: int = typer.Option(
296
+ None,
297
+ "--max-instances",
298
+ help="[Deprecated] Use --max-agents instead",
299
+ hidden=True,
300
+ min=1,
301
+ max=50,
302
+ ),
284
303
  ):
304
+
305
+ # Handle @deprecated options
306
+ if min_instances is not None:
307
+ logger.warning("min_instances is deprecated, use min_agents instead")
308
+ min_agents = min_instances
309
+
310
+ if max_instances is not None:
311
+ logger.warning("max_instances is deprecated, use max_agents instead")
312
+ max_agents = max_instances
313
+
285
314
  org = organization or config.get("org")
286
315
 
287
316
  # Compose deployment config from CLI options and config file (if provided)
@@ -290,15 +319,7 @@ def create_deploy_command(app: typer.Typer):
290
319
  # 2. Values from the config toml file
291
320
  # 3. CLI command defaults
292
321
 
293
- partial_config = DeployConfigParams()
294
-
295
- # Load values from deployment config file (if one exists)
296
- try:
297
- if deploy_config := load_deploy_config_file():
298
- partial_config = deploy_config
299
- except Exception as e:
300
- console.error(str(e))
301
- return typer.Exit()
322
+ partial_config = deploy_config or DeployConfigParams()
302
323
 
303
324
  # Override any local config values from passed CLI arguments
304
325
  partial_config.agent_name = agent_name or partial_config.agent_name
@@ -306,12 +327,12 @@ def create_deploy_command(app: typer.Typer):
306
327
  partial_config.image_credentials = credentials or partial_config.image_credentials
307
328
  partial_config.secret_set = secret_set or partial_config.secret_set
308
329
  partial_config.scaling = ScalingParams(
309
- min_instances=min_instances
310
- if min_instances is not None
311
- else partial_config.scaling.min_instances,
312
- max_instances=max_instances
313
- if max_instances is not None
314
- else partial_config.scaling.max_instances,
330
+ min_agents=min_agents
331
+ if min_agents is not None
332
+ else partial_config.scaling.min_agents,
333
+ max_agents=max_agents
334
+ if max_agents is not None
335
+ else partial_config.scaling.max_agents,
315
336
  )
316
337
  partial_config.enable_krisp = krisp or partial_config.enable_krisp
317
338
 
@@ -328,8 +349,11 @@ def create_deploy_command(app: typer.Typer):
328
349
  table = Table(show_header=False, border_style="dim", show_edge=True, show_lines=True)
329
350
  table.add_column("Property", style="cyan")
330
351
  table.add_column("Value", style="green")
331
- table.add_row("Min instances", str(partial_config.scaling.min_instances))
332
- table.add_row("Max instances", str(partial_config.scaling.max_instances))
352
+ table.add_row("Min agents", str(partial_config.scaling.min_agents))
353
+ if partial_config.scaling.max_agents:
354
+ table.add_row("Max agents", str(partial_config.scaling.max_agents))
355
+ else:
356
+ table.add_row("Max agents", "[dim]Use existing or default[/dim]")
333
357
 
334
358
  content = Group(
335
359
  (f"[bold white]Agent name:[/bold white] [green]{partial_config.agent_name}[/green]"),
@@ -344,11 +368,11 @@ def create_deploy_command(app: typer.Typer):
344
368
  (
345
369
  [
346
370
  Text(
347
- f"Note: Usage costs will apply for {partial_config.scaling.min_instances} reserved instance(s). Please see: https://www.daily.co/pricing/pipecat-cloud/",
371
+ f"Note: Usage costs will apply for {partial_config.scaling.min_agents} reserved agent(s). Please see: https://www.daily.co/pricing/pipecat-cloud/",
348
372
  style="red",
349
- )] if partial_config.scaling.min_instances else [
373
+ )] if partial_config.scaling.min_agents else [
350
374
  Text(
351
- "Note: Deploying with 0 minimum instances may result in cold starts",
375
+ "Note: Deploying with 0 minimum agents may result in cold starts",
352
376
  style="red",
353
377
  )]),
354
378
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pipecatcloud
3
- Version: 0.1.5
3
+ Version: 0.1.6
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/
File without changes
File without changes
File without changes
File without changes