Can a generator wait with yielding until another function is triggered?
up vote
1
down vote
favorite
I have written the following testing code for a website. The index shows a relatively empty page, but it'll open a stream from which it can receive more messages from the server, effectively allowing me to make server side events. For this, I need to insert a generator into the Response
object.
from flask import Flask, Response, render_template
app = Flask(__name__)
def answer():
while True:
q = input("Whaddaya wanna say? ")
yield 'data: {} nn'.format(q)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/stream')
def stream():
return Response(answer(), mimetype="text/event-stream")
if __name__ == "__main__":
app.run(threaded=True, debug=True)
Together with a file called index.html
, this works perfectly fine. I am receiving any text that I have given as an input to the terminal. However, if a second user were to visit the server, Python starts going back and forth between the two users - some input will be sent to one user, the next will always be sent to the other. I understand that this is how it's supposed to work, but I wondered if it was possible to create a generator that would yield to all clients.
Currently, I could think of two possible ways to do this. The first one isn't too complicated, but I'm not sure if it's a good idea to put in practice. Here, one Messenger
instance would be created, after which its ànswer()
function would be given as a generator.
class Messenger:
def __init__(self):
self.message = ""
def send_msg(self,msg):
self.message = msg
def answer(self):
current_message = self.message
while True:
# Yield when the message has been updated
if self.message != current_message:
current_message = self.message
yield current_message
I do not really like this code for two reasons. First off, it does not allow the user to send the same message twice in a row. Second, checking constantly seems like wasting a lot of time on checking stuff. There has to be a better way. Is there?
I have been trying multiple methods, but I just can't think of any. I couldn't find any solution on the internet either. My current guess is to somehow make the function wait until the update is made. Something like the following, though I wouldn't know how to finish this code.
class Messenger:
def __init__(self):
self.message = ""
def send_msg(self,msg):
self.message = msg
def answer(self):
while True:
pass # Pause function until send_msg() is executed
yield self.message
Is it possible to create such a function? Is there a better way to solve this issue? Would you instead recommend looking into finding an alternative to the generator? Is the first option not as bad as it seems, and if so, why?
python function flask generator
add a comment |
up vote
1
down vote
favorite
I have written the following testing code for a website. The index shows a relatively empty page, but it'll open a stream from which it can receive more messages from the server, effectively allowing me to make server side events. For this, I need to insert a generator into the Response
object.
from flask import Flask, Response, render_template
app = Flask(__name__)
def answer():
while True:
q = input("Whaddaya wanna say? ")
yield 'data: {} nn'.format(q)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/stream')
def stream():
return Response(answer(), mimetype="text/event-stream")
if __name__ == "__main__":
app.run(threaded=True, debug=True)
Together with a file called index.html
, this works perfectly fine. I am receiving any text that I have given as an input to the terminal. However, if a second user were to visit the server, Python starts going back and forth between the two users - some input will be sent to one user, the next will always be sent to the other. I understand that this is how it's supposed to work, but I wondered if it was possible to create a generator that would yield to all clients.
Currently, I could think of two possible ways to do this. The first one isn't too complicated, but I'm not sure if it's a good idea to put in practice. Here, one Messenger
instance would be created, after which its ànswer()
function would be given as a generator.
class Messenger:
def __init__(self):
self.message = ""
def send_msg(self,msg):
self.message = msg
def answer(self):
current_message = self.message
while True:
# Yield when the message has been updated
if self.message != current_message:
current_message = self.message
yield current_message
I do not really like this code for two reasons. First off, it does not allow the user to send the same message twice in a row. Second, checking constantly seems like wasting a lot of time on checking stuff. There has to be a better way. Is there?
I have been trying multiple methods, but I just can't think of any. I couldn't find any solution on the internet either. My current guess is to somehow make the function wait until the update is made. Something like the following, though I wouldn't know how to finish this code.
class Messenger:
def __init__(self):
self.message = ""
def send_msg(self,msg):
self.message = msg
def answer(self):
while True:
pass # Pause function until send_msg() is executed
yield self.message
Is it possible to create such a function? Is there a better way to solve this issue? Would you instead recommend looking into finding an alternative to the generator? Is the first option not as bad as it seems, and if so, why?
python function flask generator
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have written the following testing code for a website. The index shows a relatively empty page, but it'll open a stream from which it can receive more messages from the server, effectively allowing me to make server side events. For this, I need to insert a generator into the Response
object.
from flask import Flask, Response, render_template
app = Flask(__name__)
def answer():
while True:
q = input("Whaddaya wanna say? ")
yield 'data: {} nn'.format(q)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/stream')
def stream():
return Response(answer(), mimetype="text/event-stream")
if __name__ == "__main__":
app.run(threaded=True, debug=True)
Together with a file called index.html
, this works perfectly fine. I am receiving any text that I have given as an input to the terminal. However, if a second user were to visit the server, Python starts going back and forth between the two users - some input will be sent to one user, the next will always be sent to the other. I understand that this is how it's supposed to work, but I wondered if it was possible to create a generator that would yield to all clients.
Currently, I could think of two possible ways to do this. The first one isn't too complicated, but I'm not sure if it's a good idea to put in practice. Here, one Messenger
instance would be created, after which its ànswer()
function would be given as a generator.
class Messenger:
def __init__(self):
self.message = ""
def send_msg(self,msg):
self.message = msg
def answer(self):
current_message = self.message
while True:
# Yield when the message has been updated
if self.message != current_message:
current_message = self.message
yield current_message
I do not really like this code for two reasons. First off, it does not allow the user to send the same message twice in a row. Second, checking constantly seems like wasting a lot of time on checking stuff. There has to be a better way. Is there?
I have been trying multiple methods, but I just can't think of any. I couldn't find any solution on the internet either. My current guess is to somehow make the function wait until the update is made. Something like the following, though I wouldn't know how to finish this code.
class Messenger:
def __init__(self):
self.message = ""
def send_msg(self,msg):
self.message = msg
def answer(self):
while True:
pass # Pause function until send_msg() is executed
yield self.message
Is it possible to create such a function? Is there a better way to solve this issue? Would you instead recommend looking into finding an alternative to the generator? Is the first option not as bad as it seems, and if so, why?
python function flask generator
I have written the following testing code for a website. The index shows a relatively empty page, but it'll open a stream from which it can receive more messages from the server, effectively allowing me to make server side events. For this, I need to insert a generator into the Response
object.
from flask import Flask, Response, render_template
app = Flask(__name__)
def answer():
while True:
q = input("Whaddaya wanna say? ")
yield 'data: {} nn'.format(q)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/stream')
def stream():
return Response(answer(), mimetype="text/event-stream")
if __name__ == "__main__":
app.run(threaded=True, debug=True)
Together with a file called index.html
, this works perfectly fine. I am receiving any text that I have given as an input to the terminal. However, if a second user were to visit the server, Python starts going back and forth between the two users - some input will be sent to one user, the next will always be sent to the other. I understand that this is how it's supposed to work, but I wondered if it was possible to create a generator that would yield to all clients.
Currently, I could think of two possible ways to do this. The first one isn't too complicated, but I'm not sure if it's a good idea to put in practice. Here, one Messenger
instance would be created, after which its ànswer()
function would be given as a generator.
class Messenger:
def __init__(self):
self.message = ""
def send_msg(self,msg):
self.message = msg
def answer(self):
current_message = self.message
while True:
# Yield when the message has been updated
if self.message != current_message:
current_message = self.message
yield current_message
I do not really like this code for two reasons. First off, it does not allow the user to send the same message twice in a row. Second, checking constantly seems like wasting a lot of time on checking stuff. There has to be a better way. Is there?
I have been trying multiple methods, but I just can't think of any. I couldn't find any solution on the internet either. My current guess is to somehow make the function wait until the update is made. Something like the following, though I wouldn't know how to finish this code.
class Messenger:
def __init__(self):
self.message = ""
def send_msg(self,msg):
self.message = msg
def answer(self):
while True:
pass # Pause function until send_msg() is executed
yield self.message
Is it possible to create such a function? Is there a better way to solve this issue? Would you instead recommend looking into finding an alternative to the generator? Is the first option not as bad as it seems, and if so, why?
python function flask generator
python function flask generator
asked Nov 22 at 7:42
Randium
113
113
add a comment |
add a comment |
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53426055%2fcan-a-generator-wait-with-yielding-until-another-function-is-triggered%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53426055%2fcan-a-generator-wait-with-yielding-until-another-function-is-triggered%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown