Skip to content
This repository was archived by the owner on Dec 12, 2022. It is now read-only.

Commit 56ec8a9

Browse files
Auth and update Readme
1 parent 5d5b4ae commit 56ec8a9

14 files changed

+81
-19
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Simple-quiz-api
22
Simple flask app wich run a server with an api implemented
33
## Features
4+
* JWT authentification
45
* Multiple choice question
56
* Simple Choice Question
67
## Requirements
@@ -16,10 +17,10 @@ In the repository open bash and run:
1617
go in app folder and run in a cmd
1718
```python run.py```
1819
## Usage
19-
### To show a question with the id provided
20+
### To show a question with the id provided (Require no auth)
2021
```http://<your_url>/show-question/<id>```
2122
return json
2223
### To create a new question
23-
```http://<your_url>/create-question/``` and argument (POST method) question, answer, category, level (int between 1 and 3), it returns json
24+
```$ curl -X POST http://localhost:5000/create-question/ -H "Authorization: JWT <your token> -d "question=<question>" -d "answer=<answer>" -d "level=<>" -d "category=<>"``` and argument (POST method) question, answer, category, level (int between 1 and 3), it returns json
2425
## In the next releases
2526
authentification, update question, exception ...

app/__pycache__/run.cpython-37.pyc

911 Bytes
Binary file not shown.

app/api/MultipleChoiceQuestion.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,27 @@ def show_question(self, question_id):
2828
}
2929

3030
def create_question(self):
31+
"""create a question and add it in the json file specified in config_mutiplechoice.txt"""
3132
parser = reqparse.RequestParser()
3233
parser.add_argument('question', type=str, help="the question", required=True)
3334
parser.add_argument('choice', action='append', help="choice for the question", required=True)
3435
parser.add_argument('answer', type=str, required=True, help="the answer")
36+
3537
#category of the questions
3638
parser.add_argument('category', type=str)
37-
#int between 1 and 3 to define args
39+
40+
#int between 1 and 3
3841
parser.add_argument('level', type=int, help="int between 1 and 3 to define level")
3942
args = parser.parse_args()
43+
44+
#check if arg level is between 1 and 3
45+
try:
46+
if args['level'] != None: assert args['level'] < 3, "Level must be between 1 and 3"
47+
except AssertionError as error:
48+
return {
49+
"error" : str(error)
50+
}
51+
4052
#converts args object to a dict
4153
keys = ['question', 'choice', 'answer', 'category', 'level']
4254
dict_element = {}

app/api/OperationQuestion.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from flask_restful import Resource
22
from . Question import Question
33
from . MultipleChoiceQuestion import MultipleChoiceQuestion
4-
4+
from flask_jwt import JWT, jwt_required
5+
from . User import *
56

67
class ShowQuestion(Resource):
78
def get(self, question_id):
@@ -12,9 +13,11 @@ def get(self, question_id):
1213
return MultipleChoiceQuestion().show_question(question_id)
1314

1415
class CreateQuestion(Resource):
16+
@jwt_required()
1517
def post(self):
1618
return Question().create_question()
1719
class CreateMultipleChoiceQuestion(Resource):
20+
@jwt_required()
1821
def post(self):
1922
return MultipleChoiceQuestion().create_question()
2023

app/api/Question.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,26 @@
66
class Question:
77

88
def path_to_file_question(self):
9-
#find the path where is located the questions file
9+
"""find the path where is located the questions file"""
1010
with open('config.txt', 'r') as file:
1111
path_to_file = file.read()
1212
return path_to_file
1313

1414
def read_question_file(self):
15-
#open and copy the questions file
15+
"""open and copy the questions file"""
1616
path_to_file = self.path_to_file_question()
1717
with open(path_to_file, 'r') as json_file:
1818
questions_json_file = json.load(json_file)
1919
return questions_json_file
2020

2121
def write_questions_json_file(self, questions_json_file):
22-
#write question json file with the object provided
22+
"""write question json file with the list provided"""
2323
path_to_file = self.path_to_file_question()
2424
with open(path_to_file, 'w') as file_question:
2525
json.dump(questions_json_file, file_question)
2626

2727
def show_question(self, question_id):
28-
#return the question according to the question_id provided
28+
"""return the question according to the question_id provided"""
2929
question_file = self.read_question_file()
3030
for dic_quest in question_file:
3131
if dic_quest['id'] == question_id:
@@ -43,28 +43,44 @@ def show_question(self, question_id):
4343
}
4444

4545
def create_question(self):
46+
"""create a question and add it in the json file specified in config.txt"""
4647
parser = reqparse.RequestParser()
4748
parser.add_argument('question', type=str, help="the question", required=True)
4849
parser.add_argument('answer', type=str, required=True, help="the answer")
50+
4951
#category of the questions
5052
parser.add_argument('category', type=str)
51-
#int between 1 and 3 to define args
53+
54+
#int between 1 and 3
5255
parser.add_argument('level', type=int, help="int between 1 and 3 to define level")
5356
args = parser.parse_args()
54-
#converts args object to a dict
57+
58+
#check if arg level is between 1 and 3
59+
try:
60+
if args['level'] != None: assert args['level'] < 3, "Level must be between 1 and 3"
61+
except AssertionError as error:
62+
return {
63+
"error" : str(error)
64+
}
65+
66+
#create dict_element with the args provided in POST and add random id
5567
keys = ['question', 'answer', 'category', 'level']
5668
dict_element = {}
5769
for key in keys:
5870
dict_element[key] = args[key]
5971
dict_element['id'] = int(uuid.uuid4())
72+
73+
#rewrite file with the added question"
6074
questions_json_file = self.read_question_file()
6175
questions_json_file.append(dict_element)
6276
self.write_questions_json_file(questions_json_file)
77+
6378
return {
6479
'status' : '200 question added'
6580
}
6681

6782
def delete_question(self):
83+
"""Delete question with the id provided"""
6884
parser = reqparse.RequestParser()
6985
parser.add_argument('id', type=int, required=True)
7086
args = parser.parse_args()
@@ -79,5 +95,6 @@ def delete_question(self):
7995
}
8096

8197
def update_question(self, dic_change):
98+
"""Update question, answer, ..."""
8299
pass
83100

app/api/User.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import json
2+
from flask_jwt import JWT, jwt_required
3+
import sys
4+
5+
USER_DATA = {"admin": "admin"}
6+
7+
class User:
8+
def __init__(self, id):
9+
self.id = id
10+
11+
def __str__(self):
12+
return f"User(id={self.id})"
13+
14+
def verify(username, password):
15+
if not (username and password):
16+
return False
17+
if USER_DATA.get(username) == password:
18+
return User(id=1)
19+
20+
def identity(payload):
21+
user_id = payload['identity']
22+
return {"user_id": user_id}
23+
2.01 KB
Binary file not shown.
2.07 KB
Binary file not shown.
3 KB
Binary file not shown.
995 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)