0

Running the following Python 3 script and for some reason that I cannot fathom the startWebview function executes twice resulting in two PyWebView windows being opened.

# Import Modules Here
import os
import time
import webview
import os.path
import multiprocessing
from dotenv import load_dotenv
from flask_wtf import FlaskForm
from flask_mde import Mde, MdeField
from wtforms import SubmitField, StringField
from wtforms.validators import InputRequired, DataRequired, Length
from flask import Flask, request, render_template, flash, session, url_for

app = Flask(__name__)
load_dotenv()
mde = Mde(app)
app.config['SECRET_KEY'] = os.environ.get("FLASK_SECRET_KEY")

windowTitle = os.environ.get("WINDOW_TITLE")
fileDirPath = os.environ.get("FILE_DIRECTORY")


def error_flasher(form):
    for field, message_list in form.errors.items():
        for message in message_list:
            flash(form[field].label.text + ': ' + message, 'error')
    print(message, message_list)


def fileHandler(form):
    savePath = os.path.join(fileDirPath, form.title.data)
    f = open(savePath, "w+")
    f.write(form.editor.data)
    f.close()


def contentLoader(form):
    savePath = os.path.join(fileDirPath, form.title.data)
    fileName = savePath
    f = open(fileName, "r")
    return f.read()


class MdeForm(FlaskForm):

    title = StringField('Title', validators=[DataRequired()])

    editor = MdeField(
        validators=[
            #InputRequired("Input required"),
            Length(min=0, max=30000)
        ]
    )
    submit = SubmitField()


@app.route('/', methods=['GET', 'POST'])
def index():
    form = MdeForm()

    if form.validate_on_submit() and form.editor.data == "":
        form.editor.data = contentLoader(form)

    elif form.validate_on_submit() and form.editor.data != "":
        session['editor'] = request.form['editor']
        fileHandler(form)
        form.title.data = ""
        form.editor.data = ""

    return render_template("index.html", form=form, windowTitle=windowTitle)


def startFlaskServer():
    app.run(debug=True)


def startWebview():
    webview.create_window(windowTitle, 'http://localhost:5000')
    webview.start(debug=True)


if __name__ == "__main__":

    p1 = multiprocessing.Process(target=startFlaskServer)
    p2 = multiprocessing.Process(target=startWebview)

    p1.start()
    time.sleep(2)
    p2.start()
    p2.join()
    p1.terminate()

enter image description here

As seen in the above image it would appear that the cause is two GET requests as the second Webview only loads after the second GET request.

Thanks in advance!

arthem
  • 141
  • 3
  • 13
  • 1
    I know very little about Flask, but note that the creation of a process causes the file to be re-evaluated in the new process. [A demo](https://gist.github.com/carcigenicate/e9db66780377d1032534ca0cfe6f1c87). I have no clue if that stuff at the top being evaluated more than once would have the effect you describe, but it's worth looking into. – Carcigenicate Dec 25 '20 at 16:46

1 Answers1

0

It would appear that this issue is caused by Multiprocessing re-evaluating the file as suggested by @Carcigenicate.

Problem solved by moving from Multithreading to threading.

arthem
  • 141
  • 3
  • 13
  • 1
    Be very careful though; the two ways aren't equivilent. Multithreading can't be used to execute multiple Python instructions at once. At best, you'll have multiple threads fighting for CPU time on a single core, which may lead to lag when under load. You may want to instead switch back to multiprocessing, find out what specifically is causing the duplicate behavior, and move that part (or all of the top-level, non-function code) into the `if __name__ == "__main__"` check, since `__name__` will be different in the spawned process. – Carcigenicate Dec 25 '20 at 17:56
  • @Carcigenicate Will be trying to find the bug for sure. However as the PyWebview docs indicate that threading is better for use with their module then that is what I have moved over to for now. Many thanks for the tip! – arthem Dec 25 '20 at 18:45