GNUnet 0.22.0
flask_base.py
Go to the documentation of this file.
1"""
2 sphinxcontrib.autohttp.flask
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5 The sphinx.ext.autodoc-style HTTP API reference builder (from Flask)
6 for sphinxcontrib.httpdomain.
7
8 :copyright: Copyright 2011 by Hong Minhee
9 :license: BSD, see LICENSE for details.
10
11"""
12
13import re
14import itertools
15import six
16
17from docutils import nodes
18from docutils.parsers.rst import directives
19from docutils.statemachine import ViewList
20
21from sphinx.util import force_decode
22from sphinx.util.compat import Directive
23from sphinx.util.nodes import nested_parse_with_titles
24from sphinx.util.docstrings import prepare_docstring
25from sphinx.pycode import ModuleAnalyzer
26
27from sphinxcontrib import httpdomain
28from sphinxcontrib.autohttp.common import http_directive, import_object
29
30
31def translate_werkzeug_rule(rule):
32 from werkzeug.routing import parse_rule
33 buf = six.StringIO()
34 for conv, arg, var in parse_rule(rule):
35 if conv:
36 buf.write('(')
37 if conv != 'default':
38 buf.write(conv)
39 buf.write(':')
40 buf.write(var)
41 buf.write(')')
42 else:
43 buf.write(var)
44 return buf.getvalue()
45
46
47def get_routes(app, endpoint=None, order=None):
48 endpoints = []
49 for rule in app.url_map.iter_rules(endpoint):
50 url_with_endpoint = (
51 six.text_type(next(app.url_map.iter_rules(rule.endpoint))),
52 rule.endpoint
53 )
54 if url_with_endpoint not in endpoints:
55 endpoints.append(url_with_endpoint)
56 if order == 'path':
57 endpoints.sort()
58 endpoints = [e for _, e in endpoints]
59 for endpoint in endpoints:
60 methodrules = {}
61 for rule in app.url_map.iter_rules(endpoint):
62 methods = rule.methods.difference(['OPTIONS', 'HEAD'])
63 path = translate_werkzeug_rule(rule.rule)
64 for method in methods:
65 if method in methodrules:
66 methodrules[method].append(path)
67 else:
68 methodrules[method] = [path]
69 for method, paths in methodrules.items():
70 yield method, paths, endpoint
71
72
73def quickref_directive(method, path, content):
74 rcomp = re.compile("^\s*.. :quickref:\s*(?P<quick>.*)$")
75 method = method.lower().strip()
76 if isinstance(content, six.string_types):
77 content = content.splitlines()
78 description=""
79 name=""
80 ref = path.replace("<","(").replace(">",")").replace("/","-").replace(":","-")
81 for line in content:
82 qref = rcomp.match(line)
83 if qref:
84 quickref = qref.group("quick")
85 parts = quickref.split(";",1)
86 if len(parts)>1:
87 name = parts[0]
88 description= parts[1]
89 else:
90 description= quickref
91 break
92
93 row ={}
94 row['name'] = name
95 row['operation'] = ' - `%s %s <#%s-%s>`_' % (method.upper(), path, method.lower(), ref)
96 row['description'] = description
97
98 return row
99
100class AutoflaskBase(Directive):
101
102 has_content = True
103 required_arguments = 1
104 option_spec = {'endpoints': directives.unchanged,
105 'blueprints': directives.unchanged,
106 'modules': directives.unchanged,
107 'order': directives.unchanged,
108 'undoc-endpoints': directives.unchanged,
109 'undoc-blueprints': directives.unchanged,
110 'undoc-modules': directives.unchanged,
111 'undoc-static': directives.unchanged,
112 'include-empty-docstring': directives.unchanged}
113
114 @property
115 def endpoints(self):
116 endpoints = self.options.get('endpoints', None)
117 if not endpoints:
118 return None
119 return re.split(r'\s*,\s*', endpoints)
120
121 @property
123 undoc_endpoints = self.options.get('undoc-endpoints', None)
124 if not undoc_endpoints:
125 return frozenset()
126 return frozenset(re.split(r'\s*,\s*', undoc_endpoints))
127
128 @property
129 def blueprints(self):
130 blueprints = self.options.get('blueprints', None)
131 if not blueprints:
132 return None
133 return frozenset(re.split(r'\s*,\s*', blueprints))
134
135 @property
137 undoc_blueprints = self.options.get('undoc-blueprints', None)
138 if not undoc_blueprints:
139 return frozenset()
140 return frozenset(re.split(r'\s*,\s*', undoc_blueprints))
141
142 @property
143 def modules(self):
144 modules = self.options.get('modules', None)
145 if not modules:
146 return frozenset()
147 return frozenset(re.split(r'\s*,\s*', modules))
148
149 @property
150 def undoc_modules(self):
151 undoc_modules = self.options.get('undoc-modules', None)
152 if not undoc_modules:
153 return frozenset()
154 return frozenset(re.split(r'\s*,\s*', undoc_modules))
155
156 @property
157 def order(self):
158 order = self.options.get('order', None)
159 if order not in (None, 'path'):
160 raise ValueError('Invalid value for :order:')
161 return order
162
163 def make_rst(self, qref=False):
164 app = import_object(self.arguments[0])
165 if self.endpointsendpoints:
166 routes = itertools.chain(*[get_routes(app, endpoint, self.orderorder)
167 for endpoint in self.endpointsendpoints])
168 else:
169 routes = get_routes(app, order=self.orderorder)
170 for method, paths, endpoint in routes:
171 try:
172 blueprint, _, endpoint_internal = endpoint.rpartition('.')
173 if self.blueprintsblueprints and blueprint not in self.blueprintsblueprints:
174 continue
175 if blueprint in self.undoc_blueprintsundoc_blueprints:
176 continue
177 except ValueError:
178 pass # endpoint is not within a blueprint
179
180 if endpoint in self.undoc_endpointsundoc_endpoints:
181 continue
182 try:
183 static_url_path = app.static_url_path # Flask 0.7 or higher
184 except AttributeError:
185 static_url_path = app.static_path # Flask 0.6 or under
186 if ('undoc-static' in self.options and endpoint == 'static' and
187 static_url_path + '/(path:filename)' in paths):
188 continue
189 view = app.view_functions[endpoint]
190
191 if self.modulesmodules and view.__module__ not in self.modulesmodules:
192 continue
193
194 if self.undoc_modulesundoc_modules and view.__module__ in self.modulesmodules:
195 continue
196
197 docstring = view.__doc__ or ''
198 if hasattr(view, 'view_class'):
199 meth_func = getattr(view.view_class, method.lower(), None)
200 if meth_func and meth_func.__doc__:
201 docstring = meth_func.__doc__
202 if not isinstance(docstring, six.text_type):
203 analyzer = ModuleAnalyzer.for_module(view.__module__)
204 docstring = force_decode(docstring, analyzer.encoding)
205
206 if not docstring and 'include-empty-docstring' not in self.options:
207 continue
208 docstring = prepare_docstring(docstring)
209 if qref == True:
210 for path in paths:
211 row = quickref_directive(method, path, docstring)
212 yield row
213 else:
214 for line in http_directive(method, paths, docstring):
215 yield line
static int replace
Replace DID Document Flag.
Definition: gnunet-did.c:52
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:62
def http_directive(method, path, content)
Definition: common.py:25
def import_object(import_name)
Definition: common.py:15
def get_routes(app, endpoint=None, order=None)
Definition: flask_base.py:47
def quickref_directive(method, path, content)
Definition: flask_base.py:73