Hi all,
I am using web.py to dynamically generate basic CRUD operations on objects defined in my SQLAlchemy model on startup of the application. This was working fine up to now. Now I added an extra SQLAlchemy object and somehow I get a 404 error when calling a url for it that is defined in the application mapping and does work for the other SQLAlchemy objects.
I did a debug session, showing the mapping of my application. You can see that /rvc_species/sample/ and /rvc_species/speciesgroup/ are both present in the mapping and point to a web.appliation.application instance and both have exactly the same urls defined for them, using the same classes for each url.
#Issue the requests
>>> app.request('/rvc_species/sample/').status
'200 OK'
>>> app.request('/rvc_species/speciesgroup/').status
'404 Not Found'
#Check the applications in /rvc_species
>>> dict(dict(app.mapping)['/rvc_species'].mapping).keys()
['/sample', '/speciesgroup', '/site', '/observation', '/species', '/new', '/observer']
>>> dict(dict(app.mapping)['/rvc_species'].mapping)['/sample']
<web.application.application instance at 0x7feed45f3a70>
>>> dict(dict(app.mapping)['/rvc_species'].mapping)['/speciesgroup']
<web.application.application instance at 0x7feed45f5fc8>
#check the urls/controllers defined for both /rvc_species/sample and /rvc_species/speciesgroup
>>> dict(dict(app.mapping)['/rvc_species'].mapping)['/sample'].mapping
[['/', <class controllers.dynamic_controller.lst at 0x7feed411f390>], ['/new', <class controllers.dynamic_controller.new at 0x7feed411f4c8>], ['/([0-9]+)', <class controllers.dynamic_controller.show at 0x7feed411f3f8>], ['/delete', <class controllers.dynamic_controller.deletectl at 0x7feed411f460>]]
>>> dict(dict(app.mapping)['/rvc_species'].mapping)['/speciesgroup'].mapping
[['/', <class controllers.dynamic_controller.lst at 0x7feed411fbb0>], ['/new', <class controllers.dynamic_controller.new at 0x7feed411fce8>], ['/([0-9]+)', <class controllers.dynamic_controller.show at 0x7feed411fc18>], ['/delete', <class controllers.dynamic_controller.deletectl at 0x7feed411fc80>]]
This is my basic web.py application script. I left out some extra stuff but what is there is unaltered.
render = web.template.render('templates/')
class new:
def GET(self):
return render.new()
class index:
def GET(self):
datasets = [d.__name__.split('.')[-1] for d in model.datasets]
return render.index(datasets)
urls = [
"/", index
]
for dataset in [d.__name__.split('.')[-1] for d in model.datasets]:
#loop over the different 'datasets' in the SQLAlchemy model
ds_urls = ["/new",new] #create a "new" controller with a standard form for each dataset
for obj in getattr(model,dataset).tables:
#for each 'table' in the SQLAlchemy model, create a subapplication defining basic CRUD operations
application = getApplication(obj)
name = obj.__name__.lower()
ds_urls += ["/%s"%name,application]
ds_app = web.application(tuple(ds_urls), locals(), autoreload=False)
urls.append("/%s"%dataset)
urls.append(ds_app)
app = web.application(tuple(urls), globals(),autoreload=False)
This code calls getApplication which is pretty simple and looks like the following:
def getApplication(orm_cls):
class lst(BaseListController):
ORM_CLS = orm_cls
class show(BaseShowController):
ORM_CLS = orm_cls
class deletectl(BaseDeleteController):
ORM_CLS = orm_cls
class new(BaseController):
ID = orm_cls.__name__.lower()
TITLE = 'New %s'%orm_cls.__name__
ORM_CLS = orm_cls
urls = (
"/", lst,
"/new", new,
"/([0-9]+)", show,
"/delete", deletectl
)
return web.application(urls, locals())
The BaseListController, BaseDeleteController, BaseController and BaseShowController just define GET and sometimes POST methods that provide basic CRUD operations on the object defined in it's ORM_CLS.
I have no clue why I get 404 errors for /rvc_species/speciesgroup/ but not for /rvc_species/sample/.
Does anyone have any idea how I can debug this further?
Cheers,
Dolf.