python-betterproto icon indicating copy to clipboard operation
python-betterproto copied to clipboard

Dictionary representation improvement?

Open fundthmcalculus opened this issue 4 years ago • 0 comments

Is there a better way to represent this dictionary into a Struct()? (Currently using 2.0.0b3)

capability_dict = {"@context": "https://w3id.org/security/v2",
			  "target": "urn:trinsic:wallets:noop",
			  "proof": {
				  "created": datetime.datetime.now()
			  }
			  }

The following does work, but seems pretty kludgy:

proof = Struct()
proof.fields["created"] = Value(string_value=str(datetime.datetime.now()))
capability = Struct()
capability.fields["@context"] = Value(string_value="https://w3id.org/security/v2")
capability.fields["target"] = Value(string_value="urn:trinsic:wallets:noop")
capability.fields["proof"] = Value(struct_value=proof)
  • It seems to me that we could/should at least have a Struct.from_dictionary(obj: dict) method. I'd be happy to write this if it doesn't exist.
  • Struct.from_dict() does NOT work for this, tested.

Example code of what I'm thinking:

def value_to_proto_value(obj: Any) -> Value:
    value = Value()
    if isinstance(obj, str) or isinstance(obj, datetime.datetime):
        value = Value(string_value=str(obj))
    elif isinstance(obj, int) or isinstance(obj, float):
        value = Value(number_value=float(obj))
    elif isinstance(obj, bool):
        value = Value(bool_value=obj)
    elif isinstance(obj, dict):
        value = Value(struct_value=dictionary_to_struct(obj))
    elif isinstance(obj, list):
        value = Value(list_value=list_to_proto_list(obj))

    return value


def list_to_proto_list(obj: List) -> ListValue:
    return ListValue(values=[value_to_proto_value(item) for item in obj])


def dictionary_to_struct(obj: Dict[str, Any]) -> Struct:
    return Struct(fields=dict([(k, value_to_proto_value(v)) for k, v in obj.items()]))

fundthmcalculus avatar Jun 28 '21 17:06 fundthmcalculus