Skip to content

Commit a35d3d1

Browse files
authored
Merge pull request #3 from puentesarrin/options_describe_2
Add OPTIONS method to allow providing documentation
2 parents 1b343ba + 935ed56 commit a35d3d1

4 files changed

Lines changed: 36 additions & 9 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ MANIFEST
66
dist
77
.cache
88
.eggs/*
9+
build/*
910
restea.egg-info/*

restea/resource.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import collections
44
import collections.abc
55

6+
import six
7+
68
import restea.errors as errors
79
import restea.formats as formats
810
import restea.fields as fields
@@ -20,6 +22,7 @@ class Resource(object):
2022
'post': 'create',
2123
'put': 'edit',
2224
'delete': 'delete',
25+
'options': 'describe',
2326
}
2427

2528
def __init__(self, request, formatter):
@@ -46,7 +49,7 @@ def _iden_required(self, method_name):
4649
:returns: boolean value of whatever iden is needed or not
4750
:rtype: bool
4851
'''
49-
return method_name not in ('list', 'create')
52+
return method_name not in ('list', 'create', 'describe')
5053

5154
def _match_response_to_fields(self, dct):
5255
'''
@@ -105,9 +108,10 @@ def _get_method_name(self, has_iden):
105108
'HTTP_X_HTTP_METHOD_OVERRIDE',
106109
method
107110
)
108-
method_name = self.method_map.get(method.lower())
109111

110-
if not method_name:
112+
try:
113+
method_name = self.method_map[method.lower()]
114+
except KeyError:
111115
raise errors.MethodNotAllowedError(
112116
'Method "{}" is not supported'.format(self.request.method)
113117
)
@@ -232,6 +236,8 @@ def process(self, *args, **kwargs):
232236
method = self._get_method(method_name)
233237
method = self._apply_decorators(method)
234238

239+
if method_name == 'describe':
240+
self._add_available_methods_to_response_headers()
235241
self.prepare()
236242
response = method(self, *args, **kwargs)
237243
response = self.finish(response)
@@ -243,11 +249,10 @@ def process(self, *args, **kwargs):
243249

244250
def dispatch(self, *args, **kwargs):
245251
'''
246-
Dispatches the request and handles exception to return data, status
247-
and content type
248-
249-
:returns: 4-element tuple: result, HTTP status code, content type, and
252+
Dispatches the request and handles exception to return data, status, content type, and
250253
headers
254+
255+
:returns: 4-element tuple: result, HTTP status code, content type, and headers
251256
:rtype: tuple
252257
'''
253258
try:
@@ -268,6 +273,22 @@ def dispatch(self, *args, **kwargs):
268273
self._response_headers
269274
)
270275

276+
def _add_available_methods_to_response_headers(self):
277+
methods_available = []
278+
for http_method, method_name in self._stream_http_method_and_restea_method():
279+
if hasattr(self, method_name):
280+
methods_available.append(http_method.upper())
281+
self.set_header('Allow', ','.join(set(methods_available)))
282+
283+
@classmethod
284+
def _stream_http_method_and_restea_method(cls):
285+
for http_method, method_names in six.iteritems(cls.method_map):
286+
if isinstance(method_names, tuple):
287+
for method_name in method_names:
288+
yield http_method, method_name
289+
else:
290+
yield http_method, method_names
291+
271292
def set_header(self, name, value):
272293
'''
273294
Sets the given response header name and value.

setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
from setuptools import setup
22

3-
readme_content = ''
43
with open("README.rst") as f:
54
readme_content = f.read()
65

76
setup(
87
name='restea',
98
packages=['restea', 'restea.adapters'],
10-
version='0.4.1',
9+
version='0.4.2',
1110
description='Simple RESTful server toolkit',
1211
long_description=readme_content,
1312
author='Walery Jadlowski',

tests/test_resource.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ def test_get_method_name_delete():
7373
assert 'delete' == resource._get_method_name(has_iden=True)
7474

7575

76+
def test_get_method_name_options():
77+
resource, _, _ = create_resource_helper(method='OPTIONS')
78+
assert 'describe' == resource._get_method_name(has_iden=True)
79+
80+
7681
def test_get_method_name_unpecefied_method():
7782
resource, _, _ = create_resource_helper(method='HEAD')
7883

@@ -98,6 +103,7 @@ def test_iden_required_negative():
98103
resource, _, _ = create_resource_helper()
99104
assert resource._iden_required('create') is False
100105
assert resource._iden_required('list') is False
106+
assert resource._iden_required('describe') is False
101107

102108

103109
def test_match_response_to_fields():

0 commit comments

Comments
 (0)