Loguru stops logging flask exceptions in production - python

I am using Loguru to handle the logging in my flask rest api. When testing the app locally it logs exactly as expected. When I deploy my app to my linux server running apache the logging stops. I can run the app manually on the server using python app.py and the logging works again but that just spins up the development server.
from flask import Flask
from loguru import logger
import logging
import os
class InterceptHandler(logging.Handler):
def emit(self, record):
# Retrieve context where the logging call occurred, this happens to be in the 6th frame upward
logger_opt = logger.opt(depth=6, exception=record.exc_info)
logger_opt.log(record.levelno, record.getMessage())
# create the Flask application
app = Flask(__name__)
logger.add(
'logs/events.log',
level='DEBUG',
format='{time} {level} {message}',
backtrace=True,
rotation='5 MB',
retention=9
)
app.logger.addHandler(InterceptHandler())
logging.basicConfig(handlers=[InterceptHandler()], level=20)
if __name__ == '__main__':
app.run(debug=False)

Figured out the issue. By default using the werkzeug dev server it was using the logs/events.log file. When I deployed the application to the apache server, it rerouted the logs that would have been placed here and put them in with the apache server logs

Related

Serving Flask app with waitress on windows using SSL public/private key

How do I run my Flask app which uses SSL keys using waitress. The SSL context is specified in my Flask's run() as in
app.run(ssl_context=('cert.pem', 'key.pem'))
But app.run() is not used when using waitress as in the code below. So, where do I specify the keys? Thanks for the help.
from flask import Flask, request
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == '__main__':
# app.run(ssl_context=('../cert.pem', '../key.pem'))
from waitress import serve
serve(app, host="0.0.0.0", port=5000)
At the current version (1.4.3), Waitress does not natively support TLS.
See TLS support in https://github.com/Pylons/waitress/blob/36240c88b1c292d293de25fecaae1f1d0ad9cc22/docs/reverse-proxy.rst
You either need a reverse proxy in front to handle the tls/ssl part, or use another WSGI server (CherryPy, Tornado...).

Docker and WSGI with a Python Pyramid app?

I am looking at two articles on how to Dockerize a Pyramid app. I am not that familiar with Python, but I am fairly certain with a Pyramid app you need to use WSGI.
This article uses WSGI:
https://medium.com/#greut/minimal-python-deployment-on-docker-with-uwsgi-bc5aa89b3d35
This one just runs the python executable directly:
https://runnable.com/docker/python/dockerize-your-pyramid-application
It seems unlikely to me that you can run python directly and not incorporate WSGI, can anyone provide an explanation for why the runnable.com article's docker solution would work?
Per the scripts in the second link:
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
~snip~
if __name__ == '__main__':
config = Configurator()
config.add_route('hello', '/')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app() # The wsgi server is configured here
server = make_server('0.0.0.0', 6543, app) # and here
This contains an explanation of why the wsgi server is built in the if __name__=="__main__" block

Flask-Python redirection to https The connection was reset

