pipecatcloud 0.0.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.
- pipecatcloud-0.0.6/.github/workflows/python-publish.yml +98 -0
- pipecatcloud-0.0.6/.gitignore +92 -0
- pipecatcloud-0.0.6/CHANGELOG.md +28 -0
- pipecatcloud-0.0.6/PKG-INFO +13 -0
- pipecatcloud-0.0.6/README.md +51 -0
- pipecatcloud-0.0.6/dev-requirements.txt +8 -0
- pipecatcloud-0.0.6/pipecat-cloud.png +0 -0
- pipecatcloud-0.0.6/pyproject.toml +34 -0
- pipecatcloud-0.0.6/setup.cfg +4 -0
- pipecatcloud-0.0.6/src/pipecatcloud/__init__.py +12 -0
- pipecatcloud-0.0.6/src/pipecatcloud/__main__.py +9 -0
- pipecatcloud-0.0.6/src/pipecatcloud/__version__.py +6 -0
- pipecatcloud-0.0.6/src/pipecatcloud/_utils/__init__.py +0 -0
- pipecatcloud-0.0.6/src/pipecatcloud/_utils/agent_utils.py +9 -0
- pipecatcloud-0.0.6/src/pipecatcloud/_utils/async_utils.py +20 -0
- pipecatcloud-0.0.6/src/pipecatcloud/_utils/auth_utils.py +26 -0
- pipecatcloud-0.0.6/src/pipecatcloud/_utils/console_utils.py +25 -0
- pipecatcloud-0.0.6/src/pipecatcloud/_utils/deploy_utils.py +18 -0
- pipecatcloud-0.0.6/src/pipecatcloud/_utils/http_utils.py +43 -0
- pipecatcloud-0.0.6/src/pipecatcloud/agent.py +83 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/__init__.py +3 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/agent.py +405 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/auth.py +274 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/deploy.py +230 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/entry_point.py +83 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/init.py +0 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/organizations.py +351 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/run.py +28 -0
- pipecatcloud-0.0.6/src/pipecatcloud/cli/secrets.py +426 -0
- pipecatcloud-0.0.6/src/pipecatcloud/config.py +158 -0
- pipecatcloud-0.0.6/src/pipecatcloud/errors.py +11 -0
- pipecatcloud-0.0.6/src/pipecatcloud/exception.py +55 -0
- pipecatcloud-0.0.6/src/pipecatcloud.egg-info/PKG-INFO +13 -0
- pipecatcloud-0.0.6/src/pipecatcloud.egg-info/SOURCES.txt +36 -0
- pipecatcloud-0.0.6/src/pipecatcloud.egg-info/dependency_links.txt +1 -0
- pipecatcloud-0.0.6/src/pipecatcloud.egg-info/entry_points.txt +3 -0
- pipecatcloud-0.0.6/src/pipecatcloud.egg-info/requires.txt +9 -0
- pipecatcloud-0.0.6/src/pipecatcloud.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,98 @@
|
|
|
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
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
release:
|
|
13
|
+
types: [published]
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
release-build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: '3.10'
|
|
28
|
+
- name: Setup virtual environment
|
|
29
|
+
run: |
|
|
30
|
+
python -m venv .venv
|
|
31
|
+
- name: Install basic Python dependencies
|
|
32
|
+
run: |
|
|
33
|
+
source .venv/bin/activate
|
|
34
|
+
python -m pip install --upgrade pip
|
|
35
|
+
pip install -r dev-requirements.txt
|
|
36
|
+
- name: Build project
|
|
37
|
+
run: |
|
|
38
|
+
source .venv/bin/activate
|
|
39
|
+
python -m build
|
|
40
|
+
- name: Install project and other Python dependencies
|
|
41
|
+
run: |
|
|
42
|
+
source .venv/bin/activate
|
|
43
|
+
pip install --editable .
|
|
44
|
+
- name: Upload distributions
|
|
45
|
+
uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: release-dists
|
|
48
|
+
path: dist/
|
|
49
|
+
|
|
50
|
+
pypi-publish:
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
needs:
|
|
53
|
+
- release-build
|
|
54
|
+
permissions:
|
|
55
|
+
id-token: write
|
|
56
|
+
contents: read
|
|
57
|
+
|
|
58
|
+
environment:
|
|
59
|
+
name: pypi
|
|
60
|
+
url: https://pypi.org/p/pipecatcloud
|
|
61
|
+
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v4
|
|
64
|
+
|
|
65
|
+
- name: Retrieve release distributions
|
|
66
|
+
uses: actions/download-artifact@v4
|
|
67
|
+
with:
|
|
68
|
+
name: release-dists
|
|
69
|
+
path: dist/
|
|
70
|
+
|
|
71
|
+
- name: Publish release distributions to PyPI
|
|
72
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
73
|
+
with:
|
|
74
|
+
packages-dir: dist/
|
|
75
|
+
|
|
76
|
+
- name: Read CHANGELOG
|
|
77
|
+
id: changelog
|
|
78
|
+
run: |
|
|
79
|
+
if [ -f "CHANGELOG.md" ]; then
|
|
80
|
+
echo "CHANGELOG_CONTENT<<EOF" >> $GITHUB_ENV
|
|
81
|
+
cat CHANGELOG.md >> $GITHUB_ENV
|
|
82
|
+
echo "EOF" >> $GITHUB_ENV
|
|
83
|
+
else
|
|
84
|
+
echo "CHANGELOG_CONTENT=No changelog available." >> $GITHUB_ENV
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
- name: Create GitHub Release
|
|
88
|
+
uses: softprops/action-gh-release@v2
|
|
89
|
+
with:
|
|
90
|
+
tag_name: ${{ github.ref }}
|
|
91
|
+
name: Release ${{ github.ref_name }}
|
|
92
|
+
body: |
|
|
93
|
+
${{ env.CHANGELOG_CONTENT }}
|
|
94
|
+
draft: false
|
|
95
|
+
prerelease: false
|
|
96
|
+
files: |
|
|
97
|
+
dist/*.tar.gz
|
|
98
|
+
dist/*.whl
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
*.egg
|
|
11
|
+
*.egg-info
|
|
12
|
+
.installed.cfg
|
|
13
|
+
.eggs/
|
|
14
|
+
downloads/
|
|
15
|
+
lib/
|
|
16
|
+
lib64/
|
|
17
|
+
parts/
|
|
18
|
+
sdist/
|
|
19
|
+
var/
|
|
20
|
+
wheels/
|
|
21
|
+
share/python-wheels/
|
|
22
|
+
MANIFEST
|
|
23
|
+
|
|
24
|
+
# Virtual Environments
|
|
25
|
+
venv/
|
|
26
|
+
env/
|
|
27
|
+
.env
|
|
28
|
+
.venv/
|
|
29
|
+
ENV/
|
|
30
|
+
env.bak/
|
|
31
|
+
venv.bak/
|
|
32
|
+
|
|
33
|
+
# IDE
|
|
34
|
+
.idea/
|
|
35
|
+
.vscode/
|
|
36
|
+
.spyderproject
|
|
37
|
+
.spyproject
|
|
38
|
+
.ropeproject
|
|
39
|
+
|
|
40
|
+
# Testing and Coverage
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
htmlcov/
|
|
44
|
+
.pytest_cache/
|
|
45
|
+
.tox/
|
|
46
|
+
.nox/
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*.cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Logs and Databases
|
|
55
|
+
*.log
|
|
56
|
+
*.db
|
|
57
|
+
db.sqlite3
|
|
58
|
+
db.sqlite3-journal
|
|
59
|
+
pip-log.txt
|
|
60
|
+
|
|
61
|
+
# System Files
|
|
62
|
+
.DS_Store
|
|
63
|
+
Thumbs.db
|
|
64
|
+
desktop.ini
|
|
65
|
+
*.swp
|
|
66
|
+
*.swo
|
|
67
|
+
*.bak
|
|
68
|
+
*.tmp
|
|
69
|
+
*~
|
|
70
|
+
|
|
71
|
+
# Build and Documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
.pybuilder/
|
|
74
|
+
target/
|
|
75
|
+
instance/
|
|
76
|
+
.webassets-cache
|
|
77
|
+
.pdm.toml
|
|
78
|
+
.pdm-python
|
|
79
|
+
.pdm-build/
|
|
80
|
+
__pypackages__/
|
|
81
|
+
|
|
82
|
+
# Other
|
|
83
|
+
*.mo
|
|
84
|
+
*.pot
|
|
85
|
+
*.sage.py
|
|
86
|
+
.mypy_cache/
|
|
87
|
+
.dmypy.json
|
|
88
|
+
dmypy.json
|
|
89
|
+
.pyre/
|
|
90
|
+
.pytype/
|
|
91
|
+
cython_debug/
|
|
92
|
+
.ipynb_checkpoints
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 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.6] - 2025-02-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `pipecatcloud.agent` module for working with agents via Python scripts
|
|
13
|
+
- `start_agent` method for starting an agent
|
|
14
|
+
|
|
15
|
+
### Backlog
|
|
16
|
+
|
|
17
|
+
- `deploy` make image pull secrets non-optional, but allow for bypassing
|
|
18
|
+
- Fix: update docs to assert that the bot method must be async
|
|
19
|
+
- Fix: Secrets are not upserting (overriding each time, which may be preferrable?)
|
|
20
|
+
- Fix: deployment process needs better output
|
|
21
|
+
- `organizations keys create` should ask if you'd like to set the created key as default after creation (if org matches)
|
|
22
|
+
- Sense check image parameter of the deploy command (does it have a tag, etc)
|
|
23
|
+
- `agent logs` paginate / filter / sort and tidy up display for logs
|
|
24
|
+
- Fix: start command should clear the live text
|
|
25
|
+
- Secrets from .env method
|
|
26
|
+
- Fix: .pcc-deploy.toml should read correctly
|
|
27
|
+
- New conveience method to add account associated Daily API Key to a secret set
|
|
28
|
+
- Add: concurrency support for agent deployments
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: pipecatcloud
|
|
3
|
+
Version: 0.0.6
|
|
4
|
+
Requires-Python: >=3.10
|
|
5
|
+
Requires-Dist: aiohttp~=3.10.10
|
|
6
|
+
Requires-Dist: fastapi~=0.115.5
|
|
7
|
+
Requires-Dist: loguru~=0.7.2
|
|
8
|
+
Requires-Dist: python-dotenv~=1.0.1
|
|
9
|
+
Requires-Dist: uvicorn~=0.32.0
|
|
10
|
+
Requires-Dist: typer~=0.13.0
|
|
11
|
+
Requires-Dist: synchronicity~=0.7.6
|
|
12
|
+
Requires-Dist: toml~=0.10.2
|
|
13
|
+
Requires-Dist: questionary~=2.1.0
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
|
|
2
|
+
<h1><div align="center">
|
|
3
|
+
<img alt="pipecat cloud" width="500px" height="auto" src="./pipecat-cloud.png">
|
|
4
|
+
</div></h1>
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
[](https://docs.pipecat.cloud)
|
|
8
|
+
[](https://pypi.org/project/pipecat-cloud)
|
|
9
|
+
|
|
10
|
+
# Pipecat Cloud
|
|
11
|
+
|
|
12
|
+
Python module and CLI for interacting with [Pipecat Cloud](https://pipecat.cloud).
|
|
13
|
+
|
|
14
|
+
### Requirements
|
|
15
|
+
|
|
16
|
+
- Python 3.10+
|
|
17
|
+
- Docker and a Docker repository (e.g. Docker Hub)
|
|
18
|
+
- Active [Pipecat Cloud](https://dashboard.pipecat.cloud)
|
|
19
|
+
account
|
|
20
|
+
|
|
21
|
+
### Documentation
|
|
22
|
+
|
|
23
|
+
Documentation for Pipecat Cloud is available [here](https://docs.pipecat.cloud).
|
|
24
|
+
|
|
25
|
+
### Installation
|
|
26
|
+
|
|
27
|
+
```shell
|
|
28
|
+
pip install pipecatcloud
|
|
29
|
+
|
|
30
|
+
# Note: you can use `pipecat` or `pcc` interchangeably
|
|
31
|
+
|
|
32
|
+
pipecat --help
|
|
33
|
+
pipecat --version
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
! All CLI commands have a `--help` flag that will display the command usage and options.
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
1. Create an account at [Pipecat Cloud](https://pipecat.cloud)
|
|
41
|
+
|
|
42
|
+
2. Login to your account `pipecat auth login`
|
|
43
|
+
|
|
44
|
+
3. (Optional): Clone the starter agent [here](https://github.com/pipecat-ai/pipecat-cloud-starter-agent)
|
|
45
|
+
|
|
46
|
+
4. Build your agent `docker build --platform linux/arm64 -t your-agent-name .`
|
|
47
|
+
|
|
48
|
+
5. Push your Docker image to your repository `docker push your-repository/your-agent-name:0.1`
|
|
49
|
+
|
|
50
|
+
6. Deploy your agent `pipecat deploy starter-agent your-repository/your-agent-name:0.1`
|
|
51
|
+
|
|
Binary file
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64", "setuptools_scm>=8"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pipecatcloud"
|
|
7
|
+
version = "0.0.6"
|
|
8
|
+
requires-python = ">=3.10"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"aiohttp~=3.10.10",
|
|
11
|
+
"fastapi~=0.115.5",
|
|
12
|
+
"loguru~=0.7.2",
|
|
13
|
+
"python-dotenv~=1.0.1",
|
|
14
|
+
"uvicorn~=0.32.0",
|
|
15
|
+
"typer~=0.13.0",
|
|
16
|
+
"synchronicity~=0.7.6",
|
|
17
|
+
"toml~=0.10.2",
|
|
18
|
+
"questionary~=2.1.0",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.scripts]
|
|
22
|
+
pcc = "pipecatcloud.__main__:main"
|
|
23
|
+
pipecat = "pipecatcloud.__main__:main"
|
|
24
|
+
|
|
25
|
+
[tool.setuptools]
|
|
26
|
+
package-dir = {"" = "src"}
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.packages.find]
|
|
29
|
+
where = ["src"]
|
|
30
|
+
include = ["pipecatcloud*"]
|
|
31
|
+
|
|
32
|
+
[tool.ruff]
|
|
33
|
+
exclude = ["*_pb2.py"]
|
|
34
|
+
line-length = 100
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from loguru import logger
|
|
5
|
+
|
|
6
|
+
PIPECAT_CLI_NAME = "pcc"
|
|
7
|
+
PIPECAT_CREDENTIALS_PATH = "~/.pipecatcloud.toml"
|
|
8
|
+
PIPECAT_DEPLOY_CONFIG_PATH = ".pcc-deploy.toml"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
logger.remove()
|
|
12
|
+
logger.add(sys.stderr, level=str(os.getenv("PCC_LOG_LEVEL", "INFO")))
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from typing import (
|
|
3
|
+
TypeVar,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
import synchronicity
|
|
7
|
+
|
|
8
|
+
synchronizer = synchronicity.Synchronizer()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def synchronize_api(obj, target_module=None):
|
|
12
|
+
if inspect.isclass(obj) or inspect.isfunction(obj):
|
|
13
|
+
blocking_name = obj.__name__.lstrip("_")
|
|
14
|
+
elif isinstance(obj, TypeVar):
|
|
15
|
+
blocking_name = "_BLOCKING_" + obj.__name__
|
|
16
|
+
else:
|
|
17
|
+
blocking_name = None
|
|
18
|
+
if target_module is None:
|
|
19
|
+
target_module = obj.__module__
|
|
20
|
+
return synchronizer.create_blocking(obj, blocking_name, target_module=target_module)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
from rich.panel import Panel
|
|
5
|
+
|
|
6
|
+
from pipecatcloud import PIPECAT_CLI_NAME
|
|
7
|
+
from pipecatcloud.cli import PANEL_TITLE_ERROR
|
|
8
|
+
from pipecatcloud.config import config
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def requires_login(func):
|
|
12
|
+
@functools.wraps(func)
|
|
13
|
+
def wrapper(*args, **kwargs):
|
|
14
|
+
console = Console()
|
|
15
|
+
org = config.get("org")
|
|
16
|
+
token = config.get("token")
|
|
17
|
+
if org is None or token is None:
|
|
18
|
+
console.print(Panel(
|
|
19
|
+
f"You are not logged in. Please run `{PIPECAT_CLI_NAME} auth login` first.",
|
|
20
|
+
title=f"[red]{PANEL_TITLE_ERROR}[/red]",
|
|
21
|
+
title_align="left",
|
|
22
|
+
border_style="red",
|
|
23
|
+
))
|
|
24
|
+
return
|
|
25
|
+
return func(*args, **kwargs)
|
|
26
|
+
return wrapper
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.panel import Panel
|
|
6
|
+
|
|
7
|
+
from pipecatcloud.cli import PANEL_TITLE_ERROR
|
|
8
|
+
from pipecatcloud.errors import ERROR_CODES
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def print_api_error(error_code: Optional[str], title: str):
|
|
14
|
+
error_message = "Unknown error" if not error_code else ERROR_CODES.get(
|
|
15
|
+
error_code, "Unknown error")
|
|
16
|
+
|
|
17
|
+
console.print(Panel(
|
|
18
|
+
f"[red]{title}[/red]\n\n"
|
|
19
|
+
f"[dim]Error message:[/dim]\n{error_message}",
|
|
20
|
+
title=f"[bold red]{PANEL_TITLE_ERROR} - {error_code}[/bold red]",
|
|
21
|
+
subtitle=f"[dim]Docs: https://docs.pipecat.cloud/troubleshooting/#{error_code}[/dim]",
|
|
22
|
+
title_align="left",
|
|
23
|
+
subtitle_align="left",
|
|
24
|
+
border_style="red"
|
|
25
|
+
))
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from loguru import logger
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def load_deploy_config_file() -> dict | None:
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
import toml
|
|
8
|
+
|
|
9
|
+
from pipecatcloud.config import deploy_config_path
|
|
10
|
+
|
|
11
|
+
logger.info(f"Deploy config path: {deploy_config_path}")
|
|
12
|
+
logger.info(f"Deploy config path exists: {os.path.exists(deploy_config_path)}")
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
with open(deploy_config_path, "r") as f:
|
|
16
|
+
return toml.load(f)
|
|
17
|
+
except Exception:
|
|
18
|
+
return None
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
import logging
|
|
3
|
+
import socket
|
|
4
|
+
|
|
5
|
+
from aiohttp.web import Application
|
|
6
|
+
from aiohttp.web_runner import AppRunner, SockSite
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@contextlib.asynccontextmanager
|
|
12
|
+
async def run_temporary_http_server(app: Application):
|
|
13
|
+
sock = socket.socket()
|
|
14
|
+
try:
|
|
15
|
+
sock.bind(("", 0))
|
|
16
|
+
port = sock.getsockname()[1]
|
|
17
|
+
host = f"http://127.0.0.1:{port}"
|
|
18
|
+
|
|
19
|
+
runner = AppRunner(app)
|
|
20
|
+
await runner.setup()
|
|
21
|
+
site = SockSite(runner, sock=sock)
|
|
22
|
+
await site.start()
|
|
23
|
+
try:
|
|
24
|
+
yield host
|
|
25
|
+
finally:
|
|
26
|
+
await runner.cleanup()
|
|
27
|
+
except Exception as e:
|
|
28
|
+
logger.error(f"Error setting up temporary HTTP server: {e}")
|
|
29
|
+
raise
|
|
30
|
+
finally:
|
|
31
|
+
sock.close()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def construct_api_url(path: str) -> str:
|
|
35
|
+
from pipecatcloud.config import config
|
|
36
|
+
|
|
37
|
+
if not config.get("server_url", ""):
|
|
38
|
+
raise ValueError("Server URL is not set")
|
|
39
|
+
|
|
40
|
+
if not config.get(path, ""):
|
|
41
|
+
raise ValueError(f"Endpoint {path} is not set")
|
|
42
|
+
|
|
43
|
+
return f"{config.get('server_url', '')}{config.get(path, '')}"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
import aiohttp
|
|
5
|
+
from loguru import logger
|
|
6
|
+
|
|
7
|
+
from pipecatcloud._utils.agent_utils import handle_agent_start_error
|
|
8
|
+
from pipecatcloud._utils.http_utils import construct_api_url
|
|
9
|
+
from pipecatcloud.exception import AgentStartError
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class AgentParams:
|
|
14
|
+
data: Optional[dict] = None
|
|
15
|
+
use_daily: Optional[bool] = False
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Agent:
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
agent_name: str,
|
|
22
|
+
organization: str,
|
|
23
|
+
api_key: str,
|
|
24
|
+
params: Optional[AgentParams] = None,
|
|
25
|
+
):
|
|
26
|
+
self.agent_name = agent_name
|
|
27
|
+
self.api_key = api_key
|
|
28
|
+
self.organization = organization
|
|
29
|
+
|
|
30
|
+
if not self.organization or not self.agent_name:
|
|
31
|
+
raise ValueError("Organization and agent name are required")
|
|
32
|
+
|
|
33
|
+
self.params = params or AgentParams()
|
|
34
|
+
|
|
35
|
+
async def start(self) -> bool:
|
|
36
|
+
if not self.api_key:
|
|
37
|
+
raise AgentStartError(error_code="PCC-1002")
|
|
38
|
+
|
|
39
|
+
# @TODO: Public route not yet implemented
|
|
40
|
+
"""
|
|
41
|
+
# Check deployment heath
|
|
42
|
+
error_code = None
|
|
43
|
+
agent_data = None
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
async with aiohttp.ClientSession() as session:
|
|
47
|
+
response = await session.get(
|
|
48
|
+
f"{construct_api_url('services_path').format(org=self.organization)}/{self.agent_name}",
|
|
49
|
+
headers={"Authorization": f"Bearer {self.api_key}"},
|
|
50
|
+
)
|
|
51
|
+
if response.status != 200:
|
|
52
|
+
error_code = str(response.status)
|
|
53
|
+
response.raise_for_status()
|
|
54
|
+
agent_data = await response.json()
|
|
55
|
+
if agent_data is None or not agent_data["ready"]:
|
|
56
|
+
raise AgentNotHealthyError(error_code=error_code)
|
|
57
|
+
except Exception as e:
|
|
58
|
+
raise Exception(f"Error checking agent health: {e}")
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
logger.debug(f"Starting agent {self.agent_name}")
|
|
62
|
+
|
|
63
|
+
start_error_code = None
|
|
64
|
+
try:
|
|
65
|
+
async with aiohttp.ClientSession() as session:
|
|
66
|
+
response = await session.post(
|
|
67
|
+
f"{construct_api_url('start_path').format(service=self.agent_name)}",
|
|
68
|
+
headers={"Authorization": f"Bearer {self.api_key}"},
|
|
69
|
+
json={
|
|
70
|
+
"createDailyRoom": bool(self.params.use_daily),
|
|
71
|
+
"body": self.params.data
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
if response.status != 200:
|
|
75
|
+
start_error_code = handle_agent_start_error(response.status)
|
|
76
|
+
response.raise_for_status()
|
|
77
|
+
else:
|
|
78
|
+
logger.debug(f"Agent {self.agent_name} started successfully")
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger.error(f"Error starting agent {self.agent_name}: {e}")
|
|
81
|
+
raise AgentStartError(error_code=start_error_code)
|
|
82
|
+
|
|
83
|
+
return True
|