{"CallResponse":[0, {"Signature":[{"sig":{"name":"len","description":"calculates the length of its input","extra_description":"","search_terms":[],"required_positional":[],"optional_positional":[],"rest_positional":null,"vectorizes_over_list":false,"named":[{"long":"help","short":"h","arg":null,"required":false,"desc":"Display the help message for this command","var_id":null,"default_value":null}],"input_type":"String","output_type":"Int","input_output_types":[],"allow_variants_without_examples":false,"is_filter":false,"creates_scope":false,"allows_unknown_args":false,"category":"Default"},"examples":[]}]}]}
```
The plugin prints its signature serialized as JSON. We'll reformat for readability.
```json
{
"Signature": [
{
"sig": {
"name": "len",
"description": "calculates the length of its input",
"extra_description": "",
"search_terms": [],
"required_positional": [],
"optional_positional": [],
"rest_positional": null,
"vectorizes_over_list": false,
"named": [
{
"long": "help",
"short": "h",
"arg": null,
"required": false,
"desc": "Display the help message for this command",
"var_id": null,
"default_value": null
}
],
"input_type": "String",
"output_type": "Int",
"input_output_types": [],
"allow_variants_without_examples": false,
"is_filter": false,
"creates_scope": false,
"allows_unknown_args": false,
"category": "Default"
},
"examples": []
}
]
}
```
This signature tells Nu everything it needs to pass data in and out of the plugin as well as format the help message and support type aware tab completion. A full description of these fields is beyond the scope of this tutorial, but the response is simply a serialized form of the [`PluginSignature`](https://docs.rs/nu-protocol/latest/nu_protocol/struct.PluginSignature.html) struct in the `nu-plugin` crate.
Now let's try simulating an invocation. Above we tested the plugin within Nu by executing the command `"hello" | len` and we got the response `5`. Of course this hides all of the typed data handling that makes Nu so powerful.
```nu
$ echo '{"Hello":{"protocol":"nu-plugin","version":"0.90.2","features":[]}}{"Call":[0,{"Run":{"name":"len","call":{"head":{"start":100953,"end":100957},"positional":[],"named":[]},"input":{"Value":{"String":{"val":"hello","span":{"start":100953,"end":100957}}}}}}]}' | target/release/nu_plugin_len --stdio
json{"Hello":{"protocol":"nu-plugin","version":"0.90.2","features":[]}}
{"PipelineData":{"Value":{"Int":{"val":5,"span":{"start":100953,"end":100957}}}}}
```
We invoked our plugin and passed a [`Run`](plugin_protocol_reference.md#run-plugin-call) plugin call that looks like the following on stdin:
```json
{
"Run": {
"name": "len",
"call": {
"head": {
"start": 100953,
"end": 100957
},
"positional": [],
"named": []
},
"input": {
"Value": {
"String": {
"val": "hello",
"span": {
"start": 100953,
"end": 100957
}
}
}
}
}
}
```
That is, we passed len the string "hello" and it replied with the following [`PipelineData`](plugin_protocol_reference.md#pipelinedata-plugin-call-response) response:
```json
{
"PipelineData": {
"Value": {
"Int": {
"val": 5,
"span": {
"start": 100953,
"end": 100957
}
}
}
}
}
```
with the integer 5 along with preserving source span information that may be useful for error messages later.
When implementing a plugin in a non-Rust language like Python, you must manage this input and output serialization. Please refer to the [protocol documentation](plugin_protocol_reference.md) for more specific details on the protocol itself.
## Creating a plugin (in Python)