This library provides a complete and extensible implementation of the Debug Adapter Protocol (DAP) in Python.
DapClient that handles the message framing (Content-Length headers) and asynchronous request/response matching.Here is a basic example of how to use the DapClient to connect to a debug adapter and send an initialize request:
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())
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.
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:
DapClient::send_request method directly with your custom command string and arguments.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:
Define your custom arguments:
from dataclasses import dataclass @dataclass class StartProfilingArguments: # Duration in milliseconds. duration: int
Send the custom request:
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) )