# Network Utilities

Utilities for streaming configuration, input validation, and URL handling.

## Overview[​](#overview "Overview에 대한 직접 링크")

The `synapse_sdk.utils.network` module provides essential utilities for streaming operations and input validation used by the Ray client mixins.

## StreamLimits[​](#streamlimits "StreamLimits에 대한 직접 링크")

Configuration for streaming resource limits to prevent memory exhaustion.

### Constructor[​](#constructor "Constructor에 대한 직접 링크")

```python
from synapse_sdk.utils.network import StreamLimits

limits = StreamLimits(
    max_messages=10_000,
    max_lines=50_000,
    max_bytes=50 * 1024 * 1024,  # 50MB
    max_message_size=10_240,     # 10KB
    queue_size=1_000
)

```

### Parameters[​](#parameters "Parameters에 대한 직접 링크")

| Parameter          | Type | Default | Description                                               |
| ------------------ | ---- | ------- | --------------------------------------------------------- |
| `max_messages`     | int  | 10,000  | Maximum WebSocket messages before termination             |
| `max_lines`        | int  | 50,000  | Maximum lines for HTTP streaming                          |
| `max_bytes`        | int  | 50MB    | Maximum total bytes to receive                            |
| `max_message_size` | int  | 10KB    | Maximum size per message (oversized messages are skipped) |
| `queue_size`       | int  | 1,000   | Internal queue size for async operations                  |

### Usage with Clients[​](#usage-with-clients "Usage with Clients에 대한 직접 링크")

```python
from synapse_sdk.clients.agent import AgentClient
from synapse_sdk.utils.network import StreamLimits

client = AgentClient(base_url, agent_token)

# Configure custom limits
client.stream_limits = StreamLimits(
    max_messages=50_000,
    max_lines=100_000,
    max_bytes=200 * 1024 * 1024  # 200MB
)

# Stream with custom limits
for line in client.tail_job_logs('job-123'):
    print(line)

```

***

## Validation Functions[​](#validation-functions "Validation Functions에 대한 직접 링크")

### validate\_resource\_id()[​](#validate_resource_id "validate_resource_id()에 대한 직접 링크")

Validates resource identifiers to prevent injection attacks.

```python
from synapse_sdk.utils.network import validate_resource_id

# Valid usage
job_id = validate_resource_id('raysubmit_abc123', 'job')
node_id = validate_resource_id('node_abc_123', 'node')

# Invalid usage raises ClientError (400)
try:
    validate_resource_id('', 'job')  # Empty
except ClientError as e:
    print(e)  # "job ID cannot be empty"

try:
    validate_resource_id('job/../malicious', 'job')  # Invalid chars
except ClientError as e:
    print(e)  # "Invalid job ID format"

```

**Validation Rules:**

* Must not be empty
* Only alphanumeric, hyphens (`-`), and underscores (`_`) allowed
* Maximum length: 100 characters
* Pattern: `^[a-zA-Z0-9\-_]+$`

**Parameters:**

| Parameter       | Type | Description                                     |
| --------------- | ---- | ----------------------------------------------- |
| `resource_id`   | Any  | The ID to validate (converted to string)        |
| `resource_name` | str  | Name for error messages (default: `'resource'`) |

**Returns:** `str` - Validated resource ID

**Raises:** `ClientError` (400) if validation fails

***

### validate\_timeout()[​](#validate_timeout "validate_timeout()에 대한 직접 링크")

Validates timeout values with bounds checking.

```python
from synapse_sdk.utils.network import validate_timeout

# Valid timeouts
timeout = validate_timeout(30)      # 30 seconds -> 30.0
timeout = validate_timeout(10.5)    # 10.5 seconds -> 10.5

# Invalid timeouts raise ClientError (400)
try:
    validate_timeout(-1)  # Negative
except ClientError as e:
    print(e)  # "Timeout must be a positive number"

try:
    validate_timeout(500)  # Exceeds max (default 300)
except ClientError as e:
    print(e)  # "Timeout cannot exceed 300 seconds"

```

**Parameters:**

| Parameter     | Type      | Default | Description              |
| ------------- | --------- | ------- | ------------------------ |
| `timeout`     | int/float | -       | Timeout value in seconds |
| `max_timeout` | float     | 300.0   | Maximum allowed timeout  |

**Returns:** `float` - Validated timeout value

**Raises:** `ClientError` (400) if invalid

***

## URL Utilities[​](#url-utilities "URL Utilities에 대한 직접 링크")

### http\_to\_websocket\_url()[​](#http_to_websocket_url "http_to_websocket_url()에 대한 직접 링크")

Converts HTTP/HTTPS URLs to WebSocket URLs.

```python
from synapse_sdk.utils.network import http_to_websocket_url

# HTTP -> WS
ws_url = http_to_websocket_url("http://localhost:8000/ws/")
# Result: "ws://localhost:8000/ws/"

# HTTPS -> WSS
wss_url = http_to_websocket_url("https://api.example.com/stream/")
# Result: "wss://api.example.com/stream/"

# Already WebSocket (returns unchanged)
url = http_to_websocket_url("wss://api.example.com/")
# Result: "wss://api.example.com/"

```

**Parameters:**

| Parameter | Type | Description                 |
| --------- | ---- | --------------------------- |
| `url`     | str  | HTTP, HTTPS, WS, or WSS URL |

**Returns:** `str` - WebSocket URL (ws\:// or wss\://)

**Raises:** `ClientError` (400) if URL scheme is invalid

***

## Error Utilities[​](#error-utilities "Error Utilities에 대한 직접 링크")

### sanitize\_error\_message()[​](#sanitize_error_message "sanitize_error_message()에 대한 직접 링크")

Sanitizes error messages to prevent information leakage.

```python
from synapse_sdk.utils.network import sanitize_error_message

# Redacts quoted strings
clean = sanitize_error_message('Failed with token="secret123"', 'connection')
# Result: 'connection: Failed with token="[REDACTED]"'

# Truncates long messages (200 char limit)
clean = sanitize_error_message('Very long error...' * 50, 'error')
# Result: 'error: Very long error...' (truncated)

```

**Parameters:**

| Parameter   | Type | Default | Description             |
| ----------- | ---- | ------- | ----------------------- |
| `error_msg` | str  | -       | Original error message  |
| `context`   | str  | `''`    | Optional context prefix |

**Returns:** `str` - Sanitized error message

***

## Complete Example[​](#complete-example "Complete Example에 대한 직접 링크")

```python
from synapse_sdk.utils.network import (
    StreamLimits,
    validate_resource_id,
    validate_timeout,
    http_to_websocket_url,
    sanitize_error_message,
)
from synapse_sdk.exceptions import ClientError

def stream_job_logs(client, job_id: str, timeout: float = 30.0):
    """Stream job logs with proper validation."""
    # Validate inputs
    validated_id = validate_resource_id(job_id, 'job')
    validated_timeout = validate_timeout(timeout)

    # Configure limits for this operation
    client.stream_limits = StreamLimits(max_lines=10_000)

    try:
        for line in client.tail_job_logs(validated_id, validated_timeout):
            yield line
    except ClientError as e:
        clean_msg = sanitize_error_message(str(e), f'job {job_id}')
        raise ClientError(e.status_code, clean_msg)

# Usage
for line in stream_job_logs(client, 'raysubmit_abc123', 60.0):
    print(line)

```

***

## Error Codes[​](#error-codes "Error Codes에 대한 직접 링크")

| Code | Cause                                       |
| ---- | ------------------------------------------- |
| 400  | Invalid resource ID, timeout, or URL format |
| 429  | Stream limits exceeded                      |

***

## See Also[​](#see-also "See Also에 대한 직접 링크")

* [RayClient](/ko/api/clients/ray.md) - Uses these utilities for streaming
* [AgentClient](/ko/api/clients/agent.md) - Client with StreamLimits support
* [Storage](/ko/utils/storage.md) - Storage provider utilities
