개요

grais-asgi를 개발하면서 커맨드라인 인터페이스 라이브러리를 선택한 기준을 정리해보았습니다.

cli

선택 기준

커맨드라인 인터페이스를 구현하는 데에서 가장 중요하게 여긴 기준은 dataclass로 옵션을 정의할 수 있어야 한다는 점입니다. dataclass로 옵션을 정의하면 코드 양을 줄일 수 있습니다. Config를 위한 클래스를 사용하는 것은 확정적이고, 이것을 그대로 커맨드라인 인터페이스로 재사용할 수 있습니다. 선언적으로 정의하므로 코드를 읽는 과정에서 로직을 배제할 수 있습니다. 실질적으로 코드를 읽는 관점에서 양을 줄이는 효과를 기대할 수 있습니다. 또한 dataclass 표준 라이브러리이므로 다른 라이브러리의 지원을 높은 확률로 기대할 수 있습니다. 사용해볼 수 있는 관련 라이브러리가 많으니 자연스럽게 문제가 생기면 교체가 쉽구요.

click, typer, fire

커맨드라인 인터페이스 구현에 있어 가장 우선적으로 고민해본 라이브러리들입니다. click은 Python 생태계에서 가장 범용적으로 쓰이는 CLI 라이브러리입니다. uvicorn, litestar 구현에도 사용되었습니다. 하지만 데코레이터를 계속 사용해야 하고, 데코레이터에서 문자열로 함수의 파라미터와 매칭하다보니 코드 양 자체가 굉장히 길어져서 제외했습니다. dataclass와 click을 연동해보는 라이브러리도 찾아보았는데, 공식적인 구현은 아닌 것 같아 제외했습니다. typer, fire도 click의 wrapper이기 때문에 제외했습니다.

jsonargparse

  • 데이터클래스 지원 안됨 jsonargparse는 Python 표준 라이브러리에 포함된 argparse 인터페이스를 동일하게 유지하면서 json, yaml, toml 설정 파일/환경변수를 통한 옵션 주입 기능을 추가로 제공하는 라이브러리입니다. argparse의 ArgumentParser를 이용해서 옵션 정의를 하고, 이를 통해 Config 클래스를 작성합니다. dataclass로 선언적인 옵션 선언이 불가능해서 제외했습니다. 표준 라이브러리 호환은 굉장한 장점이지만

SimpleParsing과 tyro

마지막으로 남은 후보는 SimpleParsing과 tyro였습니다. 둘 다 데이터클래스로 옵션을 정의하는 기능을 잘 지원합니다. 요구하는 바를 모두 만족해서 두 라이브러리르 사용해보고 tyro가 조금 더 사용이 마음에 들어 선택했습니다.

결론

tyro가 dataclass를 지원하고 코드 양이 적어서 grais-asgi에 사용했습니다. 살짝 아쉬운 점은 필수 옵션 파라미터 선언이 Annotated wrapper 구현인데 dataclass.field 스타일 선언이 가능했으면 하는 점이 살짝 아쉽습니다. 하지만 다른 점이 마음에 들어 tyro를 계속 사용할 것 같습니다.