{"id":49285163,"url":"https://github.com/ktav-lang/python","last_synced_at":"2026-04-25T21:06:50.256Z","repository":{"id":353511911,"uuid":"1219719945","full_name":"ktav-lang/python","owner":"ktav-lang","description":"Python bindings for Ktav — a plain configuration format with three rules, zero indentation, and zero quoting. PyO3 over the reference Rust crate, abi3 wheels, json-shaped API.","archived":false,"fork":false,"pushed_at":"2026-04-24T07:45:51.000Z","size":62,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-24T09:08:57.613Z","etag":null,"topics":["config","config-format","configuration","ktav","parser","pyo3","python"],"latest_commit_sha":null,"homepage":null,"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/ktav-lang.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-24T06:45:21.000Z","updated_at":"2026-04-24T07:55:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ktav-lang/python","commit_stats":null,"previous_names":["ktav-lang/python"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ktav-lang/python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fpython","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fpython/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fpython/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fpython/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ktav-lang","download_url":"https://codeload.github.com/ktav-lang/python/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktav-lang%2Fpython/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32276669,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["config","config-format","configuration","ktav","parser","pyo3","python"],"created_at":"2026-04-25T21:06:49.529Z","updated_at":"2026-04-25T21:06:50.248Z","avatar_url":"https://github.com/ktav-lang.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ktav (Python)\n\n\u003e Python bindings for [Ktav](https://github.com/ktav-lang/spec) — a plain\n\u003e configuration format. JSON-shape, no quotes, no commas, dotted keys.\n\u003e Powered by Rust under the hood.\n\n**Languages:** **English** · [Русский](README.ru.md) · [简体中文](README.zh.md)\n\n**Specification:** this package implements **Ktav 0.1**. The format is\nversioned and maintained independently of this package — see\n[`ktav-lang/spec`](https://github.com/ktav-lang/spec) for the formal\ndocument.\n\n---\n\n## Install\n\n```\npip install ktav\n```\n\nWheels are published for every major platform and every supported\nPython version:\n\n- **Linux** (manylinux + musllinux) — `x86_64`, `aarch64`\n- **macOS** — `x86_64`, `arm64` (Apple Silicon)\n- **Windows** — `x64`, `arm64`\n\nPython **3.9+** is required. The wheels target the stable ABI\n(`abi3-py39`), so a single wheel per platform serves every supported\nCPython release.\n\nIf no prebuilt wheel matches your platform, `pip` falls back to the\nsource distribution and compiles it locally — you need a Rust toolchain\n(`rustup`) and the Python development headers.\n\n## Quick start\n\n### Parse — read typed fields straight off the dict\n\n```python\nimport ktav\n\nsrc = \"\"\"\nservice: web\nport:i 8080\nratio:f 0.75\ntls: true\ntags: [\n    prod\n    eu-west-1\n]\ndb.host: primary.internal\ndb.timeout:i 30\n\"\"\"\n\ncfg = ktav.loads(src)\n\nservice: str = cfg[\"service\"]\nport:    int = cfg[\"port\"]\nratio: float = cfg[\"ratio\"]\ntls:    bool = cfg[\"tls\"]\ntags: list[str] = cfg[\"tags\"]\ndb_host:    str = cfg[\"db\"][\"host\"]\ndb_timeout: int = cfg[\"db\"][\"timeout\"]\n```\n\n### Walk — dispatch on the runtime type\n\n```python\nfor k, v in cfg.items():\n    if v is None:              kind = \"null\"\n    elif isinstance(v, bool):  kind = f\"bool={v}\"   # bool first — True is also an int!\n    elif isinstance(v, int):   kind = f\"int={v}\"\n    elif isinstance(v, float): kind = f\"float={v}\"\n    elif isinstance(v, str):   kind = f\"str={v!r}\"\n    elif isinstance(v, list):  kind = f\"array({len(v)})\"\n    elif isinstance(v, dict):  kind = f\"object({len(v)})\"\n    print(f\"{k} -\u003e {kind}\")\n```\n\n### Build \u0026 render — construct a document in code\n\n```python\ndoc = {\n    \"name\": \"frontend\",\n    \"port\": 8443,\n    \"tls\": True,\n    \"ratio\": 0.95,\n    \"upstreams\": [\n        {\"host\": \"a.example\", \"port\": 1080},\n        {\"host\": \"b.example\", \"port\": 1080},\n    ],\n    \"notes\": None,\n}\ntext = ktav.dumps(doc)\n# name: frontend\n# port:i 8443\n# tls: true\n# ratio:f 0.95\n# upstreams: [\n#     { host: a.example  port:i 1080 }\n#     { host: b.example  port:i 1080 }\n# ]\n# notes: null\n```\n\nA complete runnable version lives in [`examples/basic.py`](examples/basic.py).\n\nFour entry points mirror the standard library `json` module:\n\n| Function              | Purpose                                      |\n|-----------------------|----------------------------------------------|\n| `ktav.loads(s)`       | Parse a Ktav string (or UTF-8 `bytes`).      |\n| `ktav.dumps(obj)`     | Serialise a native Python value.             |\n| `ktav.load(fp)`       | Parse from a file-like object.               |\n| `ktav.dump(obj, fp)`  | Serialise to a file-like object.             |\n\n`load` / `dump` accept both text-mode and binary-mode files.\n\n## Type mapping\n\n| Ktav                 | Python   |\n|----------------------|----------|\n| `null`               | `None`   |\n| `true` / `false`     | `bool`   |\n| `:i \u003cdigits\u003e`        | `int`    |\n| `:f \u003cnumber\u003e`        | `float`  |\n| bare scalar          | `str`    |\n| `[ ... ]`            | `list`   |\n| `{ ... }`            | `dict`   |\n\nKtav keeps **\"no magic types\"** — a bare `port: 8080` stays a string at\nthe parser level. Use the typed markers `:i` / `:f` when you want\nnumbers, or type-coerce at the application layer.\n\n`dict` preserves insertion order (Python 3.7+ guarantee), matching the\nordered-object semantics of Ktav.\n\nSerialisation is the inverse:\n\n- Python `int` → `:i` marker (including arbitrary-precision bigints).\n- Python `float` → `:f` marker (decimal point always present;\n  `NaN` / `±Infinity` are rejected — Ktav 0.1.0 does not represent them).\n- Python `tuple` is accepted as an array, for symmetry with `list`.\n- Non-`str` keys in a `dict` raise `KtavEncodeError`.\n\n## Errors\n\n```python\nimport ktav\n\ntry:\n    ktav.loads(\"x: [\")\nexcept ktav.KtavDecodeError as e:\n    print(\"decode:\", e)\n\ntry:\n    ktav.dumps({\"v\": float(\"nan\")})\nexcept ktav.KtavEncodeError as e:\n    print(\"encode:\", e)\n\n# Catching the base class catches either.\ntry:\n    ktav.loads(\"a: 1\\na: 2\")\nexcept ktav.KtavError:\n    ...\n```\n\n| Exception           | Raised by   | Base                |\n|---------------------|-------------|---------------------|\n| `KtavError`         | (base)      | `Exception`         |\n| `KtavDecodeError`   | `loads` / `load` | `KtavError`    |\n| `KtavEncodeError`   | `dumps` / `dump` | `KtavError`    |\n\n## Philosophy\n\nKtav is intentionally small. Its five design principles\n(from [`spec/CONTRIBUTING.md`](https://github.com/ktav-lang/spec/blob/main/CONTRIBUTING.md)):\n\n1. **Locality** — a line's meaning does not depend on another line.\n2. **One sentence** — any new rule fits in one sentence of the spec.\n3. **No whitespace sensitivity** (line breaks aside).\n4. **No magic types** — the format never decides `\"8080\"` means a number.\n5. **Explicit over clever** — `::` is verbose on purpose.\n\nThe Python bindings honour this: they add no schema inference, no\nauto-casting, no defaulting. If you want typing, you do it at the\nboundary with your own tool — `pydantic`, `dataclasses`, `attrs` —\nagainst the native Python structures this library returns.\n\n## Related projects\n\n- [`ktav-lang/spec`](https://github.com/ktav-lang/spec) — canonical\n  format specification and language-agnostic conformance test suite.\n- [`ktav-lang/rust`](https://github.com/ktav-lang/rust) — reference Rust\n  implementation. These Python bindings are a thin PyO3 wrapper around\n  that crate.\n\n## Versioning\n\nThis package follows [Semantic Versioning](https://semver.org/) with the\npre-1.0 convention that a MINOR bump is breaking. The package version\nand the `ktav` crate version move together. `ktav.__spec_version__`\nreports the Ktav format version this binding supports.\n\n## Development\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, test layout,\nand the contribution workflow.\n\n## Support the project\n\nThe author has many ideas that could be broadly useful to IT worldwide —\nnot limited to Ktav. Realizing them requires funding. If you'd like to\nhelp, please reach out at **phpcraftdream@gmail.com**.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktav-lang%2Fpython","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fktav-lang%2Fpython","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktav-lang%2Fpython/lists"}