Python Twisted integration with Cmd module

2024/9/8 9:25:47

I like Python's Twisted and Cmd. I want to use them together.

I got some things working, but so far I haven't figured out how to make tab-completion work, because I don't see how to receive tab keypres events right away (without pressing Enter) in Twisted's LineReceiver.

Here's my code so far:

#!/usr/bin/env pythonfrom cmd import Cmd
from twisted.internet import reactor
from twisted.internet.stdio import StandardIO
from twisted.protocols.basic import LineReceiverclass CommandProcessor(Cmd):def do_EOF(self, line):return Trueclass LineProcessor(LineReceiver):from os import linesep as delimiter # makes newline workdef __init__(self):self.processor = CommandProcessor()self.setRawMode()def connectionMade(self):self.transport.write('>>> ')def rawDataReceived(self, data):self.processor.onecmd(data)self.transport.write('>>> ')StandardIO(LineProcessor())
reactor.run()

Apart from tab completion, this somewhat works. I can enter a command like "help" and the Cmd module will print the results. But I've lost the nifty tab-complete functionality of the Cmd module, because Twisted is buffering one line at a time. I tried setting LineProcessor.delimiter to the empty string, to no avail. Maybe I need to find some other piece of Twisted to use instead of LineReceiver? Or maybe there's a simpler approach that will avoid my having to process every character one-by-one?

I can't use Cmd alone, because I want to make this a network application, where some commands will result in sending data, and receiving data from the network will happen asynchronously (and be displayed to the user).

So whether we start from the above code or something completely different, I'd like to build a nice, friendly terminal application in Python that responds to network events and also to tab completion. I hope I can use what's already out there and not have to implement too much myself.

Answer

You have a couple of difficulties with this approach:

  • Cmd.onecmd is not going to do any tab processing.
  • Even if it did, your terminal needs to be in cbreak mode in order for individual keystrokes to make it to the Python interpreter (tty.setcbreak can take care of that).
  • As you know, Cmd.cmdloop is not reactor aware and will block waiting for input.
  • Yet, to get all of the cool line-editing you want, Cmd (actually readline) needs to have direct access to stdin and stdout.

Given all of these difficulties, you might want to look at letting the CommandProcessor run in its own thread. For example:

#!/usr/bin/env pythonfrom cmd import Cmd
from twisted.internet import reactorclass CommandProcessor(Cmd):def do_EOF(self, line):return Truedef do_YEP(self, line):reactor.callFromThread(on_main_thread, "YEP")def do_NOPE(self, line):reactor.callFromThread(on_main_thread, "NOPE")def on_main_thread(item):print "doing", itemdef heartbeat():print "heartbeat"reactor.callLater(1.0, heartbeat)reactor.callLater(1.0, heartbeat)
reactor.callInThread(CommandProcessor().cmdloop)
reactor.run()
https://en.xdnf.cn/q/73055.html

Related Q&A

Read .pptx file from s3

I try to open a .pptx from Amazon S3 and read it using the python-pptx library. This is the code: from pptx import Presentation import boto3 s3 = boto3.resource(s3)obj=s3.Object(bucket,key) body = obj.…

PIL image display error It looks like the image was moved or renamed

Here is a bit of my code:from PIL import Imageimage = Image.open(fall-foliage-1740841_640.jpg) image.show()The error is when the default photo viewer is started and shows the error "It looks like …

How to delete numpy nan from a list of strings in Python?

I have a list of strings x = [A, B, nan, D]and want to remove the nan.I tried:x = x[~numpy.isnan(x)]But that only works if it contains numbers. How do we solve this for strings in Python 3+?

Pasting data into a pandas dataframe

This is the same question as this question, which is marked as a duplicate of this one. The problem, and the reason Im still asking, is that the solution provided (using pandas.read_clipboard()) curren…

Add graph description under graph in pylab [duplicate]

This question already has answers here:Closed 11 years ago.Possible Duplicate:Is there a way of drawing a caption box in matplotlib Is it possible to add graph description under graph in pylab?Lets s…

Using Python textwrap.shorten for string but with bytes width

Id like to shorten a string using textwrap.shorten or a function like it. The string can potentially have non-ASCII characters. Whats special here is that the maximal width is for the bytes encoding of…

How to create a transparent mask in opencv-python

I have sign (signs with arbitrary shape) images with white background and I want to get an image of the sign with transparent background. I have managed to create a mask and apply it to the image and t…

Variables with dynamic shape TensorFlow

I need to create a matrix in TensorFlow to store some values. The trick is the matrix has to support dynamic shape.I am trying to do the same I would do in numpy: myVar = tf.Variable(tf.zeros((x,y), va…

python protobuf cant deserialize message

Getting started with protobuf in python I face a strange issue:a simple message proto definition is:syntax = "proto3"; package test;message Message {string message = 1;string sender = 2; }gen…

Seaborn: title and subtitle placement

H all,Id like to create a scatterplot with a title, subtitle, colours corresponding to a specific variable and size corresponding to another variable. I want to display the colour legend but not the si…