launchdarkly / python-server-sdk

LaunchDarkly Server-side SDK for Python
https://docs.launchdarkly.com/sdk/server-side/python
Other
38 stars 45 forks source link

I wish ContextBuilder would take a dict of attributes to set #243

Closed katylava closed 9 months ago

katylava commented 9 months ago

Is your feature request related to a problem? Please describe.

I wish ContextBuilder would take a dict of attributes to set. I have a dict of about 20 attributes, converted from an API response, and I don't want to write a .set() line for each attribute.

Describe the solution you'd like

Instead of:

context = Context.builder("context-key-123abc") \
    .set("firstName", "Sandy") \
    .set("lastName", "Smith") \
    .set("email", "sandy@example.com") \
    .set("groups", ["Google", "Microsoft"]) \
    .build()

I'd like to be able to:

pre_existing_dict = {
    'firstName': 'Sandy',
    'lastName': 'Smith',
    'email': 'sandy@example.com',
    'groups': ['Google', 'Microsoft'],
}

context = Context.builder("context-key-123abc") \
    .setMany(pre_existing_dict) \
    .build()

Describe alternatives you've considered

  1. Not using the builder... i.e. doing context = Context(kind='user', key='somekey', attributes=pre_existing_dict) -- I'm fine with this but it's not documented so is there some reason not to do this?
  2. Looping over the items in the dict and calling set in the loop -- unnecessary loop, do not like. Also, ugly.
  3. Hard-coding a .set() line for each attribute -- please, no.

Additional context

I'm not talking about setting kind, name, or anonymous this way. Only the custom attributes.

keelerm84 commented 9 months ago

Thank you for opening this issue. We do provide a method on Context to create the context directly from a dictionary. For your example, I think you could do:

pre_existing_dict = {
    'firstName': 'Sandy',
    'lastName': 'Smith',
    'email': 'sandy@example.com',
    'groups': ['Google', 'Microsoft'],
}
pre_existing_dict['key'] = 'context-key-123abc'

context = Context.from_dict(pre_existing_dict)

Is that an acceptable alternative?

katylava commented 9 months ago

Is that an acceptable alternative?

Yeah that works great! Is that preferred over context = Context(kind='user', key='somekey', attributes=pre_existing_dict)?

keelerm84 commented 9 months ago

Yes. You should avoid instantiating contexts directly and instead prefer our builder methods where available. There are some subtle differences between the two.

katylava commented 9 months ago

Thank you very much!

katylava commented 9 months ago

FWIW I had to set kind in addition to key. Otherwise I got [WARNING] - Context was invalid for flag evaluation (invalid data type for "kind"); returning default value