{"id":15733173,"url":"https://github.com/yukinarit/oppapi","last_synced_at":"2025-03-13T05:31:19.665Z","repository":{"id":57449342,"uuid":"437443234","full_name":"yukinarit/oppapi","owner":"yukinarit","description":"Ergonomic option parser on top of dataclasses, inspired by structopt.","archived":false,"fork":false,"pushed_at":"2022-10-11T13:01:13.000Z","size":25,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-26T18:57:03.180Z","etag":null,"topics":["dataclasses","option-parser","python","structopt"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yukinarit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-12-12T03:27:46.000Z","updated_at":"2022-07-19T07:16:41.000Z","dependencies_parsed_at":"2022-09-14T07:22:14.931Z","dependency_job_id":null,"html_url":"https://github.com/yukinarit/oppapi","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yukinarit%2Foppapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yukinarit%2Foppapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yukinarit%2Foppapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yukinarit%2Foppapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yukinarit","download_url":"https://codeload.github.com/yukinarit/oppapi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243351258,"owners_count":20276894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dataclasses","option-parser","python","structopt"],"created_at":"2024-10-04T00:41:18.815Z","updated_at":"2025-03-13T05:31:19.248Z","avatar_url":"https://github.com/yukinarit.png","language":"Python","readme":"# `oppapī`\n\n*Ergonomic option parser on top of [dataclasses](https://docs.python.org/3/library/dataclasses.html), inspired by [structopt](https://github.com/TeXitoi/structopt).*\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.png\" width=25% /\u003e\n\u003c/p\u003e\n\n## Usage\n\n```python\nfrom typing import Optional\nfrom oppapi import from_args, oppapi\n\n@oppapi\nclass Opt:\n    \"\"\"\n    Option parser using oppapi\n    \"\"\"\n\n    host: str\n    \"\"\" This will be positional argument of type `str` \"\"\"\n\n    port: Optional[int] = 8000\n    \"\"\" Optional argument will be option argument \"\"\"\n\nopt = from_args(Opt)\nprint(opt)\n```\n\nThe code above generates such option parser that\n* Generates parser description from class's docstring\n* Generates argument description from field's docstring\n* A field will be a positional argument\n* An optional field will be an optional argument\n\nSee the parser help message:\n\n```\n$ python simple.py -h\nusage: simple.py [-h] [-p PORT] host\n\nOption parser using oppapi\n\npositional arguments:\n  host                  This will be positional argument of type `str`\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -p PORT, --port PORT  Optional argument will be option argument\n```\n\nRunning the program deserializes the command line arguments into an object of the declared class.\n\n```\n$ python simple.py localhost -p 20000\nOpt(host='localhost', port=20000)\n```\n\n## Supported types\n\n* Primitives (`int`, `float`, `str`, `bool`)\n* Containers (`List`, `Tuple`)\n* [`typing.Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)\n* [`Enum`](https://docs.python.org/3/library/enum.html#enum.Enum) and [`IntEnum`](https://docs.python.org/3/library/enum.html#enum.IntEnum)\n* [`datetime`](https://github.com/yukinarit/oppapi/blob/main/examples/mod_datetime.py)\n* [`decimal`](https://github.com/yukinarit/oppapi/blob/main/examples/mod_decimal.py)\n* [`ipaddress`](https://github.com/yukinarit/oppapi/blob/main/examples/mod_ipaddress.py)\n* [`pathlib`](https://github.com/yukinarit/oppapi/blob/main/examples/mod_path.py)\n* [`uuid`](https://github.com/yukinarit/oppapi/blob/main/examples/mod_uuid.py)\n\n\n## `short`/`long`\n\n`oppapi` generates flag names automatically, but you can specify arbitrary short/long names.\n\n```python\nfrom typing import Optional\nfrom oppapi import from_args, oppapi, field\n\n@oppapi\nclass Opt:\n    host: Optional[str] = field(short=\"-n\", long=\"--hostname\")\n```\n\n## `enum`\n\n`enum.Enum` and `enum.IntEnum` will be an argument with [choices](https://docs.python.org/3/library/argparse.html#choices) parameter.\n\n```python\nclass Food(Enum):\n    A = \"Apple\"\n    B = \"Beer\"\n    C = \"Chocolate\"\n\nclass Price(IntEnum):\n    A = 10\n    B = 20\n    C = 30\n\n@oppapi\nclass Opt:\n    food: Food\n    price: Optional[Price]\n```\n\nusage will be like this:\n```\npositional arguments:\n  {Apple,Beer,Chocolate}\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -p {10,20,30}, --price {10,20,30}\n```\n\noppapi converts the command line arguments back to Enum.\n\n```python\n$ python choice.py Apple --price 20\nOpt(food=\u003cFood.A: 'Apple'\u003e, price=\u003cPrice.B: 20\u003e)\n```\n\n## `List`/`Tuple`\n\n`List` will be an arbitrary number of arguments (`nargs=\"+\"`). `Tuple` will be a fixed number of arguments (`nargs=NUM`).\n\n```python\n@oppapi\nclass Opt:\n    values: List[int]\n    opts: Optional[Tuple[int, str, float, bool]]\n```\n\n```\n$ python nargs.py 1 2 3 --opts 10 foo 10.0 True\nOpt(values=[1, 2, 3], opts=(10, 'foo', 10.0, True))\n```\n\n## SubCommand\n\n`Union` of dataclasses will be subcommands.\n\n```python\n@oppapi\nclass Foo:\n    a: int\n\n@oppapi\nclass Bar:\n    a: str\n    b: Optional[int]\n\n@oppapi\nclass Opt:\n    sub: Union[Foo, Bar]\n\n```\n\n```\nusage: subcommand.py [-h] {foo,bar} ...\n\npositional arguments:\n  {foo,bar}\n\n  optional arguments:\n    -h, --help  show this help message and exit\n```\n\n## Flatten\n\nTODO\n\n## LICENSE\n\nThis project is licensed under the [MIT license](https://github.com/yukinarit/oppapi/blob/main/LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyukinarit%2Foppapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyukinarit%2Foppapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyukinarit%2Foppapi/lists"}