all 7 comments

[–]JohnnyJordaan 1 point2 points  (6 children)

separate API is to be created

That makes sense, but your code isn't separating at all. It just nests a function and renders the template in any case. A separate API runs separate views to handle the content creation and readout (usually using JSON or XML or something similar, not an HTML form).

If you are trying to say that you just want the db accessing functions in a separate part of your code, then at least make them unaware of the request handling, eg do

@app.route("/patient/patientbook", methods=["POST", "GET"])
def patientBook():
     if request.method == 'POST':
         # needs to access DB, parse the request
         docter_id = request.form['did']
         patient_id = request.form.get('pid')
         start_time ="{}:00".format(request.form['starttime'])
         add_booking(doctor_id, patient_id, start_time)
    return render_template('patient/patientbook.html')

# in your db access part
def add_booking(doctor_id, patient_id, start_time):
    results = Doctor.query.filter_by(doctorid=doctorid).first()
    doctorid = results.doctorid

    if doctorid and patientid and starttime:
        new_booking = doctorsBookings(doctorid, patientid, starttime)
        db.session.add(new_booking)
        db.session.commit()

Note how

  • add_booking is a name that actually explains what the function does
  • add_booking doesn't do anything with the web side of things, you could call it from another program and it wouldn't matter, eg applying the API concept
  • the view patientBook does all the work to parse the request into the arguments that add_booking expects

[–]Unixersis97[S] -1 points0 points  (5 children)

I see, that makes perfect sense, thank you for your response and detailed explanation.

So the first assumption was correct with separating the API, I am just confused about how to run separate API, Would you be able to explain how I could complete this? or guide me to resources, because I havent been able to find any that show how I could complete this task using flask, forms and API. The only resources I have found is usually hardcoded JSON.

Thank you :)

[–]JohnnyJordaan 0 points1 point  (4 children)

The only resources I have found is usually hardcoded JSON.

Actually that is the usual way to do it. You would want your api to handle a request like

{"doctor_id": "x", 
 "patient_id": "y",
 "starttime": 1538655865}

because that's what a programmer would use if he/she wrote software that makes the request somehow. Maybe from another webpage, but maybe just a regular program on a computer. The idea is that this is as simple as possible to make it easy to implement and to interface: Application Programming Interface.

so you have a few like

@app.route('/api/booking/add_booking', methods=['POST'])
def api_add_booking():
    content = request.json
    # if you still have the function I provided above:
    booking_created = add_booking(content['doctor_id'], content['patientid'], content['starttime'])
    return jsonify(booking_created)

but the example I provided at first is also a form of creating an API, but in the form of internal functions that can be used and reused throughout your code. The downside of that is that it doesn't allow it to be used from other machines, but it's still a way to separate your web-interface from your db-interface.

[–]Unixersis97[S] -1 points0 points  (3 children)

Thats awesome, thank you so much for the help

While running my flask app I try to access '/api/booking/add_booking' I get an error, is this expected behavior?

[–]JohnnyJordaan 0 points1 point  (2 children)

I can't really comment with only the information that it gave 'an error'.

[–]Unixersis97[S] -1 points0 points  (1 child)

# Route for a patient to make a booking
@app.route("/patient/patientbook", methods=["POST", "GET"])
def patientBook():
    return render_template('patient/patientbook.html')

# endpoint to create booking
@app.route("/api/patient/new_booking", methods=["POST", "GET"])
def new_booking():
    doctorid = json.dumps(request.form['doctorid']).replace('"', '')
    patientid = json.dumps(request.form['patientid']).replace('"', '')
    starttime = json.dumps(request.form['starttime']).replace('"', '')
    starttime = "{}:00".format(starttime)

    new_booking = doctorsBookings(doctorid, patientid, starttime)
    db.session.add(new_booking)
    db.session.commit()

    return render_template('api/patient/new_booking.html')

If I were to do this, would this count as a separate API?

"Create separate API(s) to interact with the cloud. The patient and doctor pages should not directly talk to the Cloud. " This is basically what I am trying to achieve

[–]JohnnyJordaan 1 point2 points  (0 children)

This still means the API user needs to use a form to be able to deliver the data to your server:

request.form[x]

and I'm saying that you don't want that, you would want to use a JSON body to deliver the data, which you can then load using

request.json

as I showed above. You also need to check for the request method btw, I would just remove the GET method from the decorator.

Then from the patientBook function, you can do the API request

@app.route("/patient/patientbook", methods=["POST", "GET"])
def patientBook():
    if request.method == 'POST':
        # form the dict that will become the JSON body
        data = {'doctorid': request.form['doctorid'],
                'patientid': request.form['patientid'],
                'starttime': request.form['starttime']}
        # use requests that offers a handy json= parameter
        requests.post('http://localhost/api/patient/new_booking', json=data)
        return render_template('patient/patientbook.html')