Skip to content

Fetching sys.stdin using annotations in a command #345

Description

@sbordeynemics

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the Typer documentation, with the integrated search.
  • I already searched in Google "How to X in Typer" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to Typer but to Click.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

# This does not work as far as I know in the current version of typer
import typer


app = typer.Typer()

@app.command()
def cat(data: typer.StdIn):
    '''Prints all the data piped into it from stdin'''
    for line in data:
        typer.echo(line)


if __name__ == '__main__':
    app()

Description

I would like to have typer integrate seemlessly with sys.stdin. Currently, it is quite complicated to integrate sys.stdin in a typer app. You can obviously use something like :

import sys
import typer

app = typer.Typer()

@app.callback(invoke_without_command=True)
def main(value: typer.FileText = typer.Argument(..., allow_dash=True)):
    """Echo out the input from value."""
    value = sys.stdin.read() if value == "-" else value.read()
    typer.echo(value)

if __name__ == "__main__":
    app()

See this issue : #156

But it is definitely not seemless.

Wanted Solution

The goal would be to have something like in the code example provided, direct access to stdin from the argument type (which is handy when designing CLIs so that they can be used in conjunction with other unix tools -- like cut, cat, sed or find for instance)

Wanted Code

# This does not work as far as I know in the current version of typer
import typer


app = typer.Typer()

@app.command()
def cat(data: typer.StdIn):
    '''Prints all the data piped into it from stdin'''
    for line in data:
        typer.echo(line)


if __name__ == '__main__':
    app()

Alternatives

Use the aforementionned workaround, using '-' as the marker for an stdin input.

I also tried reading from sys.stdin directly, but it doesn't integrate well in a typer app (especially around the coding style)

Operating System

Linux, Windows, macOS

Operating System Details

  • Windows : Windows 10 Professional (latest build)
  • Mac OS : Monterey 12.0.1
  • Linux : Ubuntu 20.04 LTS, Fedora 34

Typer Version

0.3.2

Python Version

3.9.9

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions