Repository navigation
metadata model, query API, docs and housekeeping - #14
Open
arthurmccray wants to merge 10 commits into
Open
arthurmccray wants to merge 10 commits into
arthurmccray wants to merge 10 commits into
Conversation
… a location field distinguishing shared vs user files
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follows #13 (tooling, correctness fixes, typing/pathlib). Base:
c966b14.Breaking. The dataset YAML schema and the public attribute surface both
change. Needs a minor version bump and release notes.
1.
metadatais a dataclassjson-schema.jsoncloses the dataset entry withadditionalProperties: false,so an entry is a fixed set of fields. It is now a frozen dataclass,
DatasetMetadata, withAuthornested, built only throughDatasetMetadata.from_spec().Before, the constructor named some fields and left the rest in a
metadatadict, so
ds.detectorworked andds.techniqueraised. Now everything the YAMLdeclares is on
ds.metadata.ds.description,ds.license,ds.doi,ds.detector,ds.detector_manufacturerds.metadata.<field>ds.techniqueraisedds.metadata.techniqueds.source,ds.file,ds.checksumThe four fields the download machinery needs —
source,file,checksum,size_bytes— stay reachable off the dataset, plussizefor display. They areread-only; override one through the constructor
(
data.CuZnHAADF(checksum=...)).Validation runs when the class is built, not when it is instantiated. A
malformed YAML fails the import that reads it, naming the file and the offending
key, rather than making the dataset disappear from the browser.
folderwas declared in the schema and used by none of the 20 files.qualitywas popped by the constructor, absent from the schema and from every file. Both
dropped.
__repr__is one line (<DatasetMetadata smallPtychography.hspy · 4D-STEM · 12.5 MB>); the generated dataclass repr ran to about 1000 characters, nearly alldescription.
print(ds.metadata)gives the full record, wrapped, unset fieldsomitted.
2.
data_sizebecomessize_bytes"1.4 GB"cannot be sorted, summed or compared. All 20 files now carry aninteger, taken from the
Content-Lengthof each source.ds.size_bytes->intds.size->"1.4 GB", driving the repr and the widgetsjson-schema.json:size_bytes, integer, minimum 0test_source_url_resolvesasserts the header still matches the declared value,which also catches a source file being replaced — invisible today until someone's
checksum fails.
One correction fell out:
AlNanocrystalswas declared1.4 GBand is1381831542 bytes, so it now displays as
1.38 GB. The other 19 reproduce theirold strings exactly.
3. The YAML is validated
Nothing checked the shipped files against the shipped schema — not CI, not
import, not the issue action.
test_yaml_matches_schema, parametrized over every fileDatasetMetadataandAuthor, so the twodescriptions of one record cannot drift
on_new_issue.yml, before the PR is openedjsonschemais a test/dev dependency only; the files are validated in CI, sovalidating again at import would cost every user startup time for nothing
jsonschemawas added to thetestsextra as well asdev— it was only indev, so the test matrix would have skipped validation entirely.4. Vendor lists
Two lists, hand-duplicated in two files, with nothing checking they agreed, and a
third entry path ignoring both.
json-schema.jsonmicroscope_vendorjson-schema.jsondetector_manufactureroptionskey, inert_build_docs.py:860_MANUFACTURERS/_VENDORStuplesTwo of the five detector manufacturers in use,
NORDIFandAllied Vision,were already outside the list and passed only because that enum was inert.
Both enums are dropped. One canonical list in
datasets/vendors.yamlfeeds thedocs form (as a
datalist, suggesting without constraining) and adifflib.get_close_matchescheck that fails a near-miss and warns on agenuinely new vendor. A hard enum fails the legitimate new vendor and blocks a
contributor who has done nothing wrong; this catches the failure that actually
happens.
Short names are the check's weak point —
JOELforJEOLscores too low to becalled a typo and comes back as a warning. Documented on the function.
5. A query API
The only way to filter the catalogue was the widget's search box. From Python
you reached into a private-looking module.
All three return dataset objects, so a result can be downloaded directly.
search()matches the same lowercased blobcatalogue.entry()builds for thewidget, by the same rule — every whitespace-separated term must appear, not
necessarily in the same field. The widget keeps matching in the browser, because
a round trip to the kernel on every keystroke would make typing lag; what is
shared is the blob and the rule.
filter()compares strings exactly but case-insensitively, tests membership fortagsandauthors, treats a list as any-of, and raises on an unknown field —a typo that quietly returned the whole index would be worse than an error.
It is
list_datasets(), notdatasets(), becauseem_database/datasets/is asubpackage: importing it binds the module onto the parent package and replaces a
function of the same name. Sphinx's autosummary walks every submodule, so this
is not hypothetical.
query.pyis named that way rather thansearch.pyfor thesame reason. A test walks every submodule and asserts no exported name was
replaced.
Not in this PR
sphinx_galleryexecutes every example on every docs build, and two of themdownload a 12.5 MB dataset. Same problem as the HEAD requests above; the fix
costs those two examples their rendered output.
_build_docs.pyis 1255 lines shipping inside the installed package, importedonly by
doc/source/conf.py. It belongs indoc/.