Dynamic database connection Flask-SQLAlchemy - python-3.x

i need to connect two database. the default database is fixed but the other one is dynamic, its based on URL.
for example if url is : yourapp.myweb.com then second database name will be yourapp
i try connect database into init.py but its show me following error
builtins.AssertionError
AssertionError: A setup function was called after the first request was handled. This usually indicates a bug in the application where a module was not imported and decorators or other functionality was called too late.
To fix this make sure to import all your view modules, database models and everything related at a central place before the application starts serving requests.
here is my init.py
from flask import Flask,session
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__,static_url_path='/static')
# Database Connection
database = request.url.split("/")[2].split(".")[0]
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:root#localhost/main_database"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_BINDS'] = {
'user_db': 'mysql+pymysql://root:root#localhost/database_'+str(database), #dynamic Connection
}
db = SQLAlchemy(app)
db.create_all()
db.create_all(bind=['user_db'])
# db.init_app(app)
from . import views
here is the viwe.py
#app.route('/login', methods = ['GET'])
def index():
try:
from .model import Users
# Some Code
except Exception as e:
raise e
# return "Failed to login ! Please try again."
here is the model.py
from application import db
class Users(db.Model):
__bind_key__ = 'user_db'
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key = True)
email = db.Column(db.String(50))
name = db.Column(db.String(50))
password = db.Column(db.String())
def __repr__(self):
return '<User %r>' % self.name

