Skip to content

Commit f4476bb

Browse files
committed
CSDK-2788 daily-python: added Daily.set_log_level()
1 parent 84534bd commit f4476bb

File tree

5 files changed

+151
-58
lines changed

5 files changed

+151
-58
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ All notable changes to the **daily-python** SDK will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Added
11+
12+
- Added `Daily.set_log_level()` as well as a new `log_level` argument to
13+
`Daily.init()`. The available log levels are: `LogLevel.Off`,
14+
`LogLevel.Error`, `LogLevel.Warn`, `LogLevel.Info`, `LogLevel.Debug`,
15+
`LogLevel.Trace`.
16+
817
## [0.19.3] - 2025-06-17
918

1019
### Added

daily.pyi

Lines changed: 65 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,20 @@
66
# See https://docs.python.org/3/library/typing.html
77
#
88

9+
from enum import Enum
910
from typing import Any, Callable, List, Mapping, Optional
1011

11-
class Daily:
12-
@staticmethod
13-
def init(worker_threads: int = 2) -> None: ...
14-
@staticmethod
15-
def deinit() -> None: ...
16-
@staticmethod
17-
def create_camera_device(
18-
device_name: str, width: int, height: int, color_format: str = "RGBA"
19-
) -> VirtualCameraDevice: ...
20-
@staticmethod
21-
def create_speaker_device(
22-
device_name: str, sample_rate: int = 16000, channels: int = 1, non_blocking: bool = False
23-
) -> VirtualSpeakerDevice: ...
24-
@staticmethod
25-
def create_microphone_device(
26-
device_name: str, sample_rate: int = 16000, channels: int = 1, non_blocking: bool = False
27-
) -> VirtualMicrophoneDevice: ...
28-
@staticmethod
29-
def create_native_vad(
30-
reset_period_ms: int = 500, sample_rate: int = 16000, channels: int = 1
31-
) -> NativeVad: ...
32-
@staticmethod
33-
def select_speaker_device(device_name: str) -> None: ...
12+
class AudioData:
13+
@property
14+
def bits_per_sample(self) -> int: ...
15+
@property
16+
def sample_rate(self) -> int: ...
17+
@property
18+
def num_channels(self) -> int: ...
19+
@property
20+
def num_audio_frames(self) -> int: ...
21+
@property
22+
def audio_frames(self) -> bytes: ...
3423

3524
class CallClient:
3625
def __init__(self, event_handler: Optional[EventHandler] = None) -> None: ...
@@ -240,6 +229,45 @@ class CallClient:
240229
completion: Optional[Callable[[Optional[str]], None]] = None,
241230
) -> None: ...
242231

232+
class CustomAudioSource:
233+
def __init__(self, sample_rate: int, channels: int) -> None: ...
234+
@property
235+
def sample_rate(self) -> int: ...
236+
@property
237+
def channels(self) -> int: ...
238+
def write_frames(
239+
self, frame: bytes, completion: Optional[Callable[[int], None]] = None
240+
) -> int: ...
241+
242+
class CustomAudioTrack:
243+
def __init__(self, audio_source: CustomAudioSource) -> None: ...
244+
@property
245+
def id(self) -> str: ...
246+
247+
class Daily:
248+
@staticmethod
249+
def init(worker_threads: int = 2) -> None: ...
250+
@staticmethod
251+
def deinit() -> None: ...
252+
@staticmethod
253+
def create_camera_device(
254+
device_name: str, width: int, height: int, color_format: str = "RGBA"
255+
) -> VirtualCameraDevice: ...
256+
@staticmethod
257+
def create_speaker_device(
258+
device_name: str, sample_rate: int = 16000, channels: int = 1, non_blocking: bool = False
259+
) -> VirtualSpeakerDevice: ...
260+
@staticmethod
261+
def create_microphone_device(
262+
device_name: str, sample_rate: int = 16000, channels: int = 1, non_blocking: bool = False
263+
) -> VirtualMicrophoneDevice: ...
264+
@staticmethod
265+
def create_native_vad(
266+
reset_period_ms: int = 500, sample_rate: int = 16000, channels: int = 1
267+
) -> NativeVad: ...
268+
@staticmethod
269+
def select_speaker_device(device_name: str) -> None: ...
270+
243271
class EventHandler:
244272
def __init__(self) -> None: ...
245273
def on_active_speaker_changed(self, participant: Mapping[str, Any]) -> None: ...
@@ -277,32 +305,26 @@ class EventHandler:
277305
def on_transcription_started(self, status: Mapping[str, Any]) -> None: ...
278306
def on_transcription_stopped(self, stopped_by: str, stopped_by_error: bool) -> None: ...
279307

280-
class AudioData:
281-
@property
282-
def bits_per_sample(self) -> int: ...
283-
@property
284-
def sample_rate(self) -> int: ...
285-
@property
286-
def num_channels(self) -> int: ...
287-
@property
288-
def num_audio_frames(self) -> int: ...
308+
class LogLevel(Enum):
309+
Off: LogLevel
310+
Error: LogLevel
311+
Warn: LogLevel
312+
Info: LogLevel
313+
Debug: LogLevel
314+
Trace: LogLevel
315+
316+
def __str__(self) -> str: ...
289317
@property
290-
def audio_frames(self) -> bytes: ...
318+
def value(self) -> int: ...
291319

292-
class CustomAudioSource:
293-
def __init__(self, sample_rate: int, channels: int) -> None: ...
320+
class NativeVad:
321+
@property
322+
def rest_period_ms(self) -> int: ...
294323
@property
295324
def sample_rate(self) -> int: ...
296325
@property
297326
def channels(self) -> int: ...
298-
def write_frames(
299-
self, frame: bytes, completion: Optional[Callable[[int], None]] = None
300-
) -> int: ...
301-
302-
class CustomAudioTrack:
303-
def __init__(self, audio_source: CustomAudioSource) -> None: ...
304-
@property
305-
def id(self) -> str: ...
327+
def analyze_frames(self, frame: bytes) -> float: ...
306328

307329
class VideoFrame:
308330
@property
@@ -348,12 +370,3 @@ class VirtualSpeakerDevice:
348370
def read_frames(
349371
self, num_frame: int, completion: Optional[Callable[[bytes], None]] = None
350372
) -> bytes: ...
351-
352-
class NativeVad:
353-
@property
354-
def rest_period_ms(self) -> int: ...
355-
@property
356-
def sample_rate(self) -> int: ...
357-
@property
358-
def channels(self) -> int: ...
359-
def analyze_frames(self, frame: bytes) -> float: ...

docs/src/api_reference.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ API Reference
44
.. autoclass:: daily.AudioData
55
:members:
66

7-
.. autoclass:: daily.CustomAudioSource
7+
.. autoclass:: daily.CallClient
88
:members:
99

10-
.. autoclass:: daily.CustomAudioTrack
10+
.. autoclass:: daily.CustomAudioSource
1111
:members:
1212

13-
.. autoclass:: daily.CallClient
13+
.. autoclass:: daily.CustomAudioTrack
1414
:members:
1515

1616
.. autoclass:: daily.Daily
@@ -19,6 +19,9 @@ API Reference
1919
.. autoclass:: daily.EventHandler
2020
:members:
2121

22+
.. autoclass:: daily.NativeVad
23+
:members:
24+
2225
.. autoclass:: daily.VideoFrame
2326
:members:
2427

docs/src/types.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,15 @@ LiveStreamUpdate
548548
- string
549549

550550

551+
.. _LogLevel:
552+
553+
LogLevel
554+
-----------------------------------
555+
556+
Off | Error | Warn | Info | Debug | Trace
557+
558+
559+
551560
.. _MediaDeviceInfo:
552561

553562
MediaDeviceInfo

