Core API changes: read, scan, load, save#76
Conversation
|
Thanks @g-kimbell I verified Two behavior changes need a decision before merge:
|
Add `scan` to public API Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
This will be covered by the BDF table normalizer Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Use this for `human` flag in `save` Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Removed lazy kwarg, read returns DataFrame Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Add unit tests for these options Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Add cached decompression to `resolve_source` Moves compression logic to `file_utils` Strip compression suffixes when checking extension Adds tests for reading/writing compressed bdf artifacts and caching Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
|
Hi @jsimonclark, I have rebased on main to get all the recent merges
I moved the compression logic to file_utils, strip the known compression extensions when checking filetype in read, and cache the decompressed files by their filename+size+mtime key, so they don't get repeatedly decompressed for e.g. reading column names. Remaining issue: extra columnsCurrently I would suggest the default behaviour is to leave unknown columns as-is. We already have As a separate issue, if you set Remaining issue: default human=FalseBy default, save converts to machine readable labels. This goes against the FAQ, which says "You should use the Preferred Label for your column headings." We should be consistent, I don't mind which way. Practically, I don't think we have any issues saving with preferred labels in the formats we offer. @tomjholland @pghege would be great to have your opinion on these issues too |
Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
|
Thanks @g-kimbell I re-tested the rebase; looks good. Ran the full format x compression matrix: all 15 round-trip, cache works, tests green on the merge with main. On the other points
One small issueOne thing I hit while testing: OverallWith |
|
I can take a more thorough look at this tomorrow, but a couple of quick things:
|
|
I'd lean towards leaving everything as close to the dataframe object as possible. Don't change column names or numbers, don't drop columns etc. unless user asks. So:
CSV assuming string we can look at a later time, for columns outside spec or normalize=false I feel like it's unexpected behaviour. Maybe there's a way to say 'if we know the column, cast to dtype, otherwise guess and warn'. |
Taking this a step further, do we actually require a |
|
It's a good point, you could easily do .write_parquet etc. directly. I guess it's a convenience to give a path and have it pick the method and do compression for you. Warning/error on validation fail is also useful if you're making a bdf from some other source. It also depends what we plan to do with metadata. I think the point of save should be "if you save the data through this and get no warnings/errors, we guarantee you can read it back in without problems". As opposed to saving yourself, where you could do e.g. pandas to_hdf, or zip the file, and the file won't load here. |
Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
|
@jsimonclark added the BDF XLSX reader. Split on this because I don't personally like Excel as a format for time series data, but people in general are familiar with it and like it. We also basically get it for free as we already have the excel table parser. |
|
@g-kimbell I agree that excel is not a good time series format. But people use it anyway, so it's good to support. We should just make clear that xlsx and human labels are convenience outputs, never a default or canonical form. Verified the xlsx reader round-trips. I agree that "save with no warnings/errors --> guaranteed readable back" is the right identity for My take on the other decision points:
On metadata: the current dict param is fine for this PR; a richer metadata object (@tomjholland's work) can be accepted additively later without breaking the signature. @pghege, any thoughts from your side before we bring this to a conclusion? |
I suggest we should be more opinionated then in I think this only makes sense if we consider all the user facing methods together, and I think we should aim to minimise the number of function arguments. Instead we should trust the user to do the data transformations that they want for simple dropping and renaming columns (beyond the bdf).
|
Remove `include_optional`, `extra_columns`, add `include_unknown` Remove normalization on save Also affects CLI ingest, convert Change `rename_label_to_mr` to `rename_labels`, works either direction Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Moves `test_read` to `test_io` Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
|
Removed Remaining issues
|
There was a problem hiding this comment.
(Edited after catching up on the thread. Simon, here are my thoughts.)
On save validation failing with machine-readable names: validation should accept any column name style. Convert the names to the underlying quantities first, then run the checks. read() already does this, so save can use the same logic. Then the confusing failure goes away.
On naming the option: the README calls them "Preferred Label" and "Machine-readable name", so I'd match that: labels: Literal["preferred", "machine", "unchanged"].
On the default: I'd default to "unchanged". save shouldn't rename columns unless asked, and since read() accepts any name style, files still round-trip fine. For published reference files we can recommend labels="machine" in the docs. If you both prefer "machine" as the default I'm fine with that too.
One fix I'd like before merge, the TODO in __init__.py: the old load() only opened real BDF files, so validate() on a raw vendor file gave a clear error. The new read() auto-detects and opens anything, so a raw Arbin file now gets converted and validated as if it were already BDF. Fix: check which plugin detect() picks, and if it isn't a bdf_ one, return the error like before.
Also, since this PR has the biggest API changes of the release, it should get its own section in the changelog.
On the later items: agreed, both are on the roadmap and fold into the repair/validate work I'm picking up after this lands. I'll rebase #70 and #71 once this merges.
Argument `labels: Literal["preferred", "machine", "unchanged"]` Defaults to `"unchanged"` for save Updates tests, docs, CLI Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
`save` now runs `normalize` and disposes of the result This surfaces any errors or warnings to the user on save If the df can normalize on save, then it can be normalized on read Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
Use `detect` to get plugin name Remove old methods checking filepath or csv headers Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
|
I suggest we complete the 0.2.0 CHANGELOG in another PR before 0.2.0 / during 0.2.0rc{x} testing. |
|
All sounds right. Changelog as a separate PR works, I'll own it as part of the release prep. Mark ready when you're set and I'll approve. |
| # Do not mutate df, this is just to confirm the dataset can be normalized and raise/warn on inconsistencies | ||
| BDF_NORMALIZER.normalize(df, validate=validate, include_unknown=True) |
There was a problem hiding this comment.
We should use spec.ColumnOntology.validate_df() here I think instead (as that is what the normaliser calls). Needs a quick fix to allow machine readable names, which I can do tomorrow. can be a separate quick PR after this branch is merged if that's easiest.
There was a problem hiding this comment.
I tried it both ways, this just cut out the conversion from machine readable first. But I don't think I checked if the warnings are quiet when we expect, I can add some checks
Edit: changed it to validate_df as you suggest, with some extra checks
`validate_df` now catches: * Legacy BDF * Non-canonical unit * Missing required * Extra unknown Signed-off-by: Graham Kimbell <88666181+g-kimbell@users.noreply.github.com>
|
Changed the I had to move Marking as ready now if y'all are happy with it. |
pghege
left a comment
There was a problem hiding this comment.
Verified the changes since my review: the artifact check works as discussed, save validation is label-agnostic through validate_df, and the labels decisions match the thread. CI green. Nice work on this one.
This is a big, breaking API change ahead of 0.2.0 that touches many parts of the repo, so will need serious review
Splits
readintoread(eager) andscan(lazy)Remove
loadand associated functionsread- simplifies the API and removes a lot of duplicate logicUse polars for
savesavecovering more extensions and using polars write_xNeed to fix
Thefixed nowhumanflag in save currently does nothing, breaking a few testsThere is no JSON TableParser (can also add ndjson, ipc, excel), sofixed in Add json, ndjson, ipc/arrow/featherreadfails on JSON whereasloadhandled it beforeTableParser#78Rebased this on top of #78 for now