I am a new Flask user and i have a problem. I want to redirect all url from http to https but I am having this error:
The connection was reset
This is my Flask code:
#! /usr/bin/python
# -*- coding:utf-8 -*-
from flask import *
from OpenSSL import SSL
import psycopg2
import os
from datetime import timedelta
import sys
from flask_sslify import SSLify
reload(sys)
sys.setdefaultencoding('utf8')
db_conn = psycopg2.connect("dbname=billjobs host=192.168.42.96 port=50434 user=username password=password")
app = Flask(__name__)
db = db_conn.cursor()
app.permanent_session_lifetime = timedelta(seconds=900)
sslify = SSLify(app)
app.secret_key='\xatYK\x1ba\x1dz\xa6-D\x9d\x97\x83\xfa\xcf\xcbd\xfa\xfb\x1a|\x08\x1af'
context = ('ssl.crt','ssl.key')
#app.route('/')
def pre_log():
return render_template('index.html')
if __name__ == '__main__':
app.run(host="192.168.42.186", ssl_context=context, debug=False)
If I enter directly the address https://192.168.42.186:5000 it work but with http only its not
Thanks for helping me in advance
You cannot do this using ssl_context and Werkzung (default server of Flask) now. A functionality to allow this was proposed and rejected in 2014: auto http to https redirect; citing:
That requires running another HTTP server. Werkzeug is not capable of that and IMO it's out of scope. run_simple should only be used for development anyway.
So what's going on is your Flask application calls run_simple underneath, passing ssl_context and some other variables. SSLify has no impact on your routing as long as you use ssl_context, because sole presence of this variable makes Werkzung host only using https schema. To get redirection from http to https, you need either to set up another server, listening at http and redirecting to https or migrate to other, more advanced server which allows redirection easily.
I recommend to migrate to Apache or gunicorn. Flask provides comprehensive instructions on deployment: Deployment Options. Keep in mind that built-in server of Flask (Werkzung) is not suitable for production, as authors of Flask write:
While lightweight and easy to use, Flask’s built-in server is not
suitable for production as it doesn’t scale well and by default serves
only one request at a time.
Using Apache you could redirect all http requests using VirtualHost rule, listening at 80:
<VirtualHost *:80>
ServerName mysite.example.com
DocumentRoot /usr/local/apache2/htdocs
Redirect /secure https://mysite.example.com/secure
</VirtualHost>
See more on this on Redirect Request to SSL Apache wiki.

How to run WSGIServer in verbose or debug mode ?

I'm using the following code snippet to run WSGIServer in python:
from bottle import request, Bottle, abort
app = Bottle()
.. other stuff ...
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketError
from geventwebsocket.handler import WebSocketHandler
server = WSGIServer(("0.0.0.0", 8080), app,
handler_class=WebSocketHandler)
server.serve_forever()
The server works fine but every time I send a request to this server, there is nothing printed out on console (the way bottle or flask do when you run their server directly). Those console logs would really help me understand what requests the browser is making. I tried inserting debug=True in several places in above code, but none seemed to work. What am I doing wrong ?
I believe you should add this line before starting the server .
app.debug = True

Tornado web server in webfaction

I am starting with web development. I am trying to develop and webapp using the Instagram API and Django. I was looking that a lot of people it's using Tornado Web Server for Real Time Subscriptions. So I am using Webfaction as a host and found this code so I can wrap my Django project with the "WSGI Container" that Tornado Web Server provides:
import os
import tornado.httpserver
import tornado.ioloop
import tornado.wsgi
import tornado.web
import sys
import django.core.handlers.wsgi
sys.path.append('/path/to/project')
class HelloHandler(tornado.web.RequestHandler):
def get(self):
self.write('Hello from tornado')
def main():
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings' # path to your settings module
wsgi_app = tornado.wsgi.WSGIContainer(django.core.handlers.wsgi.WSGIHandler())
tornado_app = tornado.web.Application(
[
('/hello-tornado', HelloHandler),
('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
]
)
http_server = tornado.httpserver.HTTPServer(tornado_app)
http_server.listen(8080)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
So I run this python script inside my Webfaction server and everytime I try to access "http://mywebsite.com/hello-tornado/" does not seem to work. I know I am running that Tornado web server on that port but do not know how too access from the browser or something like that. What I am doing wrong here? Thanks for your help and patience. Will cyber high-five for every answer.
EDIT: What I am really trying to do is that I want to receive all the calls from the subscriptions that I make with the Instagram RealTime Subscription API through Tornado, for that I have a callback url "http://mysite.com/sub" and I want to be able to receive through Tornado.
You are starting the server at port 8080, Web browsers use port 80 by default, try using: http://mywebsite.com:8080/hello-tornado
if you want to use port 80 and you already have a web server running in the box you can try following Ali-Akber Saifee suggestion, or run the WSGI application directly from the server, using something like mod_python (http://www.modpython.org), you will lose the ability to run Tornado code, but Django will work.
You have to create a custom app (listening on port), note the port that is assigned to your app then configure tornado to serve on that port: http_server.listen(my port)
You can also avoid tornado and start directly by installing a django app.

Categories

Resources