Package: uai-openlabel
uai_openlabelThis repository is an implementation of theASAM OpenLABELv1.0.0 standard.
OpenLABEL defines a JSON schema for saving annotations in the context of data labeling.How to useThe entry point to the uai_openlabel data structure isOpenLabel, importable viafrom uai_openlabel import OpenLabel.
To export an example OpenLABEL file and save it to disk, doimportjsonfrompathlibimportPathfromuai_openlabelimportOpenLabelexample=OpenLabel.example()withPath("where/to/save/example.json").open("w")asf:json.dump(example.to_dict(exclude_none=True),f)Useto_dict(exlude_none=True)to remove any none-valued fields from the dataclass.
This makes the export much more compact and is also the way the official ASAM examples are serialized.DevelopmentPoetryThis package uses Poetry, a tool for dependency management and packaging.
Please install it via the official installer fromhere.Working with this repositoryThis repository employs several tools to ensure a constant and good code quality.BlackBlackis a code formatter that we use to assure consistent code style across our projects.
Use it in-between, or after your code changes, viapoetry run black .in the root directory of this repository.MyPyMypyis a static type checker for Python.
Mypy can be run withpoetry run mypy .in the root directory of this repository.RuffRuffis a Python linter and code formatter.
It can be run withpoetry run ruff .in the root directory of this repository.Things left to be implementedNot implemented because they aren't needed yet.Section7.10.2 Semantic segmentation: imageSection7.10.4 MeshSection7.10.5 Mat and binarySection7.10.6 Point2d and Point3dPlease choose a test-driven-development: Find an example JSON in the OpenLABEL spec and create a de- & re-serialization
test for it. Then implement the features required to pass the test.Debugging apischemaDebugging problems in (de)serialization with apischema is tricky because apischema is in a compiled state when
installing it from PyPI.
To have a better debugging experience, it is advisable to clone theapischema repositorylocally alongside this repository.
Then, set the apischema dependency asapischema = { path="../apischema", develop=true }inpyproject.toml.
Follow up withpoetry lock; poetry install --sync.
Now you can more easily get the keys and values where apischema is throwing exceptions.MyPy specialties in this libraryMapping instead of dictThroughout this repository, you'll find the usage ofMappingtype decorators instead ofdict.
The typeMappingiscovariant, whiledictisinvariant(read about ithere).This is important if you want to extend the base OpenLABEL spec with a customer-specific spec that overrides fields
and narrows down the type, like such:fromdataclassesimportdataclass,fieldfromtypingimportMappingclassLowerCaseStr(str):def__init__(self,val:str):ifnotval.islower():raiseValueError(f"{val}isn't lower-case")@dataclassclassAction:name:str=field()@dataclassclassCustomAction(Action):name:LowerCaseStr=field()@dataclassclassOpenLabel:# Setting the type to dict will cause a MyPy erroractions:Mapping[str,Action]=field()@dataclassclassCustomOpenLabel(OpenLabel):actions:dict[str,CustomAction]=field()Why all these_no_defaultdefault values?When creating dataclasses that inherit from each other, an issue that can occur is that a subclass has a field without
a default, while the parent class contains fields with defaults.
When this occurs, you'll seeTypeErrorswhen trying to execute it, and PyCharm will complain too.To fix this, there are several possibilities, the best of them are discussedhere.
Other possibilities involve using metaclass magic and a deep forest of complicated code that would make the code harder to
understand.The cleanest solution that a) doesn't double the class count, b) is understood by PyCharm, and c) sticks with plain dataclasses,
is the following:
On fields that may not be left empty according to the official OpenLABEL spec, we set adefault_factorythat raises an exception.In order for apischema to work, we have to add theapischema.metadata.requiredin the field's metadata,
otherwise apischema will call the default factory before checking if there even is a value to be deserialized.