blob: 97a35aa14fce01513156c8a4e01e50546649d4cb [file] [view] [edit]
# Debug Adapter Protocol (DAP) Library
This library provides a complete and extensible implementation of the [Debug
Adapter Protocol
(DAP)](https://microsoft.github.io/debug-adapter-protocol/specification) in
Python.
## Features
- **Protocol Models**: Full set of Python types representing DAP requests,
responses, and events.
- **Client Implementation**: A `DapClient` that handles the message framing
(Content-Length headers) and asynchronous request/response matching.
- **Extensible Architecture**: Easy to add vendor-specific extensions without
modifying the core library.
## Client Usage Example
Here is a basic example of how to use the `DapClient` to connect to a debug
adapter and send an initialize request:
```python
import asyncio
from pydap.client import DapClient
from pydap.models import InitializeArguments
async def run():
client = DapClient()
# Connect to the debug adapter (e.g., via TCP)
reader, writer = await asyncio.open_connection("127.0.0.1", 12345)
# Send initialize request
args = InitializeArguments(adapterID="test")
# We create a task to send the request
# In a full implementation, you would also have a task reading from 'reader'
response = await client.initialize(writer, args)
print(f"Response: {response}")
asyncio.run(run())
```
## Naming Convention
To ensure exact compliance with the DAP specification and simplify serialization, this library uses the **specification casing** for all dataclass field names. This means that fields use `camelCase` or specific acronym casing (e.g., `adapterID`) as defined in the official protocol, rather than standard Python `snake_case`.
When instantiating dataclasses, always use the field names with the casing specified by the protocol. For example, use `adapterID` instead of `adapter_id`.
## Extensibility
One of the key design goals of this library is extensibility. The base protocol
is often extended by specific debuggers to support unique features.
To extend the library:
1. Define your custom argument types as dataclasses.
2. Use the `DapClient::send_request` method directly with your custom command
string and arguments.
### Example: Custom Profiling Extension
Suppose you are building a debug adapter that supports a custom profiling
feature not covered by the standard protocol. You can extend `DapClient` to
support this server feature by subclassing or adding helper methods:
1. **Define your custom arguments**:
```python
from dataclasses import dataclass
@dataclass
class StartProfilingArguments:
# Duration in milliseconds.
duration: int
```
2. **Send the custom request**:
```python
import asyncio
from pydap.models import dataclass_to_dict
class CustomDapClient(DapClient):
async def start_profiling(
self, writer: asyncio.StreamWriter, duration: int
):
args = StartProfilingArguments(duration=duration)
return await self.send_request(
writer, "startProfiling", dataclass_to_dict(args)
)
```