Reputation: 127
I have a flask restful api that fetches the question and possible answers from JSON file and displays as it is in my browser. The selection of next question from the JSON file depends upon the selected option of previous question. My app is working fine but I am giving input using the URL now I want a front end page that displays the question and all of its options using radio buttons and input must be given by selecting a radio button and then pressing a button (submit/next etc).
Here is my flask code:
from flask import Flask, jsonify
import json
import sys
# global variables
num = 0
last_choice = 'empty'
questionnaire_key = ''
user_choice = []
data = {}
app = Flask(__name__)
with open('static/data.json') as f:
data = json.load(f)
print(data, file=sys.stdout)
@app.route('/<int:index>/Start')
def StartQuestionnaire(index):
global num, last_choice, questionnaire_key, user_choice
num = 0
last_choice = 'empty'
user_choice.clear()
questionnaire_key = 'questionnaire_' + str(index)
user_choice.append(data[questionnaire_key][0]['question'])
print(user_choice, file=sys.stdout)
return jsonify(data[questionnaire_key][0])
# last selected option will be passed as keyword argument
@app.route('/<int:index>/<string:option>')
def GetQuestion(index, option):
global num, last_choice, questionnaire_key
num = num + 1
response = {}
user_choice.append(option)
if last_choice != 'empty':
response = data[questionnaire_key][num][last_choice][option]
else:
if option != 'Yes' and option != 'No':
last_choice = option
response = data[questionnaire_key][num][option]
if option == 'No' or num == len(data[questionnaire_key]) - 1:
for elem in user_choice:
print(elem, file=sys.stdout)
return jsonify(response)
if __name__ == '__main__':
app.run(debug=True, use_reloader=False)
Here is my JSON:
{
"questionnaire_0" :
[
{
"question": "Are you Hungry?",
"options": ["Yes", "No"]
},
{
"Yes": {
"question": "What would you like to eat?",
"options": ["Hamburger", "Pizza", "Pop Corn", "Chicken"]
},
"No": {
"message": "OK, call me when you are hungry."
}
},
{
"Hamburger": {
"message": "Nice, I will order a hamburger for you."
},
"Pizza": {
"question": "Would you like pizza with mushroom?",
"options": ["Yes", "No"]
},
"Pop Corn": {
"question": "Would you like pop corn with cheese?",
"options": ["Yes", "No"]
},
"Chicken": {
"question": "Would you like chicken with cheese?",
"options": ["Yes", "No"]
}
},
{
"Pizza": {
"Yes": {
"message": "Ok, i will order the best pizza in town for you."
},
"No": {
"message": "No? Well... stay hungry then."
}
},
"Pop Corn": {
"Yes": {
"message": "Ok, i will order the best pop corn in town for you."
},
"No": {
"message": "No? Well... stay hungry then."
}
},
"Chicken": {
"Yes": {
"message": "Ok, i will order the best chicken in town for you."
},
"No": {
"message": "No? Well... stay hungry then."
}
}
}
],
"questionnaire_1":
[
{
"question": "Are you bored?",
"options": ["Yes", "No"]
},
{
"Yes": {
"question": "What would you like me to play?",
"options": ["Song", "Movie", "Music", "Ted Talk"]
},
"No": {
"message": "OK, call me when you are bored."
}
},
{
"Song": {
"message": "Nice, I will play your favorite song."
},
"Movie": {
"question": "Would you like to watch action movie?",
"options": ["Yes", "No"]
},
"Music": {
"question": "Would you like relaxing music?",
"options": ["Yes", "No"]
},
"Ted Talk": {
"question": "Would you like me to play simon sinek talk?",
"options": ["Yes", "No"]
}
},
{
"Movie": {
"Yes": {
"message": "Ok, i am playing Avengers."
},
"No": {
"message": "No? Well... stay bored then."
}
},
"Music": {
"Yes": {
"message": "Ok, i will play the most relaxing music."
},
"No": {
"message": "No? Well... stay bored then."
}
},
"Ted Talk": {
"Yes": {
"message": "Ok, get ready to feel inspired."
},
"No": {
"message": "No? Well... stay bored then."
}
}
}
]
}
How do I connect a fron-end so that user can answer the questions using a nice view instead of a need to change the url.
PS: As I mentioned any question other than first level questions are dependent on previous answers, so one question at a time should be visible. First page should show the list of radio button to select a questionnaire.
Upvotes: 2
Views: 2419
Reputation: 79
See as it is a restful api, there are two ways you could go about this,
You could use Flask templates to display the major layout of your website and then throw in some javascript to make the updates on the website using AJAX.
You could go all in and learn a frontend javascript framework like React, Vue or Angular. If you like the ideology flask is built upon, you would love react!
For any further queries, comment!
Upvotes: 1
Reputation: 640
This is a really broad question - you're essentially asking how can I make the font end of a website.
There's lots of options. You can either build a client side application using a framework like React which will use javascript to call your API and then display the information to the user.
Alternatively you can render pages on your server and return them to the user instead of the raw json. In your case use Flask templates. The previous link contains the 'Flask Mega Tutorial' written by the creator of flask. There is really too much to talk about around building the front end of a website in a single SO answer - that tutorial will give you an excellent start to building websites with python.
Upvotes: 1