Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Add async support to Typer #2354

Closed
dgarros opened this issue Feb 26, 2024 · 1 comment · Fixed by #2453
Closed

feature: Add async support to Typer #2354

dgarros opened this issue Feb 26, 2024 · 1 comment · Fixed by #2453
Labels
state/ref This issue is referenced in our internal tooling type/feature New feature or request

Comments

@dgarros
Copy link
Collaborator

dgarros commented Feb 26, 2024

Component

Python SDK

Describe the Feature Request

Currently we are using Typer for our various cli commands (infrahubctl, infrahub). Because Typer doesn't support Async natively we often have to create 2 versions of each command (see example below),

  • one Sync for Typer with the definition of Options/Arguments,
  • one Async that will execute the real logic and we are calling the second one from the first one with aiorun
@app.command()
def merge(
    branch_name: str,
    config_file: Path = typer.Option(DEFAULT_CONFIG_FILE, envvar=ENVVAR_CONFIG_FILE),
) -> None:
    """Merge a Branch with main."""
    config.load_and_exit(config_file=config_file)
    aiorun(_merge(branch_name=branch_name))

There is a long discussion on the Typer project about that and it looks like Typer is planning to support Async natively at some point. Meanwhile, there are a number of workaround discussed in this Thread that would be easy to implement
fastapi/typer#88 (comment)

Like this one

class AsyncTyper(Typer):
    @staticmethod
    def maybe_run_async(decorator, f):
        if inspect.iscoroutinefunction(f):

            @wraps(f)
            def runner(*args, **kwargs):
                return asyncio.run(f(*args, **kwargs))

            decorator(runner)
        else:
            decorator(f)
        return f

    def callback(self, *args, **kwargs):
        decorator = super().callback(*args, **kwargs)
        return partial(self.maybe_run_async, decorator)

    def command(self, *args, **kwargs):
        decorator = super().command(*args, **kwargs)
        return partial(self.maybe_run_async, decorator)

app = AsyncTyper()

Describe the Use Case

Simplify how to write our cli commands and reduce the maintenance effort

Additional Information

No response

@dgarros dgarros added type/feature New feature or request group/python-sdk labels Feb 26, 2024
@opsmill-bot opsmill-bot added the state/ref This issue is referenced in our internal tooling label Feb 26, 2024
@dgarros dgarros added this to the Infrahub - 0.12 - Beta #1 milestone Mar 11, 2024
@dgarros
Copy link
Collaborator Author

dgarros commented Mar 11, 2024

completed in #2453

@dgarros dgarros closed this as completed Mar 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state/ref This issue is referenced in our internal tooling type/feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants