-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable dot notation in parameter expressions #44
Comments
I am not entirely sure , but shouldn't using fstrings fix that? |
The requirement is slightly different as you won't have a reference to the parameters in the annotation. Let's say you create a container as follows: import wireup
container = wireup.create_container(
parameters={
"mailer": {"from": {"name": "foo", "email": "[email protected]"}}
},
) Currently, a service that only wants the "from email" will have to request "mailer" and extract the info it needs from it which is not optimal as it depends on more things than is necessary. It's fixable using a factory but is more code to write. class SomeService:
def __init__(self, mailer: ...):
self.from = mailer["from"]["email"] This makes it so that for configs with nested structures (anything that supports Ideally this should work for objects as well (say, mailer is a pydantic object) but it's not strictly necessary for now. |
Thanks for the explanation! Just to confirm , we want to add functionality so that nested dictionaries that are extracted from any object using functions like get_item() on the object , should allow for dot notation right? One way could be to create a new class called DotDict which inherits from dictionaries and use it whenever a __get_item() returns a dictionary ? For example: class DotDict(dict):
"""Dictionary with dot notation access."""
def __getattr__(self, attr):
return self.get(attr) and then for any get_item() function in any container or some class # or anything like a container class
class container:
# some code of the class
def __getitem__(self):
# do something and store the dict in originalDict
return DotDict(originalDict) Would this not work? |
It's even simpler than that. What we want to do is for expressions only to split the requested parameter name on the dots and retrieve the value from the dict by traversing it. So in the example above "mailer" expr returns the entire param. Whereas mailer.from.email returns [email protected]. In the parameterbag class there is the interpolate function which resolves string expressions. This doesn't affect the container itself just the parameterbag which is responsible for resolving parameter values. https://github.com/maldoinc/wireup/blob/master/wireup/ioc/parameter.py#L87 |
I'm sorry , but I am slightly confused about the exact expectations . Could you please give an actual example by creating an actual object/dict called I am unable to understand the link between Apologies if this question seems too basic. I just want to ensure I grasp the concept correctly. Thanks! |
So the container has several parts, the parameter bag in this case is responsible for providing it with parameter values. When the container encounters something like Inject(param=x) or Inject(expr=x), it will call the get method parameter bag with the value x, eg: self.params.get(x). The get method's only parameter is either a string which is when we request a param by name, or a templated string which is used for expressions. Once that value is returned the parameterbag's job is done. The issue here is about changing how the container deals with templated strings. All calls of Inject(expr=x) are translated to ParameterBag.get(TemplatedString(x)). Referring to the above container example with the mailer param. "mailer": {"from": {"name": "foo", "email": "[email protected]"}} ParameterBag.get(TemplatedString(x)) should result in the entire dict value being injected. However if the template contains dots then we should traverse the dict's value and fetch the value of that key.
Right now the container will only look for parameters in the keys, the change is about it being able to navigate the values and inject specific parts of it denoted with this dot syntax you're already familiar. |
Hi, are you still interested in working on this? It's a lot easier than it sounds and entirely isolated in one function of the parameter bag. Let me know if the above helped. |
For cases where parameters are nested it should be possible to do
Inject(expr="${foo.bar.baz}")
to inject a value.The text was updated successfully, but these errors were encountered: