Skip to content

An example plugin for Nushell in Python that catches ascii pokemon

Notifications You must be signed in to change notification settings

vsoch/nushell-plugin-pokemon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Nushell Plugin in Python

img/nushell-plugin-pokemon.png

This is an example implementation of a Pokemon plugin for Nushell in Python. I wanted to create this to clearly lay out how someone should provide named arguments.

See the asciinema example too:

asciicast

Build

You can optionally build the container:

$ docker build -t vanessa/nu-plugin-pokemon .

If you don't, it's available on Docker Hub and will be pulled automatically.

Usage

Run the container to access the nu entrypoint!

$ docker run -it vanessa/nu-plugin-pokemon

Once inside you can ask for help for the plugin:

/code> help pokemon
Catch an asciinema pokemon on demand.

  --avatar AVATAR    generate a pokemon avatar for some unique id.
  --pokemon POKEMON  generate ascii for a particular pokemon (by name)
  --catch            catch a random pokemon!
  --list             list pokemon available
  --list-sorted      list pokemon available (sorted)
  --help             show this usage


Usage:
  > pokemon {flags} 

flags:
  --avatar <String>
  --pokemon <String>
  --catch
  --help
  --list-sorted

I also implemented the (more expected) --help command, which looks cleaner too:

/code> pokemon --help
Catch an asciinema pokemon on demand.

  --avatar AVATAR    generate a pokemon avatar for some unique id.
  --pokemon POKEMON  generate ascii for a particular pokemon (by name)
  --catch            catch a random pokemon!
  --list             list pokemon available
  --list-sorted      list pokemon available (sorted)
  --help             show this usage

Catch A Pokemon

To catch a random pokemon, use the --catch flag.

/code> pokemon --catch
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+,.,@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,::.:@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.,,:*.@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,,,:**S@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*,,,:**S@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,,,,**S.***@@@@@@@@@@@
@@@+,,,,,,,,,*@@@@@@@@@@@@@@@@@@@@@@@*,,:,**%++..*@@@@@@@@@@
@,,,,,,,,,,,,,,,@,.@@@@@@@@@@@@@@@@@@*,:::*.::+++.@@@@@@@@@@
,,,,,,,,,,,,,,,,,,,,@,@@@@@@@@@@@@@@@@::::*.S,:::+@@@@@@@@@@
@,,,,,,,,,,,,,::,,,,,,,@.@@@@@@@@@@@@@*:::**.S::,:.+.@@@@@@@
@@,,,,,,,,,:::::::::::,,,,*@@@@@@@@@@@@*:::*.S..%%.++++.S@@@
@@@,,,,,,,,:*:::**.::*:**::,@@@@@@@@@@...+::*@@@@@@@@@@@@@@@
@@@@.,,,,,,:*::*@@@@@@@@...::,@@@@@@@*:+**@@@.@@@@@@@@@@@@@@
@@@@@@*,,,,,*::.@@@@@@@@@@@..::@@@@@:*:,:*@@@@@@@@@@@@@@@@@@
@@@@@@@@:,,:::.*:@@@@@@@@@@@@.:,@@@****::+@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@.,::*.+@@@@@@@@@@@@,*@@+:**.::+@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@*::*.,@@@@@@@@@@@@*:::::+::*@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@::..@@@@@@@.:,::::::.::.@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@*+.:::::::::***:*::.@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@.*:::::::++:::::****+**S*S.@@@@@@@@@@@@@@@@@
@@@@@@@@@@,+::::::::::.+.::::*****.....S:*++@@@@@@@@@@@@@@@@
@@@@@+****.:::::::.:+++::*******S+++++****+S...@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@:.++***********+.+S***...?@@@@...@@@@@@@@@@
@@@@@@@@@@@@@@@:...,...*******.++.+..****@@@@@@@@***.@@@@@@@
@@@@@@@@@@@@@,****@@@+......+++..******,..*@@@@@@@@:::.@@@@@
@@@@@@@@@@@@::::,@@@@@@@+..++******+@@@@@@@....,@@@@::::@@@@
@@@@@@@@@@@::::*,,:.:*::**.@@@@@@@@@@@@@@@@@@@@*:::*:*:::@@@
@@@@@@@@@:*:****::*:***.@@@@@@@@@@@@@@@@@@@@@@@@@@@@:.::::@@
@@@@@@@@@***:*::****+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@****:*::.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Cresselia http:https://pokemondb.net/pokedex/cresselia

Pokemon Avatar

You can generate a unique avatar based on a string input (maybe your alias?)

/code> pokemon --avatar dinosaur
@@@@@@@@@@@@.?%..%%.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@%*.........****.*%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@?.+S%?%.+++++.....++?.*..+@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@.......%...**+.++..%+.+##.#@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@,.%......%...S....?+%SSSS+S.@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@SS*..+***..........*+?+S+?.S@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@:+*..,,,:::*S+......*.++++.*@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@%S@,,,:::#.:%........+++++@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@S,,,::::.?..*........++++,@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@,,::::,,::::**....+%*.+++,@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@.S,@+,:::::::*:*.....%++S@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@.:::::.*...*..S++@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@,:::,@.%+++++S+@@@@@@@@@@@@@@@@@@.*..?@@@@
@@@@@@@@@@@@@@@@@@,:::,@@@@@@@@@@@@@@@@@@@@@@@@@@@+....++@@@
@@@@@@@@@@@@@@@S..,::::S%*@@@@@@@@@@@@@@@@@@@@+...++++++++++
@@@@@@@@:.,,,,:+::::::::*%+:*,,#@@@@@@@@@@@@@+....+.#S.S+...
@@@@@@@,,,:.,,:,::::::,::::::,#::,.@@@@@@@@@@@.++++%*.#+++++
@@@@@@@@.,,,,,,:?,,,,,,?::::::::,@@@@@@@@@@@@@@@@@S?::S+,,@@
@@@@@@@*,,,:,++SS:,,,,,?S+%:::::,,@@@@@@@@@@@@@@@@,,::@@@@@@
@@@@@@@%+%?++....*@,,,,SS+#S?S+@@@@@@@@@@@@@@@@@@+,,:.@@@@@@
@@@@:.+..S+*........*.S...S%S++@@@@@@@@@@@@@@@@@.,,:.@@@@@@@
@@@,....S%%............?.+.++S#%@@@@@@@@@@@@@@+,,,::@@@@@@@@
@@@@%S+S.+S..............?S+?.++%@@@@@@@@@@+,,,,::%@@@@@@@@@
@@@@@@.......................++++%@@@@:%*,,,,,::,:@@@@@@@@@@
@@@@@@?...+?++.....+++.......+++++.******::::::?@@@@@@@@@@@@
@@@@@@:....+?+++++++++?.....++++++%******::::%@@@@@@@@@@@@@@
@@@@@@@@.+++++#++++++++.++++++S++++:******::@@@@@@@@@@@@@@@@
@@@@@@@@@@@.++++..++++++.++++++++++:***:%@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@.+++.@@@@*????#%++++++?@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@*..+++:@@@@@@@@@@@@@@++++#@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@%.S%S.++++?@@@@@@@@@@@@@@@S+++++@@@@@@@@@@@@@@@@@@@@@@
@@@S.S?+SSS+++++*@@@@@@@@@@@@@%?...%?.@@@@@@@@@@@@@@@@@@@@@@
@%S?+SSSSSS+.@@@@@@@@@@@@@@@.*SS++%SSS+@@@@@@@@@@@@@@@@@@@@@
@,.SSS%.:@@@@@@@@@@@@@@@@@@S.SSSS#+SSSS+@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@.SSSS,%SSSSSS@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@,S+.@@@%SS+?@@@@@@@@@@@@@@@@@@@@@@

dinosaur

List

You can list all the pokemon names in the database

/code> pokemon --list
...
Sliggoo
Goodra
Klefki
Phantump
Trevenant
Pumpkaboo
Gourgeist
Bergmite
Avalugg
Noibat
Noivern
Xerneas
Yveltal
Zygarde
Diancie
Hoopa
Volcanion

You can also list them sorted (ABC-Z)

/code> pokemon --list-sorted

Pokemon

Once you know a specific pokemon, you can request him by name

/code> pokemon --pokemon goodra
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@..@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@.::::*S,,,,,,:,@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@.%..+,+,,,::::::,:*@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@+:..?:::::::::::::::,@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@:,,,:::::%++*:::::::@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@,,,,,,::::::SS@*::::,:@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@,,,,:+,*++::.S@@@:::::*@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@,,,:.+:.S+SS:S@@@@.::::@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@,S.......*:*S@@@@@,:::,@@@@@@@@::
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@::?....%%S@@@@@@@%::::S@@@@.:@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,@S....%@+*@@@@@@@@,*:::::S@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@:S....*@*.@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,:.....@@@@...+@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@S::%....,@@@@@@*S@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@+:::..:..:,,,,.@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@::,::::::,::::*@@S:,,,,,.?@@@@@@@@@@
@@@@@,,,,+@@@@@@@@@@@,::::::::::::::::....::::.@@@@@@@@@@@@@
@@,:,,,.::@@@@@@@@@,:::::::.+:::::.::.....%::,@@@@@@@@@@@@@@
@@,,,+,::@@@@@@@@,:::::::....:*.....:S@@@@@,,@@@@@@@@@@@@@@@
@*:,:::.@@@@@@@@*::::::....*::*......:*@@@@@@@@@@@@@@@@@@@@@
:::,:::::.@@@@@::::::::..*::::*......%::@@@@@@@@@@@@@@@@@@@@
.::::::::::::,:::,::::::+:::::.......+:::@@@@@@@@@@@@@@@@@@@
:.:,:::::::::*:::,:::::::*::*.........::,,@@@@@@@@@@@@@@@@@@
@SS:,,:::::,,:::,,,:::::::...........:::,,@@@@@@@@@@@@@@@@@@
@@+++S::,,,,,::::,,,:::::::.........::::::@@@@@@@@@@@@@@@@@@
@@@S+S+SS.++..::::::::::::*+++++++........@@@@@@@@@@@@@@@@@@
@@@@%+++S.SS+..............++++S.........@@@@@@@@@@@@@@@@@@@
@@@@@@@[email protected]@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@*%++++........,@@@@@@@%.....:@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@.....@@@@@@@@@@@@,.%.@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@...+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Goodra

