Closed zmoog closed 1 year ago
Starting by collecting some info:
From https://www.digitalocean.com/community/tutorials/read-stdin-python:
There are three ways to read data from stdin in Python.
- sys.stdin
- input() built-in function
- fileinput.input() function
After skimming through the article I guess sys.stdin
may be the way to go.
Using:
import sys
if __name__ == "__main__":
data = sys.stdin.read()
print(data.upper())
Here' a quick test:
$ echo "hogwarts legacy is cool" | python main.py
HOGWARTS LEGACY IS COOL
The Click framework has some nice utilities that deals with streams:
https://click.palletsprojects.com/en/8.1.x/utils/#standard-streams
import click
stdin_text = click.get_text_stream('stdin')
stdout_binary = click.get_binary_stream('stdout')
As mentioned in zmoog/til#15.
I like this approach, it's quite flexible.
Here's one take on this that allows three different input sources:
--text
--text-file
text_file.read()
will wait until the user has typed the message and hit CTRL + D
@message.command(name="send")
@click.option(
"--text",
help="Text to send. If not provided, text will be read from a file or stdin.",
default=None,
)
@click.option(
"--text-file",
help="Text file to read from. If not provided, stdin will be used.",
type=click.File("r"),
default=click.get_text_stream("stdin"),
)
@click.option(
"--chat-id",
required=True,
)
@click.option(
'--parse-mode',
type=click.Choice(
['HTML', 'MarkdownV2'],
case_sensitive=False
),
default=None,
)
@click.pass_context
def send(ctx: click.Context, text: str, text_file: typing.TextIO, chat_id: str, parse_mode: str):
"""Send a text message to a chat."""
client = telegram.Client.from_envorinment(verbose=ctx.obj["verbose"])
if text:
message_text = text
elif text_file and text_file.readable():
message_text = text_file.read()
else:
raise Exception("No text or text file provided")
resp = client.send(message_text, chat_id, parse_mode=parse_mode)
message_id = resp.get("result", {}).get("message_id", "No message id found")
click.echo(f"message-id: {message_id}")
Implemented with https://github.com/zmoog/telegram-cli/pull/4
Sometimes in CLI tools it is conveniente read data from stdin instead of an argument or an option. This allows chaining different CLI tools together, for example: