Skip to content

Commit ddc2231

Browse files
committed
Day 7 - ApiStar Basics
- load marvel data function - created outline methods - first implementation of list all and get_character
1 parent 32e3dc3 commit ddc2231

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ venv/
8989
ENV/
9090
env.bak/
9191
venv.bak/
92+
*_venv/
9293

9394
# Spyder project settings
9495
.spyderproject
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
from collections import Counter, namedtuple
2+
import csv
3+
import re
4+
from typing import List
5+
6+
from apistar import App, Route, types, validators
7+
from apistar.http import JSONResponse
8+
9+
# helpers
10+
11+
DATA = './marvel-wikia-data.csv'
12+
Character = namedtuple('Character', 'pid name sid align sex appearances year')
13+
14+
15+
def _load_marvel_data(data=DATA):
16+
'''write a function to parse marvel-wikia-data.csv, see
17+
https://docs.python.org/3.7/library/csv.html#csv.DictReader
18+
should return a list of OrderedDicts or a list of Character
19+
namedtuples (see Character namedtuple above')'''
20+
with open(data) as csvfile:
21+
for row in csv.DictReader(csvfile):
22+
name = re.sub(r'(.*?)\(.*', r'\1', row['name']).strip()
23+
# could do:
24+
# yield row
25+
# but namedtuple is more elgant
26+
# tried to make pytest work with both
27+
if row['Year'] == '':
28+
row['Year'] = None
29+
else:
30+
row['Year'] = int(row['Year'])
31+
yield Character(pid=int(row['page_id']),
32+
name=name,
33+
sid=row['ID'],
34+
align=row['ALIGN'],
35+
sex=row['SEX'],
36+
appearances=row['APPEARANCES'],
37+
year=row['Year'])
38+
39+
40+
data = list(_load_marvel_data())
41+
characters = {character.pid: character._asdict() for character in data}
42+
43+
VALID_SIDS = set([value['sid'] for key, value in characters.items()])
44+
VALID_ALIGNS = set([value['align'] for key, value in characters.items()])
45+
VALID_SEXES = set([value['sex'] for key, value in characters.items()])
46+
MIN_YEAR = min([value['year'] if value['year'] is not None else 10000 for key, value in characters.items()])
47+
48+
CHARACTER_NOT_FOUND = 'This character is so secret, they don\'t exist!'
49+
50+
# definition
51+
52+
class MarvelCharacter(types.Type):
53+
pid = validators.Integer(allow_null=True)
54+
name = validators.String(max_length=100)
55+
sid = validators.String(enum=list(VALID_SIDS) , default='')
56+
align = validators.String(enum=list(VALID_ALIGNS) , default='')
57+
sex = validators.String(enum=list(VALID_SEXES) , default='')
58+
appearances = validators.String(default='')
59+
year = validators.Integer(minimum=MIN_YEAR, allow_null=True)
60+
61+
# API methods
62+
63+
def list_characters() -> List[MarvelCharacter]:
64+
return [MarvelCharacter(character) for key, character in sorted(characters.items())]
65+
66+
def create_character(character: MarvelCharacter) -> JSONResponse:
67+
pass
68+
69+
def get_character(character_id: int) -> JSONResponse:
70+
character = characters.get(character_id)
71+
if not character:
72+
error = {'error': CHARACTER_NOT_FOUND}
73+
return JSONResponse(error, status_code=404)
74+
75+
return JSONResponse(MarvelCharacter(character), status_code=200)
76+
77+
def update_character(character_id: int, character: MarvelCharacter) -> JSONResponse:
78+
pass
79+
80+
def delete_character(character_id: int) -> JSONResponse:
81+
pass
82+
83+
routes = [
84+
Route('/', method='GET', handler=list_characters),
85+
Route('/', method='POST', handler=create_character),
86+
Route('/{character_id}/', method='GET', handler=get_character),
87+
Route('/{character_id}/', method='PUT', handler=update_character),
88+
Route('/{character_id}/', method='DELETE', handler=delete_character),
89+
]
90+
91+
app = App(routes=routes)
92+
93+
if __name__ == '__main__':
94+
app.serve('127.0.0.1', 5000, debug=True)
95+
# for key, val in characters.items():
96+
# print(val)

days/009-012-modern-apis-starred/code/marvel-wikia-data.csv

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
apistar==0.5.41
2+
pytest

0 commit comments

Comments
 (0)