Open azmeuk opened 2 months ago
I'm afraid we're reaching the limit of what the library can do. I think the syntax you're proposing adds complexity for a relatively narrow use case (as soon as the list grows, you're better off using JSON or another approach anyway). Maybe you have some real-world use case you can share so I can think of alternative approaches?
My use-case is that I am considering to use pydanclick in scim2-cli. In short, scim2-cli just takes input from the users, build HTTP payload and send them to a given server. I handles common objects defined by the SCIM RFCs (in particular RFC7643), such as User or Group.
In particular, User.emails is a list of Email objects. I would love a way to create an user with several email addresses with something simpler than:
scim create user --user-name "foobar" --emails '[{"value":"foo@bar.example", "primary": true}, {"value": "foo@baz.example"}]'
However, I understand the difficulty here.
I just thought of another syntax. I think this is the neatest I can think of:
scim create user --user-name "foobar" \
--emails --emails-value "foo@bar.example" --primary "true" \
--emails --emails-value "foo@baz.example"
Here --emails
would just mark the creation of a new Email
object, filled by the following --emails-*
parameters, until a new --emails
is met.
If something like this is ok with you, I would volunteer for working on it. What do you think?
I've drafted a solution to your problem here: #26
It can quickly become complex when you start nesting models, or using list of unions, or deeply nested lists, but I'm confident we'll be able to support basic use cases. Not sure how much time I'll have to work on it until next week end, though.
@felix-martel I just had a quick look at your patch. This works for regular fields but it stops working if a field is optional:
import click
from typing import Optional
from pydantic import BaseModel
from pydanclick import from_pydantic
class Author(BaseModel):
name: str
primary: bool = False
class Book(BaseModel):
title: str
authors: Optional[list[Author]]
@click.command()
@from_pydantic(Book, unpack_list=True)
def cli(book: Book):
pass
if __name__ == "__main__":
cli()
I am well aware that this is a difficult question, but I would love if there could be a clean API for lists of sub-models instead of having to pass JSON.
With such models I can think of two possible ways to handle this:
--subs-foo=foo0 --subs-bar=bar0 --subs-foo=foo1
--subs-0-foo=foo0 --subs-0-bar=bar0 --subs-1-foo=foo1
. However I am not even sure click will allows this.What do you think?