emmett-framework / granian

A Rust HTTP server for Python applications
BSD 3-Clause "New" or "Revised" License
2.67k stars 79 forks source link

Rewrite CLI to use click instad of typer #270

Closed WAKayser closed 5 months ago

WAKayser commented 5 months ago

As discussed in #261 typer changed the scope of the project and started pulling in other dependencies.

This pull request changes the dependency used from typer to click. The resulting code is a bit more verbose, but the general way of working with it is largely similar. I found that there were two features missing in click.

First is no support for enums as choices. But this is easy to work around by supplying a list of choices and in the function itself convert to an enum. Second feature missing was the option to show the environment variables for each option. I have added a simple monkey patch to the option function to extend the help text.

Current state is functional, all option types work and environment variables in general work.. But some more testing is wise.

WAKayser commented 5 months ago

I have added a simple EnumType to create the click.Choice from the enum. This is based on: https://github.com/pallets/click/issues/605#issuecomment-917022108

Finally I have also added a pretty printer to print the defaults a bit neater. This allows to turn all booleans into "disabled" or "enabled" without duplicate configurations.

Finally, I have also finished testing. This was primarily done by adding the following snippet to the start of the cli function. Then check the diff between the version from this PR and what is currently on pypi.

    print(f'{app=}, {host=}, {port=}, {interface=}, {http=}, {websockets=}, {workers=}, {threads=}, {blocking_threads=}')
    print(f'{loop=}, {loop_opt=}, {backlog=}, {http1_buffer_size=}, {http1_keep_alive=}, {http1_pipeline_flush}')
    print(f'{http2_adaptive_window=}, {http2_initial_connection_window_size=}, {http2_initial_stream_window_size}')
    print(f'{http2_keep_alive_interval=}, {http2_keep_alive_timeout=}, {http2_max_concurrent_streams=}')
    print(f'{http2_max_frame_size=}, {http2_max_headers_size=}, {http2_max_send_buffer_size=}, {log_enabled=}')
    print(f'{log_level=}, {log_config=}, {ssl_keyfile=}, {ssl_certificate=}, {url_path_prefix=}')
    print(f'{respawn_failed_workers=}, {reload=}, {process_name=}')
    return

This returned the same when using all the defaults and with all values set via either the command options or via environment variables.