add AsimovReader for retrieving measurements from asimov.enci.dk#198
Conversation
…_portable_value. A version of as_dict() with no reference to the ixdat backend; for storage in databases and sent over web APIs (asimov project).
…where needed in series classes, to support [asimov f590483]
…dict, to support [asimov f590483]
… in conjuction with asimov reader class for authenticating access to the asimov db
…nProvider [6e0514e] to authenticat the retrieval of measurements from asimov.enci.dk and to init ixdat Measurements from those queries
…tabase id (dataset_id) and login
|
The current commits sketch out the base implementation. Additional endpoints for asimov are scheduled, meaning more potential properties for the AsimovReader class; like a
|
|
Added portable dict support for Also: Round-trip tests for |
|
After more consideration, I think it be best if we keep this PR to the base reader and portable dict, and move the search/list features to a new future PR. Created feature-issue #201 for now. |
|
I'm having trouble testing this, possibly because I don't quite understand the demo script. Could you add some comments / documentation in that script? which I guess is generated by Finding dataset-id's on asimov is tricky, but clicking a "Measurement" from "Graph View" opens an "Inspector" which includes an "Entity ID". I copied the one from "demo_03" in project "ixdat_demo" and ran the following from a terminal (Anaconda prompt): This opened a browser window asking for permissions, as described in the docstring. After I granted the permissions, a long error was printed to the Anaconda Prompt terminal, of which the important part is: My normal workflow is to start with the demo script. I'll start on code review of |
|
I pulled the shared portable-dict metadata handling into a couple of small helpers so we are not repeating the same @ScottSoren I also simplified the demo flow so it no longer depends on |
ScottSoren
left a comment
There was a problem hiding this comment.
Hi Frederik,
Great work. However, there are serious problems in the portable_dict implementation, which I've commented on in data_series.py. I would much rather have the AsimovReader do what it needs to to get the data from asimov into a normal ixdat dictionary. I also recommend going through this totorial to get a better sense of what ixdat has to do (and tries to do in a smart way, though it can surely be smarter) with regards to organising its data series.
A tool that you might need instead could be an AsimovExporter on asimov's side, to format the data coming out of asimov. That would be a more appropriate place to put a new structure of ixdat dat, since it defeats the point of a modular structure, and would set a precedent leading to a huge proliferation of representations of ixdat data, if a PR adding a new reader could also add something like to_portable_dict.
Other comments I have center around the question of whether some of the keycloak interface could be done with another package? python-keycloak for example has 166 contributors, many of whom are probably professionals in exactly that - the more we can rely on something like that, the more robust I think it makes ixdat going forward. It could be that our use case is so special that it requires bottom-up coding, but then my question is why? (Some of your instinct to make a new serialization is no doubt because I kind of poorly re-invented the wheel of object-relational mapping instead of using something like SQLalchemy from the start.)
|
@ScottSoren; thanks for the thorough review. You were right on the big stuff. This turned out to be a bit more complex than I first thought, so bear with me here; I am just gonna one reply here since the remaining review comments fit well together. The changes made here are in 4464fb7. The big one:
The "ixdat dicts should be redone" conversation stays a separate PR, as you suggested. Fixing the name-collision and the duplication of data To fix the naming-collision I had to redo the payload format itself on the server-side. Asimov's writer and the reader now both use payload-local keys. Every entry in While going through this, I realized that I might be re-inventing the wheel once again, and so I went into a rabbit hole of trying to figure out if the reader could just lean on ixdat's I hope you can see the point in doing this; else let me know! New: AsimovConfig
Already pushed earlier in the branch
Still open between us Other |
ScottSoren
left a comment
There was a problem hiding this comment.
Very nice! Thanks for the thoughtful addressing of my previous review. Mainly questions remaining, plus some small change requests, mostly asking for comments.
I like your solution with "key", and though I also in principle think that it should be covered by the id's of ixdat objects, I know that the latter are a bit of a mess at present.
I'd like to see where the "key"s get set, though, for my curiosity and thinking ahead to #75 ! Can you point me to it in the asimov code base?
| } | ||
|
|
||
|
|
||
| @dataclass |
There was a problem hiding this comment.
dataclass is new to me :) thanks! I've used attrs before for the same. For curiosity: https://www.attrs.org/en/stable/why.html
It seems like this means that we're killing python 3.6 compatability, though. I think that's fine - we already had to stop testing for it in the continuous integration. We'll have to warn about that somehow when releasing this on PyPI. There are a few groups around the world using ixdat for EC-MS who might be affected. Also, Spectro Inlets, who have built some things on top of ixdat.
Let's sit together when releasing this and work through it.
There was a problem hiding this comment.
Ah okay haha, this is where it shows when we both entered the python programming scene! I really only started programming for real in python when 3.7 was released, so I have only used that. We should definitely think about how to release this in a way that does not break current users; but I also think that we could argue that they should be using >=3.7 in 2026 ;-)
Lets agree fully on this before we merge.
…hink we should add some sort of pre-commit)
FrederikLizakJohansen
left a comment
There was a problem hiding this comment.
I do not know why I need to "submit review" here since I just commented on your review. But here it is.
|
All comments resolved except for the one reminding us to deal with dropping python 3.6 support when releasing. |
|
@ScottSoren Thanks for the review and the merge! In asimov, the key map is built in all_series = list(getattr(measurement, "series_list", []) or [])
series_key_map: dict[int, str] = {id(s): f"s{i}" for i, s in enumerate(all_series)}Here |
AsimovReader(src/ixdat/readers/asimov.py)New reader class that connects to asimov.enci.dk and retrieves measurements via REST API. Supports retrieval by
dataset_id: Direct lookup using the asimov database ID.The reader returns ixdat
Measurementobjects with with data fetched from the asimov API.KeycloakDeviceTokenProvider(src/ixdat/auth/keycloak.py)Authentication handler implementing the OAuth 2.0 Device Flow protocol for Keycloak. This enables passwordless authentication to asimov.enci.dk without exposing user credentials directly to ixdat. The flow:
Portable Serialization
Added
to_portable_dict()/from_portable_dict()methods to:Saveablebase classMeasurementclassValueSeries,TimeSeries, etc.)These provide backend-agnostic serialization that doesn't reference ixdat backend classes. The current
as_dict()method has ties to potential ixdat DB plans discussed in PR #75. These new "portable" versions provide an alternative for storing measurements in external databases and passing them over web APIs until the #75 plan is finalized.Note on dependency: The asimov DB internally uses ixdat to store Measurement objects in the form of the portable dicts generated by this implementation of to_portable_dict(). Therefore, this implementation have a direct dependency on that data flow - the reader retrieves the same portable dict format that asimov stores internally, ensuring compatibility between ixdat and the asimov backend.
Tests
KeycloakDeviceTokenProvider(tests/unit/test_keycloak_token_provider.py)Demo
A demo script (development_scripts/reader_demonstrators/demo_asimov_reader.py) showcases: