'MySQL server has gone away' after Flask app restart - flask-sqlalchemy

I believe the problem of 'MySQL server has gone away' error is quite common but what I've found related to long running or long not used application.
In my case the issue happens mainly only after the application is (re)started. First several requests are failed with that error and then everything is ok.
I have pool_pre_ping: true set as suggested in SQLAlchemy docs. But it doesn't seem to help.
Also it happens only at the production server and never dev.
I don't use Session object. Instead I initialise the SQLAlchemy in __init__.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
flask_app = Flask(__name__)
db.init_app(flask_app)

Related

Frontend no longer accessible after dependency updates

We have a rather standard web app, that consists of a Flask backend and a Vue.js frontend. In production, we use uWSGI to serve that application. We have uWSGI configured to serve frontend pages and access backend calls for their respective routes.
[uwsgi]
module = app
callable = create_app()
buffer-size=65535
limit-post=0
wsgi-disable-file-wrapper=true
check-static=./public
# enable threads for sentry
enable-threads = true
# dont show errors if the client disconnected
ignore-sigpipe=true
ignore-write-errors=true
disable-write-exception=true
; redirect all frontend requests that are not static files to the index
route-host = ^$(FRONTEND_HOST_NAME)$ goto:frontend
; also handle if the host name is frontend, for the dokku checks
route-host = ^frontend$ goto:frontend
; continue if its a backend call
route-host = ^$(BACKEND_HOST_NAME)$ last:
route-host = ^backend$ last:
; log and abort if none match
route-run = log:Host Name "${HTTP_HOST}" is neither "$(FRONTEND_HOST_NAME)" nor "$(BACKEND_HOST_NAME)"
route-run = break:500
route-label = frontend
route-if = isfile:/app/src/backend/public${PATH_INFO} static:/app/src/backend/public${PATH_INFO}
route-run = static:/app/src/backend/public/index.html
This worked perfectly fine and behaved just like our dev setup, where we use containers for both front- and backend. But after the update of some vulnerable dependencies, trying to access the frontend results in a 404.
In the frontend we moved from vue-cli ~4.5.9 to ~5.0.4. We long suspected that this might be the main issue, but we're not so sure about that anymore.
We also upgraded from Flask ~1.1 to ^2.0.3 but we kept the version 2.0 of uWSGI. The configuration of that should therefore probably not have changed.
We're treading in the dark on this one. Does anyone of you have any idea on what might be going wrong in here?
I tried to isolate the problem by creating a rather small setup, but have not been able to track down the underlying issue until now.
I have no idea what it exactly was, but I did in the end upgrade each dependency one by one until all of them were upgraded and things still worked. It must have been something related to the Dockerfile that we use. That one is now slightly more like the old one rather than the one I used previously to doing things one by one.

Heroku crashed when following Basic Auth example on Plotly Dash website

After following the Deploying Dash Apps on Heroku example, I then changed app.py to the Basic Auth Example on the Plotly Dash website. My Heroku site then crashed as a result. How do I make the example work on Heroku?
Looking through the Heroku logs, I found two errors:
ModuleNotFoundError: No module named 'requests'
Failed to find attribute 'server' in 'app'.
I installed the requests library, making sure to update requirements.txt. (Not sure if this step was necessary, but it was the first error I fixed.) In the Basic Auth Example, you will notice server = app.server is not present, but is present in Deploying Dash Apps. Once I added the server info, everything worked:
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server

How to send multiple identical HTTP POST message instantly

I have people cheating in my game by sending multiple HTTP POST message the game server (php + apache) to gain items. I have fixed that loophole but I want to test if my fix was correct.
I have tried some of the chrome plugin to send POST messages but I cant imitate sending them in the same instant, for example 5 identical POST message all send out less that 100ms to the same IP in between them.
I have a Centos and a windows machine, would appreciate any script or program recommendation.
If you have Python installed (your CentOS machine would), the following will do what you're after using only built-ins. You'll just need to tweak the conn.request line to pass in any body or headers your server requires.
from threading import Thread
import httplib, sys
REQUESTS = 5
def doRequest():
conn = httplib.HTTPConnection("www.google.com")
conn.request("POST", '/some/url')
for i in range(REQUESTS):
t = Thread(target=doRequest)
t.daemon = True
t.start()

Getting CORS headers in a Flask 500 error

I've got a Flask app set up like this
from flask import Flask
from flask.ext.cors import CORS
app = Flask( . . . )
app.debug = True
CORS(app, allow_headers='Content-Type')
CORS works correctly for routes that complete properly. However, if an exception is raised, the debug output is generated without CORS headers. This means I cannot see the debug output in chrome. Can I fix this?
The issue has to do with setting debug mode. You can see the discussion about this in this GitHub issue.
There are two ways you could get around this. The easiest is to set the PROPAGATE_EXCEPTIONS configuration parameter to False, but this deprives you of the debug-mode stack trace page:
app.config['PROPAGATE_EXCEPTIONS'] = False
The second would be to write your own exception handler. I haven't tried this myself, but the flask source can give you guidance.

Run Non-Twisted-based Python script daemonized with twistd

I'm writing a Python program consisting of a server (using Twisted) and a client (without Twisted)
The server part is implemented using Twisted and Twisted's application framework and launched with Twistd to be daemonized.
The client which runs on a different server is a simple Python script without any Twisted stuff (and no application framework specific stuff). It should also be run as a Daemon. FYI, this is the source:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import sys
import time
import syslog
SERVER_IP = '127.0.0.1'
SERVER_PORT = 43278
BEAT_PERIOD = 1
class HeartbeatClient:
'''
A Client sending heartbeats to a monitoring server.
'''
def __init__(self, server_ip, port, beat_period):
syslog.syslog( ('Sending heartbeat to IP %s , port %d' +
'\n press Ctrl-C to stop\n')
% (SERVER_IP, SERVER_PORT))
def run(self):
while True:
hbSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
hbSocket.sendto('PyHB', (SERVER_IP, SERVER_PORT))
if __debug__:
print 'Time: %s' % time.ctime()
time.sleep(BEAT_PERIOD)
if __name__ == '__main__':
hbc = HeartbeatClient()
hbc.run()
Now I wonder if I can daemonize the client also with Twistd? Therefore I would have create an Twisted-Application out of the client. But all examples I saw concerning Twisted applications where implementing some Twisted internet-server stuff (like in my case internet.UDPServer...), which my client does not use.
So is it possible to use Twistd to launch my client as a daemon, and what changes do I have to make? Should I rewrite the client to take full use of Twisted? If yes, are there any similar examples out there how to write a Twisted based network client?
Or do I have to use a different daemonize library for the client? There is a good library for that, but I'm trying to be consistent and use the same daemonizing mechanism for client and server.
With Twisted, as a tac file, your HeartbeatClient would look something like this:
from twisted.application.service import Application, Service
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
from twisted.internet.protocol import DatagramProtocol
class HeartbeatClient(Service):
def startService(self):
self._call = LoopingCall(self._heartbeat)
self._call.start(BEAT_PERIOD)
def stopService(self):
self._call.stop()
def _heartbeat(self):
port = reactor.listenUDP(0, DatagramProtocol())
port.write('PyHB', (SERVER_IP, SERVER_PORT))
port.stopListening()
application = Application("PyHB")
HeartbeatClient().setServiceParent(application)
Note the use of reactor.listenUDP, even though you're only sending UDP datagrams, not receiving any. UDP doesn't really have the concept of clients and servers, it only has open ports. All UDP ports can send and receive datagrams. That's why there's only reactor.listenUDP, not reactor.connectUDP.
Aside from that, LoopingCall gives you the loop you want, and putting the code into a custom Service subclass lets you start and stop the loop at the appropriate times.