src/lib.rs

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,63 @@ unsafe extern "C" fn create_audio_device_module(
7474
#[pyclass(name = "Daily", module = "daily")]
7575
struct PyDaily;
7676

77+
/// Logging levels for controlling application output verbosity.
78+
#[pyclass(name = "LogLevel", module = "daily")]
79+
#[derive(Debug, Clone, Copy)]
80+
pub enum PyLogLevel {
81+
/// No logging.
82+
Off,
83+
/// Critical errors only.
84+
Error,
85+
/// Warnings and above.
86+
Warn,
87+
/// General information.
88+
Info,
89+
/// Debug-level information.
90+
Debug,
91+
/// All trace output.
92+
Trace,
93+
}
94+
95+
impl From<LogLevel> for PyLogLevel {
96+
fn from(level: LogLevel) -> Self {
97+
match level {
98+
LogLevel::Off => PyLogLevel::Off,
99+
LogLevel::Error => PyLogLevel::Error,
100+
LogLevel::Warn => PyLogLevel::Warn,
101+
LogLevel::Info => PyLogLevel::Info,
102+
LogLevel::Debug => PyLogLevel::Debug,
103+
LogLevel::Trace => PyLogLevel::Trace,
104+
}
105+
}
106+
}
107+
108+
impl From<PyLogLevel> for LogLevel {
109+
fn from(py_level: PyLogLevel) -> Self {
110+
match py_level {
111+
PyLogLevel::Off => LogLevel::Off,
112+
PyLogLevel::Error => LogLevel::Error,
113+
PyLogLevel::Warn => LogLevel::Warn,
114+
PyLogLevel::Info => LogLevel::Info,
115+
PyLogLevel::Debug => LogLevel::Debug,
116+
PyLogLevel::Trace => LogLevel::Trace,
117+
}
118+
}
119+
}
120+
77121
#[pymethods]
78122
impl PyDaily {
79123
/// Initializes the SDK. This function needs to be called before anything
80124
/// else, usually done at the application startup.
81125
///
82126
/// :param int worker_threads: Number of internal worker threads. Increasing this number might be necessary if the application needs to create a large number of concurrent call clients
127+
/// :param log_level: Set application log level
128+
/// :type log_level: :ref:`LogLevel`
83129
#[staticmethod]
84-
#[pyo3(signature = (worker_threads = 2))]
85-
pub fn init(worker_threads: usize) {
130+
#[pyo3(signature = (worker_threads = 2, log_level = PyLogLevel::Off))]
131+
pub fn init(worker_threads: usize, log_level: PyLogLevel) {
86132
unsafe {
87-
daily_core_set_log_level(LogLevel::Off);
133+
daily_core_set_log_level(log_level.into());
88134
}
89135

90136
let library_cstr = CString::new(DAILY_PYTHON_NAME).expect("invalid library string");
@@ -136,6 +182,18 @@ impl PyDaily {
136182
unsafe { daily_core_context_destroy() };
137183
}
138184

185+
/// Sets the application log level.
186+
///
187+
/// :param log_level: Set application log level
188+
/// :type log_level: :ref:`LogLevel`
189+
#[staticmethod]
190+
#[pyo3(signature = (log_level = PyLogLevel::Off))]
191+
pub fn set_log_level(log_level: PyLogLevel) {
192+
unsafe {
193+
daily_core_set_log_level(log_level.into());
194+
}
195+
}
196+
139197
/// Creates a new virtual camera device. Camera devices are used to
140198
/// send video (i.e. video frames) into the meeting.
141199
///
@@ -251,6 +309,7 @@ fn daily(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
251309
m.add_class::<PyCustomAudioTrack>()?;
252310
m.add_class::<PyDaily>()?;
253311
m.add_class::<PyEventHandler>()?;
312+
m.add_class::<PyLogLevel>()?;
254313
m.add_class::<PyNativeVad>()?;
255314
m.add_class::<PyVideoFrame>()?;
256315
m.add_class::<PyVirtualCameraDevice>()?;

0 commit comments

Comments
 (0)