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 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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue