Why can't I find a single example of validating string input? #1738
Replies: 3 comments
-
|
Hi! You should be able to accomplish what you want quite easily with a parameter callback, see https://typer.tiangolo.com/tutorial/options/callback-and-context/#validate-cli-parameters (the example in the docs there is literally one around validating string input) |
Beta Was this translation helpful? Give feedback.
-
|
Pretty close, but I'm not seeing how that would help with a list of strings. If I can only attach one callback to the list then I'm ultimately still writing some enumeration out longhand--rejecting the entire list as invalid when in reality only a subset of elements in it might be bad--and I'd just assume have the brute force approach be blatantly obvious than hidden under some metaprogramming magic rocks. Disappointing, but it is what it is. |
Beta Was this translation helpful? Give feedback.
-
|
A parameter callback does give you per-element validation. The trick is that the callback receives the whole list, so you loop over it, collect the elements that fail, and raise import re
from typing import List
import typer
IPV4 = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$")
def valid_ip(s: str) -> bool:
m = IPV4.match(s)
return bool(m) and all(0 <= int(g) <= 255 for g in m.groups())
def validate_servers(value: List[str]) -> List[str]:
bad = [v for v in value if not valid_ip(v)]
if bad:
raise typer.BadParameter(f"not valid IPv4: {', '.join(bad)}")
return value
app = typer.Typer()
@app.command()
def main(server: List[str] = typer.Option(None, callback=validate_servers)):
typer.echo(f"ok: {server}")Run it with a couple of bad entries and you get a precise message, not a blanket rejection: The callback returns the validated list, so Two variations depending on what you actually want:
On the custom-type idea: you can write a Tested on Typer 0.26.8, Python 3.11. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
First Check
Commit to Help
Example Code
Description
I feel like I've been searching for this for way too long and should just go back to
argparseif it's really not a practical use case fortyper.I want to pass a list of strings to my tool.
I want to verify that those strings match against some arbitrary pattern--say IP addresses or email addresses or something else that absolutely cannot be represented by an enum.
If those strings do not match against my arbitrary pattern, I want to print some useful error text.
I see that I can define formatters for datetimes. I don't see an obvious means of applying that option to a list of strings or supplying it with a regex so it seems like a non-starter.
I see that I can define custom types and it's conceivable that I could design a class which takes a string in its construction and raises an exception if that string doesn't fit its expectations, but what exception would be appropriate? What should that look like for a list of those custom objects? Should my custom object actually be the list itself?
If I'm being stupid and missing something obvious please let me know as I feel like I've read the phrase "you'll learn more about validations later" over and over but never actually learned anything whatsoever.
Operating System
macOS
Operating System Details
No response
Typer Version
0.25.1
Python Version
3.13.2
Additional Context
No response
Beta Was this translation helpful? Give feedback.
All reactions