mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
[enh] Allow multiple api routes for an action
This commit is contained in:
parent
f2fed4a8b5
commit
abb1517a74
1 changed files with 43 additions and 12 deletions
|
@ -3,6 +3,7 @@
|
|||
import os
|
||||
import re
|
||||
import errno
|
||||
import logging
|
||||
import binascii
|
||||
import argparse
|
||||
from json import dumps as json_encode
|
||||
|
@ -321,6 +322,7 @@ class ActionsMapParser(BaseActionsMapParser):
|
|||
super(ActionsMapParser, self).__init__(parent)
|
||||
|
||||
self._parsers = {} # dict({(method, path): _HTTPArgumentParser})
|
||||
self._route_re = re.compile(r'(GET|POST|PUT|DELETE) (/\S+)')
|
||||
|
||||
@property
|
||||
def routes(self):
|
||||
|
@ -361,23 +363,29 @@ class ActionsMapParser(BaseActionsMapParser):
|
|||
A new _HTTPArgumentParser object for the route
|
||||
|
||||
"""
|
||||
keys = []
|
||||
try:
|
||||
# Validate action route
|
||||
m = re.match('(GET|POST|PUT|DELETE) (/\S+)', api)
|
||||
# Extract action route
|
||||
keys.append(self._extract_route(api))
|
||||
except TypeError:
|
||||
raise AttributeError("the action '%s' doesn't provide api access" % name)
|
||||
if not m:
|
||||
# TODO: Log error
|
||||
raise ValueError("the action '%s' doesn't provide api access" % name)
|
||||
|
||||
# Check if a parser already exists for the route
|
||||
key = (m.group(1), m.group(2))
|
||||
if key in self.routes:
|
||||
raise AttributeError("a parser for '%s' already exists" % key)
|
||||
if isinstance(api, list):
|
||||
# Iterate over action routes
|
||||
for r in api:
|
||||
try:
|
||||
keys.append(self._extract_route(r))
|
||||
except ValueError as e:
|
||||
logging.warning("cannot add api route '%s' for " \
|
||||
"action '%s': %s" % (r, tid, str(e)))
|
||||
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
|
||||
parser = _HTTPArgumentParser()
|
||||
self._parsers[key] = (tid, parser)
|
||||
for k in keys:
|
||||
self._parsers[k] = (tid, parser)
|
||||
|
||||
# Return the created parser
|
||||
return parser
|
||||
|
@ -419,6 +427,29 @@ class ActionsMapParser(BaseActionsMapParser):
|
|||
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):
|
||||
"""Application Programming Interface for the moulinette
|
||||
|
||||
|
|
Loading…
Reference in a new issue