Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@podhmo
Created January 18, 2020 11:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save podhmo/58ffa7ad0195cbbb06c2307bcdf6f6e7 to your computer and use it in GitHub Desktop.
Save podhmo/58ffa7ad0195cbbb06c2307bcdf6f6e7 to your computer and use it in GitHub Desktop.
import typing as t
import sys
import argparse
import json
def JSONDictType(
filename_or_content: str, *, prefix: str = "file://"
) -> t.Dict[str, t.Any]:
try:
if filename_or_content.startswith(prefix):
with open(filename_or_content[len(prefix) :]) as rf:
d: t.Dict[str, t.Any] = json.load(rf)
else:
d = json.loads(filename_or_content)
return d
except (ValueError, FileNotFoundError) as e:
raise argparse.ArgumentTypeError(str(e))
parser = argparse.ArgumentParser()
parser.add_argument("--config", type=JSONDictType)
args = parser.parse_args()
json.dump(args.config, sys.stdout, indent=2)
print("")
--- 01pydantic.py 2020-01-18 19:53:30.000000000 +0900
+++ 02pydantic-with-schema.py 2020-01-18 19:57:50.000000000 +0900
@@ -22,15 +22,21 @@
parser = argparse.ArgumentParser()
-parser.add_argument("--config", type=ConfigType)
-
+parser.add_argument("--config", type=ConfigType, required=False)
+parser.add_argument("--show-schema", action="store_true")
args = parser.parse_args()
-def use(config: Config) -> None:
- # ここでconfigがConfigと認識されるのは地味に便利
- # t.TYPE_CHECKING and reveal_type(config)
- print(args)
+if args.show_schema:
+ from pydantic.schema import schema
+
+ toplevel_schema = schema([Config])
+ print(json.dumps(toplevel_schema, indent=2, ensure_ascii=False))
+ parser.exit()
+
+
+def use(config: "Config") -> None:
+ print(config)
use(args.config)
import typing as t
import json
import argparse
from pydantic.error_wrappers import ValidationError
from config import Config
def ConfigType(filename_or_content: str, *, prefix: str = "file://") -> Config:
try:
if filename_or_content.startswith(prefix):
with open(filename_or_content[len(prefix) :]) as rf:
d = json.load(rf)
else:
d = json.loads(filename_or_content)
except (ValueError, FileNotFoundError) as e:
raise argparse.ArgumentTypeError(str(e))
try:
return Config(**d)
except ValidationError as e:
raise argparse.ArgumentTypeError(str(e))
parser = argparse.ArgumentParser()
parser.add_argument("--config", type=ConfigType)
args = parser.parse_args()
def use(config: Config) -> None:
# ここでconfigがConfigと認識されるのは地味に便利
# t.TYPE_CHECKING and reveal_type(config)
print(args)
use(args.config)
--- 02pydantic-with-schema.py 2020-01-18 19:57:50.000000000 +0900
+++ 03pydantic-with-schema.py 2020-01-18 20:06:29.000000000 +0900
@@ -1,11 +1,15 @@
import typing as t
import json
import argparse
-from pydantic.error_wrappers import ValidationError
-from config import Config
+if t.TYPE_CHECKING:
+ from config import Config
+
+
+def ConfigType(filename_or_content: str, *, prefix: str = "file://") -> "Config":
+ from pydantic.error_wrappers import ValidationError
+ from config import Config
-def ConfigType(filename_or_content: str, *, prefix: str = "file://") -> Config:
try:
if filename_or_content.startswith(prefix):
with open(filename_or_content[len(prefix) :]) as rf:
@@ -21,6 +25,14 @@
raise argparse.ArgumentTypeError(str(e))
+def show_schema() -> None:
+ from config import Config
+ from pydantic.schema import schema
+
+ toplevel_schema = schema([Config])
+ print(json.dumps(toplevel_schema, indent=2, ensure_ascii=False))
+
+
parser = argparse.ArgumentParser()
parser.add_argument("--config", type=ConfigType, required=False)
parser.add_argument("--show-schema", action="store_true")
@@ -28,10 +40,7 @@
if args.show_schema:
- from pydantic.schema import schema
-
- toplevel_schema = schema([Config])
- print(json.dumps(toplevel_schema, indent=2, ensure_ascii=False))
+ show_schema()
parser.exit()
import typing as t
import json
import argparse
from pydantic.error_wrappers import ValidationError
from config import Config
def ConfigType(filename_or_content: str, *, prefix: str = "file://") -> Config:
try:
if filename_or_content.startswith(prefix):
with open(filename_or_content[len(prefix) :]) as rf:
d = json.load(rf)
else:
d = json.loads(filename_or_content)
except (ValueError, FileNotFoundError) as e:
raise argparse.ArgumentTypeError(str(e))
try:
return Config(**d)
except ValidationError as e:
raise argparse.ArgumentTypeError(str(e))
parser = argparse.ArgumentParser()
parser.add_argument("--config", type=ConfigType, required=False)
parser.add_argument("--show-schema", action="store_true")
args = parser.parse_args()
if args.show_schema:
from pydantic.schema import schema
toplevel_schema = schema([Config])
print(json.dumps(toplevel_schema, indent=2, ensure_ascii=False))
parser.exit()
def use(config: "Config") -> None:
print(config)
use(args.config)
import typing as t
import json
import argparse
if t.TYPE_CHECKING:
from config import Config
def ConfigType(filename_or_content: str, *, prefix: str = "file://") -> "Config":
from pydantic.error_wrappers import ValidationError
from config import Config
try:
if filename_or_content.startswith(prefix):
with open(filename_or_content[len(prefix) :]) as rf:
d = json.load(rf)
else:
d = json.loads(filename_or_content)
except (ValueError, FileNotFoundError) as e:
raise argparse.ArgumentTypeError(str(e))
try:
return Config(**d)
except ValidationError as e:
raise argparse.ArgumentTypeError(str(e))
def show_schema() -> None:
from config import Config
from pydantic.schema import schema
toplevel_schema = schema([Config])
print(json.dumps(toplevel_schema, indent=2, ensure_ascii=False))
parser = argparse.ArgumentParser()
parser.add_argument("--config", type=ConfigType, required=False)
parser.add_argument("--show-schema", action="store_true")
args = parser.parse_args()
if args.show_schema:
show_schema()
parser.exit()
def use(config: "Config") -> None:
print(config)
use(args.config)
{
"thirdparty": {
"xxx": {
"token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"zzz": {
"clientId": "xxxxxxxxxx",
"clientSecret": "xxxxxxxxxxxxxxxxxxxx"
}
}
}
{
"main": {
"db": "sqlite://:memory"
},
"thirdparty": {
"xxx": {
"token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"zzz": {
"clientId": "xxxxxxxxxx",
"clientSecret": "xxxxxxxxxxxxxxxxxxxx"
}
}
}
00:
python $(shell echo $@*.py) --config='{"main": {"db": "sqlite://:memory:"}}'
python $(shell echo $@*.py) --config=file://config.json
python $(shell echo $@*.py) --config=file://config-ng.json
python $(shell echo $@*.py) --config=file://missing.json
01:
python $(shell echo $@*.py) --config='{"main": {"db": "sqlite://:memory:"}}'
python $(shell echo $@*.py) --config=file://config.json
python $(shell echo $@*.py) --config=file://config-ng.json || exit 0
python $(shell echo $@*.py) --config=file://missing.json
02:
python $(shell echo $@*.py) --config=file://config.json
python $(shell echo $@*.py) --config='{"main": {"db": "sqlite://:memory:"}}'
python $(shell echo $@*.py) --config=file://config-ng.json || exit 0
python $(shell echo $@*.py) --config=file://missing.json || exit 0
python $(shell echo $@*.py) --show-schema
03:
python $(shell echo $@*.py) --config='{"main": {"db": "sqlite://:memory:"}}'
python $(shell echo $@*.py) --config=file://config.json
python $(shell echo $@*.py) --config=file://config-ng.json
diff:
diff -u 01*.py 02*.py > 0102.diff || exit 0
diff -u 02*.py 03*.py > 0203.diff || exit 0
.PHONY: diff
{
"definitions": {
"MainConfig": {
"title": "MainConfig",
"type": "object",
"properties": {
"db": {
"title": "Db",
"type": "string"
}
},
"required": [
"db"
]
},
"XXXConfig": {
"title": "XXXConfig",
"type": "object",
"properties": {
"token": {
"title": "Token",
"type": "string"
}
},
"required": [
"token"
]
},
"ZZZConfig": {
"title": "ZZZConfig",
"type": "object",
"properties": {
"clientId": {
"title": "Clientid",
"type": "string"
},
"clientSecret": {
"title": "Clientsecret",
"type": "string"
}
},
"required": [
"clientId",
"clientSecret"
]
},
"ThirdpartyConfig": {
"title": "ThirdpartyConfig",
"type": "object",
"properties": {
"xxx": {
"$ref": "#/definitions/XXXConfig"
},
"zzz": {
"$ref": "#/definitions/ZZZConfig"
}
},
"required": [
"xxx",
"zzz"
]
},
"Config": {
"title": "Config",
"type": "object",
"properties": {
"main": {
"$ref": "#/definitions/MainConfig"
},
"thirdparty": {
"$ref": "#/definitions/ThirdpartyConfig"
}
},
"required": [
"main"
]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment