Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SBOL 2 to 3 Converter: Empty ComponentDefinition conversion #283

Open
fxbuson opened this issue Sep 4, 2024 · 2 comments
Open

SBOL 2 to 3 Converter: Empty ComponentDefinition conversion #283

fxbuson opened this issue Sep 4, 2024 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@fxbuson
Copy link
Collaborator

fxbuson commented Sep 4, 2024

I tried converting something very minimal with the python native converter:

import sbol2
from sbol_utilities import conversion

doc2 = sbol2.Document()
comp = sbol2.ComponentDefinition()
doc2.add(comp)

doc3 = conversion.convert2to3(doc2, use_native_converter = True)

(Note this converts with no problems in the JS converter)

The first error I get is related to namespaces. it seems like the current code does not accept None namespaces when it clearly should (there is even a default mode that should return None):

r._sbol3_namespace(self, obj2)
    351     return namespaces[0]
    352 # Check if the object starts with any of the provided namespaces
--> 353 for namespace in self.namespaces:
    354     if obj2.identity.startswith(namespace):
    355         return namespace

TypeError: 'NoneType' object is not iterable

I then tried giving it a namespace with:

doc3 = conversion.convert2to3(doc2, namespaces = [sbol2.DEFAULT_NS], use_native_converter = True)

I then got an error when extracting the identity to sbol3:

File ~\AppData\Local\Programs\Python\Python311\Lib\site-packages\sbol3\identified.py:60, in extract_display_id(identity)
     58 msg += ' A displayId MUST be composed of only alphanumeric'
     59 msg += ' or underscore characters and MUST NOT begin with a digit.'
---> 60 raise ValueError(msg)

We can see from the code in pysbol3.identified.py that it tries to extract whatever is after the last forward slash:

    [...]
    display_id = parsed.path.split('/')[-1]
    if is_valid_display_id(display_id):
        return display_id
    else:
        msg = f'"{display_id}" is not a valid displayId.'
        msg += ' A displayId MUST be composed of only alphanumeric'
        msg += ' or underscore characters and MUST NOT begin with a digit.'
        raise ValueError(msg)

But the identity in SBOL2 ends with the version, not the ID. In this case my component had identity = 'http://examples.org/ComponentDefinition/example/1'. If I trim the identity first:

comp.identity = "/".join(comp.identity.split('/')[:-1])

Then the conversion runs ok. Should I just implement the trimming or is this expected to break something else? And for the namespace, should the function be looking for a None namespace or is this expected behaviour?

@fxbuson fxbuson added the bug Something isn't working label Sep 4, 2024
@fxbuson fxbuson added this to the Python SBOL2-3 Converter milestone Sep 4, 2024
@fxbuson
Copy link
Collaborator Author

fxbuson commented Sep 4, 2024

The same applies to the conversion back to SBOL2. I first assumed the version should default to None (which it does right now), but according to the SBOL 3.1 specification:

When SBOL 3.x Identified object is converted to SBOL 2.x, if its identity is a URL, then the identity of
the SBOL 2.x object SHOULD be constructed as [SBOL3 identity]/[SBOL2 version]. If the object does
not have an SBOL2 version property, then its version SHOULD default to 1.

Re-checking the roundtrip conversion, going from 2 > 3 > 2 with component of version = "2.2", I first start with an identity of "http://examples.org/example/2.2" and end with "http://examples.org/example"

@fxbuson
Copy link
Collaborator Author

fxbuson commented Nov 4, 2024

Adding to this, keeping the namespace as None and expecting pysbol3 to handle it does not work because it just uses everything before the last separator.

For http://examples.org/ComponentDefinition/example it assumes the namespace is http://examples.org/ComponentDefinition, when it should just be http://examples.org

Therefore to avoid changes to pysbol3 this will have to be handled inside the converter code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant