pipecatcloud 0.0.6__tar.gz → 0.0.8__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 (53) hide show
  1. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/.github/workflows/python-publish.yml +3 -12
  2. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/.gitignore +2 -0
  3. pipecatcloud-0.0.8/CHANGELOG.md +69 -0
  4. {pipecatcloud-0.0.6/src/pipecatcloud.egg-info → pipecatcloud-0.0.8}/PKG-INFO +1 -1
  5. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/README.md +20 -4
  6. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/pyproject.toml +1 -1
  7. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/__init__.py +0 -5
  8. pipecatcloud-0.0.8/src/pipecatcloud/_utils/auth_utils.py +19 -0
  9. pipecatcloud-0.0.8/src/pipecatcloud/_utils/console_utils.py +76 -0
  10. pipecatcloud-0.0.8/src/pipecatcloud/_utils/deploy_utils.py +98 -0
  11. pipecatcloud-0.0.8/src/pipecatcloud/_utils/local_runner.py +34 -0
  12. pipecatcloud-0.0.8/src/pipecatcloud/api.py +325 -0
  13. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/cli/__init__.py +4 -0
  14. pipecatcloud-0.0.8/src/pipecatcloud/cli/api.py +4 -0
  15. {pipecatcloud-0.0.6/src/pipecatcloud/cli → pipecatcloud-0.0.8/src/pipecatcloud/cli/commands}/agent.py +97 -129
  16. pipecatcloud-0.0.8/src/pipecatcloud/cli/commands/auth.py +239 -0
  17. pipecatcloud-0.0.8/src/pipecatcloud/cli/commands/deploy.py +341 -0
  18. pipecatcloud-0.0.8/src/pipecatcloud/cli/commands/init.py +16 -0
  19. pipecatcloud-0.0.8/src/pipecatcloud/cli/commands/organizations.py +357 -0
  20. pipecatcloud-0.0.8/src/pipecatcloud/cli/commands/run.py +29 -0
  21. pipecatcloud-0.0.8/src/pipecatcloud/cli/commands/secrets.py +505 -0
  22. pipecatcloud-0.0.8/src/pipecatcloud/cli/config.py +124 -0
  23. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/cli/entry_point.py +27 -30
  24. pipecatcloud-0.0.8/src/pipecatcloud/config.py +60 -0
  25. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/errors.py +5 -5
  26. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/exception.py +5 -1
  27. pipecatcloud-0.0.6/src/pipecatcloud/agent.py → pipecatcloud-0.0.8/src/pipecatcloud/session.py +8 -32
  28. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8/src/pipecatcloud.egg-info}/PKG-INFO +1 -1
  29. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud.egg-info/SOURCES.txt +13 -9
  30. pipecatcloud-0.0.6/CHANGELOG.md +0 -28
  31. pipecatcloud-0.0.6/src/pipecatcloud/_utils/auth_utils.py +0 -26
  32. pipecatcloud-0.0.6/src/pipecatcloud/_utils/console_utils.py +0 -25
  33. pipecatcloud-0.0.6/src/pipecatcloud/_utils/deploy_utils.py +0 -18
  34. pipecatcloud-0.0.6/src/pipecatcloud/_utils/http_utils.py +0 -43
  35. pipecatcloud-0.0.6/src/pipecatcloud/cli/auth.py +0 -274
  36. pipecatcloud-0.0.6/src/pipecatcloud/cli/deploy.py +0 -230
  37. pipecatcloud-0.0.6/src/pipecatcloud/cli/organizations.py +0 -351
  38. pipecatcloud-0.0.6/src/pipecatcloud/cli/run.py +0 -28
  39. pipecatcloud-0.0.6/src/pipecatcloud/cli/secrets.py +0 -426
  40. pipecatcloud-0.0.6/src/pipecatcloud/config.py +0 -158
  41. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/dev-requirements.txt +0 -0
  42. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/pipecat-cloud.png +0 -0
  43. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/setup.cfg +0 -0
  44. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/__main__.py +0 -0
  45. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/__version__.py +0 -0
  46. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/_utils/__init__.py +0 -0
  47. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/_utils/agent_utils.py +0 -0
  48. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud/_utils/async_utils.py +0 -0
  49. /pipecatcloud-0.0.6/src/pipecatcloud/cli/init.py → /pipecatcloud-0.0.8/src/pipecatcloud/cli/commands/__init__.py +0 -0
  50. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
  51. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
  52. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud.egg-info/requires.txt +0 -0
  53. {pipecatcloud-0.0.6 → pipecatcloud-0.0.8}/src/pipecatcloud.egg-info/top_level.txt +0 -0
@@ -1,12 +1,4 @@
1
- # This workflow will upload a Python Package to PyPI when a release is created
2
- # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
-
4
- # This workflow uses actions that are not certified by GitHub.
5
- # They are provided by a third-party and are governed by
6
- # separate terms of service, privacy policy, and support
7
- # documentation.
8
-
9
- name: Upload Python Package
1
+ name: Build and publish Python package
10
2
 
11
3
  on:
12
4
  release:
@@ -77,9 +69,8 @@ jobs:
77
69
  id: changelog
78
70
  run: |
79
71
  if [ -f "CHANGELOG.md" ]; then
80
- echo "CHANGELOG_CONTENT<<EOF" >> $GITHUB_ENV
81
- cat CHANGELOG.md >> $GITHUB_ENV
82
- echo "EOF" >> $GITHUB_ENV
72
+ CHANGELOG_CONTENT=$(cat CHANGELOG.md)
73
+ echo "CHANGELOG_CONTENT=${CHANGELOG_CONTENT}" >> $GITHUB_ENV
83
74
  else
84
75
  echo "CHANGELOG_CONTENT=No changelog available." >> $GITHUB_ENV
85
76
  fi
@@ -1,3 +1,5 @@
1
+ pcc-deploy.toml
2
+
1
3
  # Python
2
4
  __pycache__/
3
5
  *.py[cod]
@@ -0,0 +1,69 @@
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.8] - 2025-02-03
9
+
10
+ ### Added
11
+ - `secrets set [set-name] --file` allowing you to create a secret set from .env file
12
+ - `agent scale` to modify agent configuration without pushing a new image
13
+ - `run` command for running bot.py files locally via FastAPI. This initial implementation is very basic and will be expanded in the future.
14
+ - `organizations select` allows passing an `--org / -o` option to bypass prompt
15
+
16
+ ### Fixed
17
+ - All commands use the correct shorthand flag syntax (`-` vs. `--`)
18
+ - CLI config extends from module config to avoid loading config TOML with package imports
19
+ - `secrets list` now correctly lists all secrets vs. just a single entry
20
+ - `deploy` command displays live status to prevent skewed terminal output
21
+ - `deploy` command no longer allows pushing images without a tag
22
+ - `agent logs` paginate / filter / sort and tidy up display for logs
23
+ - `start` command correctly clears the live terminal text
24
+ - `pcc-deploy.toml` files now work as intended with `deploy` command
25
+ - `deploy` method now passes configuration parameters correctly
26
+ - Switching organizations will fully remove any default API tokens from the previously selected organization
27
+
28
+ ### Changed
29
+ - Local config now retains default keys when switching between organizations
30
+ - Local config now retains defaukt keys when logging in again
31
+ - `deploy` will check passed secret set exists before deployment
32
+ - `secrets list` now takes an optional `--sets / -s` parameter that filters by secret sets or image pull secrets
33
+ - `organizations keys create` now prompts you to set the newly created key as the default after creation (if active org matches)
34
+ - `organizations keys delete` not prompts to confirm if selected key is currently your local config default
35
+ - `Agent` module import has been renamed to `Session` to better reflect API
36
+
37
+
38
+ ## [0.0.7] - 2025-02-01
39
+
40
+ ### Added
41
+
42
+ - `run` command for running an agent locally. This initial implementation is very basic and will be expanded in the future.
43
+
44
+ ### Changed
45
+
46
+ - `start_agent` method no longer requires an organization. If not provided, it will assume the namespace of the API token owner.
47
+ - `start` command no longer looks up the agent before starting (health check is handled by the proxy route.)
48
+
49
+ ## [0.0.6] - 2025-02-01
50
+
51
+ ### Added
52
+
53
+ - `pipecatcloud.agent` module for working with agents via Python scripts
54
+ - `start_agent` method for starting an agent
55
+
56
+ ### Backlog
57
+
58
+ - `deploy` make image pull secrets non-optional, but allow for bypassing
59
+ - Fix: update docs to assert that the bot method must be async
60
+ - Fix: Secrets are not upserting (overriding each time, which may be preferrable?)
61
+ - Fix: deployment process needs better output
62
+ - `organizations keys create` should ask if you'd like to set the created key as default after creation (if org matches)
63
+ - Sense check image parameter of the deploy command (does it have a tag, etc)
64
+ - `agent logs` paginate / filter / sort and tidy up display for logs
65
+ - Fix: start command should clear the live text
66
+ - Secrets from .env method
67
+ - Fix: .pcc-deploy.toml should read correctly
68
+ - New conveience method to add account associated Daily API Key to a secret set
69
+ - Add: concurrency support for agent deployments
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pipecatcloud
3
- Version: 0.0.6
3
+ Version: 0.0.8
4
4
  Requires-Python: >=3.10
5
5
  Requires-Dist: aiohttp~=3.10.10
6
6
  Requires-Dist: fastapi~=0.115.5
@@ -5,7 +5,7 @@
5
5
 
6
6
 
7
7
  [![Docs](https://img.shields.io/badge/documentation-blue)](https://docs.pipecat.cloud)
8
- [![PyPI](https://img.shields.io/pypi/v/pipecat-cloud)](https://pypi.org/project/pipecat-cloud)
8
+ [![PyPI](https://img.shields.io/pypi/v/pipecatcloud)](https://pypi.org/project/pipecatcloud)
9
9
 
10
10
  # Pipecat Cloud
11
11
 
@@ -27,10 +27,11 @@ Documentation for Pipecat Cloud is available [here](https://docs.pipecat.cloud).
27
27
  ```shell
28
28
  pip install pipecatcloud
29
29
 
30
- # Note: you can use `pipecat` or `pcc` interchangeably
31
-
32
- pipecat --help
33
30
  pipecat --version
31
+ pipecat --help
32
+
33
+ # Note: you can use `pipecat` or `pcc` interchangeably
34
+ pcc auth login
34
35
  ```
35
36
 
36
37
  ! All CLI commands have a `--help` flag that will display the command usage and options.
@@ -49,3 +50,18 @@ pipecat --version
49
50
 
50
51
  6. Deploy your agent `pipecat deploy starter-agent your-repository/your-agent-name:0.1`
51
52
 
53
+ ### Usage in Python scripts
54
+
55
+ If want to programmatically start an agent within a Python script, you can use the `pipecatcloud.agent` module.
56
+
57
+ ```python
58
+ from pipecatcloud.agent import Agent
59
+
60
+ agent = Agent(
61
+ agent_name="your-agent-name",
62
+ organization="your-organization",
63
+ api_key="your-api-key",
64
+ )
65
+
66
+ await agent.start()
67
+ ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pipecatcloud"
7
- version = "0.0.6"
7
+ version = "0.0.8"
8
8
  requires-python = ">=3.10"
9
9
  dependencies = [
10
10
  "aiohttp~=3.10.10",
@@ -3,10 +3,5 @@ import sys
3
3
 
4
4
  from loguru import logger
5
5
 
6
- PIPECAT_CLI_NAME = "pcc"
7
- PIPECAT_CREDENTIALS_PATH = "~/.pipecatcloud.toml"
8
- PIPECAT_DEPLOY_CONFIG_PATH = ".pcc-deploy.toml"
9
-
10
-
11
6
  logger.remove()
12
7
  logger.add(sys.stderr, level=str(os.getenv("PCC_LOG_LEVEL", "INFO")))
@@ -0,0 +1,19 @@
1
+ import functools
2
+
3
+ from pipecatcloud._utils.console_utils import console
4
+ from pipecatcloud.cli import PIPECAT_CLI_NAME
5
+ from pipecatcloud.cli.config import config
6
+
7
+
8
+ def requires_login(func):
9
+ @functools.wraps(func)
10
+ def wrapper(*args, **kwargs):
11
+ org = config.get("org")
12
+ token = config.get("token")
13
+ if org is None or token is None:
14
+ console.error(
15
+ f"You are not logged in. Please run `{PIPECAT_CLI_NAME} auth login` first.",
16
+ )
17
+ return
18
+ return func(*args, **kwargs)
19
+ return wrapper
@@ -0,0 +1,76 @@
1
+ from typing import Optional
2
+
3
+ from rich.console import Console
4
+ from rich.panel import Panel
5
+
6
+ from pipecatcloud.cli import PANEL_TITLE_ERROR, PANEL_TITLE_SUCCESS
7
+ from pipecatcloud.errors import ERROR_CODES
8
+
9
+
10
+ class PipecatConsole(Console):
11
+ def success(
12
+ self,
13
+ message,
14
+ title: Optional[str] = None,
15
+ title_extra: Optional[str] = None,
16
+ subtitle: Optional[str] = None):
17
+
18
+ if not title:
19
+ title = f"{PANEL_TITLE_SUCCESS}{f' - {title_extra}' if title_extra is not None else ''}"
20
+
21
+ self.print(
22
+ Panel(
23
+ message,
24
+ title=f"[bold green]{title}[/bold green]",
25
+ subtitle=subtitle,
26
+ title_align="left",
27
+ subtitle_align="left",
28
+ border_style="green"))
29
+
30
+ def error(
31
+ self,
32
+ message,
33
+ title_extra: Optional[str] = None,
34
+ subtitle: Optional[str] = None):
35
+
36
+ title = f"{PANEL_TITLE_ERROR}{f' - {title_extra}' if title_extra is not None else ''}"
37
+
38
+ self.print(
39
+ Panel(
40
+ message,
41
+ title=f"[bold red]{title}[/bold red]",
42
+ subtitle=subtitle,
43
+ title_align="left",
44
+ subtitle_align="left",
45
+ border_style="red"))
46
+
47
+ def cancel(self):
48
+ self.print("[yellow]Cancelled by user[/yellow]")
49
+
50
+ def unauthorized(self):
51
+ self.api_error("401", "Unauthorized", hide_subtitle=True)
52
+
53
+ def api_error(
54
+ self,
55
+ error_code: Optional[str],
56
+ title: Optional[str] = "API Error",
57
+ hide_subtitle: bool = False):
58
+ DEFAULT_ERROR_MESSAGE = "Unknown error. Please contact support."
59
+ ERROR_MESSAGE = ERROR_CODES.get(error_code, None) if error_code else None
60
+
61
+ if not ERROR_MESSAGE:
62
+ hide_subtitle = True
63
+
64
+ error_message = ERROR_MESSAGE if ERROR_MESSAGE else DEFAULT_ERROR_MESSAGE
65
+ self.print(
66
+ Panel(
67
+ f"[red]{title}[/red]\n\n"
68
+ f"[dim]Error message:[/dim]\n{error_message}",
69
+ title=f"[bold red]{PANEL_TITLE_ERROR} - {error_code}[/bold red]",
70
+ subtitle=f"[dim]Docs: https://docs.pipecat.cloud/troubleshooting/#{error_code}[/dim]" if not hide_subtitle else None,
71
+ title_align="left",
72
+ subtitle_align="left",
73
+ border_style="red"))
74
+
75
+
76
+ console = PipecatConsole()
@@ -0,0 +1,98 @@
1
+ import os
2
+ from typing import Optional
3
+
4
+ import toml
5
+ from attr import dataclass
6
+ from loguru import logger
7
+
8
+ from pipecatcloud.exception import ConfigFileError
9
+
10
+ DEPLOY_STATUS_MAP = {
11
+ "Unknown": "[dim]Waiting[/dim]",
12
+ "True": "[green]Ready[/green]",
13
+ "False": "[yellow]Creating[/yellow]"
14
+ }
15
+
16
+
17
+ @dataclass
18
+ class ScalingParams:
19
+ min_instances: Optional[int] = 0
20
+ max_instances: Optional[int] = 10
21
+
22
+ def __attrs_post_init__(self):
23
+ if self.min_instances is not None:
24
+ if self.min_instances < 0:
25
+ raise ValueError("min_instances must be greater than or equal to 0")
26
+
27
+ if self.max_instances is not None:
28
+ if self.max_instances < 1:
29
+ raise ValueError("max_instances must be greater than 0")
30
+
31
+ if self.min_instances is not None and self.max_instances < self.min_instances:
32
+ raise ValueError("max_instances must be greater than or equal to min_instances")
33
+
34
+ def to_dict(self):
35
+ return {
36
+ "min_instances": self.min_instances,
37
+ "max_instances": self.max_instances
38
+ }
39
+
40
+
41
+ @dataclass
42
+ class DeployConfigParams():
43
+ agent_name: Optional[str] = None
44
+ image: Optional[str] = None
45
+ image_credentials: Optional[str] = None
46
+ secret_set: Optional[str] = None
47
+ scaling: ScalingParams = ScalingParams()
48
+
49
+ def __attrs_post_init__(self):
50
+ if self.image is not None and ":" not in self.image:
51
+ raise ValueError("Provided image must include tag e.g. my-image:latest")
52
+
53
+ def to_dict(self):
54
+ return {
55
+ "agent_name": self.agent_name,
56
+ "image": self.image,
57
+ "image_credentials": self.image_credentials,
58
+ "secret_set": self.secret_set,
59
+ "scaling": self.scaling.to_dict() if self.scaling else None
60
+ }
61
+
62
+
63
+ def load_deploy_config_file() -> Optional[DeployConfigParams]:
64
+ from pipecatcloud.cli.config import deploy_config_path
65
+
66
+ logger.debug(f"Deploy config path: {deploy_config_path}")
67
+ logger.debug(f"Deploy config path exists: {os.path.exists(deploy_config_path)}")
68
+
69
+ try:
70
+ with open(deploy_config_path, "r") as f:
71
+ config_data = toml.load(f)
72
+
73
+ # Extract scaling parameters if present
74
+ scaling_data = config_data.pop('scaling', {})
75
+ scaling_params = ScalingParams(**scaling_data)
76
+
77
+ # Create DeployConfigParams with validated data
78
+ validated_config = DeployConfigParams(
79
+ **config_data,
80
+ scaling=scaling_params,
81
+ )
82
+
83
+ # Check for unexpected keys
84
+ expected_keys = {
85
+ 'agent_name',
86
+ 'image',
87
+ 'image_credentials',
88
+ 'secret_set',
89
+ 'scaling'}
90
+ unexpected_keys = set(config_data.keys()) - expected_keys
91
+ if unexpected_keys:
92
+ raise ConfigFileError(f"Unexpected keys in config file: {unexpected_keys}")
93
+
94
+ return validated_config
95
+
96
+ except Exception as e:
97
+ logger.debug(e)
98
+ raise ConfigFileError(str(e))
@@ -0,0 +1,34 @@
1
+
2
+ import fastapi
3
+ import uvicorn
4
+ from loguru import logger
5
+
6
+
7
+ async def start_server(entrypoint: str, host: str = "0.0.0.0", port: int = 8000):
8
+ """Start a FastAPI server with the specified routes.
9
+
10
+ Args:
11
+ entrypoint (str): The entry point identifier
12
+ """
13
+ 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
+
20
+ # @TODO dynamically load entrypoint
21
+
22
+ @app.get("/health")
23
+ async def health_check():
24
+ return {"status": "healthy"}
25
+
26
+ config = uvicorn.Config(
27
+ app,
28
+ host=host,
29
+ port=port,
30
+ log_level="error",
31
+ )
32
+ server = uvicorn.Server(config)
33
+
34
+ await server.serve()