Skip to main content

A cute, declarative config language with fail-fast behavior and optional type safety.

Project description

・゚ Yumly ・゚

⚠️ Warning — subject to changes.

Yumly is a cute, declarative configuration language with fail-fast behavior and optional type safety, blending elements from many configuration formats and some ideas from my head. The goal is a simple, secure and a personal configuration format that i can use in my projects..

The parser is written in Nim and exports bindings for Python via NimPy. There's also a native Nim API for direct usage.


✿ What's in Yumly?

  • No indentation — blocks delimited by { } allowing flexible organization
  • Optional type hints — you can declare intent UwU
  • Fail-fast — syntax and validation errors are raised immediately with cute cute messages (you can disable this, baka!)
  • No overwriting — duplicate keys and bindings are not allowed.
  • Native env vars$["VAR"] and include { ".env" } are first class ;)
  • Readable — it's easy to read and understand ^_^
  • Extensions .yumly and .yuy (it's so cute!!)

Why i created Yumly
  1. I created Yumly for fun — I had never built a parser before. I wanted something simple and special to use in my own projects.
  2. Yumly mixes ideas from many formats, but initially YAML and JSON, but tries to be more explicit, safe.
  3. I know the “cuteness” and personality won’t be for everyone — and that’s okay.
  4. I also wanted to learn Nim and avoid going down the “Holy C” path.

✿ Syntax

Comments
;> this is a comment <;

;>
multiline
comment
<;
Key-value pairs
;> type hints are optional <;
name ;string = "Yumly"
version ;string = "1.0.0"
debug ;bool = true
port ;int = 8080
ratio ;float = 3.14

;> without type hint, type is inferred from value <;
active = true
count = 42
Blocks
(app) {
    name ;string = "Yumly",
    version ;string = "1.0.0",
    debug ;bool = false
}

Blocks can be nested:

(database) {
    (postgres) {
        host = "localhost",
        port ;int = 5432
    },
    (redis) {
        host = "127.0.0.1",
        port = 6379
    }
}
Environment variables
token ;env = $["DISCORD_TOKEN"]
home  ;env = $["HOME"]
Include
include { ".env" }           ;> loads environment variables <;
include { "base.yumly" }     ;> imports blocks from another file <;
include { "shared.yuy" }     ;> also accepts .yuy or .yumly <;
Strings and Escapes
newline = "Line 1\nLine 2"
tab = "Column 1\tColumn 2"
backslash = "C:\\Path\\Windows"
quotes = "He said: \"Hello!\""
Lists and Tuples

Lists — homogeneous, all items of the same type:

tags    ;list[string] = ["api", "v2", "stable"]
ports   ;list[int]    = [8080, 8081, 8082]

;> without type hint, inferred from elements <;
hosts = ["localhost", "0.0.0.0"]

Valid types: string, int, float, bool, env.

Tuples — heterogeneous, different types:

server_info ;tuple = ["localhost", 8080, true]

;> automatically inferred if types are mixed <;
meta = ["staging", 42, false]
Comma rules

Inside blocks, commas separate pairs and sub-blocks. The last item doesn't need a comma:

(block) {
    a = "x",
    b = "y",
    c = "z"    ;> last, no comma <;
}

At root, pairs on the same line need a comma:

name = "John", age = 30
job = "dev"

Complete example

include { ".env" }

(global) {
    project ;string = "Cid",
    version ;string = "6.0.0",
    description ;string = """
    The Cid project is a revolutionary platform that will change the world!
    Currently in version 6.0.0!
    """,
    production ;bool = true,
    tags ;list[string] = ["cloud", "scalable"]
}

(database) {
    host = "localhost",
    port ;int = 6767,
    password ;env = $["DB_PASSWORD"]
}

(services) {
    (api) {
        port = 8080,
        tls ;bool = true,
        endpoints ;list[string] = ["/auth", "/v1/data"]
    }
}

✿ Available types

Type hint Example
;string name ;string = "Yumly"
;int port ;int = 8080
;float ratio ;float = 3.14
;bool debug ;bool = true
;env token ;env = $["TOKEN"]
;list[T] tags ;list[string] = ["a", "b"]
;tuple info ;tuple = ["host", 6767, true]

✿ Python

✦ Installation

pip install yumly
Install from source (unstable/git version)
git clone https://github.com/Creeper011/Yumly
cd Yumly/
make deps   # install Nim dependencies
pip install .

✦ Usage

from yumly import Yumly
from typing import Any

PORT = 6767

yumly = Yumly()

data: dict[str, Any] = yumly.load("config.yumly")
print(data["global"]["project"])
print(data["database"]["port"])

data_to_write: dict[str, str] = {
    "port": PORT,
    "uri": "127.0.0.1", 
}
with open("config2.yumly", "w") as file:
    yumly.dump(data_to_write, file)

# or:
content: str = yumly.dumps(data_to_write)
print(content)

result: bool = yumly.validate_content(content)
print(f"Content validation result: {result}")

file_result: bool = yumly.validate_file("config2.yumly")
print(f"File validation result: {file_result}")

✿ Nim

✦ Installation

git clone https://github.com/Creeper011/Yumly
cd Yumly/
nimble install --path:.

✦ Basic usage

import Yumly

let config = loadYumly("config.yumly")

echo config["global"]["project"].getStr()
echo config.getBlock("database")["port"].getInt()
Iteration
for blk in config:
    echo blk.name
    for key, val in blk:
        echo key & " = " & val.getStr()
Mapping to objects with the to macro
type
    App = object
        project: string
        version: string
        production: bool

let app = config.getBlock("global").to(App)
echo app.project   # "Orion"
File writing
var cfg = newYumly()
cfg.addPair("name", newStringValue("Orion"), "string")

var db = newBlock("database")
db.addPair("host", newStringValue("localhost"))
db.addPair("port", newIntValue(5432), "int")
cfg.addBlock(db)

cfg.writeYumly("output.yumly")

✿ CLI

yumly_cli check config.yumly
yumly_cli load config.yumly

✿ VSCode Extension

cd yumly-vscode
npx --yes @vscode/vsce package
code --install-extension yumly.vsix

✿ Tests

python tests/run_tests.py
nim c -r tests/test_encoder.nim

✿ About Projects (Tests)

  • Yumly has a set of PoC (Proof of Concepts) projects that aim to test yumly implementations in a more integrated real-world scenario; they can be found in tests/projects.

✿ Limitations:

  • hahaha, i made sure to leave this down here.
  • The current limitations are:
    • Yumly is not streamable by my clean/modular dumb architecture and by design, as it needs all context to resolve includes, blocks and pairs. This means that the entire file needs to be loaded and parsed before any data can be accessed.

★ License ★

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yumly-0.8.2.tar.gz (4.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

yumly-0.8.2-py3-none-win_amd64.whl (240.5 kB view details)

Uploaded Python 3Windows x86-64

yumly-0.8.2-py3-none-manylinux_2_28_x86_64.whl (185.1 kB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

yumly-0.8.2-py3-none-macosx_11_0_arm64.whl (141.0 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file yumly-0.8.2.tar.gz.

File metadata

  • Download URL: yumly-0.8.2.tar.gz
  • Upload date:
  • Size: 4.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yumly-0.8.2.tar.gz
Algorithm Hash digest
SHA256 b07c38636092ebb86c5c47e37beaa172f9e43b5e92bbdfc4219aa5a91eeff112
MD5 ae2f33a31cd0714daf7999ebb1021c8a
BLAKE2b-256 447b23087403504f8149567829b4b18a13e756552bfc26d9e892e8ddb1d7b378

See more details on using hashes here.

File details

Details for the file yumly-0.8.2-py3-none-win_amd64.whl.

File metadata

  • Download URL: yumly-0.8.2-py3-none-win_amd64.whl
  • Upload date:
  • Size: 240.5 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yumly-0.8.2-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 7c675a232263b4c7e09f8d31ff691dd4282fff48de77505b7fe7c59e7c93c2a1
MD5 4e213b0188eea0c4e182ccda73c92e2b
BLAKE2b-256 7740979eeb242e9c28797449936d72af9dcaeba8b09230304e54645c8de4af84

See more details on using hashes here.

File details

Details for the file yumly-0.8.2-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for yumly-0.8.2-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 90e4ac0c6d7d70bef21f0d8c3677bad5ba0cdb245081b586c6fff8d233f6e264
MD5 f03c7d9cbfd204f98a644e71590d2de6
BLAKE2b-256 a5b0f8ea27842b651691c1ae7662943faf3b59e37473a781071ace1a7fec5a0e

See more details on using hashes here.

File details

Details for the file yumly-0.8.2-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: yumly-0.8.2-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 141.0 kB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yumly-0.8.2-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c1438a799c1ee952cf8edacab240edb1e093e726482f1f6d302c4d403e1b8cbb
MD5 f771f4460580e3fb2c65ffcd9cd5c375
BLAKE2b-256 df5dba74e513eb353e538081c4e1bb348eff7280d0121d9f140060b65bcc574c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page