ccproxy.docker.stream_process¶
ccproxy.docker.stream_process
¶
Process execution and streaming output handling.
This module provides tools for running subprocesses and handling their output streams. It supports custom output processing through middleware components, making it suitable for real-time output handling in CLI applications.
Example
from ccproxy.docker.stream_process import run_command, DefaultOutputMiddleware
# Create custom middleware to add timestamps
from datetime import datetime
class TimestampMiddleware(DefaultOutputMiddleware):
async def process(self, line: str, stream_type: str) -> str:
timestamp = datetime.now().strftime('%H:%M:%S')
return f"[{timestamp}] {await super().process(line, stream_type)}"
# Run a command with custom output handling
return_code, stdout, stderr = await run_command(
"ls -la", middleware=TimestampMiddleware()
)
OutputMiddleware
¶
Bases: Generic[T]
Base class for processing command output streams.
OutputMiddleware provides a way to intercept and process output lines from subprocesses. Implementations can format, filter, or transform the output as needed.
Type parameter T represents the return type of the process method, allowing middleware to transform strings into other types if needed.
process
async
¶
Process a line of output from a subprocess stream.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
line
|
str
|
A line of text from the process output |
required |
stream_type
|
str
|
Either "stdout" or "stderr" |
required |
Returns:
Type | Description |
---|---|
T
|
Processed output of type T |
Raises:
Type | Description |
---|---|
NotImplementedError
|
Subclasses must implement this method |
Source code in ccproxy/docker/stream_process.py
DefaultOutputMiddleware
¶
Bases: OutputMiddleware[str]
Simple middleware that prints output with optional prefixes.
This middleware prints each line to the console with configurable prefixes for stdout and stderr streams.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
stdout_prefix
|
str
|
Prefix for stdout lines (default: "") |
''
|
stderr_prefix
|
str
|
Prefix for stderr lines (default: "ERROR: ") |
'ERROR: '
|
Source code in ccproxy/docker/stream_process.py
process
async
¶
Process and print a line with the appropriate prefix.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
line
|
str
|
Output line to process |
required |
stream_type
|
str
|
Either "stdout" or "stderr" |
required |
Returns:
Type | Description |
---|---|
str
|
The original line (unmodified) |
Source code in ccproxy/docker/stream_process.py
ChainedOutputMiddleware
¶
Bases: OutputMiddleware[T]
Middleware that chains multiple middleware components together.
Processes output through a sequence of middleware components, where each middleware processes the output from the previous one. The final output type T is determined by the last middleware in the chain.
Example
# Chain progress tracking with logging
progress_middleware = CompilationProgressMiddleware(callback)
logger_middleware = LoggerOutputMiddleware(logger)
chained = ChainedOutputMiddleware([progress_middleware, logger_middleware])
# Process: line -> progress_middleware -> logger_middleware -> final result
result = docker_adapter.run_container("image", [], {}, middleware=chained)
Parameters:
Name | Type | Description | Default |
---|---|---|---|
middleware_chain
|
list[OutputMiddleware[Any]]
|
List of middleware components to chain together. Output flows from first to last middleware. |
required |
Raises:
Type | Description |
---|---|
ValueError
|
If middleware_chain is empty |
Source code in ccproxy/docker/stream_process.py
process
async
¶
Process line through the middleware chain.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
line
|
str
|
Output line to process |
required |
stream_type
|
str
|
Either "stdout" or "stderr" |
required |
Returns:
Type | Description |
---|---|
T
|
Output from the final middleware in the chain |
Source code in ccproxy/docker/stream_process.py
create_chained_middleware
¶
Factory function to create a chained middleware.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
middleware_chain
|
list[OutputMiddleware[Any]]
|
List of middleware components to chain together |
required |
Returns:
Type | Description |
---|---|
ChainedOutputMiddleware[Any]
|
ChainedOutputMiddleware instance |
Raises:
Type | Description |
---|---|
ValueError
|
If middleware_chain is empty |
Example
from ccproxy.docker.stream_process import create_chained_middleware
from ccproxy.docker.adapter import LoggerOutputMiddleware
# Create individual middleware components
logger_middleware = LoggerOutputMiddleware(logger)
# Chain them together
chained = create_chained_middleware([logger_middleware])
# Use with docker adapter
result = docker_adapter.run_container("image", [], {}, middleware=chained)
Source code in ccproxy/docker/stream_process.py
run_command
async
¶
Run a command and process its output through middleware.
This function executes a command as a subprocess and streams its output through the provided middleware for real-time processing. The processed outputs are collected and returned along with the exit code.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
cmd
|
str | list[str]
|
Command to run, either as a string or list of arguments |
required |
middleware
|
OutputMiddleware[T] | None
|
Optional middleware for processing output (uses DefaultOutputMiddleware if None) |
None
|
Returns:
Type | Description |
---|---|
ProcessResult[T]
|
Tuple containing: - Return code from the process (0 for success) - List of processed stdout lines - List of processed stderr lines |
Example
# Simple command execution
rc, stdout, stderr = await run_command("ls -l")
# With custom middleware
class CustomMiddleware(OutputMiddleware[str]):
async def process(self, line: str, stream_type: str) -> str:
return f"[{stream_type}] {line}"
rc, stdout, stderr = await run_command("ls -l", CustomMiddleware())
Source code in ccproxy/docker/stream_process.py
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
|