1

I want to follow this structure for a WEB "WSGI pep 3333" API (educational purposes):

/home/
 `--app.py
 `--API_module/
    `--__init__.py
    `--api.py
    `--exceptions.py
 `--modules/
     `--default/
        `--__init__.py
         `--default.py

app.py calls API_module with something like:

app = API_module.api()

the api.py based on "HTTP GET requests" will load modules stored on directory named modules, for now, I am just loading a module named default.

api.py looks like:

import os
import imp
from exceptions import HTTPError, HTTPException

class API(object):
    def __call__(self, env, start_response):
        self.env = env
        self.method = env['REQUEST_METHOD']
        try:
            body = self.router()
            body.dispatch()
        except HTTPError, e:
             print 'HTTP method not valid %s' % e
        except, Exception e:
             print 'something went wrong'

        start_response(status, headers)
        yield body

     def router():
         module_path = '/home/modules/default/default.py'
         if not os.access(module_path, os.R_OK):
             raise HTTPException()
         else:
             py_mod = imp.load_source('default', '/home/modules/default/default.py'
             return py_mod.Resource(self)

and default.py contains something like:

class Resoure(object):
    def __init__(self, app):
        self.app = app

    def dispatch(self):
       raise HTTPException()

So far I can import dynamically the modules but if I want to raise an exception from the default.py module I get an:

global name 'HTTPException' is not defined

Therefore I would like to know, how to take advantage of the API_module/exceptions and use them in all the dynamically modules.

Any ideas, suggestions comments are welcome.

Paolo Casciello
  • 7,982
  • 1
  • 43
  • 42
nbari
  • 25,603
  • 10
  • 76
  • 131
  • @Paolo, what about if the modules are in: `modules/API/v0/default/default.py` the emtpy `__init__.py` would be inside each subdir like modules/, APO/, v0 and default ? – nbari Nov 04 '13 at 19:01
  • Yes, that is a way to do it. Or you can play with `sys.path` for example by adding `modules/API/v0` to the list. But then you can't use `from modules.default ...` syntax which is very elegant to me. You'll instead end up using `from default import default` which is unclear from a code reader perspective. – Paolo Casciello Nov 05 '13 at 10:42
  • I notice that I had to use `__import__('root.api.v0.default.default', fromlist=[''])` the fromlist made the trick. it is ok ? – nbari Nov 05 '13 at 15:06
  • You're right @nbari! I forgot about it. For more informations about it: http://stackoverflow.com/questions/2724260/why-does-pythons-import-require-fromlist – Paolo Casciello Nov 05 '13 at 16:00

1 Answers1

2

It's a matter of sys.path.

In your setup, since your API_module is included from app.py you should have the root of your application in your sys.path so you should just include the API_module in the usual way:

from API_module import exceptions

or

from API_module.exceptions import *

based on how you use it.

Btw, i suggest you use pymod = __import__('modules.default.default', fromlist=['']) and put an __init__.py' file in themodules/` root directory.

Paolo Casciello
  • 7,982
  • 1
  • 43
  • 42