:maxdepth: 1
api_models.rst
+ routing.rst
Concepts
''''''''
--- /dev/null
+.. _routing:
+
+Routing
+=======
+
+The OpenERP framework, as an HTTP server, serves a few hard-coded URLs
+(``models``, ``db``, ...) to expose RPC endpoints. When running the web addons
+(which is almost always the case), it also serves URLs without them being RPC
+endpoints.
+
+In older version of OpenERP, adding RPC endpoints was done by subclassing the
+``openerp.netsvc.ExportService`` class. Adding WSGI handlers was done by
+registering them with the ``openerp.wsgi.register_wsgi_handler()`` function.
+
+Starting with OpenERP 7.1, exposing a new arbitrary WSGI handler is done with
+the ``openerp.service.handler`` decorator while adding an RPC endpoint is done
+with the ``openerp.service.rpc`` decorator.
+
import os
import platform
import release
-import socket
import sys
import threading
import time
threading.current_thread().uid = None
threading.current_thread().dbname = None
- service = None
- if service_name == 'object':
- service = openerp.service.model
- if service_name == 'db':
- service = openerp.service.db
if service_name == 'common':
- service = openerp.service.common
- if service_name == 'report':
- service = openerp.service.report
- result = service.dispatch(method, params)
+ dispatch = openerp.service.common.dispatch
+ elif service_name == 'db':
+ dispatch = openerp.service.db.dispatch
+ elif service_name == 'object':
+ dispatch = openerp.service.model.dispatch
+ elif service_name == 'report':
+ dispatch = openerp.service.report.dispatch
+ else:
+ dispatch = openerp.service.wsgi_server.rpc_handlers.get(service_name)
+ result = dispatch(method, params)
if rpc_request_flag or rpc_response_flag:
end_time = time.time()
openerp.phoenix = True
os.kill(os.getpid(), signal.SIGINT)
+def handler():
+ """TODO"""
+ def decorator(f):
+ wsgi_server.register_wsgi_handler(f)
+ return decorator
+
+def route(url):
+ """TODO"""
+ def decorator(f):
+ pass # TODO Same as handler() but register the handler under a specific url.
+ return decorator
+
+def rpc(endpoint):
+ """TODO"""
+ def decorator(f):
+ wsgi_server.register_rpc_endpoint(endpoint, f)
+ return decorator
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
import logging
import os
import signal
+import socket
import sys
import threading
import traceback
# WSGI handlers registered through the register_wsgi_handler() function below.
module_handlers = []
+# RPC endpoints registered through the register_rpc_endpoint() function below.
+rpc_handlers = {}
def register_wsgi_handler(handler):
""" Register a WSGI handler.
"""
module_handlers.append(handler)
+def register_rpc_endpoint(endpoint, handler):
+ """ Register a handler for a given RPC enpoint.
+ """
+ rpc_handlers[endpoint] = handler
+
def application_unproxied(environ, start_response):
""" WSGI entry point."""
openerp.service.start_internal()
self.proxy.common_60 = xmlrpclib.ServerProxy(url_60 + 'common')
self.proxy.db_60 = xmlrpclib.ServerProxy(url_60 + 'db')
self.proxy.object_60 = xmlrpclib.ServerProxy(url_60 + 'object')
+ #self.proxy.edi_60 = xmlrpclib.ServerProxy(url_60 + 'edi')
# Use the new (6.1) API.
self.proxy.url_61 = url_61 = 'http://%s:%d/openerp/xmlrpc/1/' % (HOST, PORT)
ids = proxy.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'search', [], {})
assert ids
+ # This test was written to test the creation of a new RPC endpoint, not
+ # really for the EDI itself.
+ #def test_xmlrpc_import_edi_document(self):
+ # """ Try to call an EDI method. """
+ # msg_re = 'EDI Document is empty!'
+ # with self.assertRaisesRegexp(Exception, msg_re):
+ # self.proxy.edi_60.import_edi_document(DB, ADMIN_USER_ID, ADMIN_PASSWORD, {})
+
def test_zz_xmlrpc_drop_database(self):
"""
Simulate a OpenERP client requesting the deletion of a database.