ndn.appv2 package


The ndn.appv2 package contains NDNApp class. It offers the functionalities similar to an application face in other NDN libraries. Main features include:

  • Establish a connection to NDN forwarder.

  • Consumer: express Interests and receive the reply Data.

  • Producer: attach Interest handler function to a name prefix, to handle incoming Interests.

  • Producer: register and unregister prefixes in the forwarder.

This package is a rewrite from ndn.app package. Major differences from that package are:

  • Initial support for PIT token.

  • Send signed Interests for NFD management commands.



Interest handler function associated with a name prefix.

The function should use the provided reply callback to reply with Data, which can handle PIT token properly.

(name: FormalName, app_param: Optional[BinaryStr], reply: ReplyFunc, context: PktContext) -> None
  • name (FormalName) – Interest name.

  • app_param (Optional[BinaryStr]) – Interest ApplicationParameters value, or None if absent.

  • reply (ReplyFunc) – continuation function to respond with Data.

  • context (PktContext) – packet handler context.


Interest handler function must be a normal function instead of an async one. This is on purpose, because an Interest is supposed to be replied ASAP, even it cannot finish the request in time. To provide some feedback, a better practice is replying with an Application NACK (or some equivalent Data packet saying the operation cannot be finished in time). If you want to use await in the handler, please use asyncio.create_task to create a new coroutine.

alias of Callable[[List[Union[bytes, bytearray, memoryview]], Optional[Union[bytes, bytearray, memoryview]], Callable[[Union[bytes, bytearray, memoryview]], bool], dict[str, any]], None]

class ndn.appv2.NDNApp(face=None, client_conf=None, registerer=None)

An NDN application.

attach_handler(name, handler, validator=None)

Attach an Interest handler at a name prefix. Incoming Interests under the specified name prefix will be dispatched to the handler.

This only sets the handler within NDNApp, but does not send prefix registration commands to the forwarder. To register the prefix in the forwarder, use register. The handler association is retained even if the forwarder is disconnected.

  • name (NonStrictName) – name prefix.

  • handler (IntHandler) – Interest handler function.

  • validator (Optional[Validator]) – validator for signed Interests. Non signed Interests, i.e. those without ApplicationParameters and SignatureInfo, are passed to the handler directly without calling the validator. Interests with malformed ParametersSha256DigestComponent are dropped silently. If a validator is not provided (set to None), signed Interests will be dropped. Otherwise, signed Interests are passed to the validator. Those failing the validation are dropped silently. Those passing the validation are passed to the handler function.


Detach an Interest handler at a name prefix.

This only deletes the handler within NDNApp, but does not unregister the prefix in the forwarder. To unregister the prefix in the forwarder, use unregister.


name (NonStrictName) – name prefix. This must exactly match the name passed to attach_handler. If there are Interest handlers attached to longer prefixes, each handler must be removed explicitly.

express(name, validator, app_param=None, signer=None, **kwargs)

Express an Interest.

The Interest packet is sent immediately and a coroutine used to get the result is returned. Awaiting on the returned coroutine will block until the Data is received. It then returns the Data name, Data Content value, and PktContext. An exception is raised if NDNApp is unable to retrieve the Data.

  • name (NonStrictName) – Interest name.

  • validator (Validator) – validator for the retrieved Data packet.

  • app_param (Optional[BinaryStr]) – Interest ApplicationParameters value. If this is not None, a signed Interest is sent. NDNApp does not support sending parameterized Interests that are not signed.

  • signer (Optional[Signer]) – Signer for Interest signing. This is required if app_param is specified.

  • kwargs – arguments for InterestParam.


A tuple of (Name, Content, PacketContext) after await.

Return type:

Coroutine[Any, None, Tuple[FormalName, Optional[BinaryStr], PktContext]]

The following exceptions may be raised by express:

  • NetworkError – the face to NFD is down before sending this Interest.

  • ValueError – when the signer is missing but app_param presents.

The following exceptions may be raised by the returned coroutine:

async main_loop(after_start=None)

The main loop of NDNApp.


after_start (Awaitable) – the coroutine to start after connection to NFD is established.

Return type:



True if the connection is shutdown not by Ctrl+C. For example, manually or by the other side.

static make_data(name, content, signer, **kwargs)

Encode a data packet without requiring an NDNApp instance. This is simply a wrapper of encoding.make_data. I write this because most people seem not aware of the make_data function in the encoding package. The corresponding make_interest is less useful (one should not reuse nonce) and thus not wrapped. Sync protocol should use encoding.make_interest if necessary. Also, since having a default signer encourages bad habit, prepare_data is removed except for command Interests sent to NFD. Please call keychain.get_signer({}) to use the default certificate.

  • name (NonStrictName) – the Name.

  • content (Optional[BinaryStr]) – the Content.

  • signer (Optional[Signer]) – the Signer used to sign the packet.

  • kwargs – arguments for MetaInfo.


TLV encoded Data packet.

async register(name)

Register a prefix in the forwarder.

This only sends the prefix registration command to the forwarder. In order to receive incoming Interests, you also need to use attach_handler to attach an Interest handler function.


name (NonStrictName) – name prefix.

  • ValueError – the prefix is already registered.

  • NetworkError – the face to NFD is down now.

Return type:


route(name, validator=None)

A decorator used to register a permanent route for a specific prefix. The decorated function should be an IntHandler.

This function is non-blocking and can be called at any time. It can be called before connecting to the forwarder. Every time a forwarder connection is established, NDNApp will automatically send prefix registration commands. Errors in prefix registration are ignored.

app = NDNApp()

def on_interest(name, app_param, reply, context):

A non-async wrapper of main_loop().


after_start (Awaitable) – the coroutine to start after connection to NFD is established.

app = NDNApp()

if __name__ == '__main__':

Manually shutdown the face to NFD.

async unregister(name)

Unregister a prefix in the forwarder.


name (NonStrictName) – name prefix.

Return type:


class ndn.appv2.PendingIntEntry(future, deadline, can_be_prefix, must_be_fresh, validator, implicit_sha256=b'', task=None)

The context for NDN Interest or Data handling.

alias of dict[str, any]

class ndn.appv2.PrefixTreeNode(callback=None, validator=None)

Continuation function for IntHandler to respond to an Interest.

(data: BinaryStr) -> bool

data (BinaryStr) – an encoded Data packet.


True for success, False upon error.

alias of Callable[[Union[bytes, bytearray, memoryview]], bool]


Validator function that validates Interest or Data signature against trust policy.

(name: FormalName, sig: SignaturePtrs, context: PktContext) -> Coroutine[ValidResult]

alias of Callable[[List[Union[bytes, bytearray, memoryview]], SignaturePtrs, dict[str, any]], Coroutine[any, None, ValidResult]]