Skip to content
Merged
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
9 changes: 2 additions & 7 deletions examples/flask/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,11 @@ def is_authenticated(self):
return True

def make_user_key(self, username):
return 'user_{}'.format(username)
return f'user_{username}'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function UserResource.make_user_key refactored with the following changes:


def list(self):
usernames = self.conn.lrange('users', 0, 100)
users = []

for user in usernames:
users.append(self.conn.hgetall(self.make_user_key(user)))

return users
return [self.conn.hgetall(self.make_user_key(user)) for user in usernames]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function UserResource.list refactored with the following changes:


def detail(self, username):
return self.conn.hgetall(self.make_user_key(username))
Expand Down
9 changes: 2 additions & 7 deletions examples/pyramid/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,11 @@ def is_authenticated(self):
return True

def make_user_key(self, username):
return 'user_{}'.format(username)
return f'user_{username}'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function UserResource.make_user_key refactored with the following changes:


def list(self):
usernames = self.conn.lrange('users', 0, 100)
users = []

for user in usernames:
users.append(self.conn.hgetall(self.make_user_key(user)))

return users
return [self.conn.hgetall(self.make_user_key(user)) for user in usernames]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function UserResource.list refactored with the following changes:


def detail(self, username):
return self.conn.hgetall(self.make_user_key(username))
Expand Down
21 changes: 7 additions & 14 deletions restless/dj.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,19 @@ def wrap_list_response(self, data):

# Because Django.
@classmethod
def as_list(self, *args, **kwargs):
return csrf_exempt(super(DjangoResource, self).as_list(*args, **kwargs))
def as_list(cls, *args, **kwargs):
return csrf_exempt(super(DjangoResource, cls).as_list(*args, **kwargs))
Comment on lines -63 to +64
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DjangoResource.as_list refactored with the following changes:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return csrf_exempt(super(DjangoResource, cls).as_list(*args, **kwargs))
return csrf_exempt(super().as_list(*args, **kwargs))

It's unnecessary to use arguments when calling super for the parent class. Read more.


@classmethod
def as_detail(self, *args, **kwargs):
return csrf_exempt(super(DjangoResource, self).as_detail(*args, **kwargs))
def as_detail(cls, *args, **kwargs):
return csrf_exempt(super(DjangoResource, cls).as_detail(*args, **kwargs))
Comment on lines -67 to +68
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DjangoResource.as_detail refactored with the following changes:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return csrf_exempt(super(DjangoResource, cls).as_detail(*args, **kwargs))
return csrf_exempt(super().as_detail(*args, **kwargs))

As above, These super arguments are unnecessary.


def is_debug(self):
return settings.DEBUG

def build_response(self, data, status=OK):
if status == NO_CONTENT:
# Avoid crashing the client when it tries to parse nonexisting JSON.
content_type = 'text/plain'
else:
content_type = 'application/json'
resp = HttpResponse(data, content_type=content_type, status=status)
return resp
content_type = 'text/plain' if status == NO_CONTENT else 'application/json'
return HttpResponse(data, content_type=content_type, status=status)
Comment on lines -74 to +75
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DjangoResource.build_response refactored with the following changes:

This removes the following comments ( why? ):

# Avoid crashing the client when it tries to parse nonexisting JSON.


def build_error(self, err):
# A bit nicer behavior surrounding things that don't exist.
Expand Down Expand Up @@ -105,9 +100,7 @@ def build_url_name(cls, name, name_prefix=None):
:rtype: string
"""
if name_prefix is None:
name_prefix = 'api_{}'.format(
cls.__name__.replace('Resource', '').lower()
)
name_prefix = f"api_{cls.__name__.replace('Resource', '').lower()}"
Comment on lines -108 to +103
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DjangoResource.build_url_name refactored with the following changes:


name_prefix = name_prefix.rstrip('_')
return '_'.join([name_prefix, name])
Expand Down
14 changes: 4 additions & 10 deletions restless/fl.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,7 @@ def is_debug(self):
return current_app.debug

def build_response(self, data, status=OK):
if status == NO_CONTENT:
# Avoid crashing the client when it tries to parse nonexisting JSON.
content_type = 'text/plain'
else:
content_type = 'application/json'
content_type = 'text/plain' if status == NO_CONTENT else 'application/json'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function FlaskResource.build_response refactored with the following changes:

This removes the following comments ( why? ):

# Avoid crashing the client when it tries to parse nonexisting JSON.

return make_response(data, status, {
'Content-Type': content_type,
})
Expand All @@ -74,9 +70,7 @@ def build_endpoint_name(cls, name, endpoint_prefix=None):
:rtype: string
"""
if endpoint_prefix is None:
endpoint_prefix = 'api_{}'.format(
cls.__name__.replace('Resource', '').lower()
)
endpoint_prefix = f"api_{cls.__name__.replace('Resource', '').lower()}"
Comment on lines -77 to +73
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function FlaskResource.build_endpoint_name refactored with the following changes:


endpoint_prefix = endpoint_prefix.rstrip('_')
return '_'.join([endpoint_prefix, name])
Expand Down Expand Up @@ -111,8 +105,8 @@ def add_url_rules(cls, app, rule_prefix, endpoint_prefix=None):
methods=methods
)
app.add_url_rule(
rule_prefix + '<pk>/',
f'{rule_prefix}<pk>/',
endpoint=cls.build_endpoint_name('detail', endpoint_prefix),
view_func=cls.as_detail(),
methods=methods
methods=methods,
Comment on lines -114 to +111
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function FlaskResource.add_url_rules refactored with the following changes:

)
13 changes: 2 additions & 11 deletions restless/preparers.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,7 @@ def lookup_data(self, lookup, data):
if callable(value) and not hasattr(value, 'db_manager'):
value = value()

if not remaining_lookup:
return value

# There's more to lookup, so dive in recursively.
return self.lookup_data(remaining_lookup, value)
return self.lookup_data(remaining_lookup, value) if remaining_lookup else value
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function FieldsPreparer.lookup_data refactored with the following changes:

This removes the following comments ( why? ):

# There's more to lookup, so dive in recursively.



class SubPreparer(FieldsPreparer):
Expand Down Expand Up @@ -234,9 +230,4 @@ def prepare(self, data):

Returns a list of data as the response.
"""
result = []

for item in self.get_inner_data(data):
result.append(self.preparer.prepare(item))

return result
return [self.preparer.prepare(item) for item in self.get_inner_data(data)]
Comment on lines -237 to +233
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function CollectionSubPreparer.prepare refactored with the following changes:

13 changes: 3 additions & 10 deletions restless/pyr.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,8 @@ def _wrapper(request):
return _wrapper

def build_response(self, data, status=OK):
if status == NO_CONTENT:
# Avoid crashing the client when it tries to parse nonexisting JSON.
content_type = 'text/plain'
else:
content_type = 'application/json'
resp = Response(data, status_code=status, content_type=content_type)
return resp
content_type = 'text/plain' if status == NO_CONTENT else 'application/json'
return Response(data, status_code=status, content_type=content_type)
Comment on lines -32 to +33
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function PyramidResource.build_response refactored with the following changes:

This removes the following comments ( why? ):

# Avoid crashing the client when it tries to parse nonexisting JSON.


@classmethod
def build_routename(cls, name, routename_prefix=None):
Expand All @@ -56,9 +51,7 @@ def build_routename(cls, name, routename_prefix=None):
:rtype: string
"""
if routename_prefix is None:
routename_prefix = 'api_{}'.format(
cls.__name__.replace('Resource', '').lower()
)
routename_prefix = f"api_{cls.__name__.replace('Resource', '').lower()}"
Comment on lines -59 to +54
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function PyramidResource.build_routename refactored with the following changes:


routename_prefix = routename_prefix.rstrip('_')
return '_'.join([routename_prefix, name])
Expand Down
41 changes: 16 additions & 25 deletions restless/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,12 @@ def handle(self, endpoint, *args, **kwargs):
try:
# Use ``.get()`` so we can also dodge potentially incorrect
# ``endpoint`` errors as well.
if not method in self.http_methods.get(endpoint, {}):
if method not in self.http_methods.get(endpoint, {}):
raise MethodNotImplemented(
"Unsupported method '{}' for {} endpoint.".format(
method,
endpoint
)
f"Unsupported method '{method}' for {endpoint} endpoint."
)

Comment on lines -273 to 277
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Resource.handle refactored with the following changes:


if not self.is_authenticated():
raise Unauthorized()

Expand Down Expand Up @@ -340,10 +338,7 @@ def deserialize_list(self, body):

:returns: The deserialized body or an empty ``list``
"""
if body:
return self.serializer.deserialize(body)

return []
return self.serializer.deserialize(body) if body else []
Comment on lines -343 to +341
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Resource.deserialize_list refactored with the following changes:


def deserialize_detail(self, body):
"""
Expand All @@ -354,10 +349,7 @@ def deserialize_detail(self, body):

:returns: The deserialized body or an empty ``dict``
"""
if body:
return self.serializer.deserialize(body)

return {}
return self.serializer.deserialize(body) if body else {}
Comment on lines -357 to +352
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Resource.deserialize_detail refactored with the following changes:


def serialize(self, method, endpoint, data):
"""
Expand Down Expand Up @@ -402,10 +394,11 @@ def serialize_list(self, data):

# Check for a ``Data``-like object. We should assume ``True`` (all
# data gets prepared) unless it's explicitly marked as not.
if not getattr(data, 'should_prepare', True):
prepped_data = data.value
else:
prepped_data = [self.prepare(item) for item in data]
prepped_data = (
[self.prepare(item) for item in data]
if getattr(data, 'should_prepare', True)
else data.value
)
Comment on lines -405 to +401
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Resource.serialize_list refactored with the following changes:


final_data = self.wrap_list_response(prepped_data)
return self.serializer.serialize(final_data)
Expand All @@ -425,10 +418,11 @@ def serialize_detail(self, data):

# Check for a ``Data``-like object. We should assume ``True`` (all
# data gets prepared) unless it's explicitly marked as not.
if not getattr(data, 'should_prepare', True):
prepped_data = data.value
else:
prepped_data = self.prepare(data)
prepped_data = (
self.prepare(data)
if getattr(data, 'should_prepare', True)
else data.value
)
Comment on lines -428 to +425
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Resource.serialize_detail refactored with the following changes:


return self.serializer.serialize(prepped_data)

