Giter Site home page Giter Site logo

openenergyplatform / omi Goto Github PK

View Code? Open in Web Editor NEW
7.0 7.0 4.0 616 KB

Repository for the Open Metadata Integration (OMI). For metadata definition see metadata repo:

Home Page: https://github.com/OpenEnergyPlatform/metadata

License: GNU Affero General Public License v3.0

Python 99.68% Batchfile 0.32%
oep open-energy-family metadata

omi's Issues

The metadata generated by the omi compiler has a modified key sequence

The meta fields in the metadata JSON do not maintain their order when using the conversion. This originally is caused by the OEMetadata object that is created by omi´s compiler.

Example:
_comment is originally the last key in the oemetadata.

caused by this compiler method:

def visit_metadata(self, metadata: oem_v15.OEPMetadata, *args, **kwargs):
publication_date = None
if metadata.publication_date is not None:
publication_date = self._compile_date(metadata.publication_date, "%Y-%m-%d")
return self._construct_dict(
("name", metadata.name),
("title", metadata.title),
("id", metadata.identifier),
("description", metadata.description),
("subject", metadata.subject),
("keywords", metadata.keywords),
("publicationDate", publication_date),
("context", metadata.context),
("spatial", metadata.spatial),
("temporal", metadata.temporal),
("review", metadata.review),
("_comment", metadata.comment),
("language", metadata.languages),
("sources", metadata.sources),
("licenses", metadata.license),
("contributors", metadata.contributions),
("resources", metadata.resources),
("@id", metadata.databus_identifier),
("@context", metadata.databus_context),
metaMetadata=self._construct_dict(
("metadataVersion", self.__METADATA_VERSION),
metadataLicense=self._construct_dict(
name="CC0-1.0",
title="Creative Commons Zero v1.0 Universal",
path="https://creativecommons.org/publicdomain/zero/1.0/",
),
),

"_comment": {
    "metadata": "Metadata documentation and explanation (https://github.com/OpenEnergyPlatform/organisation/wiki/metadata)",
    "dates": "Dates and time must follow the ISO8601 including time zone (YYYY-MM-DD or YYYY-MM-DDThh:mm:ss±hh)",
    "units": "Use a space between numbers and units (100 m)",
    "languages": "Languages must follow the IETF (BCP47) format (en-GB, en-US, de-DE)",
    "licenses": "License name must follow the SPDX License List (https://spdx.org/licenses/)",
    "review": "Following the OEP Data Review (https://github.com/OpenEnergyPlatform/data-preprocessing/wiki)",
    "null": "If not applicable use: null",
    "todo": "If a value is not yet available, use: todo"
},
"metaMetadata": {
    "metadataVersion": "OEP-1.5.1",
    "metadataLicense": {
        "name": "CC0-1.0",
        "title": "Creative Commons Zero v1.0 Universal",
        "path": "https://creativecommons.org/publicdomain/zero/1.0/"
    }
}

ValueError if parse_date gets none valid input

Hi all,

I have around 30 JSON files I try to convert from OEP-1.3 to OEP-1.4.

Around ten files are failing, because they have in temporal.reference_date a none valid input (string: "none" instead of a datestring) and produce an error ("Unknown string format:", timestr).

If I have a look at the corresponding file [parse.py] (https://github.com/OpenEnergyPlatform/omi/blob/dev/src/omi/dialects/oep/parser.py) I can see that there are multiple instances in which parse_date is used without a safety net.

I would solve the issue in the concerning code as follows. Also for all the other occurrences of parse_date in parse.py.

BEFORE:

        # filling the temporal section
        temporal = structure.Temporal(
            reference_date=parse_date(json_old["temporal"].get("reference_date")),
            start=None,
            end=None,
            resolution=None,
            ts_orientation=None,
        )

AFTER:

        # filling the temporal section
        try:
            temporal__reference_date = parse_date(json_old["temporal"].get("reference_date"))
        except ValueError:
            temporal__reference_date = json_old["temporal"].get("reference_date")
        temporal = structure.Temporal(
            reference_date=temporal__reference_date,
            start=None,
            end=None,
            resolution=None,
            ts_orientation=None,
        )

What do you think? Is this approach feasible?

Integrate metadata tools

Currently, we have two independent developments of metadata functionalities and should integrate both in one independent tool that can be used by the oeplatform, oedialect and other users.

Omi fails to parse valid(?) string with foreign keys as null

Omi is unable to parse this metadata string. As far as I can tell, the string contains a valid empty foreign key, but omi seems not to think so. Any idea as to why that is @MGlauer ?

omi translate -f oep-v1.4 cams_timeseries.json 
Traceback (most recent call last):
  File "/home/christianh/anaconda3/bin/omi", line 11, in <module>
    sys.exit(main())
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/cli.py", line 49, in main
    cli()
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/cli.py", line 35, in translate
    obj = from_dialect.parse(infile.read())
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/dialects/base/dialect.py", line 44, in parse
    return p.parse_from_string(string, *args, **kwargs)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/dialects/base/parser.py", line 69, in parse_from_string
    **(parse_kwargs or {})
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/dialects/oep/parser.py", line 348, in parse
    for field_name in fk.get("fields", [])
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/dialects/oep/parser.py", line 348, in <listcomp>
    for field_name in fk.get("fields", [])
KeyError: None

Function to split and join metadata for multiple tables

A function would come in handy to split and join metadata from existing tables.

1st use-case: 1 metadata string with multiple tables in key resources. Create one metadata string for each resource and copy the general information to each individual new resource-metadata-string.

2nd use-case: reverse 1st use-case

Use OMI translate in Python

I expected OMI to work in Python using translate(), I tried

from omi.cli import translate
translate('oep-v1.4', 'oep-v1.4', 'out.json', 'in.json')

but it outputs

Usage: oep-v1.4 [OPTIONS] FILE_PATH
Try 'oep-v1.4 --help' for help.

Error: Got unexpected extra arguments (e p - v 1 . 4)

and exits Python.
What's wrong here?

Ordered lists in RDF

JSON lists are inherently ordered. The RDF-based metadata use mostly properties which does not preserve orderings. We could use RDFS list semantics, but those are (imo) mostly unneeded for the metadata as is.

Are (explicit) orderings necessary or can they be omitted?

decode-function fails in python3

I ran into this error:

  File "/home/christianh/Schreibtisch/omi/env/lib/python3.7/site-packages/omi-0.0.2-py3.7.egg/omi/cli.py", line 42, in translate
    outfile.write(s.decode("utf-8"))
AttributeError: 'str' object has no attribute 'decode'

Stackoverflow suggests to simply drop the .decode("utf8"), because with python3 all strings are unicode objects already. Removing it worked for me and the cli worked afterwards. Going to push it in a new branch and create a PR.

The structure.py seems not to be compatible with previous OEM versions

When updating the structure.py with the latest metadata version (oem v1.5.0 and v1.5.1) I noticed that older versions are no longer supported when the structure is changed. For example in OEM v 1.5.0 the key temporal has been changed. Here the subkey timeseries is now a separate object.

Old until oem v1.4:

class Temporal(Compilable):
     __compiler_name__ = "temporal"
 
     def __init__(
         self,
         reference_date: datetime = None,
         start: datetime = None,
         end: datetime = None,
         resolution: str = None,
         ts_orientation: TimestampOrientation = None,
         aggregation: str = None,
     ):  # TODO: This should not be a string... maybe
         # we should use datetime instead?
         self.reference_date = reference_date
         self.ts_start = start
         self.ts_end = end
         self.ts_resolution = resolution
         self.ts_orientation = ts_orientation
         self.aggregation = aggregation

New in oem v1.5:

class Timeseries(Compilable):
    __compiler_name__ = "timeseries"


    def __init__(self, 
        start: datetime = None,
        end: datetime = None,
        resolution: str = None,
        ts_orientation: TimestampOrientation = None,
        aggregation: str = None):
        self.ts_start = start
        self.ts_end = end
        self.ts_resolution = resolution
        self.ts_orientation = ts_orientation
        self.aggregation = aggregation


class Temporal(Compilable):
    __compiler_name__ = "temporal"


    def __init__(
        self,
        reference_date: datetime = None,
        timeseries_collection: Iterable[Timeseries] = None
        # start: datetime = None,
        # end: datetime = None,
        # resolution: str = None,
        # ts_orientation: TimestampOrientation = None,
        # aggregation: str = None,
    ):  # TODO: This should not be a string... maybe
        # we should use datetime instead?
        self.reference_date = reference_date
        self.timeseries_collection = timeseries_collection
        # self.ts_start = start
        # self.ts_end = end
        # self.ts_resolution = resolution
        # self.ts_orientation = ts_orientation
        # self.aggregation = aggregation

Is there a way to keep the structure.py downward compatible without keeping a class for obsolete structure. Or would one structure.py have to be created for each OEM version.

@MGlauer as you implemented this could you help me out with this? Let me know if you understand my issue description.

CLI not working(?)

I'm on an Ubuntu machine and not sure whether this is an actual bug or a result of my setup. Installing omi via pip or from source both result in an error, when using the following command in via command line:

omi translate -f oep-v1.3 -t oep-v1.4 metadata_v13.json

I used the sample json from within this repo. My error looks like this:

  File "/home/christianh/anaconda3/bin/omi", line 11, in <module>
    sys.exit(main())
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/cli.py", line 49, in main
    cli()
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/cli.py", line 35, in translate
    obj = from_dialect.parse(infile.read())
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/dialects/base/dialect.py", line 18, in parse
    return p.parse(string, *args, **kwargs)
  File "/home/christianh/anaconda3/lib/python3.7/site-packages/omi/dialects/oep/parser.py", line 59, in parse
    old_spatial = json_old.get("spatial")
AttributeError: 'str' object has no attribute 'get'

I tried fiddling around with different branches and installing omi from there, but to no avail. Since it's mentioned in the documentation, I tried the same conversion with the command metadata-tool as well, which produced the same error.

New validation function needed

Validation should be based on the schema.json. Write a new function that validates a metadata json based on the schema. This should work independent of the versions. But tests should include oemetadata versions 1.5.2, 1.6 and 2.0

See #99

Make code compatible with Python3

You code seems to be written in Python2.x. According to our coding conventions we need at least python 3.5. Please make your code compatible

Import fails when local folders have the same name as dialects

Steps to reproduce:

  • install omi
  • create a folder with a name of one of the dialects, or base, that must contain a python file, e.g. test.py
  • in python, try to import omi: from omi.dialects import get_dialect

Result:

ModuleNotFoundError: No module named 'omi.dialects.base.test'

Reason:

the __import__ function gets confused because it searches in __path__ as well as the local path.

Solution:

Maybe do the dynamic import manually, for instance by replacing code in in dialects/__init__.py:

import os

from omi.dialects.base.register import get_dialect
path = os.path.dirname(__file__)
for d in os.listdir(path):
    if os.path.isfile(os.path.join(path, d, 'dialect.py')):
        module_name = 'omi.dialects.' + d + '.dialect'
        __import__(module_name)

OMI rewrite

OMI has several issues. Most importantly it's difficult to maintain and needlessly convoluted. It should reliably perform a handful of tasks and be less of everything else. @henhuy now has time time to address this in a radical rewrite. This issue is a meta level discussion space and collects things to be done.

@wingechr : you are warmly invited to ask for features, make structural remarks and get involved if you like. The goal is to have a tool that you and all of us enjoy using.

Broad plan:

  • base OMI's functions on the schema.json alone
  • Get rid of all the version and key specific classes and declutter the whole project
  • Write new functions and tests for validation and conversion

Things OMI should reliably do after the rewrite:

  • validate metadata json
  • validate that tables match metadata description
  • conversion of metadata from old to new (supported versions 1.5.2, 1.6 and 2.0)
  • return useful error messages
  • API can call OMI to validate uploads. Error messages (both from API itself and from OMI) should find their way back to the user.

Related info:

  • The oemetadata builder will also get an update.
  • OMI should be a helpful feature for the csv upload wizard. When dropping a csv file into the upload area, if it's reasonably structured, the OEP should be able to infer the structure and datatype from the first few lines and create a table. Limitations may apply.

Inconsistent omi field names compared to oemetadata spec

I used omi and when I output each field, the order is not the same as in the schema and there is a difference between the namings. Furthermore, there are also more fields displayed in omi than in the schema.

Here is a list of what I found:
General Keys:

  • ID = identifier
  • language = languages
  • publicationDate = publication_date
  • context
    • sourceCode = source_code
    • grantNo = grant_number
    • fundingAgency = funding_agency
      Spatial and Temporal Keys
  • referenceDate = reference_date
  • timeseries = timeseries_collection
    • start = ts_start
    • end = ts_end
    • resolution = ts_resolution
    • alignment = ts_orientation
    • aggregationType = aggregation
      Source Keys
  • sources, licenses (In omi.licenses but not in schema)
    • identifier = title
    • other_references
    • text
    • comment
      Contributor Keys
  • title = name
    Resource Keys
  • All resources are shown with all keys and values at the end which shouldn't happen

There is also a problem that omi only outputs fields with values, if values = null --> these are not shown

OMI stops on errors and lacks meaningful output

We use the OMI tool in eGon-data to check the metadata. It is quite helpful but lacks some speaking output:

  • Optional keys do not seem to be checked, a warning would be helpful #35
  • If there's an error (more precise: some format problem, e.g. mandatory key is missing) while processing, OMI immediately stops e.g. stating omi.dialects.base.parser.ParserException: metadata string does not contain an id. In my opinion it'd be better to parse the entire metadata and give a list of errors/warnings, otherwise one might end up in a trial-and-error odyssey.
  • Lacking details where error is located: e.g. if there's a malformed string OMI prints dateutil.parser._parser.ParserError: String does not contain a date:. Pardon, which field?

Conversion creates empty fields when adding new metadata keys

Should it be possible to add some user input to new fields like "is_about" or should omi just convert the metadata and leave the editing to tools like the MetaEditor on the OEP.

Example:

{
    "name": "id",
    "description": "Unique identifier",
    "type": "serial",
    "is_about": [
        {
            "name": "",
            "path": ""
        }
    ],
    "value_reference": [
        {
            "value": "",
            "name": "",
            "path": ""
        }
    ]
}

Information about catalog and publisher

To conform to DCAT-AP it is mandatory to have a dcat:Catalog (with its publisher) where the dataset belong to. I am not sure how to derive this information from the metadata. Who is the publisher of a dataset?

Add Error Message that compiling backwards to 1.3 is not possible

I tried to parse and compile this file which first fails with the error described in #12 . After changing the null values to dates for testing purposes, I can parse without a problem.

Compiling the parsed metadata back to v1.4 works. Compiling to 1.3 yields this error:

    print(dialect1_3.compile(parsed))
  File ".../omi/env/lib/python3.7/site-packages/omi-0.0.2-py3.7.egg/omi/dialects/base/dialect.py", line 13, in compile
    c = self._compiler()
TypeError: 'NoneType' object is not callable

Adapt to github actions from travis

Reactivate CI by introducing github actions workflow automatization features:

  • automate pypi release (test pypi on merge to branch "test-release" and official pypi on publish github release)
  • regression/unit tests
  • test oemetadata validation: validate omi result with oemetadata schema to ensure results of each dialect is compliant with the oemetadata spec

OMI omits `null` values from json during processing

When omi processes json metadata it omits values and metadata that are null.
This is due when omi reads a json into a python dict, null is read in as None. This results in missing metadata fields when compiling with omi.

e.g. missing description field and unit field

input

"schema": {
                "fields": [
                    {
                        "name": "fid",
                        "description": null,
                        "type": "int",
                        "unit": null,
                        "isAbout": [
                            {
                                "name": null,
                                "path": null
                            }
                        ],
                        "valueReference": [
                            {
                                "value": null,
                                "name": null,
                                "path": null
                            }
                        ]
                    }

output

 "schema": {
                "primaryKey": [],
                "foreignKeys": [],
                "fields": [{
                        "name": "fid",
                        "type": "int",
                        "isAbout": [{}
                        ],
                        "valueReference": [{}
                        ]
                    }

This is important as oem2orm throughs an error for some keys when generating tables from metadata for the OEP and they're missing, e.g. description.

ERROR:Could not generate tables from metadatafile:

KeyError                                  Traceback (most recent call last)
<ipython-input-17-7e96dde4dbd2> in <module>
----> 1 tables_orm = oem2orm.collect_tables_from_oem(db, metadata_folder)

~\Miniconda3\envs\p_py38_oep-upload\lib\site-packages\oem2orm\oep_oedialect_oem2orm.py in collect_tables_from_oem(db, oem_folder_path)
    272     for metadata_file in metadata_files:
    273         try:
--> 274             md_tables = create_tables_from_metadata_file(db, metadata_file)
    275             logging.info(md_tables)
    276         except:

~\Miniconda3\envs\p_py38_oep-upload\lib\site-packages\oem2orm\oep_oedialect_oem2orm.py in create_tables_from_metadata_file(db, metadata_file)
    217                     column_type,
    218                     primary_key=field["name"] in primary_keys,
--> 219                     comment=field["description"],
    220                 )
    221             columns.append(column)

KeyError: 'description'

The current status makes automatic metadata processing and upload impracticable.

EDIT

After implementing omit_none=False results

output

"schema": {
                "primaryKey": [],
                "foreignKeys": [],
                "fields": [{
                        "name": "fid",
                        "description": null,
                        "type": "int",
                        "isAbout": [{
                                "name": null,
                                "path": null
                            }
                        ],
                        "valueReference": [{
                                "value": null,
                                "name": null,
                                "path": null
                            }
                        ],
                        "unit": null
                    }

Missing Parser Warning for Undefined Keys

When parsing a metadata string, omi seems to just look for a few mandatory keys and accepts what comes with it. Keys that aren't defined in the metadata standard don't trigger a warning and are simply ignored. A warning would be quite helpful, for example in case a key was misspelled.

Return error report in OMI validation

Right now, validation stores error report into file.
But with this implementation, I cannot inspect error report directly, but have to load report from file again.
Instead I suggest to return error report from validation function.
In case of no errors an empty error report, stating "no errors found" should be returned.
This is the way it is implemented in frictionless as well.
As validation function does not return anything ATM, this can be easily implemented.
Additionally, I would make storing report on filesystem an option (with default False) as this might not be wanted by users?

How to finalize metadata and metadata usage for OMI

Hi @Bachibouzouk,

yesterday, you did send me JSON schema drafts for v1.3 and v1.4 of the OEP metadata, I included them in a gist so that other people know what we are talking about if they are reading this: link

I had a look at the getting started section on json-schema.org and realised that our draft version doesn't include descriptions (additionally to the types) and also doesn't define schema version and $id (which is obvious because we didn't decided that yet (OpenEnergyPlatform/organisation#26). I think the possibility of adding descriptions is very handy and shouldn't be missed, because we could get rid of https://github.com/OpenEnergyPlatform/examples/wiki/Metadata-Description and could point $id directly to a single JSON schema file (that is self describing).

What do you think? Shall I add the description of v1.4 into the schema draft?

And second question, where is the description of v1.3? Maybe @Ludee or @christian-rli know that ...

Conversion update for 1.5.2, 1.6 and 2.0

Conversion between different versions of the metadata needs to be extended or rewritten. Versions 1.5.2, 1.6, 2.0 need support. Only forward support is necessary. Include tests and a short documentation on how to use the conversion function.

See #99

Transform OEM141 to OEM151

In the scope of current projects, it's becoming necessary to annotate existing datasets on the OEP with the ontology. Unfortunately, these datasets are often still annotated with OEM141, which is not yet ready to work with the ontology. Therefore, instead of transforming the OEM141 strings manually to OEM151, a script could come in handy.

TODO

  • Fix encoding error of Umlaute 9a90213

OMI conversion not working anymore

Since we have developed the metadata standard OEM further and have not adapted omi immediately, the metadata conversion from a low version to the latest version is currently not supported.

With version v1.5.0 the structure of the metadata was changed, essentially under the key "temporal" the subkey timeseries (already introduced in v1.4.1) was changed to the type list of objects :[{..},{..}]. Since omi works with the current version of the oem structure and does not use one structure definition per version, it is necessary to define in the parser classes or directly in the conversion how the current structure can be translated to the desired metadata version.
Also the other new keys have to be included in the conversion method.

If you install omi and try to convert a metadata file v1.4.1 to v.1.5.0 (using the metadata from the oemetadata repository) there is some output but the output is very limited and not correct.
omi translate -f oep-v1.4 -t oep-v1.5 ..\oemetadata\metadata\v141\example.json

Output:

{
    "title": "Ludee",
    "object": "metadata",
    "comment": "Release metadata version OEP-1.3.0",
    "date": "2019-07-09"
}
],
"resources": [
{
    "profile": "tabular-data-resource",
    "name": "model_draft.oep_metadata_table_example_v141",
    "path": "http://openenergyplatform.org/dataedit/view/model_draft/oep_metadata_table_example_v141",
    "format": "PostgreSQL",
    "encoding": "UTF-8",
    "schema": {
        "primaryKey": [
            "id"
        ],
        "foreignKeys": [
            {
                "fields": [
                    "year"
                ],
                "reference": {
                    "resource": "schema.table",
                    "fields": [
                        "year"
                    ]
                }
            }
        ],
        "fields": [
            {
                "name": "id",
                "description": "Unique identifier",
                "type": "serial"
            },
            {
                "name": "year",
                "description": "Reference year",
                "type": "integer"
            },
            {
                "name": "value",
                "description": "Example value",
                "type": "double precision",
                "unit": "MW"
            },
            {
                "name": "geom",
                "description": "Geometry",
                "type": "geometry(Point, 4326)"
            }
        ]
    },
    "dialect": {
        "decimalSeparator": "."
    }
}
],
"metaMetadata": {
"metadataVersion": "OEP-1.5.0",
"metadataLicense": {
    "name": "CC0-1.0",
    "title": "Creative Commons Zero v1.0 Universal",
    "path": "https://creativecommons.org/publicdomain/zero/1.0/"
}
}
}

From language attribute to correct URI

In Metadata v1.4 the value of the language attribute is described with the Standard: IETF (BCP47). What is a good way to get the correct entry of the MDR Languages Named Authority List, which is used as obligatory controlled vocabulary for dct:language in DCAT-AP.de?

Compiling metadata with minimum or empty fields causes a NoneType error.

Using metadata json structures that do not provide all fields of the oemetadata spec. are not handled as expected by OMI. For most fields this will not raise any braking errors but with the latest version of OMI (0.0.8) the _comment field was added to the OEMetadata class as keyword-argument reading the values from the input metadata. If the _comment field is empty in the input this will cause a breaking error when trying to compile from a metadata json/dict.

Example
meta = {"id": self.test_table}

using omi to compile then raises:

File "/home/runner/work/oeplatform/oeplatform/.tox/py3/lib/python3.8/site-packages/omi/dialects/oep/compiler.py", line 372, in visit_metadata
    metadata=metadata.comment.metadata_info,
AttributeError: 'NoneType' object has no attribute 'metadata_info'

Source code is cluttered

The source code is cluttered and has a range of no longer useful bits.

Remove obsolete classes, specifically the numerous classes for every key in every version of the metadata. New functions will be based on the schema.json. Make a list of what can be reused or rewritten. Tidy up the repository with everything that will stay. Drop loose ends if necessary.

See #99

Missing Parser Warning for Missing Keys

When parsing a metadata string, omi seems to just look for a few mandatory keys and accepts what comes with it. Missing optional fields don't trigger a warning. These would be quite helpful, so there should be one.

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.