Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ MANIFEST
dist
.cache
.eggs/*
build/*
restea.egg-info/*
35 changes: 28 additions & 7 deletions restea/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import collections

import six

import restea.errors as errors
import restea.formats as formats
import restea.fields as fields
Expand All @@ -19,6 +21,7 @@ class Resource(object):
'post': 'create',
'put': 'edit',
'delete': 'delete',
'options': 'describe',
}

def __init__(self, request, formatter):
Expand All @@ -45,7 +48,7 @@ def _iden_required(self, method_name):
:returns: boolean value of whatever iden is needed or not
:rtype: bool
'''
return method_name not in ('list', 'create')
return method_name not in ('list', 'create', 'describe')

def _match_response_to_fields(self, dct):
'''
Expand Down Expand Up @@ -104,9 +107,10 @@ def _get_method_name(self, has_iden):
'HTTP_X_HTTP_METHOD_OVERRIDE',
method
)
method_name = self.method_map.get(method.lower())

if not method_name:
try:
method_name = self.method_map[method.lower()]
except KeyError:
raise errors.MethodNotAllowedError(
'Method "{}" is not supported'.format(self.request.method)
)
Expand Down Expand Up @@ -231,6 +235,8 @@ def process(self, *args, **kwargs):
method = self._get_method(method_name)
method = self._apply_decorators(method)

if method_name == 'describe':
self._add_available_methods_to_response_headers()
self.prepare()
response = method(self, *args, **kwargs)
response = self.finish(response)
Expand All @@ -242,11 +248,10 @@ def process(self, *args, **kwargs):

def dispatch(self, *args, **kwargs):
'''
Dispatches the request and handles exception to return data, status
and content type

:returns: 4-element tuple: result, HTTP status code, content type, and
Dispatches the request and handles exception to return data, status, content type, and
headers

:returns: 4-element tuple: result, HTTP status code, content type, and headers
:rtype: tuple
'''
try:
Expand All @@ -267,6 +272,22 @@ def dispatch(self, *args, **kwargs):
self._response_headers
)

def _add_available_methods_to_response_headers(self):
methods_available = []
for http_method, method_name in self._stream_http_method_and_restea_method():
if hasattr(self, method_name):
methods_available.append(http_method.upper())
self.set_header('Allow', ','.join(set(methods_available)))

@classmethod
def _stream_http_method_and_restea_method(cls):
for http_method, method_names in six.iteritems(cls.method_map):
if isinstance(method_names, tuple):
for method_name in method_names:
yield http_method, method_name
else:
yield http_method, method_names

def set_header(self, name, value):
'''
Sets the given response header name and value.
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from setuptools import setup

readme_content = ''
with open("README.rst") as f:
readme_content = f.read()

setup(
name='restea',
packages=['restea', 'restea.adapters'],
version='0.3.12',
version='0.3.13',
description='Simple RESTful server toolkit',
long_description=readme_content,
author='Walery Jadlowski',
Expand All @@ -33,6 +32,7 @@
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Internet :: WWW/HTTP',
Expand Down
6 changes: 6 additions & 0 deletions tests/test_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ def test_get_method_name_delete():
assert 'delete' == resource._get_method_name(has_iden=True)


def test_get_method_name_options():
resource, _, _ = create_resource_helper(method='OPTIONS')
assert 'describe' == resource._get_method_name(has_iden=True)


def test_get_method_name_unpecefied_method():
resource, _, _ = create_resource_helper(method='HEAD')

Expand All @@ -98,6 +103,7 @@ def test_iden_required_negative():
resource, _, _ = create_resource_helper()
assert resource._iden_required('create') is False
assert resource._iden_required('list') is False
assert resource._iden_required('describe') is False


def test_match_response_to_fields():
Expand Down