Search code examples
pythontwisted

How to avoid ImportError in twisted tac file?


I have a twisted tac file (twisted_service.py) with a code:

from twisted.application import service
# application.py file in the same dir
from .application import setup_reactor


class WebsocketService(service.Service):

    def startService(self):
        service.Service.startService(self)
        setup_reactor()

application = service.Application("ws")

ws_service = WebsocketService()
ws_service.setServiceParent(application)

Here is application.py file, which sets up the reactor:

# -*- coding: utf-8 -*-
from twisted.web.server import Site
from twisted.web.static import Data
from twisted.internet import reactor, defer
from autobahn.twisted.resource import WebSocketResource
from autobahn.twisted.websocket import WebSocketServerFactory
from txsni.snimap import SNIMap
from txsni.maputils import Cache
from txsni.snimap import HostDirectoryMap
from twisted.python.filepath import FilePath
from tools.database.async import pg_conn
from tools.database import makedsn
from tools.config import main_db
from tools.modules.external import flask_setup


import tools.config as config
import websockethandlers as wsh
from pytrapd import TrapsListener


PROTOCOLMAP = {
    'portcounters': wsh.PortCounters,
    'eqcounters': wsh.EquipmentCounters,
    'settings': wsh.Settings,
    'refresh': wsh.Refresher,
    'montraps': wsh.TrapsMonitoring,
    'fdbs': wsh.FdbParser,
    'portstate': wsh.PortState,
    'cable': wsh.CableDiagnostic,
    'eqcable': wsh.EquipmentCableDiagnostic,
    'igmp': wsh.Igmp,
    'ipmac': wsh.IpMac,
    'lldp': wsh.LLDPParser,
    'alias': wsh.AliasSetup,
    'ping': wsh.Ping
}


@defer.inlineCallbacks
def setup_reactor():
    flask_setup()
    yield pg_conn.connect(makedsn(main_db))
    root = Data("", "text/plain")
    for key in PROTOCOLMAP:
        factory = WebSocketServerFactory("wss://localhost:%s" % config.ws_port)
        factory.protocol = PROTOCOLMAP[key]
        resource = WebSocketResource(factory)
        root.putChild(key, resource)
    site = Site(root)
    context_factory = SNIMap(
        Cache(HostDirectoryMap(FilePath(config.certificates_directory)))
    )
    reactor.listenSSL(config.ws_port, site, context_factory)
    traps_listener = TrapsListener()
    traps_listener.listen_traps(config.trap_ip)
    traps_listener.listen_messages(config.fifo_file)

if __name__ == '__main__':
    setup_reactor()
    import sys

    from twisted.python import log
    log.startLogging(sys.stdout)
    reactor.run()

I use twistd -noy twisted_service.py command to run the twisted service. It has been working for twisted 16.3.2 version. After upgrade to any next version I got the error:

Unhandled Error
Traceback (most recent call last):
  File "/home/kalombo/.virtualenvs/dev/local/lib/python2.7/site-packages/twisted/application/app.py", line 662, in run
    runApp(config)
  File "/home/kalombo/.virtualenvs/dev/local/lib/python2.7/site-packages/twisted/scripts/twistd.py", line 25, in runApp
    _SomeApplicationRunner(config).run()
  File "/home/kalombo/.virtualenvs/dev/local/lib/python2.7/site-packages/twisted/application/app.py", line 380, in run
    self.application = self.createOrGetApplication()
  File "/home/kalombo/.virtualenvs/dev/local/lib/python2.7/site-packages/twisted/application/app.py", line 445, in createOrGetApplication
    application = getApplication(self.config, passphrase)
--- <exception caught here> ---
  File "/home/kalombo/.virtualenvs/dev/local/lib/python2.7/site-packages/twisted/application/app.py", line 456, in getApplication
    application = service.loadApplication(filename, style, passphrase)
  File "/home/kalombo/.virtualenvs/dev/local/lib/python2.7/site-packages/twisted/application/service.py", line 412, in loadApplication
    application = sob.loadValueFromFile(filename, 'application')
  File "/home/kalombo/.virtualenvs/dev/local/lib/python2.7/site-packages/twisted/persisted/sob.py", line 177, in loadValueFromFile
    eval(codeObj, d, d)
  File "twisted_service.py", line 3, in <module>
    from .application import setup_reactor
exceptions.ImportError: No module named application

How should I run the twisted or import module properly?


Solution

  • I found the answer here http://twistedmatrix.com/pipermail/twisted-python/2016-September/030783.html

    It is a new feature in Twisted 16.4.0. In previous versions twistd script automatically added working dir to system paths, from 16.4.0 version i have to added it manually. It can be added something like this in twisted_service.py file:

    import os
    import sys
    TWISTED_DIR = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(TWISTED_DIR)