Add field descriptions to the config schema :)
This commit is contained in:
parent
2def2aece5
commit
3cb5db7528
6 changed files with 84 additions and 23 deletions
25
pdm.lock
25
pdm.lock
|
@ -5,7 +5,7 @@
|
|||
groups = ["default", "all", "dev"]
|
||||
strategy = ["cross_platform"]
|
||||
lock_version = "4.4.1"
|
||||
content_hash = "sha256:828f8051de2c2a04cede8130abf86764edb38f0428cd1d52dd797bff43452afe"
|
||||
content_hash = "sha256:17fdf74bf4b2980c66c106cebcb936921e671e8adaeb2f2e95d95f255704aa38"
|
||||
|
||||
[[package]]
|
||||
name = "aiocache"
|
||||
|
@ -80,6 +80,19 @@ files = [
|
|||
{file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "class-doc"
|
||||
version = "0.2.6"
|
||||
requires_python = ">=3.6,<4.0"
|
||||
summary = "Extract attributes docstrings defined in various ways"
|
||||
dependencies = [
|
||||
"more-itertools>=5.0.0",
|
||||
]
|
||||
files = [
|
||||
{file = "class-doc-0.2.6.tar.gz", hash = "sha256:f5e036ed9b7f6de528affdd9f038851910b342d4c1c1252983a55ff080b530e0"},
|
||||
{file = "class_doc-0.2.6-py3-none-any.whl", hash = "sha256:e6f2cea2dfbe93f76dee25de13d70dc0d2269698e8b849f751d98dc894c52ea5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.7"
|
||||
|
@ -90,6 +103,16 @@ files = [
|
|||
{file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "more-itertools"
|
||||
version = "10.3.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "More routines for operating on iterables, beyond itertools"
|
||||
files = [
|
||||
{file = "more-itertools-10.3.0.tar.gz", hash = "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463"},
|
||||
{file = "more_itertools-10.3.0-py3-none-any.whl", hash = "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multidict"
|
||||
version = "6.0.5"
|
||||
|
|
|
@ -44,30 +44,10 @@ Issues = "https://git.00dani.me/00dani/mpd-now-playable/issues"
|
|||
[project.scripts]
|
||||
mpd-now-playable = 'mpd_now_playable.cli:main'
|
||||
|
||||
[tool.pdm.scripts]
|
||||
start = {call = 'mpd_now_playable.cli:main'}
|
||||
lint = 'ruff check src/mpd_now_playable'
|
||||
typecheck = 'mypy -p mpd_now_playable'
|
||||
check = {composite = ['lint', 'typecheck'], keep_going = true}
|
||||
|
||||
[tool.pdm.version]
|
||||
source = "scm"
|
||||
write_to = 'mpd_now_playable/__version__.py'
|
||||
write_template = "__version__ = '{}'"
|
||||
|
||||
[build-system]
|
||||
requires = ["pdm-backend"]
|
||||
build-backend = "pdm.backend"
|
||||
|
||||
[tool.pdm.build]
|
||||
excludes = ["**/.mypy_cache"]
|
||||
|
||||
[tool.pdm.dev-dependencies]
|
||||
dev = [
|
||||
"mypy>=1.7.1",
|
||||
"ruff>=0.1.6",
|
||||
]
|
||||
|
||||
[tool.mypy]
|
||||
mypy_path = 'stubs'
|
||||
|
||||
|
@ -101,3 +81,26 @@ mypy-init-return = true
|
|||
[tool.ruff.format]
|
||||
# I prefer tabs for accessibility reasons.
|
||||
indent-style = "tab"
|
||||
|
||||
[tool.pdm.scripts]
|
||||
start = {call = 'mpd_now_playable.cli:main'}
|
||||
lint = 'ruff check src/mpd_now_playable'
|
||||
typecheck = 'mypy -p mpd_now_playable'
|
||||
check = {composite = ['lint', 'typecheck'], keep_going = true}
|
||||
|
||||
[tool.pdm.version]
|
||||
source = "scm"
|
||||
write_to = 'mpd_now_playable/__version__.py'
|
||||
write_template = "__version__ = '{}'"
|
||||
|
||||
[tool.pdm.build]
|
||||
excludes = ["**/.mypy_cache"]
|
||||
|
||||
[tool.pdm.dev-dependencies]
|
||||
dev = [
|
||||
"mypy>=1.7.1",
|
||||
"ruff>=0.1.6",
|
||||
"class-doc>=0.2.6",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,12 @@
|
|||
"$ref": "#/definitions/URL"
|
||||
},
|
||||
"cache": {
|
||||
"$ref": "#/definitions/URL"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/URL"
|
||||
}
|
||||
],
|
||||
"description": "A URL describing a cache service for mpd-now-playable to use. Supported protocols are memory://, redis://, and memcached://."
|
||||
},
|
||||
"mpd": {
|
||||
"additionalProperties": false,
|
||||
|
@ -24,14 +29,17 @@
|
|||
"properties": {
|
||||
"host": {
|
||||
"default": "127.0.0.1",
|
||||
"description": "The hostname or IP address of your MPD server. If you're running MPD on your local machine, you don't need to configure this.",
|
||||
"format": "hostname",
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"description": "The password required to connect to your MPD instance, if you need one.",
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"default": 6600,
|
||||
"description": "The port on which to connect to MPD. Unless you're managing multiple MPD servers on one machine for some reason, you probably haven't changed this from the default port, 6600.",
|
||||
"maximum": 65535,
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
|
|
|
@ -11,8 +11,14 @@ __all__ = ("MpdConfig", "Config")
|
|||
|
||||
@dataclass(frozen=True)
|
||||
class MpdConfig:
|
||||
#: The password required to connect to your MPD instance, if you need one.
|
||||
password: Optional[str] = optional()
|
||||
#: The hostname or IP address of your MPD server. If you're running MPD
|
||||
#: on your local machine, you don't need to configure this.
|
||||
host: Host = Host("127.0.0.1")
|
||||
#: The port on which to connect to MPD. Unless you're managing multiple MPD
|
||||
#: servers on one machine for some reason, you probably haven't changed this
|
||||
#: from the default port, 6600.
|
||||
port: Port = Port(6600)
|
||||
|
||||
|
||||
|
@ -22,5 +28,8 @@ class Config:
|
|||
default=URL("https://cdn.00dani.me/m/schemata/mpd-now-playable/config-v1.json"),
|
||||
metadata=alias("$schema"),
|
||||
)
|
||||
|
||||
#: A URL describing a cache service for mpd-now-playable to use. Supported
|
||||
#: protocols are memory://, redis://, and memcached://.
|
||||
cache: Optional[URL] = optional()
|
||||
mpd: MpdConfig = field(default_factory=MpdConfig)
|
||||
|
|
|
@ -3,13 +3,30 @@ from pathlib import Path
|
|||
from pprint import pp
|
||||
from typing import Any, Mapping
|
||||
|
||||
from apischema import schema, settings
|
||||
from apischema.json_schema import JsonSchemaVersion, deserialization_schema
|
||||
from apischema.schemas import Schema
|
||||
from class_doc import extract_docs_from_cls_obj
|
||||
|
||||
from .model import Config
|
||||
|
||||
|
||||
def field_base_schema(tp: type, name: str, alias: str) -> Schema | None:
|
||||
desc_lines = extract_docs_from_cls_obj(tp).get(name, [])
|
||||
if desc_lines:
|
||||
print((tp, name, alias))
|
||||
return schema(description=" ".join(desc_lines))
|
||||
return None
|
||||
|
||||
|
||||
settings.base_schema.field = field_base_schema
|
||||
|
||||
|
||||
def generate() -> Mapping[str, Any]:
|
||||
return deserialization_schema(Config, version=JsonSchemaVersion.DRAFT_7)
|
||||
return deserialization_schema(
|
||||
Config,
|
||||
version=JsonSchemaVersion.DRAFT_7,
|
||||
)
|
||||
|
||||
|
||||
def write() -> None:
|
||||
|
|
1
stubs/class_doc/__init__.pyi
Normal file
1
stubs/class_doc/__init__.pyi
Normal file
|
@ -0,0 +1 @@
|
|||
def extract_docs_from_cls_obj(cls: type) -> dict[str, list[str]]: ...
|
Loading…
Reference in a new issue