Expand Down Expand Up @@ -479,10 +473,7 @@ def is_authenticated(self):
:returns: Whether the request is authenticated or not.
:rtype: boolean
"""
if self.request_method() == 'GET':
return True

return False
return self.request_method() == 'GET'
Comment on lines -482 to +476
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Resource.is_authenticated refactored with the following changes:


# Common methods the user should implement.

Expand Down
36 changes: 15 additions & 21 deletions restless/tnd.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@

from tornado.concurrent import Future

if futures is None:
FUTURES = Future
else:
FUTURES = (Future, futures.Future)

FUTURES = Future if futures is None else (Future, futures.Future)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 27-31 refactored with the following changes:

is_future = lambda x: isinstance(x, FUTURES)


Expand Down Expand Up @@ -100,22 +96,27 @@ def as_view(cls, view_type, *init_args, **init_kwargs):
global _method

new_cls = type(
cls.__name__ + '_' + _BridgeMixin.__name__ + '_restless',
(_BridgeMixin, cls._request_handler_base_,),
f'{cls.__name__}_{_BridgeMixin.__name__}_restless',
(
_BridgeMixin,
cls._request_handler_base_,
),
dict(
__resource_cls__=cls,
__resource_args__=init_args,
__resource_kwargs__=init_kwargs,
__resource_view_type__=view_type)
__resource_view_type__=view_type,
),
)

Comment on lines -103 to 111
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function TornadoResource.as_view refactored with the following changes:


"""
Add required http-methods to the newly created class
We need to scan through MRO to find what functions users declared,
and then add corresponding http-methods used by Tornado.
"""
bases = inspect.getmro(cls)
bases = bases[0:bases.index(Resource)-1]
bases = bases[:bases.index(Resource)-1]
for k, v in cls.http_methods[view_type].items():
if any(v in base_cls.__dict__ for base_cls in bases):
setattr(new_cls, k.lower(), _method)
Expand All @@ -129,13 +130,8 @@ def request_body(self):
return self.request.body

def build_response(self, data, status=OK):
if status == NO_CONTENT:
# Avoid crashing the client when it tries to parse nonexisting JSON.
content_type = 'text/plain'
else:
content_type = 'application/json'
self.ref_rh.set_header("Content-Type", "{}; charset=UTF-8"
.format(content_type))
content_type = 'text/plain' if status == NO_CONTENT else 'application/json'
self.ref_rh.set_header("Content-Type", f"{content_type}; charset=UTF-8")
Comment on lines -132 to +134
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function TornadoResource.build_response refactored with the following changes:

This removes the following comments ( why? ):

# Avoid crashing the client when it tries to parse nonexisting JSON.


self.ref_rh.set_status(status)
self.ref_rh.finish(data)
Expand All @@ -152,14 +148,12 @@ def handle(self, endpoint, *args, **kwargs):
method = self.request_method()

try:
if not method in self.http_methods.get(endpoint, {}):
if method not in self.http_methods.get(endpoint, {}):
raise MethodNotImplemented(
"Unsupported method '{}' for {} endpoint.".format(
method,
endpoint
)
f"Unsupported method '{method}' for {endpoint} endpoint."
)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function TornadoResource.handle refactored with the following changes:


if not self.is_authenticated():
raise Unauthorized()

Expand Down
5 changes: 2 additions & 3 deletions restless/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MoreTypesJSONEncoder(json.JSONEncoder):
def default(self, data):
if isinstance(data, (datetime.datetime, datetime.date, datetime.time)):
return data.isoformat()
elif isinstance(data, decimal.Decimal) or isinstance(data, uuid.UUID):
elif isinstance(data, (decimal.Decimal, uuid.UUID)):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function MoreTypesJSONEncoder.default refactored with the following changes:

return str(data)
else:
return super(MoreTypesJSONEncoder, self).default(data)
Expand All @@ -33,8 +33,7 @@ def format_traceback(exc_info):
stack = stack[:-2]
stack.extend(traceback.format_tb(exc_info[2]))
stack.extend(traceback.format_exception_only(exc_info[0], exc_info[1]))
stack_str = "Traceback (most recent call last):\n"
stack_str += "".join(stack)
stack_str = "Traceback (most recent call last):\n" + "".join(stack)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function format_traceback refactored with the following changes:

# Remove the last \n
stack_str = stack_str[:-1]
return stack_str
9 changes: 3 additions & 6 deletions tests/test_dj.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ def fake_init(self):
]

def is_authenticated(self):
if self.request_method() == 'DELETE' and self.endpoint == 'list':
return False

return True
return self.request_method() != 'DELETE' or self.endpoint != 'list'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DjTestResource.is_authenticated refactored with the following changes:


def list(self):
return self.fake_db
Expand All @@ -80,7 +77,7 @@ def detail(self, pk):
return item

# If it wasn't found in our fake DB, raise a Django-esque exception.
raise ObjectDoesNotExist("Model with pk {} not found.".format(pk))
raise ObjectDoesNotExist(f"Model with pk {pk} not found.")
Comment on lines -83 to +80
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DjTestResource.detail refactored with the following changes:


def create(self):
self.fake_db.append(FakeModel(
Expand Down Expand Up @@ -154,7 +151,7 @@ def detail(self, pk):
return item

# If it wasn't found in our fake DB, raise a Django-esque exception.
raise Http404("Model with pk {} not found.".format(pk))
raise Http404(f"Model with pk {pk} not found.")
Comment on lines -157 to +154
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DjTestResourceHttp404Handling.detail refactored with the following changes:



@unittest.skipIf(not settings, "Django is not available")
Expand Down
5 changes: 1 addition & 4 deletions tests/test_pyr.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ def create(self):
self.fake_db.append(self.data)

def is_authenticated(self):
if self.request_method() == 'DELETE':
return False

return True
return self.request_method() != 'DELETE'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function PyrTestResource.is_authenticated refactored with the following changes:



@unittest.skipIf(not testing, 'Pyramid is not available')
Expand Down
Loading