Index
๐ค AI-Generated Content
This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.
pyvider.rpcplugin.client
¶
Pyvider RPC Plugin Client Package.
This package provides the core components for creating RPC plugin clients,
including the main RPCPluginClient class, connection handling, and associated types.
Classes¶
ClientConnection
¶
Represents an active client connection with associated metrics and state.
This class wraps the asyncio StreamReader and StreamWriter with additional functionality for tracking metrics and managing connection state. It now supports dependency injection for its I/O functions, allowing tests or alternative implementations to override the default behavior.
Attributes:
| Name | Type | Description |
|---|---|---|
reader |
StreamReader
|
Stream for reading client data. |
writer |
StreamWriter
|
Stream for writing responses. |
remote_addr |
str
|
Remote address of the client. |
bytes_sent |
int
|
Total bytes sent over this connection. |
bytes_received |
int
|
Total bytes received over this connection. |
send_func |
SendFuncType | None
|
Callable used to send data; defaults to _default_send. |
receive_func |
ReceiveFuncType | None
|
Callable used to receive data; defaults to _default_receive. |
Attributes¶
Functions¶
__attrs_post_init__
¶
Post-initialization hook to set default I/O functions if not provided.
Source code in pyvider/rpcplugin/client/connection.py
__del__
¶
Ensure resources are cleaned up.
Raising exceptions in del is generally discouraged; a warning
is logged instead.
Source code in pyvider/rpcplugin/client/connection.py
close
async
¶
Close the connection and clean up resources.
This method is idempotent and can be safely called multiple times.
Source code in pyvider/rpcplugin/client/connection.py
receive_data
async
¶
Receive data from the connection using the injected receive_func.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
int | None
|
Maximum number of bytes to receive. |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
Received data as bytes. |
Raises:
| Type | Description |
|---|---|
ConnectionError
|
If the connection is closed. |
Source code in pyvider/rpcplugin/client/connection.py
send_data
async
¶
Send data over the connection using the injected send_func.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
bytes
|
Bytes to send. |
required |
Raises:
| Type | Description |
|---|---|
ConnectionError
|
If the connection is closed. |
Source code in pyvider/rpcplugin/client/connection.py
update_metrics
¶
Update connection metrics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bytes_sent
|
int
|
Number of bytes sent. |
0
|
bytes_received
|
int
|
Number of bytes received. |
0
|
Source code in pyvider/rpcplugin/client/connection.py
RPCPluginClient
¶
Bases: ClientHandshakeMixin, ClientProcessMixin
Client interface for interacting with Terraform-compatible plugin servers.
The RPCPluginClient handles the complete lifecycle of plugin communication: 1. Launching or attaching to a plugin server subprocess 2. Performing handshake, protocol negotiation, and transport selection 3. Setting up secure TLS/mTLS communication when enabled 4. Creating gRPC channels and service stubs 5. Providing plugin logs (stdout/stderr) streaming 6. Managing broker subchannels for multi-service communication 7. Handling graceful shutdown of plugin processes
The client follows the Terraform go-plugin protocol, which includes a standardized handshake format, negotiated protocol version, and support for Unix socket or TCP transport modes.
Attributes:
| Name | Type | Description |
|---|---|---|
command |
list[str]
|
List containing the plugin executable command and arguments |
config |
dict[str, Any] | None
|
Optional configuration dictionary for customizing client behavior |
Example
# Create a client for a plugin
client = RPCPluginClient(
command=["terraform-provider-example"],
config={"env": {"TF_LOG": "DEBUG"}}
)
# Start the client (launches process, performs handshake, etc.)
await client.start()
# Use the created channel with protocol-specific stubs
provider_stub = MyProviderStub(client.grpc_channel)
response = await provider_stub.SomeMethod(request)
# Graceful shutdown
await client.shutdown_plugin()
await client.close()
Note
The client supports automatic mTLS if enabled in configuration, and can read/generate certificates as needed for secure communication.
Functions¶
__aenter__
async
¶
__aexit__
async
¶
__aexit__(
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> None
Async context manager exit with cleanup.
Source code in pyvider/rpcplugin/client/core.py
__attrs_post_init__
¶
close
async
¶
Close the client connection and clean up all resources.
This method performs a complete cleanup of the client state, including stopping tasks, closing channels, terminating processes, and cleaning up transport resources.
Source code in pyvider/rpcplugin/client/core.py
shutdown_plugin
async
¶
Gracefully shutdown the plugin server through gRPC controller.
This method sends a shutdown signal to the plugin server, allowing it to clean up resources before termination.
Source code in pyvider/rpcplugin/client/core.py
start
async
¶
Start the plugin client: launch process, perform handshake, create channel.
This is the main entry point for establishing communication with a plugin. It orchestrates the complete connection process.
Raises:
| Type | Description |
|---|---|
HandshakeError
|
If handshake fails |
TransportError
|
If transport setup fails |
ProtocolError
|
If protocol negotiation fails |