GithubHelp home page GithubHelp logo

Comments (11)

night-crawler avatar night-crawler commented on June 9, 2024 3

Hey folks, I started some work on creating python bindings:
https://github.com/night-crawler/jsonpath-rust-bindings

maturin develop

python
>>> from jsonpath_rust_bindings import jsonpath
>>> from jsonpath_rust_bindings import Finder
>>> f = Finder({'a': {'b': 42}})
>>> f
<builtins.Finder object at 0x7f342d92cc90>
>>> f.find('$.a')
[<builtins.JsonPathResult object at 0x7f342d4fe2f0>]
>>> f.find('$.a')[0]
<builtins.JsonPathResult object at 0x7f342d4fe830>
>>> f.find('$.a')[0].data
{'b': 42}

There's a standing question in regards Rust -> Python && Python -> Rust PyObject conversion and cloning: https://github.com/night-crawler/jsonpath-rust-bindings/blob/main/src/lib.rs#L48

Is it possible to have a JsonPathFinder not owning a Value?

from jsonpath-rust.

besok avatar besok commented on June 9, 2024 1

Right. In fact, I just wanted to have paths to the original extracted values returned always and got lost in the API a bit. I could use json_path_instance() function directly: https://github.com/night-crawler/jsonpath-rust-bindings/blob/main/src/lib.rs#L39

yeah, that works as well :). Great.

A side note and probably an off-topic. Currently, I'm converting PyObjects to Values with pythonize crate, and it seems that it clones the original values, which is not very efficient and has a side effect better demonstrated below:

Yeah, I will need to take a look at how the crate serializes the objects, but at first glance, looking into this test or that one it seems possible that the data gets cloned.

But, I wonder how to avoid cloning between Rust and Python as we don't share one object but transfer the data (maybe, I don't grasp it clearly though).

Anyway, regarding data mutations for now, even if you had gotten the pointer to the slice of original data, you would not be able to modify it, at least, from rust. There are a couple of open issues: #48 and #12

I would proceed with cloning now and then think about how to avoid it but later on.

from jsonpath-rust.

besok avatar besok commented on June 9, 2024 1

Ah sorry, I did mention it vaguely and that was the cause of the confusion. I meant the readme of this project.
Just a couple of lines that the current crate has a py binding with a link to it.

from jsonpath-rust.

besok avatar besok commented on June 9, 2024

Hi.
Thank you!

That is a very interesting idea.
But it needs to take a close look at how to do that.
Maybe you have something in mind already?

from jsonpath-rust.

arenas-guerrero-julian avatar arenas-guerrero-julian commented on June 9, 2024

Hi,

Unfortunately I am not of much help here :( I just know it should be possible with pyo3.

from jsonpath-rust.

besok avatar besok commented on June 9, 2024

No worries. I will give it a look

from jsonpath-rust.

besok avatar besok commented on June 9, 2024

Hey! Great to hear that! Thank you!
Is it possible to have a JsonPathFinder not owning a Value?

yeah, as far as I understand your question it is not possible since the given structure literally takes ownership of it.

pub struct JsonPathFinder {
    json: Box<Value>,
    path: Box<JsonPathInst>,
}

But this thing is just a helper structure to handle the given JSON (usually) from string and the given query(also usually from string).

You can try to avoid possession of the JSON value using a query directly.

  #[test]
    fn no_clone_api_test() {
        fn test_coercion(value: &Value) -> Value {
            value.clone()
        }

        let json: Value = serde_json::from_str(template_json()).expect("to get json");
        let query = JsonPathInst::from_str("$..book[?(@.author size 10)].title")
            .expect("the path is correct");

        let results = query.find_slice(&json);
        let v = results.get(0).expect("to get value");

        // V can be implicitly converted to &Value
        test_coercion(v);

        // To explicitly convert to &Value, use deref()
        assert_eq!(v.deref(), &json!("Sayings of the Century"));
    }

is it what you need?

from jsonpath-rust.

night-crawler avatar night-crawler commented on June 9, 2024

Great to hear that! Thank you!

Thank you too for your jsonpath efforts!

You can try to avoid possession of the JSON value using a query directly.

Right. In fact, I just wanted to have paths to the original extracted values returned always and got lost in the API a bit. I could use json_path_instance() function directly: https://github.com/night-crawler/jsonpath-rust-bindings/blob/main/src/lib.rs#L39

A side note and probably an off-topic. Currently, I'm converting PyObjects to Values with pythonize crate, and it seems that it clones the original values, which is not very efficient and has a side effect better demonstrated below:

Python 3.11.5 (main, Aug 30 2023, 19:09:52) [GCC 13.2.1 20230730] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> original_object_i_want_to_mutate = {'a': {'b': 'sample b'}}
>>> from jsonpath_rust_bindings import Finder
>>> f = Finder(original_object_i_want_to_mutate)
>>> b_dict = f.find('$.a')[0].data
>>> b_dict
{'b': 'sample b'}
>>> b_dict['new'] = 42
>>> original_object_i_want_to_mutate
{'a': {'b': 'sample b'}}

I wonder if it's wise to pursue it now, or save it for later. Any thoughts?

from jsonpath-rust.

night-crawler avatar night-crawler commented on June 9, 2024

So, here's the result: https://pypi.org/project/jsonpath-rust-bindings/

Regarding the conversion problem, there's already an issue but solutions mentioned in comments don't look like zero-copy to me. I'll allocate some time this week to see what else I can do with it.

And yet again, thank you!

from jsonpath-rust.

besok avatar besok commented on June 9, 2024

Very well! Thank you very much!
Yeah, the problem with cloning needs a warning but basically, it goes into serde problem.

Anyway, if you can spare some time lately, that would be nice if you add a couple of lines into the readme, mentioning binding.

from jsonpath-rust.

night-crawler avatar night-crawler commented on June 9, 2024

that would be nice if you add a couple of lines into the readme, mentioning binding.

I apologize for the confusion, probably pypi returned you an old cached version with an empty readme (v0.1.0). The current one 0.1.1 explicitly specifies the link to the jsonpath-rust project. Also, I updated the readme with your name just in case (not yet published to the pypi).

If I didn't get the meaning of mentioning binding, please follow up on this or DM me. Thank you.

from jsonpath-rust.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.