Python dictionary with base content - python

I am looking for the "good pythonic" way to define a dictionary with base elements. Let me explain:
I have a serie of key:value that configure my system. A group of key:value represent a configuration. Each configuration must have several common base elements. On the other hand each configuration has the possibility to define extra elements.
I could use python dictionaries but I do not think that could enforce the user to define "Mandatory_Elt_1" & "Mandatory_Elt_2" (or is it?):
Config_1 = { 'Mandatory_Elt_1':1,
'Mandatory_Elt_2':2,
'Optional_Elt_3':3 }
Config_2 = { 'Mandatory_Elt_1':5,
'Mandatory_Elt_2':6,
'Optional_Elt_4':7 }
A second option would be to subclass dict and define a specific constructor method where I would require the mandatory elements:
Config = MyDict( { 'Mandatory_Elt_1':5,
'Mandatory_Elt_2':6,
'Optional_Elt_4':7 } )
A third possibility would be to review the "input interface" such that other coders would not directly touch the base data. Instead, they would need to pass through a sanitization API. Or should I move to a databse based system altogether?
Are there any other alternatives? What would be the "lowest friction" way to force some elements to be defined in a dictionary?

If you need some mandatory elements in final dictionary,
you may use a basic dictionary and then update it with the user's dictionary.
E.g.
base_config = {'m1':1, 'm2': 2}
user_config = {'m1':3, 'new_param':4}
base_config.update(user_config)
final_config = base_config
>>> print final_config
{'new_param': 4, 'm1': 3, 'm2': 2}

Related

Create Flask endpoint using a Loop

I want to create multiple Flask endpoints I read from my Config. Is it possible to make a for or while loop to create them? The Endpoints Address would be variable, but there would be no limit on how many I would need.
My Idea was:
for x in myList:
#app.route(var, ...)
def route():
do smt ...
Thanks for your help
You can use
app.add_url_rule(rule, endpoint=None, view_func=None, provide_automatic_options=None, **options)
to achieve this.
For example:
for endpoint in endpoint_list:
app.add_url_rule(endpoint['route'], view_func=endpoint['view_func'])
Check out the docs.
Note that the endpoint_list contains records of endpoints. It should be a list of dictionaries, for example:
endpoint_list = [
{
"route": "/",
"view_func": index
},
.....
]
Avoid using "list" as the variable name. It would override Python's default list function.

Using google.protobuf.Any in python file

I have such .proto file
syntax = "proto3";
import "google/protobuf/any.proto";
message Request {
google.protobuf.Any request_parameters = 1;
}
How can I create Request object and populate its fields? I tried this:
import ma_pb2
from google.protobuf.any_pb2 import Any
parameters = {"a": 1, "b": 2}
Request = ma_pb2.Request()
some_any = Any()
some_any.CopyFrom(parameters)
Request.request_parameters = some_any
But I have an error:
TypeError: Parameter to CopyFrom() must be instance of same class: expected google.protobuf.Any got dict.
UPDATE
Following prompts of #Kevin I added new message to .proto file:
message Small {
string a = 1;
}
Now code looks like this:
Request = ma_pb2.Request()
small = ma_pb2.Small()
small.a = "1"
some_any = Any()
some_any.Pack(small)
Request.request_parameters = small
But at the last assignment I have an error:
Request.request_parameters = small
AttributeError: Assignment not allowed to field "request_parameters" in protocol message object.
What did I do wrong?
Any is not a magic box for storing arbitrary keys and values. The purpose of Any is to denote "any" message type, in cases where you might not know which message you want to use until runtime. But at runtime, you still need to have some specific message in mind. You can then use the .Pack() and .Unpack() methods to convert that message into an Any, and at that point you would do something like Request.request_parameters.CopyFrom(some_any).
So, if you want to store this specific dictionary:
{"a": 1, "b": 2}
...you'll need a .proto file which describes some message type that has integer fields named a and b. Personally, I'd see that as overkill; just throw your a and b fields directly into the Request message, unless you have a good reason for separating them out. If you "forget" one of these keys, you can always add it later, so don't worry too much about completeness.
If you really want a "magic box for storing arbitrary keys and values" rather than what I described above, you could use a Map instead of Any. This has the advantage of not requiring you to declare all of your keys upfront, in cases where the set of keys might include arbitrary strings (for example, HTTP headers). It has the disadvantage of being harder to lint or type-check (especially in statically-typed languages), because you can misspell a string more easily than an attribute. As shown in the linked resource, Maps are basically syntactic sugar for a repeated field like the following (that is, the on-wire representation is exactly the same as what you'd get from doing this, so it's backwards compatible to clients which don't support Maps):
message MapFieldEntry {
key_type key = 1;
value_type value = 2;
}
repeated MapFieldEntry map_field = N;

ConfigObj 'un-nest' sections

I'm using ConfigObj 5.0.6 to hold many user-defined values, some of which are nested. I use a local.ini to supercede typical values. There is no front-end, so users edit the configs as needed. To make that easier and more intuitive, there are some values that belong at the 'root' level of the config object, but are more easily understood below a nested section of the local.ini file.
I'm using a local.ini to supercede defaults. The flow of the app suggests a config layout that would have non-nested values below nested values.
# un-nested
title = my_title
# nested
[section_1]
val_s1 = val
[section_2]
val_s2 = val
# nested, but I want to be un-nested
val_2 = val
This layout, as expected, puts val_2 under section_2:
{
'title': 'my_title',
{'section_1': {'val_s1': 'val'}},
{'section_2': {'val_s2': 'val'},
{'val_2': 'val'}}
}
Is it possible to define val_2 on a line below section_2, but access it under the 'main' section of the config object?
I would like to end up with a config object like this:
{
'title': 'my_title',
{'section_1': {'val_s1': 'val'}},
{'section_2': {'val_s2': 'val'}},
'val_2': 'val'
}
The order of the config dictionary isn't important, of course; what I'm interested in is being able to use nested sections, but from within the .ini, exit a section into its parent.
I haven't tested, but suspect nesting everything from the first line onward and then slicing the config object would work. I.e., write local.ini such that it creates:
{
'main_level':
{
'title': 'my_title',
{'section_1': {'val_s1': 'val'}},
{'section_2': {'val_s2': 'val'}},
'val_2': 'val'
}
}
Then I could use config = config['main_level'] when I first instantiate the config object, but I'm wondering if I'm just missing some easy, correct way that isn't a hack.
According to the documentation, that is not possible:
In the outer section, single values can only appear before any sub-section.

Iterate through nested dict in django template

I found some solutions to iterate through dict in django templates (such as How to iterate over nested dictionaries in django templates) but it's always for a defined depth.
For instance, if I have this dict :
{'a':{'b':'c',
'd':'e',
'f':'g',
'h':{'i':'j',
'k':'l',
'm':'n'
}
}
'o':'p'
}
But I can also have :
{'a':{'b':{'c':{'d':'e',
'f':'g'
}
}
}
}
Is there another way than the recursive one to do this ? If not, is it possible to do recursion in django templates ?
The only way to do this I think is to create custom filters such as get_sons and has_son and work with it. Is it the good way to do this ?
Additional informations :
I have the structure stored in a model such as :
class XMLStructure(Model.models):
node_name = models.CharField()
parent = models.ForeignKey('XMLStructure')
#staticmethod
def get_root(self):
# return the root of the structure
def has_children(self):
# return true / false if it's a leaf
#staticmethod
def get_leaves(self):
# return all leaves of my xml
and a function build who generate the xml structure as a dict.
I tried to use code from Django Snippets but I cannot make them work (Always got an RuntimeError: maximum recursion depth exceeded while calling a Python object)
I though it would be easier to transform my dict into a list. My first dict would be :
dict_as_list = ['a','/','b','d','f','h','/','i','k','m','\','\','o','\']
and then store the values into a dict. As you can see, I'm pretty desperate.
Thanks

Redis key management

So im working with redis in a python app. any advice on key management? i try and keep all redis calls in one location but something seems off with hardcoding keys everywhere. tips?
I use a set of wrapper classes that handle key generation, something like:
public User Get(string username) {
return redis.Get("user:"+username);
}
I have an instance of each of these classes globally available, so just need to call
Server.Users.Get(username);
That's in .NET of course, but something similar should work in any language. An additional advantage of this approach over using a generic mapping tool is that it provides a good place to put things like connection sharing and indexing.
Well, key names are comparable to classes and attributes in your application, so some degree of 'repetition' will happen.
However, if you find you're repeating a lot of code to actually build your keys, then you might want to look at a mapper. In Python there's Redisco.
Or if you need something simpler, in Ruby there's Nest (porting it to Python should be trivial). It allows you to DRY up your references to keys:
users = Nest.new("User")
user = users[1]
# => "User:1"
user[:name]
# => "User:1:name"
redis.set(user[:name], "Foo")
# or even:
user[:name].set("Foo")
user[:name].get
# => "Foo"

Categories

Resources