Skip to content

The object_hook param of load/loads Does Not Provide Support For MultiDict #154

Closed

Description

@RGAlexander216

rapidjson-lack-of-MultiDict-suport
I have a very large site that I pull data from that uses repeated keys. The native json (what is used for transforming website responses by requests), still provides the object_pairs_hook, however this is not supported by python-rapidjson.

Activity

  1. lelit commented on Jun 8, 2021

    @lelit
    Contributor

    Can you upload here a sample of the incoming stream?

  2. RGAlexander216 commented on Jun 8, 2021

    @RGAlexander216
    Author

    I can provide a way that you can recreate it, but those two cells in the jupyter notebook are the output from the same request. I was able to replicate the lower cell's output and still use rapidjson via a lambda function, but I haven't dug into the source code yet to see what to modify to submit a pull.

    So that said, what's easiest for you? You'll need requests and Werkzeug to test it.

  3. lelit commented on Jun 9, 2021

    @lelit
    Contributor

    So that said, what's easiest for you? You'll need requests and Werkzeug to test it.

    Whatever helps to replicate the problem, as in this kind of problems, "an image is worth a thousand words" does not hold 😉

  4. lelit commented on Jun 9, 2021

    @lelit
    Contributor

    This helped me to understand the object_pairs_hook functionality.
    I will try to implement it, as time permits.

  5. RGAlexander216 commented on Jun 9, 2021

    @RGAlexander216
    Author

    Do you still need my example?

  6. lelit commented on Jun 9, 2021

    @lelit
    Contributor

    No, thanks.

    Until I manage to implement that option, a better workaround is maybe using the Decoder.start_object() method...

  7. RGAlexander216 commented on Jun 9, 2021

    @RGAlexander216
    Author

    Ah, I'll try that. Thank you!

  8. lelit commented on Jun 10, 2021

    @lelit
    Contributor

    I've come up with a different approach that does not require a new option and is even more versatile:

    class ObjectsAsKeyValuePairsDecoder(Decoder):
        def start_object(self):
            return []
    
    
    def test_objects_as_key_value_pairs():
        kvp = ObjectsAsKeyValuePairsDecoder()
        result = kvp('{"a": 1, "b": {"b1": 1, "b2": 2}}')
        assert result == [('a', 1), ('b', [('b1', 1), ('b2', 2)])]
    
    
    class JoinDuplicatedKeysDecoder(ObjectsAsKeyValuePairsDecoder):
        def end_object(self, ordered_pairs):
            # Adapted from https://stackoverflow.com/a/38307621
            d = {}
            for k, v in ordered_pairs:
                if k in d:
                    if type(d[k]) == list:
                        d[k].append(v)
                    else:
                        newlist = []
                        newlist.append(d[k])
                        newlist.append(v)
                        d[k] = newlist
                else:
                    d[k] = v
            return d
    
    
    def test_join_duplicated_keys():
        jdk = JoinDuplicatedKeysDecoder()
        result = jdk('{"a": 1, "b": {"b1": 1, "b2": 2}, "b": {"b1": 3, "b2": 2,"b4": 8}}')
        assert result == {'a': 1, 'b': [{'b1': 1, 'b2': 2}, {'b1': 3, 'b2': 2, 'b4': 8}]}

    What do you think?

  9. lelit commented on Jun 12, 2021

    @lelit
    Contributor

    See also last entry in the incompatibilites section for another example.

  10. lelit commented on Jun 25, 2021

    @lelit
    Contributor

    This is fixed in v1.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions