uSIP


NameuSIP JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryA lightweight Python-based SIP client with voice support
upload_time2025-07-13 23:18:17
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords sip voip audio telecommunications rtp telephony
VCS
bugtrack_url
requirements pjsua2 click python-dotenv colorama rich pyaudio wave pytest
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # uSIP - Lightweight Python SIP Client

[![Python Version](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![Build Status](https://img.shields.io/badge/build-passing-brightgreen.svg)](https://github.com/Dashhhhhhhh/uSIP)
[![Coverage](https://img.shields.io/badge/coverage-71%25-brightgreen.svg)](https://github.com/Dashhhhhhhh/uSIP)

A lightweight Python-based SIP client with full voice support, designed for professional VoIP applications.

## Features

- **🎯 Full SIP Protocol Support**: Registration, calls, messaging, presence
- **🔊 Voice Communication**: Real-time audio streaming with RTP
- **🎧 Audio Device Management**: List, select, and switch audio devices dynamically
- **📱 Event-Driven Architecture**: Comprehensive callback system for all SIP events
- **📊 Call Management**: Multiple concurrent calls, call history, statistics
- **🎛️ Flexible Audio**: Runtime device switching, audio preferences
- **🔄 Automatic Session Management**: Keep-alive, re-registration, session refresh

## Installation

### From PyPI (Recommended)

```bash
pip install uSIP
```

### From Source

```bash
git clone https://github.com/Dashhhhhhhh/uSIP.git
cd uSIP
pip install -e .
```

### Development Installation

```bash
git clone https://github.com/Dashhhhhhhh/uSIP.git
cd uSIP
pip install -e ".[dev]"
```

## Requirements

- Python 3.8+
- PyAudio (for audio functionality)
- python-dotenv (for configuration)
- rich (for enhanced console output)

### System Dependencies

#### Ubuntu/Debian
```bash
sudo apt-get install portaudio19-dev
```

#### macOS
```bash
brew install portaudio
```

#### Windows
PyAudio wheels are available for Windows, no additional setup required.

## Quick Start

### Basic Usage

```python
from sip_client import SIPClient, SIPAccount

# Create SIP account
account = SIPAccount(
    username="your_username",
    password="your_password",
    domain="your_sip_provider.com"
)

# Create and start client
client = SIPClient(account)
client.start()

# Register with server
client.register()

# Make a call
call_id = client.make_call("1234567890")

# Clean up
client.stop()
```

### Using Environment Variables

Create a `.env` file:
```env
SIP_USERNAME=your_username
SIP_PASSWORD=your_password
SIP_DOMAIN=your_sip_provider.com
SIP_PORT=5060
```

```python
from sip_client import SIPClient

# Client will automatically load from environment
client = SIPClient()
client.start()
client.register()
```

### Event Handling

```python
from sip_client import SIPClient, CallState, RegistrationState

client = SIPClient()

# Set up event callbacks
def on_registration_state(state: RegistrationState):
    print(f"Registration: {state.value}")

def on_incoming_call(call_info):
    print(f"Incoming call from {call_info.remote_uri}")
    client.answer_call(call_info.call_id)

def on_call_state(call_info):
    print(f"Call {call_info.call_id}: {call_info.state.value}")

# Register callbacks
client.on_registration_state = on_registration_state
client.on_incoming_call = on_incoming_call
client.on_call_state = on_call_state

client.start()
client.register()
```

## API Reference

### SIPClient

The main client class providing all SIP functionality.

#### Core Methods

- `start()` - Start the SIP client
- `stop()` - Stop the client and clean up resources
- `register()` - Register with SIP server
- `unregister()` - Unregister from SIP server

#### Call Management

- `make_call(target_uri, input_device=None, output_device=None)` - Make outgoing call
- `answer_call(call_id, input_device=None, output_device=None)` - Answer incoming call
- `hangup(call_id)` - End a call
- `get_calls()` - Get list of active calls
- `get_call(call_id)` - Get specific call information

#### Audio Management

- `get_audio_devices()` - List available audio devices
- `switch_audio_device(call_id, input_device=None, output_device=None)` - Switch devices during call

#### Event Callbacks

- `on_registration_state` - Registration state changes
- `on_incoming_call` - Incoming call notifications
- `on_call_state` - Call state changes
- `on_call_media` - Media events
- `on_message` - SIP message events

### Data Models

#### SIPAccount
```python
@dataclass
class SIPAccount:
    username: str
    password: str
    domain: str
    port: int = 5060
    display_name: Optional[str] = None
```

#### CallInfo
```python
@dataclass
class CallInfo:
    call_id: str
    local_uri: str
    remote_uri: str
    state: CallState
    direction: str  # "incoming" or "outgoing"
    start_time: Optional[float] = None
    answer_time: Optional[float] = None
    end_time: Optional[float] = None
    
    @property
    def duration(self) -> float:
        # Returns call duration in seconds
```

#### AudioDevice
```python
@dataclass
class AudioDevice:
    index: int
    name: str
    max_input_channels: int
    max_output_channels: int
    default_sample_rate: float
    
    @property
    def is_input(self) -> bool
    
    @property
    def is_output(self) -> bool
```

### Enums

#### CallState
- `IDLE` - No active call
- `CALLING` - Outgoing call initiated
- `RINGING` - Call is ringing
- `CONNECTED` - Call is active
- `DISCONNECTED` - Call ended normally
- `BUSY` - Remote party is busy
- `FAILED` - Call failed

#### RegistrationState
- `UNREGISTERED` - Not registered
- `REGISTERING` - Registration in progress
- `REGISTERED` - Successfully registered
- `FAILED` - Registration failed

## Examples

### Basic Call Example

```python
from sip_client import SIPClient, SIPAccount, CallState

account = SIPAccount(
    username="user",
    password="pass",
    domain="provider.com"
)

client = SIPClient(account)
client.start()
client.register()

# Make a call
call_id = client.make_call("1234567890")

# Wait for call to connect
import time
time.sleep(5)

# Check call status
call = client.get_call(call_id)
if call and call.state == CallState.CONNECTED:
    print(f"Call connected! Duration: {call.duration:.2f}s")
    
    # End call after 10 seconds
    time.sleep(10)
    client.hangup(call_id)

client.stop()
```

### Audio Device Management

```python
from sip_client import SIPClient

client = SIPClient()
client.start()

# List available audio devices
devices = client.get_audio_devices()
for device in devices:
    print(f"{device.index}: {device.name} ({'INPUT' if device.is_input else ''} {'OUTPUT' if device.is_output else ''})")

# Make call with specific devices
call_id = client.make_call("1234567890", input_device=1, output_device=2)

# Switch devices during call
client.switch_audio_device(call_id, input_device=3, output_device=4)

client.stop()
```

### Multiple Concurrent Calls

```python
from sip_client import SIPClient

client = SIPClient()
client.start()
client.register()

# Make multiple calls
call1 = client.make_call("1234567890")
call2 = client.make_call("0987654321")

# Manage calls independently
calls = client.get_calls()
for call in calls:
    print(f"Call {call.call_id}: {call.remote_uri} ({call.state.value})")

# End specific call
client.hangup(call1)

client.stop()
```

## Architecture

The library follows a modular architecture:

```
sip_client/
├── __init__.py          # Public API
├── client.py            # Main SIP client
├── models/              # Data models
│   ├── account.py       # SIP account
│   ├── call.py          # Call information
│   └── enums.py         # State enumerations
├── audio/               # Audio management
│   ├── manager.py       # Audio streaming
│   └── devices.py       # Device management
├── sip/                 # SIP protocol
│   ├── protocol.py      # Core protocol
│   ├── messages.py      # Message handling
│   └── authentication.py # Authentication
└── utils/               # Utilities
    └── helpers.py       # Helper functions
```

## Testing

Run the test suite:

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=sip_client

# Run specific test categories
pytest -m unit          # Unit tests only
pytest -m integration   # Integration tests only
pytest -m "not audio"   # Skip audio tests
```

## Development

### Setting up Development Environment

```bash
git clone https://github.com/Dashhhhhhhh/uSIP.git
cd uSIP
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install -e ".[dev]"
```

### Code Quality

```bash
# Format code
black src tests examples

# Sort imports
isort src tests examples

# Type checking
mypy src

# Linting
flake8 src tests examples

# Run all quality checks
pre-commit run --all-files
```

### Running Examples

```bash
# Basic usage
python examples/basic_usage.py

# Advanced features
python examples/advanced_usage.py
```


## Performance

- **Memory Usage**: ~10MB baseline, ~5MB per active call
- **CPU Usage**: <5% during calls on modern hardware
- **Latency**: <50ms audio latency with proper audio device configuration
- **Concurrent Calls**: Supports 50+ concurrent calls (limited by system resources)

## Troubleshooting

### Common Issues

1. **PyAudio Installation Problems**
   ```bash
   # Ubuntu/Debian
   sudo apt-get install portaudio19-dev
   pip install pyaudio
   
   # macOS
   brew install portaudio
   pip install pyaudio
   ```

2. **Audio Device Issues**
   ```python
   # List available devices
   devices = client.get_audio_devices()
   for device in devices:
       print(f"{device.index}: {device.name}")
   ```

3. **Registration Issues**
   - Check SIP credentials
   - Verify network connectivity
   - Ensure SIP server is accessible
   - Check firewall settings (UDP port 5060)

4. **Call Issues**
   - Verify registration status
   - Check audio device availability
   - Ensure RTP ports are not blocked (UDP 10000+)

### Debug Logging

```python
import logging
logging.basicConfig(level=logging.DEBUG)

# Enable SIP message logging
client = SIPClient()
client.on_message = lambda msg, addr: print(f"SIP: {msg}")
```

## Contributing

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.


## Acknowledgments

- Built on top of the Session Initiation Protocol (RFC 3261)
- Audio functionality powered by PyAudio
- Inspired by PJSIP and other professional SIP libraries
- Thanks to all contributors and testers

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "uSIP",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "uSIP Development Team <support@usip.dev>",
    "keywords": "sip, voip, audio, telecommunications, rtp, telephony",
    "author": null,
    "author_email": "uSIP Development Team <support@usip.dev>",
    "download_url": "https://files.pythonhosted.org/packages/09/d0/9497959b692869f2a82c42855a462727ce1dacf39f73dc05d48cbcc426be/usip-1.0.0.tar.gz",
    "platform": null,
    "description": "# uSIP - Lightweight Python SIP Client\r\n\r\n[![Python Version](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)\r\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\r\n[![Build Status](https://img.shields.io/badge/build-passing-brightgreen.svg)](https://github.com/Dashhhhhhhh/uSIP)\r\n[![Coverage](https://img.shields.io/badge/coverage-71%25-brightgreen.svg)](https://github.com/Dashhhhhhhh/uSIP)\r\n\r\nA lightweight Python-based SIP client with full voice support, designed for professional VoIP applications.\r\n\r\n## Features\r\n\r\n- **\ud83c\udfaf Full SIP Protocol Support**: Registration, calls, messaging, presence\r\n- **\ud83d\udd0a Voice Communication**: Real-time audio streaming with RTP\r\n- **\ud83c\udfa7 Audio Device Management**: List, select, and switch audio devices dynamically\r\n- **\ud83d\udcf1 Event-Driven Architecture**: Comprehensive callback system for all SIP events\r\n- **\ud83d\udcca Call Management**: Multiple concurrent calls, call history, statistics\r\n- **\ud83c\udf9b\ufe0f Flexible Audio**: Runtime device switching, audio preferences\r\n- **\ud83d\udd04 Automatic Session Management**: Keep-alive, re-registration, session refresh\r\n\r\n## Installation\r\n\r\n### From PyPI (Recommended)\r\n\r\n```bash\r\npip install uSIP\r\n```\r\n\r\n### From Source\r\n\r\n```bash\r\ngit clone https://github.com/Dashhhhhhhh/uSIP.git\r\ncd uSIP\r\npip install -e .\r\n```\r\n\r\n### Development Installation\r\n\r\n```bash\r\ngit clone https://github.com/Dashhhhhhhh/uSIP.git\r\ncd uSIP\r\npip install -e \".[dev]\"\r\n```\r\n\r\n## Requirements\r\n\r\n- Python 3.8+\r\n- PyAudio (for audio functionality)\r\n- python-dotenv (for configuration)\r\n- rich (for enhanced console output)\r\n\r\n### System Dependencies\r\n\r\n#### Ubuntu/Debian\r\n```bash\r\nsudo apt-get install portaudio19-dev\r\n```\r\n\r\n#### macOS\r\n```bash\r\nbrew install portaudio\r\n```\r\n\r\n#### Windows\r\nPyAudio wheels are available for Windows, no additional setup required.\r\n\r\n## Quick Start\r\n\r\n### Basic Usage\r\n\r\n```python\r\nfrom sip_client import SIPClient, SIPAccount\r\n\r\n# Create SIP account\r\naccount = SIPAccount(\r\n    username=\"your_username\",\r\n    password=\"your_password\",\r\n    domain=\"your_sip_provider.com\"\r\n)\r\n\r\n# Create and start client\r\nclient = SIPClient(account)\r\nclient.start()\r\n\r\n# Register with server\r\nclient.register()\r\n\r\n# Make a call\r\ncall_id = client.make_call(\"1234567890\")\r\n\r\n# Clean up\r\nclient.stop()\r\n```\r\n\r\n### Using Environment Variables\r\n\r\nCreate a `.env` file:\r\n```env\r\nSIP_USERNAME=your_username\r\nSIP_PASSWORD=your_password\r\nSIP_DOMAIN=your_sip_provider.com\r\nSIP_PORT=5060\r\n```\r\n\r\n```python\r\nfrom sip_client import SIPClient\r\n\r\n# Client will automatically load from environment\r\nclient = SIPClient()\r\nclient.start()\r\nclient.register()\r\n```\r\n\r\n### Event Handling\r\n\r\n```python\r\nfrom sip_client import SIPClient, CallState, RegistrationState\r\n\r\nclient = SIPClient()\r\n\r\n# Set up event callbacks\r\ndef on_registration_state(state: RegistrationState):\r\n    print(f\"Registration: {state.value}\")\r\n\r\ndef on_incoming_call(call_info):\r\n    print(f\"Incoming call from {call_info.remote_uri}\")\r\n    client.answer_call(call_info.call_id)\r\n\r\ndef on_call_state(call_info):\r\n    print(f\"Call {call_info.call_id}: {call_info.state.value}\")\r\n\r\n# Register callbacks\r\nclient.on_registration_state = on_registration_state\r\nclient.on_incoming_call = on_incoming_call\r\nclient.on_call_state = on_call_state\r\n\r\nclient.start()\r\nclient.register()\r\n```\r\n\r\n## API Reference\r\n\r\n### SIPClient\r\n\r\nThe main client class providing all SIP functionality.\r\n\r\n#### Core Methods\r\n\r\n- `start()` - Start the SIP client\r\n- `stop()` - Stop the client and clean up resources\r\n- `register()` - Register with SIP server\r\n- `unregister()` - Unregister from SIP server\r\n\r\n#### Call Management\r\n\r\n- `make_call(target_uri, input_device=None, output_device=None)` - Make outgoing call\r\n- `answer_call(call_id, input_device=None, output_device=None)` - Answer incoming call\r\n- `hangup(call_id)` - End a call\r\n- `get_calls()` - Get list of active calls\r\n- `get_call(call_id)` - Get specific call information\r\n\r\n#### Audio Management\r\n\r\n- `get_audio_devices()` - List available audio devices\r\n- `switch_audio_device(call_id, input_device=None, output_device=None)` - Switch devices during call\r\n\r\n#### Event Callbacks\r\n\r\n- `on_registration_state` - Registration state changes\r\n- `on_incoming_call` - Incoming call notifications\r\n- `on_call_state` - Call state changes\r\n- `on_call_media` - Media events\r\n- `on_message` - SIP message events\r\n\r\n### Data Models\r\n\r\n#### SIPAccount\r\n```python\r\n@dataclass\r\nclass SIPAccount:\r\n    username: str\r\n    password: str\r\n    domain: str\r\n    port: int = 5060\r\n    display_name: Optional[str] = None\r\n```\r\n\r\n#### CallInfo\r\n```python\r\n@dataclass\r\nclass CallInfo:\r\n    call_id: str\r\n    local_uri: str\r\n    remote_uri: str\r\n    state: CallState\r\n    direction: str  # \"incoming\" or \"outgoing\"\r\n    start_time: Optional[float] = None\r\n    answer_time: Optional[float] = None\r\n    end_time: Optional[float] = None\r\n    \r\n    @property\r\n    def duration(self) -> float:\r\n        # Returns call duration in seconds\r\n```\r\n\r\n#### AudioDevice\r\n```python\r\n@dataclass\r\nclass AudioDevice:\r\n    index: int\r\n    name: str\r\n    max_input_channels: int\r\n    max_output_channels: int\r\n    default_sample_rate: float\r\n    \r\n    @property\r\n    def is_input(self) -> bool\r\n    \r\n    @property\r\n    def is_output(self) -> bool\r\n```\r\n\r\n### Enums\r\n\r\n#### CallState\r\n- `IDLE` - No active call\r\n- `CALLING` - Outgoing call initiated\r\n- `RINGING` - Call is ringing\r\n- `CONNECTED` - Call is active\r\n- `DISCONNECTED` - Call ended normally\r\n- `BUSY` - Remote party is busy\r\n- `FAILED` - Call failed\r\n\r\n#### RegistrationState\r\n- `UNREGISTERED` - Not registered\r\n- `REGISTERING` - Registration in progress\r\n- `REGISTERED` - Successfully registered\r\n- `FAILED` - Registration failed\r\n\r\n## Examples\r\n\r\n### Basic Call Example\r\n\r\n```python\r\nfrom sip_client import SIPClient, SIPAccount, CallState\r\n\r\naccount = SIPAccount(\r\n    username=\"user\",\r\n    password=\"pass\",\r\n    domain=\"provider.com\"\r\n)\r\n\r\nclient = SIPClient(account)\r\nclient.start()\r\nclient.register()\r\n\r\n# Make a call\r\ncall_id = client.make_call(\"1234567890\")\r\n\r\n# Wait for call to connect\r\nimport time\r\ntime.sleep(5)\r\n\r\n# Check call status\r\ncall = client.get_call(call_id)\r\nif call and call.state == CallState.CONNECTED:\r\n    print(f\"Call connected! Duration: {call.duration:.2f}s\")\r\n    \r\n    # End call after 10 seconds\r\n    time.sleep(10)\r\n    client.hangup(call_id)\r\n\r\nclient.stop()\r\n```\r\n\r\n### Audio Device Management\r\n\r\n```python\r\nfrom sip_client import SIPClient\r\n\r\nclient = SIPClient()\r\nclient.start()\r\n\r\n# List available audio devices\r\ndevices = client.get_audio_devices()\r\nfor device in devices:\r\n    print(f\"{device.index}: {device.name} ({'INPUT' if device.is_input else ''} {'OUTPUT' if device.is_output else ''})\")\r\n\r\n# Make call with specific devices\r\ncall_id = client.make_call(\"1234567890\", input_device=1, output_device=2)\r\n\r\n# Switch devices during call\r\nclient.switch_audio_device(call_id, input_device=3, output_device=4)\r\n\r\nclient.stop()\r\n```\r\n\r\n### Multiple Concurrent Calls\r\n\r\n```python\r\nfrom sip_client import SIPClient\r\n\r\nclient = SIPClient()\r\nclient.start()\r\nclient.register()\r\n\r\n# Make multiple calls\r\ncall1 = client.make_call(\"1234567890\")\r\ncall2 = client.make_call(\"0987654321\")\r\n\r\n# Manage calls independently\r\ncalls = client.get_calls()\r\nfor call in calls:\r\n    print(f\"Call {call.call_id}: {call.remote_uri} ({call.state.value})\")\r\n\r\n# End specific call\r\nclient.hangup(call1)\r\n\r\nclient.stop()\r\n```\r\n\r\n## Architecture\r\n\r\nThe library follows a modular architecture:\r\n\r\n```\r\nsip_client/\r\n\u251c\u2500\u2500 __init__.py          # Public API\r\n\u251c\u2500\u2500 client.py            # Main SIP client\r\n\u251c\u2500\u2500 models/              # Data models\r\n\u2502   \u251c\u2500\u2500 account.py       # SIP account\r\n\u2502   \u251c\u2500\u2500 call.py          # Call information\r\n\u2502   \u2514\u2500\u2500 enums.py         # State enumerations\r\n\u251c\u2500\u2500 audio/               # Audio management\r\n\u2502   \u251c\u2500\u2500 manager.py       # Audio streaming\r\n\u2502   \u2514\u2500\u2500 devices.py       # Device management\r\n\u251c\u2500\u2500 sip/                 # SIP protocol\r\n\u2502   \u251c\u2500\u2500 protocol.py      # Core protocol\r\n\u2502   \u251c\u2500\u2500 messages.py      # Message handling\r\n\u2502   \u2514\u2500\u2500 authentication.py # Authentication\r\n\u2514\u2500\u2500 utils/               # Utilities\r\n    \u2514\u2500\u2500 helpers.py       # Helper functions\r\n```\r\n\r\n## Testing\r\n\r\nRun the test suite:\r\n\r\n```bash\r\n# Run all tests\r\npytest\r\n\r\n# Run with coverage\r\npytest --cov=sip_client\r\n\r\n# Run specific test categories\r\npytest -m unit          # Unit tests only\r\npytest -m integration   # Integration tests only\r\npytest -m \"not audio\"   # Skip audio tests\r\n```\r\n\r\n## Development\r\n\r\n### Setting up Development Environment\r\n\r\n```bash\r\ngit clone https://github.com/Dashhhhhhhh/uSIP.git\r\ncd uSIP\r\npython -m venv venv\r\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\r\npip install -e \".[dev]\"\r\n```\r\n\r\n### Code Quality\r\n\r\n```bash\r\n# Format code\r\nblack src tests examples\r\n\r\n# Sort imports\r\nisort src tests examples\r\n\r\n# Type checking\r\nmypy src\r\n\r\n# Linting\r\nflake8 src tests examples\r\n\r\n# Run all quality checks\r\npre-commit run --all-files\r\n```\r\n\r\n### Running Examples\r\n\r\n```bash\r\n# Basic usage\r\npython examples/basic_usage.py\r\n\r\n# Advanced features\r\npython examples/advanced_usage.py\r\n```\r\n\r\n\r\n## Performance\r\n\r\n- **Memory Usage**: ~10MB baseline, ~5MB per active call\r\n- **CPU Usage**: <5% during calls on modern hardware\r\n- **Latency**: <50ms audio latency with proper audio device configuration\r\n- **Concurrent Calls**: Supports 50+ concurrent calls (limited by system resources)\r\n\r\n## Troubleshooting\r\n\r\n### Common Issues\r\n\r\n1. **PyAudio Installation Problems**\r\n   ```bash\r\n   # Ubuntu/Debian\r\n   sudo apt-get install portaudio19-dev\r\n   pip install pyaudio\r\n   \r\n   # macOS\r\n   brew install portaudio\r\n   pip install pyaudio\r\n   ```\r\n\r\n2. **Audio Device Issues**\r\n   ```python\r\n   # List available devices\r\n   devices = client.get_audio_devices()\r\n   for device in devices:\r\n       print(f\"{device.index}: {device.name}\")\r\n   ```\r\n\r\n3. **Registration Issues**\r\n   - Check SIP credentials\r\n   - Verify network connectivity\r\n   - Ensure SIP server is accessible\r\n   - Check firewall settings (UDP port 5060)\r\n\r\n4. **Call Issues**\r\n   - Verify registration status\r\n   - Check audio device availability\r\n   - Ensure RTP ports are not blocked (UDP 10000+)\r\n\r\n### Debug Logging\r\n\r\n```python\r\nimport logging\r\nlogging.basicConfig(level=logging.DEBUG)\r\n\r\n# Enable SIP message logging\r\nclient = SIPClient()\r\nclient.on_message = lambda msg, addr: print(f\"SIP: {msg}\")\r\n```\r\n\r\n## Contributing\r\n\r\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\r\n\r\n1. Fork the repository\r\n2. Create a feature branch\r\n3. Make your changes\r\n4. Add tests\r\n5. Submit a pull request\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\r\n\r\n\r\n## Acknowledgments\r\n\r\n- Built on top of the Session Initiation Protocol (RFC 3261)\r\n- Audio functionality powered by PyAudio\r\n- Inspired by PJSIP and other professional SIP libraries\r\n- Thanks to all contributors and testers\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A lightweight Python-based SIP client with voice support",
    "version": "1.0.0",
    "project_urls": {
        "Changelog": "https://github.com/Dashhhhhhhh/uSIP/blob/main/CHANGELOG.md",
        "Documentation": "https://sip-client-library.readthedocs.io/",
        "Homepage": "https://github.com/Dashhhhhhhh/uSIP",
        "Issues": "https://github.com/Dashhhhhhhh/uSIP/issues",
        "Repository": "https://github.com/Dashhhhhhhh/uSIP.git"
    },
    "split_keywords": [
        "sip",
        " voip",
        " audio",
        " telecommunications",
        " rtp",
        " telephony"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8fe7ec7584990e18726cb5723fe27c1082fcc9a876154cf5010324a42d9f53b3",
                "md5": "25d08dc4e5fd8aa29c548d323131deba",
                "sha256": "c9281b77f4d1aa1f412e1aea5654e08f9c1993559c2e560fb3eaa16f04335e57"
            },
            "downloads": -1,
            "filename": "usip-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "25d08dc4e5fd8aa29c548d323131deba",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 36164,
            "upload_time": "2025-07-13T23:18:15",
            "upload_time_iso_8601": "2025-07-13T23:18:15.878125Z",
            "url": "https://files.pythonhosted.org/packages/8f/e7/ec7584990e18726cb5723fe27c1082fcc9a876154cf5010324a42d9f53b3/usip-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "09d09497959b692869f2a82c42855a462727ce1dacf39f73dc05d48cbcc426be",
                "md5": "7d6bf7a1cfc90fcc50d8d727abb0b031",
                "sha256": "9ca498c0f99a667c4593bf24b4a7e8f2696824222c1b8b9395fc073f056f534f"
            },
            "downloads": -1,
            "filename": "usip-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "7d6bf7a1cfc90fcc50d8d727abb0b031",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 34230,
            "upload_time": "2025-07-13T23:18:17",
            "upload_time_iso_8601": "2025-07-13T23:18:17.227213Z",
            "url": "https://files.pythonhosted.org/packages/09/d0/9497959b692869f2a82c42855a462727ce1dacf39f73dc05d48cbcc426be/usip-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-13 23:18:17",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Dashhhhhhhh",
    "github_project": "uSIP",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "pjsua2",
            "specs": [
                [
                    "==",
                    "2.12"
                ]
            ]
        },
        {
            "name": "click",
            "specs": [
                [
                    "==",
                    "8.1.7"
                ]
            ]
        },
        {
            "name": "python-dotenv",
            "specs": [
                [
                    "==",
                    "1.0.0"
                ]
            ]
        },
        {
            "name": "colorama",
            "specs": [
                [
                    "==",
                    "0.4.6"
                ]
            ]
        },
        {
            "name": "rich",
            "specs": [
                [
                    "==",
                    "13.7.0"
                ]
            ]
        },
        {
            "name": "pyaudio",
            "specs": [
                [
                    "==",
                    "0.2.14"
                ]
            ]
        },
        {
            "name": "wave",
            "specs": []
        },
        {
            "name": "pytest",
            "specs": [
                [
                    "==",
                    "7.4.3"
                ]
            ]
        }
    ],
    "lcname": "usip"
}
        
Elapsed time: 0.41734s