Skip to content

Commit

Permalink
Add default function for retrieve
Browse files Browse the repository at this point in the history
  • Loading branch information
Ricardo Sánchez committed Feb 16, 2021
1 parent 141a534 commit 1629d34
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 16 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ SHELL := bash
PATH := ./venv/bin:${PATH}
PYTHON = python3.8
PROJECT = agave
isort = isort $(PROJECT) tests setup.py
black = black -S -l 79 --target-version py38 $(PROJECT) $(PROJECT)/lib/* tests setup.py
isort = isort $(PROJECT) examples tests setup.py
black = black -S -l 79 --target-version py38 $(PROJECT) examples $(PROJECT)/lib/* tests setup.py


.PHONY: all
Expand Down
17 changes: 8 additions & 9 deletions agave/blueprints/rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,6 @@ def retrieve(id: str):
The most of times this implementation is enough and is not
necessary define a custom "retrieve" method
"""
if hasattr(cls, 'retrieve'):
# at the moment, there are no resources with a custom
# retrieve method
return cls.retrieve(id) # pragma: no cover
try:
id_query = Q(id=id)
if self.user_id_filter_required():
Expand All @@ -156,7 +152,7 @@ def retrieve(id: str):
mimetype = self.current_request.headers.get('accept')
extension = mimetypes.guess_extension(mimetype)
filename = f'{cls.model._class_name}.{extension}'
return Response(
result = Response(
body=file.read(),
headers={
'Content-Type': mimetype,
Expand All @@ -166,7 +162,12 @@ def retrieve(id: str):
},
status_code=200,
)
return data.to_dict()
elif hasattr(cls, 'retrieve'):
result = cls.retrieve(data)
else:
result = data.to_dict()

return result

@self.get(path)
@copy_attributes(cls)
Expand Down Expand Up @@ -199,9 +200,7 @@ def query():
query_params.user_id = self.current_user_id
filters = cls.get_query_filter(query_params)
if hasattr(cls, 'query'):
return cls.query(
_all(query_params, filters)
) # pragma: no cover)
return cls.query(_all(query_params, filters))
if query_params.count:
return _count(filters)
return _all(query_params, filters)
Expand Down
2 changes: 1 addition & 1 deletion agave/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.1.0'
__version__ = '0.1.1.dev2'
3 changes: 2 additions & 1 deletion examples/chalicelib/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
__all__ = ['Account', 'Transaction']
__all__ = ['Account', 'Card', 'Transaction', 'File']

from .accounts import Account
from .cards import Card
from .files import File
from .transactions import Transaction
11 changes: 11 additions & 0 deletions examples/chalicelib/models/cards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from mongoengine import DateTimeField, Document, StringField

from agave.models import BaseModel
from agave.models.helpers import uuid_field


class Card(BaseModel, Document):
id = StringField(primary_key=True, default=uuid_field('CA'))
number = StringField(required=True)
user_id = StringField(required=True)
created_at = DateTimeField()
3 changes: 2 additions & 1 deletion examples/chalicelib/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__all__ = ['app', 'Account', 'Transaction']
__all__ = ['app', 'Account', 'Card', 'File', 'Transaction']

from .accounts import Account
from .base import app
from .cards import Card
from .files import File
from .transactions import Transaction
28 changes: 28 additions & 0 deletions examples/chalicelib/resources/cards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from typing import Dict

from chalice import Response

from agave.filters import generic_query

from ..models import Card as CardModel
from ..validators import CardQuery
from .base import app


@app.resource('/cards')
class Card:
model = CardModel
query_validator = CardQuery
get_query_filter = generic_query

@staticmethod
def retrieve(card: CardModel) -> Response:
data = card.to_dict()
data['number'] = '*' * 16
return Response(data)

@staticmethod
def query(response: Dict):
for item in response['items']:
item['number'] = '*' * 16
return response
5 changes: 5 additions & 0 deletions examples/chalicelib/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,10 @@ class AccountRequest(BaseModel):
class AccountUpdateRequest(BaseModel):
name: str


class FileQuery(QueryParams):
user_id: Optional[str] = None


class CardQuery(QueryParams):
number: Optional[str] = None
22 changes: 21 additions & 1 deletion tests/blueprint/test_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from chalice.test import Client
from mock import MagicMock, patch

from examples.chalicelib.models import Account, File
from examples.chalicelib.models import Account, Card, File

USER_ID_FILTER_REQUIRED = (
'examples.chalicelib.blueprints.authed.'
Expand Down Expand Up @@ -55,6 +55,12 @@ def test_update_resource_with_invalid_params(client: Client) -> None:
assert response.status_code == 400


def test_retrieve_custom_method(client: Client, card: Card) -> None:
resp = client.http.get(f'/cards/{card.id}')
assert resp.status_code == 200
assert resp.json_body['number'] == '*' * 16


def test_update_resource_that_doesnt_exist(client: Client) -> None:
resp = client.http.patch(
'/accounts/5f9b4d0ff8d7255e3cc3c128',
Expand Down Expand Up @@ -139,6 +145,20 @@ def test_query_resource_with_invalid_params(client: Client) -> None:
assert response.status_code == 400


@pytest.mark.usefixtures('cards')
def test_query_custom_method(client: Client) -> None:
query_params = dict(page_size=2)
resp = client.http.get(f'/cards?{urlencode(query_params)}')
assert resp.status_code == 200
assert len(resp.json_body['items']) == 2
assert all(card['number'] == '*' * 16 for card in resp.json_body['items'])

resp = client.http.get(resp.json_body['next_page_uri'])
assert resp.status_code == 200
assert len(resp.json_body['items']) == 2
assert all(card['number'] == '*' * 16 for card in resp.json_body['items'])


def test_cannot_create_resource(client: Client) -> None:
response = client.http.post('/transactions', json=dict())
assert response.status_code == 405
Expand Down
40 changes: 39 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest
from chalice.test import Client

from examples.chalicelib.models import Account, File
from examples.chalicelib.models import Account, Card, File

from .helpers import accept_json

Expand Down Expand Up @@ -90,3 +90,41 @@ def files() -> Generator[List[File], None, None]:
@pytest.fixture
def file(files: List[File]) -> Generator[File, None, None]:
yield files[0]


@pytest.fixture
def cards() -> Generator[List[Card], None, None]:
user_id = 'US123456789'
cards = [
Card(
number='5434000000000001',
user_id=user_id,
created_at=dt.datetime(2020, 1, 1),
),
Card(
number='5434000000000002',
user_id=user_id,
created_at=dt.datetime(2020, 2, 1),
),
Card(
number='5434000000000003',
user_id=user_id,
created_at=dt.datetime(2020, 3, 1),
),
Card(
number='5434000000000004',
user_id='US987654321',
created_at=dt.datetime(2020, 4, 1),
),
]

for card in cards:
card.save()
yield cards
for card in cards:
card.delete()


@pytest.fixture
def card(cards: List[Card]) -> Generator[Card, None, None]:
yield cards[0]

0 comments on commit 1629d34

Please sign in to comment.