Bioprotocols / labop

Laboratory Open Protocol (LabOP) Language
MIT License
40 stars 11 forks source link

AttributeError on paml import #84

Open tsdobbs opened 2 years ago

tsdobbs commented 2 years ago

This is inconsistent, but has shown up enough on different systems that it's worth reporting. After installation via git clone ... and pip3 install ., importing paml inside of a python environment with import paml produces this error:

AttributeError                            Traceback (most recent call last)
Input In [2], in <module>
----> 1 import paml

File /opt/conda/lib/python3.9/site-packages/paml/__init__.py:11, in <module>
      8 from sbol_factory import SBOLFactory, UMLFactory
      9 import sbol3
---> 11 import uml # Note: looks unused, but is used in SBOLFactory
     13 # Load the ontology and create a Python module called paml_submodule
     14 SBOLFactory('paml_submodule',
     15             posixpath.join(os.path.dirname(os.path.realpath(__file__)),
     16             'paml.ttl'),
     17             'http://bioprotocols.org/paml#')

File /opt/conda/lib/python3.9/site-packages/uml/__init__.py:9, in <module>
      6 import sbol3
      8 # Load ontology and create uml submodule
----> 9 SBOLFactory('uml_submodule',
     10             posixpath.join(os.path.dirname(os.path.realpath(__file__)),
     11             'uml.ttl'),
     12             'http://bioprotocols.org/uml#')
     14 # Import submodule symbols into top-level uml module
     15 from uml_submodule import *

File /opt/conda/lib/python3.9/site-packages/sbol_factory/sbol_factory.py:89, in SBOLFactory.__new__(cls, module_name, ontology_path, ontology_namespace, verbose)
     87 SBOLFactory.query = Query(ontology_path)
     88 symbol_table = {}
---> 89 for class_uri in SBOLFactory.query.query_classes():
     90     symbol_table = SBOLFactory.generate(class_uri, symbol_table, ontology_namespace)
     92 spec = importlib.util.spec_from_loader(
     93     module_name,
     94     OntologyLoader(symbol_table)
     95 )

File /opt/conda/lib/python3.9/site-packages/sbol_factory/query.py:59, in Query.query_classes(self)
     51 def query_classes(self):
     52     query = '''
     53         SELECT distinct ?cls 
     54         WHERE 
   (...)
     57         }}
     58         '''.format(str(Query.OPIL))
---> 59     response = self.graph.query(query)
     60     sbol_types = [str(row[0]) for row in response]
     61     return sbol_types

File /opt/conda/lib/python3.9/site-packages/rdflib/graph.py:1127, in Graph.query(self, query_object, processor, result, initNs, initBindings, use_store_provided, **kwargs)
   1124         pass  # store has no own implementation
   1126 if not isinstance(result, query.Result):
-> 1127     result = plugin.get(result, query.Result)
   1128 if not isinstance(processor, query.Processor):
   1129     processor = plugin.get(processor, query.Processor)(self)

File /opt/conda/lib/python3.9/site-packages/rdflib/plugin.py:107, in get(name, kind)
    104 except KeyError:
    105     raise PluginException(
    106         "No plugin registered for (%s, %s)" % (name, kind))
--> 107 return p.getClass()

File /opt/conda/lib/python3.9/site-packages/rdflib/plugin.py:69, in Plugin.getClass(self)
     67 def getClass(self):
     68     if self._class is None:
---> 69         module = __import__(self.module_path, globals(), locals(), [""])
     70         self._class = getattr(module, self.class_name)
     71     return self._class

File /opt/conda/lib/python3.9/site-packages/rdflib/plugins/sparql/__init__.py:33, in <module>
     23 """
     24 Custom evaluation functions
     25 
     26 These must be functions taking (ctx, part) and raise
     27 NotImplementedError if they cannot handle a certain part
     28 """
     31 PLUGIN_ENTRY_POINT = 'rdf.plugins.sparqleval'
---> 33 from . import parser
     34 from . import operators
     35 from . import parserutils

File /opt/conda/lib/python3.9/site-packages/rdflib/plugins/sparql/parser.py:184, in <module>
    179 PN_PREFIX = Regex(u'[%s](?:[%s\\.]*[%s])?' % (PN_CHARS_BASE_re,
    180                                               PN_CHARS_re, PN_CHARS_re), flags=re.U)
    182 # [140] PNAME_NS ::= PN_PREFIX? ':'
    183 PNAME_NS = Optional(
--> 184     Param('prefix', PN_PREFIX)) + Suppress(':').leaveWhitespace()
    186 # [173] PN_LOCAL_ESC ::= '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )
    188 PN_LOCAL_ESC_re = '\\\\[_~\\.\\-!$&"\'()*+,;=/?#@%]'

