Show HN: Valid8r, Functional validation for Python CLIs using Maybe monads
Show HN (score: 5)Description
The library uses Maybe monads (Success/Failure instead of exceptions) so you can chain parsers and validators:
# Try it: pip install valid8r
from valid8r.core import parsers, validators
# Parse and validate in one pipeline
result = (
parsers.parse_int(user_input)
.bind(validators.minimum(1))
.bind(validators.maximum(65535))
)
match result:
case Success(port): print(f"Using port {port}")
case Failure(error): print(f"Invalid: {error}")
I built integrations for argparse, Click, and Typer so you can drop valid8r parsers directly into your existing CLIs without refactoring everything.The interesting technical bit: it's 4-300x faster than Pydantic for simple parsing (ints, emails, UUIDs) because it doesn't build schemas or do runtime type checking. It just parses strings and returns Maybe[T]. For complex nested validation, Pydantic is still better. I benchmarked both and documented where each one wins.
I'm not trying to replace Pydantic. If you're building a FastAPI service, use Pydantic. But if you're building CLI tools or parsing network configs, Maybe monads compose really nicely and keep your code functional.
The docs are at https://valid8r.readthedocs.io/ and the benchmarks are in the repo. It's MIT licensed.
Would love feedback on the API design. Is the Maybe monad pattern too weird for Python, or does it make validation code cleaner?
---
Here are a few more examples showing different syntax options for the same port validation:
from valid8r.core import parsers, validators
# Option 1: Combine validators with & operator
validator = validators.minimum(1) & validators.maximum(65535)
result = parsers.parse_int(user_input).bind(validator)
# Option 2: Use parse_int_with_validation (built-in)
result = parsers.parse_int_with_validation(
user_input,
validators.minimum(1) & validators.maximum(65535)
)
# Option 3: Interactive prompting (keeps asking until valid)
from valid8r.prompt import ask
port = ask(
"Enter port number (1-65535): ",
parser=lambda s: parsers.parse_int(s).bind(
validators.minimum(1) & validators.maximum(65535)
)
)
# port is guaranteed valid here, no match needed
# Option 4: Create a reusable parser function
def parse_port(text):
return parsers.parse_int(text).bind(
validators.minimum(1) & validators.maximum(65535)
)
result = parse_port(user_input)
The & operator is probably the cleanest for combining validators. And the interactive prompt is nice because you don't need to match Success/Failure, it just keeps looping until the user gives you valid input.More from Show
Show HN: Swatchify – CLI to get a color palette from an image
Show HN: Swatchify – CLI to get a color palette from an image A fast, cross-platform CLI tool that extracts dominant colors from images using k-means clustering.
Show HN: Wozz – Agentless Kubernetes cost auditor (open source)
Show HN: Wozz – Agentless Kubernetes cost auditor (open source)
Show HN: Zephyr3D – TypeScript WebGPU/WebGL 3D engine with an in‑browser editor
Show HN: Zephyr3D – TypeScript WebGPU/WebGL 3D engine with an in‑browser editor Hi HN,<p>I’ve been working on Zephyr3D, an open-source 3D rendering engine for the modern web, plus a visual editor that runs entirely in the browser.<p>- Written in TypeScript - Supports WebGL/WebGL2/WebGPU - Comes with a visual editor that runs in the browser (no installation required)<p>With the recent updates, a few things might be interesting to people here:<p>Engine & rendering ------------------<p>- WebGL/WebGPU abstraction with a TypeScript API - PBR rendering - Cluster lighting & Shadow Maps - Clipmap-based terrain for large landscapes - Sky Atmosphere & Height-based fog - FFT water system - Temporal anti-aliasing (TAA) - Screen-space motion blur<p>The goal is to make it possible to build reasonably complex 3D experiences that run directly in the browser, without native dependencies.<p>In-browser editor -----------------<p>The editor is a web app built on top of the engine and runs completely in the browser. It currently supports:<p>- Project management - Scene editing - Node-based material blueprints - Animation editing - Script binding and a scheduling system - Prefabs for reusing entities across scenes - Preview and one-click publishing to the web<p>All project data is handled via a virtual file system (VFS) that can plug into different backends (in-memory, IndexedDB, HTTP, ZIP, DataTransfer, etc.), so saving/loading works entirely on the client side.<p>Links -----<p>Homepage: <a href="https://zephyr3d.org" rel="nofollow">https://zephyr3d.org</a> Editor (runs in the browser): <a href="https://zephyr3d.org/editor/" rel="nofollow">https://zephyr3d.org/editor/</a> GitHub: <a href="https://github.com/gavinyork/zephyr3d" rel="nofollow">https://github.com/gavinyork/zephyr3d</a><p>I'd love feedback on:<p>- How the in-browser editor workflow feels (performance, UX, what’s missing) - Whether the VFS approach for project data makes sense for real projects - Any red flags you see in the engine architecture or WebGPU/WebGL abstraction - What would be deal-breakers or must-have features for using this in games, data viz, or other interactive web experiences<p>I’ll be around to answer questions and can go into more detail about the rendering pipeline, the editor internals, or anything else you’re curious about.
Show HN: Parm – Install GitHub releases just like your favorite package manager
Show HN: Parm – Install GitHub releases just like your favorite package manager Hi all, I built a CLI tool that allows you to seamlessly install software from GitHub release assets, similar to how your system's package manager installs software.<p>It works by exploiting common patterns among GitHub releases across different open-source software such as naming conventions and file layouts to fetch proper release assets for your system and then downloading the proper asset onto your machine via the GitHub API. Parm will then extract the files, find the proper binaries, and then add them to your PATH. Parm can also check for updates and uninstall software, and otherwise manages the entire lifecycle of all software installed by Parm.<p>Parm is not meant to replace your system's package manager. It is instead meant as an alternative method to install prebuilt software off of GitHub in a more centralized and simpler way.<p>It's currently in a pre-release stage, and there's a lot of features I want to add. I'm currently working (very slowly) on some new features, so if this sounds interesting to you, check it out! It's completely free and open-source and is currently released for Linux/macOS. I would appreciate any feedback.<p>Link: <a href="https://github.com/yhoundz/parm" rel="nofollow">https://github.com/yhoundz/parm</a>
No other tools from this source yet.