Mercurial > p > roundup > code
changeset 5695:3e1b66c4e1e2
Update docs. Correct errors reported by setup.py build_docs. Add rest
interface and link to rest doc to features page. Add link to xmlrpc
doc to features page. Add rest doc to index. Update rest doc,
hopefully clarify confusing use of parameters in patch action
section. Fix code examples in "Adding new rest endpoints" section. Fix
example adding import of exception.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 07 Apr 2019 20:17:52 -0400 |
| parents | c3ffa1ef6b7f |
| children | b67636bc87d0 |
| files | doc/features.txt doc/index.txt doc/rest.txt |
| diffstat | 3 files changed, 44 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/features.txt Sat Apr 06 10:20:19 2019 -0400 +++ b/doc/features.txt Sun Apr 07 20:17:52 2019 -0400 @@ -104,10 +104,17 @@ *xmlrpc interface* - simple remote tracker interface with basic HTTP authentication + available at the /xmlrpc endpoint. - provides same access to tracker as roundup-admin, but based on XMLRPC calls + - see the `xmlrpc guide`_ for more details simple clients etc. + +*restful interface* + - accessible using basic HTTP authentication at /rest starting point + - see the `rest guide`_ for details. .. _sqlite: http://www.hwaci.com/sw/sqlite/ .. _mysql: https://pypi.org/project/MySQL-python/ .. _postgresql: http://initd.org/software/initd/psycopg - +.. _`xmlrpc guide`: xmlrpc.html +.. _`rest guide`: rest.html
--- a/doc/index.txt Sat Apr 06 10:20:19 2019 -0400 +++ b/doc/index.txt Sun Apr 07 20:17:52 2019 -0400 @@ -19,6 +19,7 @@ admin_guide debugging xmlrpc + rest overview Design (original) <design> developers
--- a/doc/rest.txt Sat Apr 06 10:20:19 2019 -0400 +++ b/doc/rest.txt Sun Apr 07 20:17:52 2019 -0400 @@ -36,7 +36,7 @@ Summary ======= -A Summary page can be reached via ``/data/summary`` via the ``GET`` method. +A Summary page can be reached via ``/summary`` via the ``GET`` method. This is currently hard-coded for the standard tracker schema shipped with roundup and will display a summary of open issues. @@ -136,13 +136,13 @@ Finally the ``PATCH`` method can be applied to individual items, e.g., ``/data/issue/42`` and to properties, e.g., ``/data/issue/42/title``. -This method gets an operator ``@op=<method>`` where ``<method`` is one +This method gets an operator ``@op=<method>`` where ``<method>`` is one of ``add``, ``replace``, ``remove``, only for an item (not for a property) an additional operator ``action`` is supported. If no operator is specified, the default is ``replace``. The first three operators are self explanatory. For an ``action`` operator an ``@action_name`` and optional ``@action_argsXXX`` parameters have to be supplied. Currently -there are only two actions without parameters, namely ``retire`` and +there are only two actions, neither has args, namely ``retire`` and ``restore``. The ``retire`` action on an item is the same as a ``DELETE`` method, it retires the item. The ``restore`` action is the inverse of ``retire``, the item is again visible. @@ -198,9 +198,10 @@ Add or edit the file interfaces.py at the root of the tracker directory. -In that file add (remove indentation): +In that file add:: from roundup.rest import Routing, RestfulInstance, _data_decorator + from roundup.exceptions import Unauthorised class RestfulInstance: @@ -210,7 +211,7 @@ result = { "hello": "world" } return 200, result -will make a new endpoint .../rest/summary2 that you can test with: +will make a new endpoint .../rest/summary2 that you can test with:: $ curl -X GET .../rest/summary2 { @@ -219,25 +220,29 @@ } } -Similarly appending this to interfaces.py after summary2: +Similarly appending this to interfaces.py after summary2:: - @Routing.route("/data/<:class_name>/@schema", 'GET') - def get_element_schema(self, class_name, input): - result = { "schema": {} } - uid = self.db.getuid () - if not self.db.security.hasPermission('View', uid, class_name) : - raise Unauthorised('Permission to view %s denied' % class_name) + # handle more endpoints + @Routing.route("/data/<:class_name>/@schema", 'GET') + def get_element_schema(self, class_name, input): + result = { "schema": {} } + uid = self.db.getuid () + if not self.db.security.hasPermission('View', uid, class_name) : + raise Unauthorised('Permission to view %s denied' % class_name) - class_obj = self.db.getclass(class_name) - props = class_obj.getprops(protected=False) - schema = result['schema'] + class_obj = self.db.getclass(class_name) + props = class_obj.getprops(protected=False) + schema = result['schema'] + + for prop in props: + schema[prop] = { "type": repr(class_obj.properties[prop]) } - for prop in props: - schema[prop] = { "type": repr(class_obj.properties[prop]) } + return result - return result +.. + the # comment in the example is needed to preserve indention under Class. -returns some data about the class +returns some data about the class:: $ curl -X GET .../rest/data/issue/@schema { @@ -258,6 +263,9 @@ } +Adding other endpoints (e.g. to allow an OPTIONS query against +``/data/issue/@schema``) is left as an exercise for the reader. + Searches and selection ====================== @@ -271,9 +279,9 @@ to get a list of items for the user to select from. Consider a multi-select box for the superseder property. Using -selectize.js (and jquery) code similar to: +selectize.js (and jquery) code similar to:: - $('#superseder').selectize({ + $('#superseder').selectize({ valueField: 'id', labelField: 'title', searchField: 'title', ... @@ -289,9 +297,9 @@ Sets up a box that a user can type the word "request" into. Then selectize.js will use that word to generate an ajax request with the -url: .../rest/data/issue?@verbose=2&title=request +url: ``.../rest/data/issue?@verbose=2&title=request`` -This will return data like: +This will return data like:: { "data": { @@ -307,6 +315,7 @@ "id": "27", "title": "Request for foo" }, + ... selectize.js will look at these objects (as passed to callback(res.data.collection)) and create a select list from the each @@ -316,7 +325,7 @@ issues. Only 440 had the word "request" somewhere in the title greatly reducing the amount of data that needed to be transferred. -Similar things can be set up to search a large list of keywords using +Similar code can be set up to search a large list of keywords using:: .../rest/data/keyword?@verbose=2&name=some @@ -326,7 +335,7 @@ Hopefully future enhancements will allow get on a collection to include other fields. Why do we want this? Selectize.js can set up option groups (optgroups) in the select pulldown. So by including -status in the returned data: +status in the returned data:: { "link": ".../rest/data/issue/27", @@ -335,7 +344,7 @@ 'status": "open" }, -a select widget like: +a select widget like:: === New === A request