Test Without Nu

It's possible to test without nushell by giving json objects to the python script, and you'll need Python3 installed on your host.

Config

$ ./nu_plugin_pokemon.py
{"method":"config"}

{"jsonrpc": "2.0", "method": "response", "params": {"Ok": {"name": "pokemon", "usage": "Catch an asciinema pokemon on demand.\n\n  --avatar AVATAR    generate a pokemon avatar for some unique id.\n  --pokemon POKEMON  generate ascii for a particular pokemon (by name)\n  --message MESSAGE  add a custom message to your ascii!\n  --catch            catch a random pokemon!\n  --list             list pokemon available\n  --list-sorted      list pokemon available (sorted)\n", "positional": [], "rest_positional": null, "named": {"avatar": {"Optional": "String"}, "pokemon": {"Optional": "String"}, "message": {"Optional": "String"}, "catch": "Switch", "list": "Switch", "list-sorted": "Switch"}, "is_filter": false}}}

Sink

Unlike a filter, the method we care about here is "sink" - where basically nu will give full control of stdout to the plugin, along with all the input parameters from the user. Here is an example with requesting to catch a pokemon:

$ ./nu_plugin_pokemon.py
{"jsonrpc":"2.0","method":"sink","params":[{"args":{"positional":null,"named":{"catch":{"tag":{"anchor":null,"span":{"start":10,"end":15}},"item":{"Primitive":{"Boolean":true}}}}},"name_tag":{"anchor":null,"span":{"start":0,"end":7}}}]}

The above will print the pokemon to the screen.

Order of Operations

Keep in mind that when nushell finds the plugin on the path, it's going to:

  • discover the plugin by way of being on the path
  • call the "config" method to get metadata and register it
  • call sink when it's invoked
  • nu passes stdout to the plugin
  • the plugin can print to stdout to it's heart's content!

That's a very high level description, see the plugin page to read more about discovery and usage.

Logging

Note that since I'm going to be using the plugin in a container, I don't mind logging to a temporary file at /tmp/nu-plugin-pokemon.log. This will show basic operations for each execution, for example:

/code> cat /tmp/nu_plugin_pokemon.log
root - INFO - REQUEST {"jsonrpc":"2.0","method":"sink","params":[{"args":{"positional":null,"named":{"catch":{"tag":{"anchor":null,"span":{"start":10,"end":15}},"item":{"Primitive":{"Boolean":true}}}}},"name_tag":{"anchor":null,"span":{"start":0,"end":7}}},[]]}

root - INFO - METHOD sink
root - INFO - PARAMS {'catch': True}
root - INFO - We want to catch a random pokemon!

Development

It's helpful to use nu -l trace to confirm that nu found your plugin, and see other debugging information (along with our temporary log file).

/code(add/circleci)> nu -l trace
...
 TRACE nu::cli > Trying "/usr/local/bin/nu_plugin_pokemon"
 TRACE nu::cli > processing response (717 bytes)

For those interested in seeing the responses that get shared with the plugin from nu, here are a few examples. This was done when I was just developing, and testing named arguments for:

  • mandatory
  • optional
  • switch
/code> pokemon --mandatory MANDATORYARG
/code> cat /tmp/nu_plugin_pokemon.log
root - INFO - REQUEST {"jsonrpc":"2.0","method":"sink","params":[{"args":{"positional":null,"named":{"mandatory":{"tag":{"anchor":null,"span":{"start":20,"end":32}},"item":{"Primitive":{"String":"MANDATORYARG"}}}}},"name_tag":{"anchor":null,"span":{"start":0,"end":7}}},[]]}

root - INFO - METHOD sink
/code> pokemon --mandatory MANDATORYARG --optional OPTIONALARG --switch
/code> cat /tmp/nu_plugin_pokemon.log
root - INFO - REQUEST {"jsonrpc":"2.0","method":"sink","params":[{"args":{"positional":null,"named":{"switch":{"tag":{"anchor":null,"span":{"start":58,"end":64}},"item":{"Primitive":{"Boolean":true}}},"mandatory":{"tag":{"anchor":null,"span":{"start":20,"end":32}},"item":{"Primitive":{"String":"MANDATORYARG"}}},"optional":{"tag":{"anchor":null,"span":{"start":44,"end":55}},"item":{"Primitive":{"String":"OPTIONALARG"}}}}},"name_tag":{"anchor":null,"span":{"start":0,"end":7}}},[]]}

I hope it helps someone!

About

An example plugin for Nushell in Python that catches ascii pokemon

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published