[英]Generate json schema from argparse CLI
我有一個用argparse
編寫的 CLI,我想知道是否有辦法從ArgumentParser
生成 JSON 架構? 這背后的想法是將 JSON 模式分發給與應用程序接口的擴展,從而消除了每個擴展編寫和維護自己的模式的需要。
我的想法是
argparse.ArgumentParser
轉換為 Python 字典或 JSON 文件import argparse
from genson import SchemaBuilder
parser = argparse.ArgumentParser(
description="Some description", prog="myprog", usage="myprog [options]"
)
parser.add_argument(
"-v",
"--version",
action="store_true",
help="Print server version number and exit",
)
parser.add_argument(
"-c",
"--config",
type=str,
default=".fortls",
help="Configuration options file (default file name: %(default)s)",
)
args = vars(parser.parse_args(""))
# Generate schema
builder = SchemaBuilder()
builder.add_schema({"type": "object", "properties": {}})
for k, v in args.items():
builder.add_object({k: v})
print(builder.to_json(indent=2))
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
"version": {
"type": "boolean"
},
"config": {
"type": "string"
}
}
}
但是,我很快意識到調用vars(parser().parse_args(""))
將 CLI 轉換為字典會導致大量信息丟失,例如描述和必需信息。
還有另一種方法嗎? 如果可以更輕松地生成模式,我願意將argparse
與其他一些 CLI 交換。
我想出的解決方案是從ArgumentParser
訪問私有變量_actions
並使用pydantic
將其轉換為模式。 在我的具體情況下,這很容易做到,因為argparse
中的所有 arguments 都是可選的。 如果不是,則在使用pydantic
創建 model 時必須多加考慮
from __future__ import annotations
from pydantic import Field, create_model
import argparse
parser = argparse.ArgumentParser(
description="Some description", prog="myprog", usage="myprog [options]"
)
parser.add_argument(
"-v",
"--version",
action="store_true",
help="Print server version number and exit",
)
parser.add_argument(
"-c",
"--config",
type=str,
default=".fortls",
help="Configuration options file (default file name: %(default)s)",
)
schema_vals = {}
for arg in parser._actions:
# if condition for arguments to exclude:
# continue
val = arg.default
desc: str = arg.help.replace("%(default)s", str(val)) # type: ignore
schema_vals[arg.dest] = Field(val, description=desc) # type: ignore
m = create_model("MySchema", **schema_vals)
m.__doc__ = "Some description"
with open("schema.json", "w") as f:
print(m.schema_json(indent=2), file=f)
Output
{
"title": "MySchema",
"description": "Some description",
"type": "object",
"properties": {
"help": {
"title": "Help",
"description": "show this help message and exit",
"default": "==SUPPRESS==",
"type": "string"
},
"version": {
"title": "Version",
"description": "Print server version number and exit",
"default": false,
"type": "boolean"
},
"config": {
"title": "Config",
"description": "Configuration options file (default file name: .fortls)",
"default": ".fortls",
"type": "string"
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.