pipecatcloud 0.2.19__tar.gz → 0.2.20__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.2.19 → pipecatcloud-0.2.20}/CHANGELOG.md +9 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/PKG-INFO +1 -1
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/commands/auth.py +69 -32
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/config.py +20 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud.egg-info/PKG-INFO +1 -1
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/.github/workflows/format.yml +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/.github/workflows/publish-pypi.yml +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/.github/workflows/publish-test.yml +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/.github/workflows/tests.yml +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/.gitignore +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/.pre-commit-config.yaml +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/LICENSE +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/README.md +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/pipecat-cloud.png +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/pyproject.toml +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/pytest.ini +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/scripts/fix-ruff.sh +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/scripts/pre-commit.sh +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/setup.cfg +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/__init__.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/__main__.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/__version__.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/_utils/__init__.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/_utils/async_utils.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/_utils/auth_utils.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/_utils/console_utils.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/_utils/deploy_utils.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/_utils/regions.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/agent.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/api.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/__init__.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/api.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/commands/__init__.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/commands/agent.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/commands/deploy.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/commands/docker.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/commands/organizations.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/commands/regions.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/commands/secrets.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/cli/entry_point.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/config.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/constants.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/exception.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/py.typed +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/session.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud/smallwebrtc/session_manager.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud.egg-info/SOURCES.txt +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud.egg-info/dependency_links.txt +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud.egg-info/entry_points.txt +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud.egg-info/requires.txt +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/src/pipecatcloud.egg-info/top_level.txt +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/tests/__init__.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/tests/test_agent_sessions.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/tests/test_agent_stop.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/tests/test_api_client.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/tests/test_docker_commands.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/tests/test_krisp_viva.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/tests/test_managed_keys.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/tests/test_regions.py +0 -0
- {pipecatcloud-0.2.19 → pipecatcloud-0.2.20}/uv.lock +0 -0
|
@@ -5,6 +5,15 @@ All notable changes to **Pipecat Cloud** will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.20] - 2026-02-11
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Fixed `auth login --headless` to be fully non-interactive by using plain text
|
|
13
|
+
output instead of Rich terminal widgets, enabling use in environments like
|
|
14
|
+
Claude Code and CI/CD pipelines.
|
|
15
|
+
|
|
16
|
+
|
|
8
17
|
## [0.2.19] - 2026-01-27
|
|
9
18
|
|
|
10
19
|
### Added
|
|
@@ -161,17 +161,22 @@ async def login(
|
|
|
161
161
|
return
|
|
162
162
|
|
|
163
163
|
# Display the authentication URL and code
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
164
|
+
if headless:
|
|
165
|
+
print("\nTo authenticate with Pipecat Cloud:\n", flush=True)
|
|
166
|
+
print(f" Visit this URL: {web_url}", flush=True)
|
|
167
|
+
print(f" Then enter this code: {code}\n", flush=True)
|
|
168
|
+
else:
|
|
169
|
+
console.print(
|
|
170
|
+
Panel(
|
|
171
|
+
"[bold]To authenticate with Pipecat Cloud:[/bold]\n\n"
|
|
172
|
+
"Visit this URL:\n"
|
|
173
|
+
f"[blue][link={web_url}]{web_url}[/link][/blue]\n\n"
|
|
174
|
+
"Then enter this code:\n"
|
|
175
|
+
f"[cyan bold]{code}[/cyan bold]",
|
|
176
|
+
title="[bold]Authentication Required[/bold]",
|
|
177
|
+
border_style="blue",
|
|
178
|
+
)
|
|
173
179
|
)
|
|
174
|
-
)
|
|
175
180
|
|
|
176
181
|
# Prompt user to open the browser (unless in headless mode)
|
|
177
182
|
if not headless:
|
|
@@ -185,44 +190,76 @@ async def login(
|
|
|
185
190
|
return typer.Exit()
|
|
186
191
|
_open_url(web_url)
|
|
187
192
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
"[dim]Waiting for authentication to complete...[/dim]", spinner="dots"
|
|
191
|
-
),
|
|
192
|
-
transient=True,
|
|
193
|
-
) as live:
|
|
193
|
+
if headless:
|
|
194
|
+
print("Waiting for authentication to complete...", flush=True)
|
|
194
195
|
for attempt in itertools.count():
|
|
195
196
|
result = await auth_flow.finish()
|
|
196
197
|
if result is not None:
|
|
197
198
|
break
|
|
198
|
-
live.update(
|
|
199
|
-
console.status(
|
|
200
|
-
f"[dim]Waiting for authentication to complete... (attempt {attempt + 1})[/dim]"
|
|
201
|
-
)
|
|
202
|
-
)
|
|
203
199
|
if result is None:
|
|
204
|
-
|
|
205
|
-
console.error("Authentication failed")
|
|
200
|
+
print("Error: Authentication failed", flush=True)
|
|
206
201
|
return typer.Exit()
|
|
207
202
|
|
|
208
|
-
|
|
203
|
+
print("Obtaining account data...", flush=True)
|
|
209
204
|
try:
|
|
210
205
|
account_name, account_name_verbose = await _get_account_org(result, active_org)
|
|
211
|
-
live.stop()
|
|
212
206
|
logger.debug(f"Setting namespace to {account_name_verbose} ({account_name})")
|
|
213
207
|
if account_name is None:
|
|
214
208
|
raise
|
|
215
209
|
except Exception:
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"
|
|
210
|
+
print(
|
|
211
|
+
"Error: Account has no associated namespace. "
|
|
212
|
+
"Have you completed the onboarding process? "
|
|
213
|
+
"Please first sign in via the web dashboard.",
|
|
214
|
+
flush=True,
|
|
219
215
|
)
|
|
220
216
|
return typer.Exit()
|
|
221
217
|
|
|
222
|
-
|
|
223
|
-
"
|
|
224
|
-
|
|
225
|
-
|
|
218
|
+
print("Web authentication finished successfully!", flush=True)
|
|
219
|
+
print(f"Account details stored to {user_config_path}", flush=True)
|
|
220
|
+
else:
|
|
221
|
+
with Live(
|
|
222
|
+
console.status(
|
|
223
|
+
"[dim]Waiting for authentication to complete...[/dim]", spinner="dots"
|
|
224
|
+
),
|
|
225
|
+
transient=True,
|
|
226
|
+
) as live:
|
|
227
|
+
for attempt in itertools.count():
|
|
228
|
+
result = await auth_flow.finish()
|
|
229
|
+
if result is not None:
|
|
230
|
+
break
|
|
231
|
+
live.update(
|
|
232
|
+
console.status(
|
|
233
|
+
f"[dim]Waiting for authentication to complete... (attempt {attempt + 1})[/dim]"
|
|
234
|
+
)
|
|
235
|
+
)
|
|
236
|
+
if result is None:
|
|
237
|
+
live.stop()
|
|
238
|
+
console.error("Authentication failed")
|
|
239
|
+
return typer.Exit()
|
|
240
|
+
|
|
241
|
+
live.update(console.status("[dim]Obtaining account data[/dim]", spinner="dots"))
|
|
242
|
+
try:
|
|
243
|
+
account_name, account_name_verbose = await _get_account_org(
|
|
244
|
+
result, active_org
|
|
245
|
+
)
|
|
246
|
+
live.stop()
|
|
247
|
+
logger.debug(
|
|
248
|
+
f"Setting namespace to {account_name_verbose} ({account_name})"
|
|
249
|
+
)
|
|
250
|
+
if account_name is None:
|
|
251
|
+
raise
|
|
252
|
+
except Exception:
|
|
253
|
+
live.stop()
|
|
254
|
+
console.error(
|
|
255
|
+
"Account has no associated namespace. Have you completed the onboarding process? Please first sign in via the web dashboard."
|
|
256
|
+
)
|
|
257
|
+
return typer.Exit()
|
|
258
|
+
|
|
259
|
+
console.success(
|
|
260
|
+
"Web authentication finished successfully!\n"
|
|
261
|
+
f"[dim]Account details stored to [magenta]{user_config_path}[/magenta][/dim]"
|
|
262
|
+
)
|
|
226
263
|
|
|
227
264
|
except Exception as e:
|
|
228
265
|
logger.debug(e)
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
#
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
|
+
import stat
|
|
9
|
+
import warnings
|
|
8
10
|
from typing import Optional
|
|
9
11
|
|
|
10
12
|
import toml
|
|
@@ -47,6 +49,18 @@ def _read_user_config():
|
|
|
47
49
|
|
|
48
50
|
if not all(isinstance(e, dict) for e in org_sections.values()):
|
|
49
51
|
config_problem = "Pipecat Cloud config file is not valid TOML. Organization sections must be dictionaries. Please log out and log back in."
|
|
52
|
+
|
|
53
|
+
# Warn if credentials file is readable by group or others (Unix only).
|
|
54
|
+
if os.name != "nt":
|
|
55
|
+
file_mode = os.stat(user_config_path).st_mode
|
|
56
|
+
if file_mode & (stat.S_IRWXG | stat.S_IRWXO):
|
|
57
|
+
warnings.warn(
|
|
58
|
+
f"Credentials file '{user_config_path}' has overly permissive "
|
|
59
|
+
f"permissions ({stat.filemode(file_mode)}). Other users on this "
|
|
60
|
+
f"system may be able to read your token. Run "
|
|
61
|
+
f"'chmod 600 {user_config_path}' to fix, or login again to repair automatically.",
|
|
62
|
+
stacklevel=2,
|
|
63
|
+
)
|
|
50
64
|
if config_problem:
|
|
51
65
|
raise ConfigError(config_problem)
|
|
52
66
|
|
|
@@ -63,6 +77,12 @@ def _write_user_config(new_config):
|
|
|
63
77
|
with open(user_config_path, "w") as f:
|
|
64
78
|
toml.dump(new_config, f)
|
|
65
79
|
|
|
80
|
+
# Restrict permissions so only the file owner can access credentials.
|
|
81
|
+
# On Windows os.chmod is limited but home directories are already
|
|
82
|
+
# protected by ACLs, so this is effectively a Unix-only hardening.
|
|
83
|
+
os.chmod(dir_path, stat.S_IRWXU) # 0o700
|
|
84
|
+
os.chmod(user_config_path, stat.S_IRUSR | stat.S_IWUSR) # 0o600
|
|
85
|
+
|
|
66
86
|
|
|
67
87
|
def remove_user_config():
|
|
68
88
|
os.remove(user_config_path)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|