As I said in one of my comments, this might be a problem with the database connection. Here's what I'd check for:
First of all, make sure you have the right engine installed in your virtual environment (you can check easily by running pip list; just in case, let me insist that libraries need to be installed in a virtual environment). Make sure you have not pymysql, but the port to Python3, called mysqlclient. pymysql only works with Python2. In order to install this library, you need to install first the Python and MySQL development headers. For example, in Debian/Ubuntu:
sudo apt-get install python-dev libmysqlclient-dev
Then you can install the library with the following command:
pip install mysqlclient
If this is installed, make sure you can actually connect to the database using the library. Open a Python shell within the virtual environment and type the following (from the example in github):
import pymysql.cursors
connection = pymysql.connect(host='<you_host>',
user='<user>',
password='<password>',
db='<database_name>',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
do_something()
except:
pass
If this works, make sure you're running the most recent version of Flask (0.12 at the moment; this again you can check by running pip list), as there are several bugs related to running Flask in DEBUG mode that have been fixed over time.
It's surely not the case here, but another sanity check is verifying that no other process is running on the port that you want to use for Flask.
If all of the above is working fine, I'd need to see a bit of the stack trace to figure out what is actually going on.

Related

JupyterLab 3: how to get the list of running servers

Since JupyterLab 3.x jupyter-server is used instead of the classic notebook server, and the following code does not list servers served with jupyter_server:
from notebook import notebookapp
notebookapp.list_running_servers()
None
What still works for the file/notebook name is:
from time import sleep
from IPython.display import display, Javascript
import subprocess
import os
import uuid
def get_notebook_path_and_save():
magic = str(uuid.uuid1()).replace('-', '')
print(magic)
# saves it (ctrl+S)
# display(Javascript('IPython.notebook.save_checkpoint();')) # Javascript Error: IPython is not defined
nb_name = None
while nb_name is None:
try:
sleep(0.1)
nb_name = subprocess.check_output(f'grep -l {magic} *.ipynb', shell=True).decode().strip()
except:
pass
return os.path.join(os.getcwd(), nb_name)
But it's not pythonic nor fast
How to get the current running server instances - and so e.g. the current notebook file?
Migration to jupyter_server should be as easy as changing notebook to jupyter_server, notebookapp to serverapp and changing the appropriate configuration files - the server-related codebase is largely unchanged. In the case of listing servers simply use:
from jupyter_server import serverapp
serverapp.list_running_servers()

from an external python script call a python function which require root previlege(pynq library) is continuously crashed

I have to get continuous data from a python function and one of its libraries(Overlay) depends on root privilege. I have to run that python function by using Flask.
First of all, I have searched how to give root access to a python script but unfortunately, I haven't found any which mimic my case.
The approach I have taken --
1/ Python file containing Overlay library suppose the name is child.py which contains a function name status_data
from pynq import PL
from pynq import Overlay
def main_path():
ol = Overlay("/home/xilinx/pynq/overlays/design_4/design_1_wrapper.bit")
return ol
def status_data():
ol = main_path()
data = '''my_code'''
return data
2/ Flask file name is app.py where I need the continuous data via an endpoint
from create_json_data import status_data
from flask import Flask, render_template
from flask import jsonify
'''mayn others lib, doesn't include'''
'''my_code'''
#app.route("/auto_update_table")
def parse_auto_update_table(name=None):
data_json = status_data()
return jsonify(data_json)
3/ Both files are in the same folder. I have run that child.py with sudo python3 child.py and it works. Executed the Flask code by sudo python3 app.py. My guess was as app.py runs with sudo so it will take all other dependents with root privilege. But I am failed. It executes but after some moments it crashes.
Is there any workaround to call child.py file's status_data function with root privilege from app.py without crash? Security isn't an issue so I can reveal my credentials to any script file and if also require I can give password manually but only once as it is a continuous process so over and over password typing is not a tangible solution.
As I know when you give admin permission (root) to an executable (your python script).
Whatever the executable does is with admin privileges. Try with calling it with the root account itself or sudo -u root --login "python3 app.py" to see if it works or not
Also saying it doesn't work is not helping. If you have a trace back. Add it to help us answer you or any more information that helps. I can't help you like this
EDITED AFTER user10634362 COMMENT BELOW
I have found a solution. First of all, I am changing the question title as after getting the solution I have understood the present title is not fit with the situation. Though giving root privilege is quite easy. sudo python3 app.py does the work. The major flaw was in
from pynq import Overlay
and
def main_path():
ol = Overlay("/home/xilinx/pynq/overlays/design_4/design_1_wrapper.bit")
return ol
I have called this main_path function repeatedly but it needs a handsome amount of delay and it was absent there. So I got an unwanted crash. After declaring
ol = Overlay("/home/xilinx/pynq/overlays/design_4/design_1_wrapper.bit")
I have passed ol as a global variable to status_data function and it solves the issue.

python setuptools depend on absolute path

We have a large git structure and inside that we wanted to create some python libraries, where some is referencing the other. Since we pull the git all at once we don't want setup tools reference each other via the VCS repository reference.
Currently what I was able to do was this:
from setuptools import setup
import setuptools.command.install
import pip._internal
import os
try:
era_root = os.environ.get("ERA_ROOT")
if not os.path.isdir(era_root):
raise ValueError("ERA_ROOT must point to a valid directory")
except KeyError as k:
raise KeyError("Please specify the ERA_ROOT environment variable")
protobufsDependency = "{}/Products/PythonLibs/Protobufs".format(
era_root)
class my_install(setuptools.command.install.install):
def run(self):
pip._internal.main(['install', '-I', protobufsDependency])
setuptools.command.install.install.run(self)
setup(name='replication_tools',
version='1.0',
packages=["FakeAgent", "EventGenerator"],
cmdclass={"install": my_install},
)
However this is problematic because if someone is installing this library with --user or some other params I would have to manually name them all in the pip._internal.main . So my question is is there some way I can reference with setuptools.setup the protobufsDependency directly as if it was a url package?
Something like (as this doesnt work but something like that)
setup(name='replication_tools',
version='1.0',
packages=["FakeAgent", "EventGenerator"],
install_requires=[
protobufsDependency
]
)
Ok it seems that I can use direct reference link
setup(name='replication_tools',
version='1.0',
packages=["FakeAgent", "EventGenerator"],
install_requires=[
"protobufs-generated # file://C:/PathToMyLib"
]
)

Why does the program run in command line but not with IDLE?

The code uses a Reddit wrapper called praw
Here is part of the code:
import praw
from praw.models import MoreComments
username = 'myusername'
userAgent = 'MyAppName/0.1 by ' + username
clientId = 'myclientID'
clientSecret = 'myclientSecret'
threadId = input('Enter your thread id: ');
reddit = praw.Reddit(user_agent=userAgent, client_id=clientId, client_secret=clientSecret)
submission = reddit.submission(id=threadId)
subredditName = submission.subreddit
subredditName = str(subredditName)
act = input('type in here what you want to see: ')
comment_queue = submission.comments[:] # Seed with top-level
submission.comments.replace_more(limit=None)
def dialogues():
for comment in submission.comments.list():
if comment.body.count('"')>7 or comment.body.count('\n')>3:
print(comment.body + '\n \n \n')
def maxLen():
res = 'abc'
for comment in submission.comments.list():
if len(comment.body)>len(res):
res=comment.body
print(res)
#http://code.activestate.com/recipes/269708-some-python-style-switches/
eval('%s()'%act)
Since I am new to Python and don't really get programming in general, I am surprised to see that the every bit of code in the commandline works but I get an error in IDLE on the first line saying ModuleNotFoundError: No module named 'praw'
you have to install praw using the command
pip install praw which install latest version of praw in the environment
What must be happening is that your cmd and idle are using different python interpreters i.e., you have two different modules which can execute python code. It can either be different versions of python or it can be the same version but, installed in different locations in your machine.
Let's call the two interpreters as PyA and PyB for now. If you have pip install praw in PyA, only PyA will be able to import and execute functions from that library. PyB still has no idea what praw means.
What you can do is install the library for PyB and everything will be good to go.

mock #patch does not patch redis class

I'm trying to mock redis class using mockredis as show below. But the original redis class is not getting masked.
test_hitcount.py
import unittest
from mock import patch
import mockredis
import hitcount
class HitCountTest(unittest.TestCase):
#patch('redis.StrictRedis', mockredis.mock_strict_redis_client)
def testOneHit(self):
# increase the hit count for user peter
hitcount.hit("pr")
# ensure that the hit count for peter is just 1
self.assertEqual(b'0', hitcount.getHit("pr"))
if __name__ == '__main__':
unittest.main()
hitcount.py
import redis
r = redis.StrictRedis(host='0.0.0.0', port=6379, db=0)
def hit(key):
r.incr(key)
def getHit(key):
return (r.get(key))
Where am I making the mistake?
When you import hitcount module you build redis.StrictRedis() object and assign it to r. After this import every patch of redis.StrictRedis class cannot have effect on r reference at least you patch some redis.StrictRedis's methods.
So what you need to do is patch hitcount.r instance. Follow (untested) code do the job by replace hitcount.r instance with your desired mock object:
#patch('hitcount.r', mockredis.mock_strict_redis_client(host='0.0.0.0', port=6379, db=0))
def testOneHit(self):
# increase the hit count for user peter
hitcount.hit("pr")
# ensure that the hit count for peter is just 1
self.assertEqual(b'0', hitcount.getHit("pr"))
You need to patch the exact thing that you imported in hitcount.
So if you imported import redis in hitcount then you need to #patch('hitcount.redis.StrictRedis').
If you imported from redis import StrictRedis then you need to #patch('hitcount.StrictRedis').
I'd the same issue. What I did is uninstall all the old versions of python from my machine. I used only python3 and it worked.
sudo apt-get remove python2.7
and I installed following
sudo easy_install3 pip
sudo apt-get install python3-setuptools
and then it worked.

Resources