Crossbar.io configure WSGI for Django app

569 Views Asked by At

I am experimenting with Crossbar.io 0.10.4 and Django 1.6.11, trying to follow the example here. The code shows you can configure Crossbar.io to serve up the Django app at "/" -- but when I try that in my configuration, I get a Python import error:

ApplicationError: ApplicationError('crossbar.error.invalid_configuration', args = (u"WSGI app module 'apache/django.wsgi' import failed: Import by filename is not supported. - Python search path was ....

My config.json is here:

{
   "controller": {
   },
   "workers": [
      {
         "type": "router",
         "realms": [
            {
               "name": "backstage-producer",
               "roles": [
                  {
                     "name": "anonymous",
                     "permissions": [
                        {
                           "uri": "*",
                           "publish": false,
                           "subscribe": true,
                           "call": false,
                           "register": false
                        }
                     ]
                  }
               ]
            }
         ],
         "transports": [
            {
               "type": "web",
               "endpoint": {
                  "type": "tcp",
                  "port": 8080
               },
               "paths": {
                   "/": {
                     "type": "wsgi",
                     "module": "apache/django.wsgi",
                     "object": "application"
                  },
                  "ws": {
                     "type": "websocket",
                     "debug": false
                  },
                  "notify": {
                     "type": "publisher",
                     "realm": "backstage-producer",
                     "role": "anonymous"
                  },
                  "static": {
                     "type": "static",
                     "directory": "../static"
                  }
               }
            }
         ]
      }
   ]
}

Where the Python paths searched do not include my Django project directory. Typically I append my specific project directories to sys.path in my wsgi file, but apparently that workflow doesn't work with Crossbar.io. Trying a relative import fails (need to specify "package" argument) as does full path (same import by filename error as above).

Removing the definition for "/" does not work, because Crossbar.io complains that it must be defined.

How can I set this up properly with Crossbar.io? My apache/django.wsgi file is below, for reference:

ALLDIRS = ['/usr/local/pythonenv/myapp/lib/python2.6/site-packages']

import os
import sys
import site

# from https://code.google.com/p/modwsgi/wiki/VirtualEnvironments

sys.path.insert(0, '/var/www/myapp/myapp_main/')
sys.path.insert(1, '/var/www/myapp/')

prev_sys_path = list(sys.path)
for directory in ALLDIRS:
    site.addsitedir(directory)

new_sys_path = []
for item in list(sys.path):
    if item not in prev_sys_path:
        new_sys_path.append(item)
        sys.path.remove(item)

sys.path[:0] = new_sys_path

os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp_main.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

----UPDATE 1------

Per Daniel's suggestion, I changed the file to just wsgi.py and my config to use the Python module path, not the filename / directory path. Config then looked like this:

"paths": {
       "/": {
         "type": "wsgi",
         "module": "apache.wsgi",
         "object": "application"
      },

Throws the same exception:

ApplicationError: ApplicationError('crossbar.error.invalid_configuration', args = (u"WSGI app module 'apache.wsgi' import failed: No module named apache.wsgi - Python search path was

My directory structure is:

  Project
    |- apache
    |     |-__init__.py
    |     |-wsgi.py
    |-.crossbar
          |-config.json 

-------UPDATE 2-------

The only solution (read "hack") I have found is to hard-code my project path into crossbar/worker/router.py so that it is included in the Python search path list:

sys.path.insert(0, '/var/www/myapp/myapp_main/')
sys.path.insert(1, '/var/www/myapp/')

Seems like there should be a better way...

1

There are 1 best solutions below

2
On BEST ANSWER

The error is telling you that you have a file path in the setting that points to your WSGI file, whereas you need a Python module path. Your WSGI file should actually be a file called "wsgi.py" inside your project directory (which presumably is "apache", which is a strange name for a project that explicitly is not using Apache).

               "/": {
                 "type": "wsgi",
                 "module": "apache.wsgi",
                 "object": "application"
              },

Update So I found the config docs at last: they really don't go out of their way to make it easy, like actually providing an index. Oh well.

It looks like you can provide an options hash to the router configuration including a pythonpath setting:

"workers": [
      {
         "type": "router",
         "options": {
             "pythonpath": ["/var/myapp/myapp_main/", "/var/myapp"]
         },
         ...
         "transports": {
             ...