The localhost is not running and I am getting an OS:Error of 'No route to host' error when I run the flask app.
I've tried adding this:
app.run(host='0.0.0.0')
but it does not work.Also I have tried changing the port from 5000 to 4996 and various other ports but still I am facing the same issue .
Here is my complete code:
from flask import Flask
from flask_mail import Mail,Message
app = Flask(__name__)
app.config['DEBUG']=True
app.config['TESTING']=False
app.config['MAIL_SERVER']='smtp.gmail.com'
app.config['MAIL_PORT']=456
app.config['MAIL_USE_SSL']=True
#app.config['MAIL_DEBUG']=
app.config['MAIL_USERNAME']='trvt1234#gmail.com'
app.config['MAIL_PASSWORD']='#insert password here'
app.config['MAIL_DEFAULT_SENDER']='trvt1234#gmail.com'
app.config['MAIL_MAX_EMAILS']=None
#app.config['MAIL_SUPRESS_SEND']=
app.config['MAIL_ASCII_ATTACHMENTS']=False
email = Mail(app)
#app.route('/')
def mail():
message = Message('Hello',recipients=['trvt1234#gmail.com'])
email.send(message)
return('message sent successfully')
if __name__ == '__main__':
app.run(host='0.0.0.0')
I am a newbie to Flask and was figuring out how should I go on about this problem.
I think you have the wrong MAIL_PORT - it should be 465 not 456.
Related
I have been running locally, without host param nor port param and it has been working well without a webhook (very unintuitive, how is just bot token enough?).
I decided to put my bot on a server. I've created a python3 file and I've now:
created the webhook on ipv4 port 8443
{"ok":true,"result":true,"description":"Webhook is already set"}
edited the lines in main:
context=('/path_to/cert.pem', '/path_to/privkey.pem')
app.run(host="xxx.xx.xxx.xxx",port="8443", ssl_context=context, debug=False)
This gives output of
* Serving Flask app 'xx'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on https://xxx.xx.xxx.xxx:8443
Press CTRL+C to quit
Bot is unresponsive.
I've used the following command and it didn't help:
sudo ufw allow 8443
I've tried running with:
context=('/path_to/cert.pem', '/path_to/privkey.pem')
app.run(host="0.0.0.0",port="8443", ssl_context=context, debug=False)
And the output is:
* Serving Flask app 'xx'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on https://xxx.0.0.x:8443
* Running on https://xxx.xx.xxx.xxx:8443
Press CTRL+C to quit
Bot is unresponsive...
Edit: bot code:
from flask import Flask
from flask import request
from flask import Response
import requests
TOKEN = "..."
app = Flask(__name__)
def parse_message(message):
print("message-->",message)
chat_id = message['message']['chat']['id']
txt = message['message']['text']
print("chat_id-->", chat_id)
print("txt-->", txt)
return chat_id,txt
def tel_send_message(chat_id, text):
url = f'https://api.telegram.org/bot{TOKEN}/sendMessage'
payload = {
'chat_id': chat_id,
'text': text
}
r = requests.post(url,json=payload)
return r
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
msg = request.get_json()
chat_id,txt = parse_message(msg)
if txt == "hi":
tel_send_message(chat_id,"Hello!!")
else:
tel_send_message(chat_id,'from webhook')
return Response('ok', status=200)
else:
return "<h1>Welcome!</h1>"
if __name__ == '__main__':
context=('path/cert.pem', 'path/privkey.pem')
app.run(host="xxx.xx.xxx.xxx",port="8443", ssl_context=context,debug=False)
I'm using Flask on a project on an embedded system and I'm having performance issues. I'm running gunicorn with one eventlet worker by running:
gunicorn -b 0.0.0.0 --worker-class eventlet -w 1 'app:create_app()'
The problem I'm facing is that, when the MQTT messages start to pour with more cadence, the application starts to use almost all the CPU I have available. My initial thought was that I was handling the messages not ideally but, I even took out my handler, and just receive the messages, and the problem still persists.
I have another python application that subscribes to the same information with the paho client and this is not an issue, so I'm assuming I'm missing something on my Flask application and not the information itself.
My code is:
import eventlet
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, current_user
from flask_socketio import SocketIO
from flask_mqtt import Mqtt
eventlet.monkey_patch()
#USERS DB
db_alchemy = SQLAlchemy()
#socketIO
socketio = SocketIO(cors_allowed_origins="*", async_mode='eventlet')
# MQTT
mqtt_client = Mqtt()
'''
APPLICATION CREATION
'''
def create_app():
app = Flask(__name__)
if app.config["ENV"] == "production":
app.config.from_object("config.ProductionConfig")
else:
app.config.from_object("config.DevelopmentConfig")
#USERS DB
db_alchemy.init_app(app)
#LoginManager
login_manager = LoginManager()
login_manager.login_view = "auth.login"
login_manager.init_app(app)
#SOCKETIO
socketio.init_app(app)
#FLASK-MQTT
app.config['MQTT_BROKER_URL'] = 'localhost' #
app.config['MQTT_BROKER_PORT'] = 1883
app.config['MQTT_KEEPALIVE'] = 20
app.config['MQTT_TLS_ENABLED'] = False
mqtt_client.init_app(app)
return app
#MQTT
#mqtt_client.on_connect()
def mqtt_on_connect():
mqtt_client.subscribe('testTopic/#', 0)
#mqtt_client.on_disconnect()
def mqtt_on_disconnect():
loggerMqtt.warning(' > Disconnected from broker')
#mqtt_client.on_subscribe()
def mqtt_on_subscribe(client, obj, mid, granted_qos):
pass
#mqtt_client.on_message()
def mqtt_on_message(client, userdata, message):
pass
#mqtt_topicSplitter(client, userdata, message)
As you can see my handler mqtt_topicSplitter is commented but I'm still having performance issues. I've tried adding an sleep command [eventlet.sleep(0.1)] on the on_message handler which solved the CPU consumption problem but resulted on my application being constantly kicked from the broker.
I also tried using other workers (gevent, asyncio, ..) without success. Using the Flask development server is not an option, since is not recommended for production.
I'm sorry if I wasn't clear, but I'm not an expert, please feel free to ask me any questions if needed.
Thanks in advance.
I am not able to get http://127.0.0.1:5000/movie Url from the browser.
Every time it gives 404. The only time it worked was with URL from hello world.
I am trying to run a recommender system deployment solution with flask, based on https://medium.com/analytics-vidhya/build-a-movie-recommendation-flask-based-deployment-8e2970f1f5f1.
I have tried uninstall flask and install again but nothing seems to work.
Thank you!
from flask import Flask,request,jsonify
from flask_cors import CORS
import recommendation
app = Flask(__name__)
CORS(app)
#app.route('/movie', methods=['GET'])
def recommend_movies():
res = recommendation.results(request.args.get('title'))
return jsonify(res)
if __name__=='__main__':
app.run(port = 5000, debug = True)
http://127.0.0.1:5000/movie
be careful not writing '/' after movie like http://127.0.0.1:5000/movie/
I am using telegram bot api (telebot), flask and gunicorn.
When I use command python app.py everything is work fine but when I use python wsgi.py flask is stated on http://127.0.0.1:5000/ and bot doesn't answer and if I am using gunicorn --bind 0.0.0.0:8443 wsgi:app webhook is setting but telegram bot doesn't answer. I tried to add app.run from app.py to wsgi.py but it doesn't work
app.py
import logging
import time
import flask
import telebot
API_TOKEN = '111111111:token_telegram'
WEBHOOK_HOST = 'droplet ip'
WEBHOOK_PORT = 8443 # 443, 80, 88 or 8443 (port need to be 'open')
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
WEBHOOK_SSL_CERT = 'webhook_cert.pem' # Path to the ssl certificate
WEBHOOK_SSL_PRIV = 'webhook_pkey.pem' # Path to the ssl private key
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
WEBHOOK_URL_PATH = "/%s/" % (API_TOKEN)
logger = telebot.logger
telebot.logger.setLevel(logging.DEBUG)
bot = telebot.TeleBot(API_TOKEN)
app = flask.Flask(__name__)
# Empty webserver index, return nothing, just http 200
#app.route('/', methods=['GET', 'HEAD'])
def index():
return ''
# Process webhook calls
#app.route(WEBHOOK_URL_PATH, methods=['POST'])
def webhook():
if flask.request.headers.get('content-type') == 'application/json':
json_string = flask.request.get_data().decode('utf-8')
update = telebot.types.Update.de_json(json_string)
bot.process_new_updates([update])
return ''
else:
flask.abort(403)
# Handle all other messages
#bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)
# Remove webhook, it fails sometimes the set if there is a previous webhook
bot.remove_webhook()
#
time.sleep(1)
# Set webhook
bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
certificate=open(WEBHOOK_SSL_CERT, 'r'))
if __name__ == "__main__":
# Start flask server
app.run(host=WEBHOOK_LISTEN,
port=WEBHOOK_PORT,
ssl_context=(WEBHOOK_SSL_CERT, WEBHOOK_SSL_PRIV),
debug=True)
wsgi.py
from app import app
if __name__ == "__main__":
app.run()
It's a bad practice to show python webservers to the world. It's not secure.
Good practice - using a reverse proxy, e.g. nginx
Chain
So the chain shoud be:
api.telegram.org -> your_domain -> your_nginx -> your_webserver -> your_app
SSL
Your ssl certificates shoud be checked on nginx level. On success just pass request to your webserver (flask or something else). It's also a tip about how to use infitity amount of bots on one host/port :)
How to configure nginx reverse proxy - you can find in startoverflow or google.
Telegram Webhooks
telebot is so complicated for using webhooks.
Try to use aiogram example. It's pretty simple:
from aiogram import Bot, Dispatcher, executor
from aiogram.types import Message
WEBHOOK_HOST = 'https://your.domain'
WEBHOOK_PATH = '/path/to/api'
bot = Bot('BOT:TOKEN')
dp = Dispatcher(bot)
#dp.message_handler()
async def echo(message: Message):
return message.answer(message.text)
async def on_startup(dp: Dispatcher):
await bot.set_webhook(f"{WEBHOOK_HOST}{WEBHOOK_PATH}")
if __name__ == '__main__':
executor.start_webhook(dispatcher=dp, on_startup=on_startup,
webhook_path=WEBHOOK_PATH, host='localhost', port=3000)
app.run(host=0.0.0.0, port=5000, debug=True)
Change port number and debug arguments based on your case.
I am running a Python 2.7 Flask app on CherryPy Cheroot WSGI server usinh HTTP now as below.
from cheroot.wsgi import Server as WSGIServer
from cheroot.wsgi import PathInfoDispatcher as WSGIPathInfoDispatcher
from MyFlaskApp import app
d = WSGIPathInfoDispatcher({'/': app})
server = WSGIServer(('0.0.0.0', 80), d)
if __name__ == '__main__':
try:
server.start()
except KeyboardInterrupt:
server.stop()
What would I have to to move to HTTPS from here?
I found below instruction, but it does not seem to applicable to my application.
from cheroot.server import HTTPServer
from cheroot.ssl.builtin import BuiltinSSLAdapter
HTTPServer.ssl_adapter = BuiltinSSLAdapter(
certificate='cert/domain.crt',
private_key='cert/domain.key')
Can I apply above sample to my Flask app on Cheroot? If not, what would be a simple example for Flask app on Cheroot for HTTPS?
I figured out the necessary modification.
Not much information on Flask app on Cheroot with https, so I thought I'd share it.
from cheroot.wsgi import Server as WSGIServer
from cheroot.wsgi import PathInfoDispatcher as WSGIPathInfoDispatcher
from cheroot.ssl.builtin import BuiltinSSLAdapter
from MyFlaskApp import app
my_app = WSGIPathInfoDispatcher({'/': app})
server = WSGIServer(('0.0.0.0', 443), my_app)
ssl_cert = "[path]/myapp.crt"
ssl_key = "[path]/myapp.key"
server.ssl_adapter = BuiltinSSLAdapter(ssl_cert, ssl_key, None)
if __name__ == '__main__':
try:
server.start()
except KeyboardInterrupt:
server.stop()