[enh] Allow multiple api routes for an action

This commit is contained in:
Jérôme Lebleu 2014-05-19 12:49:12 +02:00
parent f2fed4a8b5
commit abb1517a74

View file

@ -3,6 +3,7 @@
import os import os
import re import re
import errno import errno
import logging
import binascii import binascii
import argparse import argparse
from json import dumps as json_encode from json import dumps as json_encode
@ -321,6 +322,7 @@ class ActionsMapParser(BaseActionsMapParser):
super(ActionsMapParser, self).__init__(parent) super(ActionsMapParser, self).__init__(parent)
self._parsers = {} # dict({(method, path): _HTTPArgumentParser}) self._parsers = {} # dict({(method, path): _HTTPArgumentParser})
self._route_re = re.compile(r'(GET|POST|PUT|DELETE) (/\S+)')
@property @property
def routes(self): def routes(self):
@ -361,23 +363,29 @@ class ActionsMapParser(BaseActionsMapParser):
A new _HTTPArgumentParser object for the route A new _HTTPArgumentParser object for the route
""" """
keys = []
try: try:
# Validate action route # Extract action route
m = re.match('(GET|POST|PUT|DELETE) (/\S+)', api) keys.append(self._extract_route(api))
except TypeError: except TypeError:
raise AttributeError("the action '%s' doesn't provide api access" % name) if isinstance(api, list):
if not m: # Iterate over action routes
# TODO: Log error for r in api:
raise ValueError("the action '%s' doesn't provide api access" % name) try:
keys.append(self._extract_route(r))
# Check if a parser already exists for the route except ValueError as e:
key = (m.group(1), m.group(2)) logging.warning("cannot add api route '%s' for " \
if key in self.routes: "action '%s': %s" % (r, tid, str(e)))
raise AttributeError("a parser for '%s' already exists" % key) continue
if len(keys) == 0:
raise ValueError("no valid api route found")
else:
raise AttributeError("no api route for action '%s'" % name)
# Create and append parser # Create and append parser
parser = _HTTPArgumentParser() parser = _HTTPArgumentParser()
self._parsers[key] = (tid, parser) for k in keys:
self._parsers[k] = (tid, parser)
# Return the created parser # Return the created parser
return parser return parser
@ -419,6 +427,29 @@ class ActionsMapParser(BaseActionsMapParser):
return parser.parse_args(args, ret) return parser.parse_args(args, ret)
## Private methods
def _extract_route(self, string):
"""Extract action route from a string
Extract, validate and return an action route as a 2-tuple (method, path)
from a string.
Keyword arguments:
- string -- An action route string (e.g. 'GET /')
"""
m = self._route_re.match(string)
if not m:
raise ValueError("invalid route string '%s'" % string)
key = (m.group(1), m.group(2))
if key in self.routes:
raise ValueError("route '%s' already defined" % string)
return key
class Interface(BaseInterface): class Interface(BaseInterface):
"""Application Programming Interface for the moulinette """Application Programming Interface for the moulinette