NCP connection

NCP connections are used by the NCP client and NCP server to represent each side of a connection.

Overview

Spawning tasks

Spawn a concurrent task to handle long-running commands:

import asyncio

loop = asyncio.get_event_loop()

async def handle_dspc_time(field):
    field.send(ACKN=1)
    await asyncio.sleep(10)  # Simulate a blocking task.
    field.send(TSDC=0, TIMM=1)

for field in connection:
    if field.packet_type == "DSPC" and field.name == "TIME":
        # Spawn a concurrent task to avoid blocking the accept loop.
        loop.create_task(handle_dspc_time(field))
    # Handle other field types here.

API reference

Important

Do not instantiate these classes directly. Use connect() to create a NCP client connection. Use start_server() to create a NCP server.

class ncplib.Connection(reader: asyncio.streams.StreamReader, writer: asyncio.streams.StreamWriter, predicate: Callable[[ncplib.connection.Field], bool], *, logger: logging.Logger, remote_hostname: str, timeout: int)

A connection between a NCP client and a NCP server.

Connections can be used as async iterators to loop over each incoming Field:

async for field in connection:
    pass

Important

The async for loop will only terminate when the underlying connection closes.

Connections can also be used as async context managers to automatically close the connection:

async with connection:
    pass

# Connection is automatically closed.
logger

The logging.Logger used by this connection. Log messages will be prefixed with the host and port of the connection.

remote_hostname

The identifying hostname for the remote end of the connection.

close() → None

Closes the connection.

Hint

If you use the connection as an async context manager, there’s no need to call Connection.close() manually.

is_closing() → bool

Returns True if the connection is closing.

A closing connection should not be written to.

recv() → ncplib.connection.Field

Waits for the next Field received by the connection.

Raises:ncplib.NCPError – if a field could not be retrieved from the connection.
Returns:The next Field received.
Return type:Field
recv_field(packet_type: str, field_name: str) → ncplib.connection.Field

Waits for the next matching Field received by the connection.

Parameters:
  • packet_type (str) – The packet type, must be a valid identifier.
  • field_name (str) – The field name, must be a valid identifier.
Raises:

ncplib.NCPError – if a field could not be retrieved from the connection.

Returns:

The next Field received.

Return type:

Field

send(packet_type: str, field_name: str, **params) → ncplib.connection.Response

Sends a NCP packet containing a single NCP field.

Parameters:
  • packet_type (str) – The packet type, must be a valid identifier.
  • field_name (str) – The field name, must be a valid identifier.
  • **params – Keyword arguments, one per NCP parameter. Each parameter name should be a valid identifier, and each parameter value should be one of the supported value types.
Returns:

A Response providing access to any Field instances received in reply to the sent packet.

Return type:

Response

Raises:
  • ValueError – if any of the packet, field or parameter names were not a valid identifier, or any of the parameter values were invalid.
  • TypeError – if any of the parameter values were not one of the supported value types.
send_packet(packet_type: str, **fields) → ncplib.connection.Response

Sends a NCP packet containing multiple NCP fields.

Hint

Prefer send() unless you need to send multiple fields in a single packet.

Parameters:
  • packet_type (str) – The packet type, must be a valid identifier.
  • **fields – Keyword arguments, one per field. Each field name should be a valid identifier, and the field value should be a dict of parameter names mapped to parameter values. Each parameter name should be a valid identifier, and each parameter value should be one of the supported value types.
Returns:

A Response providing access to any Field instances received in reply to the sent packet.

Return type:

Response

Raises:
  • ValueError – if any of the packet, field or parameter names were not a valid identifier, or any of the parameter values were invalid.
  • TypeError – if any of the parameter values were not one of the supported value types.
transport

The asyncio.WriteTransport used by this connection.

wait_closed() → None

Waits for the connection to finish closing.

Hint

If you use the connection as an async context manager, there’s no need to call Connection.wait_closed() manually.

class ncplib.Response(connection: ncplib.connection.Connection, packet_type: str, expected_fields: Set[Tuple[str, int]])

A response to a NCP packet, returned by Connection.send(), Connection.send_packet() and Field.send().

Provides access to any Field received in reply to the sent packet.

Responses can be used as async iterators to loop over each incoming Field:

async for field in response:
    pass

Important

The async for loop will only terminate when the underlying connection closes.

recv() → ncplib.connection.Field

Waits for the next Field received in reply to the sent NCP packet.

Raises:ncplib.NCPError – if a field could not be retrieved from the connection.
Returns:The next Field received.
Return type:Field
recv_field(field_name: str) → ncplib.connection.Field

Waits for the next matching Field received in reply to the sent NCP packet.

Hint

Prefer recv() unless the sent packet contained multiple fields.

Parameters:field_name (str) – The field name, must be a valid identifier.
Raises:ncplib.NCPError – if a field could not be retrieved from the connection.
Returns:The next Field received.
Return type:Field
class ncplib.Field(connection: ncplib.connection.Connection, packet_type: str, packet_id: int, packet_timestamp: datetime.datetime, name: str, id: int, params: Iterable[Tuple[str, Union[bytes, bytearray, str, int, float, ncplib.values.u32, ncplib.values.i64, ncplib.values.u64, ncplib.values.f64, bool, array.array]]])

A NCP field received by a Connection.

Access NCP parameter values using item access:

print(field["PDAT"])
connection

The Connection that created this field.

packet_type

The type of NCP packet that contained this field. This will be a valid identifier.

packet_id

The ID of the of NCP packet that contained this field.

packet_timestamp

A timezone-aware datetime.datetime describing when the containing packet was sent.

name

The name of the NCP field. This will be a valid identifier.

id

The unique int ID of this field.

send(**params) → ncplib.connection.Response

Sends a NCP packet containing a single field in reply to this field.

Parameters:

**params – Keyword arguments, one per NCP parameter. Each parameter name should be a valid identifier, and each parameter value should be one of the supported value types.

Returns:

A Response providing access to any Field instances received in reply to the sent packet.

Return type:

Response

Raises:
  • ValueError – if any of the packet, field or parameter names were not a valid identifier, or any of the parameter values were invalid.
  • TypeError – if any of the parameter values were not one of the supported value types.