File /opt/conda/lib/python3.9/site-packages/rdflib/plugins/sparql/parserutils.py:114, in Param.__init__(self, name, expr, isList)
    113 def __init__(self, name, expr, isList=False):
--> 114     self.name = name
    115     self.isList = isList
    116     TokenConverter.__init__(self, expr)

AttributeError: can't set attribute

The error appears related to the rdflib import, and I see there are already outstanding issues ( #78 ) and PRs ( #79, #82 ). Perhaps this is related?

Regardless, most of my team initially gets this error once they've installed paml, but are sometimes able to fix it by trying a seemingly-random collection of installs and uninstalls of various packages inside and outside of virtualenvs, conda environments, and even Docker containers. Two anecdotes:

The desired behavior is, of course, that paml imports with no errors on all machines.

tsdobbs commented 2 years ago

I suspect it's a red herring, but if it's useful, here is the Dockerfile I used:

# syntax=docker/dockerfile:1
FROM jupyter/minimal-notebook

USER root

RUN apt-get update && \
    apt-get install -y gcc graphviz

# set environment variables
ENV APP_HOME=/usr/src/app
ENV PYTHONDONOTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# set working directory
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME

# add and install requirements
COPY . .
RUN pip3 install .

# set up jupyter to run on port assigned to dyno
CMD jupyter lab --config=./jupyter_config

The file references a jupyter_config.py file, which just makes a few config changes to allow it to be deployed on the cloud. It contains the following:

import os
c = get_config()
# Kernel config
c.IPKernelApp.pylab = 'inline'  # if you want plotting support always in your notebook
# Notebook config
c.NotebookApp.notebook_dir = 'notebooks'
c.NotebookApp.allow_origin = u'IP ADDRESS' # replaced with public ip address
c.NotebookApp.ip = '*'
c.NotebookApp.allow_remote_access = True
c.NotebookApp.open_browser = False
# ipython -c "from notebook.auth import passwd; passwd()"
c.NotebookApp.password = u'PASSWORD' #replaced with hashed password
c.NotebookApp.port = int(os.environ.get("PORT", 8888))
c.NotebookApp.allow_root = True
c.NotebookApp.allow_password_change = True
c.ConfigurableHTTPProxy.command = ['configurable-http-proxy', '--redirect-port', '80']

Both files are in the top-level paml directory. I run docker build -t paml . to build the image and docker run -e PORT=8888 -p 8888:8888 paml to run it.

jakebeal commented 2 years ago

I'm pretty sure this will be addressed by fixing #78 : rdflib has been a bit of a moving target thanks to their recent major version change, and once we make the transition from 5 to 6 I suspect it will simplify.

@bbartley : I've marked #78 as critical

bbartley commented 2 years ago

@tsdobbs I've upgraded PAML to use rdflib 6 -- please see if this update resolves your installation errors and please let me know if it doesn't!

tsdobbs commented 2 years ago

Thanks @bbartley. It is importing now, at least on the Heroku dyno I tested it on.

It looks now like paml_check isn't importing though. Possibly related?

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Input In [19], in <module>
      9 from IPython.display import Markdown
     12 from paml.execution_engine import ExecutionEngine
---> 13 from paml_check.paml_check import check_doc
     14 from paml_convert.markdown.markdown_specialization import MarkdownSpecialization
     16 get_ipython().run_line_magic('load_ext', 'autoreload')

ModuleNotFoundError: No module named 'paml_check'

I propose a good metric for testing if all imports are working is if everything imports properly on the Google CoLab Notebook. If it works there, then at least we know that it can work on a fresh machine with minimal other dependencies.

bbartley commented 2 years ago

Hi @tsdobbs I recently made the paml-check utility an "extra" option upon installation -- since it requires the z3 solver which doesn't build on all systems.

I've updated the README with these instructions as well.

rpgoldman commented 2 years ago

If we were able to get PAML to run on anaconda, that might be a Good Thing, since conda has a Z3 package, which means that installing paml-check will be easier.

I'm afraid I don't really understand conda packaging -- I just have had to use conda on some projects for data analysis because it makes installing the mkl libraries not impossible...

jakebeal commented 2 years ago

@rpgoldman I've moved the conda question to a new issue, since we need to be operational outside of conda as well.

jakebeal commented 2 years ago

@tsdobbs Is there anything remaining to be done to resolve this issue, or can it be closed?