Pywin32 service fails to start, unable to read json file - python-3.x

I used the Pywin32 tools and NSSM to create a windows service for my Flask application. I noticed that the service wouldn't start giving me a message :
The service did not return an error. This could be an internal Windows error or an internal service error
I noticed that when I removed all reference to a config.json file(used to connect to the DB) the created service starts. My service.py is :
import win32serviceutil
import win32service
import win32event
import servicemanager
from multiprocessing import Process
from app import app
class Service(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "Tests Python service framework by receiving and echoing messages over a named pipe"
def __init__(self, *args):
super().__init__(*args)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.process.terminate()
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def SvcDoRun(self):
self.process = Process(target=self.main)
self.process.start()
self.process.run()
def main(self):
app.run()
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(RouterService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(RouterService)
The following sample implementation of app.py works :
from flask import Flask
import json
import socket
app = Flask(__name__)
host = "<IP>"
user = "<username>"
passwd = "XXXXX"
DB = "YYYYY"
#app.route('/')
def hello_world():
return 'Hello, World!'
app.run(host = "0.0.0.0",debug = False, port=9000, threaded=True)
But as soon as I add code to read the DB credentials from a config.json file, the created service gives me an error :
conf = open('.\\config.json', "r")
data = json.loads(conf.read())
db_conf = data['db_connection']
host = db_conf['host']
user = db_conf['username']
passwd = db_conf['password']
DB = db_conf['DB']
Are there any issues with pywin32 reading json files? When I run the same app.py file from the command prompt it reads all the json files and runs without issues.

Related

Importing pyodbc in app.py causes azure web app to fail

requirements.txt
click==8.1.3
Flask==2.2.2
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.2
pyodbc==4.0.35
Werkzeug==2.2.2
app.py
import pyodbc
from flask import Flask, render_template
#def get_db_connect():
# conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=tcp:servername.database.windows.net,1433;Database=Dev-testing;Uid=username;Pwd={supersecurepassword};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;')
# return conn
app = Flask(__name__)
#app.route('/')
def index():
# conn = get_db_connect()
# assets = conn.execute('SELECT * FROM chosen_table').fetchall()
# conn.close()
return render_template('index.html')
If I comment out the import it produces the base page and works. But having that import causes the container to crash. Any help would be greatly appreciated.
I'm needing to establish a DB connection to an Azure SQL instance. I have tried to follow tutorials but nothing seems to work.
Firstly, I have installed pyodbc in my local
pip install pyodbc
I'm needing to establish a DB connection to an Azure SQL instance. I have tried to follow tutorials but nothing seems to work.
According to the above comment I created Azure SQL Database in portal.
Then, I created a python application to connect Azure SQL server DB by importing pyodbc
from flask import Flask, render_template
import pyodbc
app = Flask(__name__)
server = 'tcp:***.database.windows.net'
database = '****'
username = '****'
password = '*****'
cnxn = pyodbc.connect('DRIVER={ODBC Driver 18 for SQL Server};SERVER='+server+';DATABASE='+database+';ENCRYPT=yes;UID='+username+';PWD='+ password)
cursor = cnxn.cursor()
#app.route('/')
def index():
cursor.execute("select current_timestamp;")
row = cursor.fetchone()
return 'Current Timestamp: ' + str(row[0])
if __name__ == '__main__':
app.run()
I Started running my application in local, Its working fine in local.
Then I deployed my application in Azure web app.
After deploying to Azure Web App also Its running fine.

How do I fix 'Popped wrong app context' in Flask with APScheduler

I'm adding background tasks with APScheduler on runtime depending on an API call. In other words, there are no background tasks when the app, starts. When user makes call on an API, tasks are added on runtime. But I'm getting an error that says:
AssertionError: Popped wrong app context
The application works just fine if I comment out the lines where background tasks are scheduled.
My app structure is as follows:
/project
manage.py
requirements.txt
/app
/models
/routes
/utils
/api
config.py
__init__.py
My manage.py file looks like this:
app = create_app('dev')
app.app_context().push()
manager = Manager(app)
migrate = Migrate(app, db, render_as_batch=True)
manager.add_command('db', MigrateCommand)
with app.app_context():
scheduler = BackgroundScheduler()
scheduler.start()
#manager.command
def run():
app.run()
atexit.register(lambda: scheduler.shutdown())
if __name__ == '__main__':
manager.run()
init.py inside app folder is:
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from email_scheduler.routes.routes import set_routes
from .config import config_by_name
# from app.models.task import TaskModel
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config_by_name[config_name])
api = Api(app)
set_routes(api)
from email_scheduler.models.api_models import TaskModel, User
db.init_app(app)
with app.app_context():
db.create_all()
return app
My api.py file is:
class SignUp(Resource):
def clean_scheduling_time(self, schedule_time):
day = schedule_time.split(' ')[0].lower()[:3]
hour, mins = schedule_time.split(' ')[1].split(':')
return day, hour, mins
def post(self):
args = user_parser.parse_args()
username, password = args.get('username'), args.get('password')
schedule_time, email_to = args.get('schedule_time'), args.get('email_to')
if username is None or password is None:
abort(400) # missing arguments
from email_scheduler.models.api_models import User
if User.query.filter_by(username=username).first() is not None:
abort(400) # existing user
user = User(username=username, schedule_time=schedule_time.split(' ')[1], email_to=email_to)
user.hash_password(password)
user.save_to_db()
from manage import scheduler
from email_scheduler.utils.utils import send_email
day, hour, mins = self.clean_scheduling_time(args.get('schedule_time'))
trigger = CronTrigger(day_of_week=day, hour=int(hour), minute=int(mins))
scheduler.add_job(send_email, trigger=trigger)
print(scheduler.get_jobs())
return make_response(jsonify({'username': username}), 200)
What's weird is that even though I get this error on the terminal, the task somehow gets scheduled and is run. And if I take out the code from api that schedules the tasks, the API runs just fine. What am I doing wrong?
The problem is in your manage.py file.
You're running the following line globally:
app.app_context().push()
Which you correctly need for the worker to have access to app context. Move it inside the function that the worker calls.
Ie NOT this:
app = create_app()
app.app_context().push()
def your_async_fn():
# your code for the worker...
But this:
def your_async_fn():
app = create_app()
app.app_context().push()
# your code for the worker...

How to set the path while working on images in Flask on localhost as well as ibm cloud

This application was running fine till yesterday but today it isn't working. No changes have been made in backend or front end. The site Output is like this. I am trying to use open cv to extract 4 sub images from a image which has been uploaded in ../static/uploads folder. While the extracted 4 images are stored in ../static/extracted folder. Now my concern is, yesterday the code was running but today it isn't working. And while deploying to the ibm cloud, I could not find open cv. "cv2 module not found". Can someone please help me improve this code.
app.py code:
from cloudant import Cloudant
from flask import Flask, render_template, request, jsonify
import atexit
import os
import json
from ocr_core import ocr_core
UPLOAD_FOLDER = '/static/uploads/'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
app = Flask(__name__,static_url_path='')
db_name = 'mydb'
client = None
db = None
if 'VCAP_SERVICES' in os.environ:
vcap = json.loads(os.getenv('VCAP_SERVICES'))
print('Found VCAP_SERVICES')
if 'cloudantNoSQLDB' in vcap:
creds = vcap['cloudantNoSQLDB'][0]['credentials']
user = creds['username']
password = creds['password']
url = 'https://' + creds['host']
client = Cloudant(user, password, url=url, connect=True)
db = client.create_database(db_name, throw_on_exists=False)
elif "CLOUDANT_URL" in os.environ:
client = Cloudant(os.environ['CLOUDANT_USERNAME'], os.environ['CLOUDANT_PASSWORD'], url=os.environ['CLOUDANT_URL'], connect=True)
db = client.create_database(db_name, throw_on_exists=False)
elif os.path.isfile('vcap-local.json'):
with open('vcap-local.json') as f:
vcap = json.load(f)
print('Found local VCAP_SERVICES')
creds = vcap['services']['cloudantNoSQLDB'][0]['credentials']
user = creds['username']
password = creds['password']
url = 'https://' + creds['host']
client = Cloudant(user, password, url=url, connect=True)
db = client.create_database(db_name, throw_on_exists=False)
# On IBM Cloud Cloud Foundry, get the port number from the environment variable PORT
# When running this app on the local machine, default the port to 8000
port = int(os.getenv('PORT', 5000))
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/')
def home_page():
return render_template('index.html')
#app.route('/upload', methods=['GET', 'POST'])
def upload_page():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
return render_template('upload.html', msg='No file selected')
file = request.files['file']
if file.filename == '':
return render_template('upload.html', msg='No file selected')
if file and allowed_file(file.filename):
file.save(os.path.join(os.getcwd() + UPLOAD_FOLDER, file.filename))
extracted_text = ocr_core(file)
return render_template('upload.html',
msg='Successfully processed',
extracted_text=extracted_text,
img_src=UPLOAD_FOLDER + file.filename)
elif request.method == 'GET':
return render_template('upload.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=port, debug=True)
ocr_py.py:
try:
from PIL import Image
except ImportError:
import Image
import pytesseract
import cv2
from random import randint
import pandas as pd
#UPLOAD_FOLDER = '/static'
def ocr_core(filename):
#text = pytesseract.image_to_string(Image.open(filename))
val=str(filename)
val=list(val)
naam=""
tt=0
for i in range(15,len(val)):
if(val[i]!="'"):
naam+=val[i]
if(val[i]=='g'):
tt=1
if(tt==1):
break
image = cv2.imread("/home/sahil/CheckCheque-deploy/static/uploads/" +str(naam))
k=randint(0, 999999)
cropped1 = image[290:500, 320:1540]
cv2.imwrite("/home/sahil/CheckCheque-deploy/static/extracted/name"+str(k)+".png", cropped1)
name=pytesseract.image_to_string(Image.open("/home/sahil/CheckCheque-deploy/static/extracted/name"+str(k)+".png"))
cropped2 = image[470:700, 670:2640]
cv2.imwrite("/home/sahil/CheckCheque-deploy/static/extracted/amount"+str(k)+".png", cropped2)
amount=pytesseract.image_to_string(Image.open("/home/sahil/CheckCheque-deploy/static/extracted/amount"+str(k)+".png"))
cropped3 = image[850:1000, 480:1040]
cv2.imwrite("/home/sahil/CheckCheque-deploy/static/extracted/acc_no"+str(k)+".png", cropped3)
acc_no=pytesseract.image_to_string(Image.open("/home/sahil/CheckCheque-deploy/static/extracted/acc_no"+str(k)+".png"))
cropped5 = image[500:850, 2940:4500]
cv2.imwrite("/home/sahil/CheckCheque-deploy/static/extracted/amt_num"+str(k)+".png", cropped5)
amt_num=pytesseract.image_to_string(Image.open("/home/sahil/CheckCheque-deploy/static/extracted/amt_num"+str(k)+".png"))
acc_no1=""
lnum=["1","0","2","3","4","5","6","7","8","9"]
for i in range(0,len(acc_no)):
if(str(acc_no[i]) in lnum):
acc_no1+=acc_no[i]
l=[name,acc_no,amt_num]
df = pd.read_csv("/home/sahil/CheckCheque-deploy/jobchahiye.csv")
df.loc[df.Account== int(l[1]), 'Amount'] -=int(l[2])
df.loc[df.Name== str(l[0]), 'Amount'] +=int(l[2])
df.to_csv("/home/sahil/CheckCheque-deploy/jobchahiye.csv", index=False)
return l
Looks like you have a dependency on either opencv-python or opencv-contrib-python. As such it needs to be installed as a pre-requisite on any machine that you want to run your application.
On localhost you do this with pip, but if you are not running something like virtualenv then all installs will be to the global space, and conflicts can easily arise, resulting in you not being able to run anything.
For cloud deployments you specify pip prerequisites in your requirements.txt file

Failed to import quarry.auth

I am trying to create a bot for Minecraft in python to integrate with Discord. I have this code from the documentation
import discord
from twisted.internet import defer, reactor
from quarry.net.client import ClientFactory, ClientProtocol
from quarry.auth import Profile
class kek:
def __init__(self, client):
self.client = client
class ExampleClientProtocol(ClientProtocol):
pass
class ExampleClientFactory(ClientFactory):
protocol = ExampleClientProtocol
#defer.inlineCallbacks
def main():
print("logging in...")
profile = yield Profile.from_credentials(
"MOJANG EMAIL", "MOJANG PASSWORD")
factory = ExampleClientFactory(profile)
print("connecting...")
factory = yield factory.connect("play.minevibe.net", 25565)
print("connected!")
if __name__ == "__main__":
main()
reactor.run()
def setup(client):
client.add_cog(kek(client))
However, I get the error "MCBot.kek was not loaded. [No module named 'quarry.auth']" when I run it. The rest of the bot runs fine however it does not login to the server.
According to the github repo for quarry auth is inside the net directory so try replacing
from quarry.auth import Profile
with
from quarry.net.auth import Profile

SQLAchemy 'No application found. Either work inside a view function or push'

Ello ello,
I found similar questions on the bug i'm facing, and tried the solutions offered but it didn't work for me.
I'm trying to separate out my models in a different directory and import them into the app.py
When I try to import the db into the python terminal, i'm getting the no application found.
app.py code
from flask import Flask
from flask_restful import Resource, Api
# from flask_sqlalchemy import SQLAlchemy
from routes import test, root, user
from models.todo import db
app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://username:pass123#localhost/db'
app.config['SECRET_KEY'] = 'thiskeyissecret'
# db.init_app(app)
with app.app_context():
api = Api(app)
db.init_app(app)
api.add_resource(root.HelloWorld, '/')
api.add_resource(test.Test, '/test')
api.add_resource(user.User, '/user')
if __name__ == '__main__':
app.run(debug=True)
models
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Todo(db.Model):
__tablename__ = 'Todos'
id = db.Column('id', db.Integer, primary_key=True)
data = db.Column('data', db.Unicode)
def __init__(self, id, data):
self.id = id
self.data = data
def __repr__(self):
return '<Todo %>' % self.id
my file directory looks like
Main_app
Models
Todo.py
routes
some routes
app.py
Flask-SQLAlchemy needs an active application context.
Try:
with app.app_context():
print(Todo.query.count())
From the flask documentation:
Purpose of the Context
The Flask application object has attributes, such as config, that are
useful to access within views and CLI commands. However, importing the
app instance within the modules in your project is prone to circular
import issues. When using the app factory pattern or writing reusable
blueprints or extensions there won’t be an app instance to import at
all.
Flask solves this issue with the application context. Rather than
referring to an app directly, you use the the current_app proxy, which
points to the application handling the current activity.
Flask automatically pushes an application context when handling a
request. View functions, error handlers, and other functions that run
during a request will have access to current_app.
It is ok to have db initialised in app.py
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from routes import test, root, user
app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://username:pass123#localhost/db'
app.config['SECRET_KEY'] = 'thiskeyissecret'
db = SQLAlchemy(app)
api.add_resource(root.HelloWorld, '/')
api.add_resource(test.Test, '/test')
api.add_resource(user.User, '/user')
if __name__ == '__main__':
app.run(debug=True)
Then in your todo.py
from app import db
class Todo(db.Model):
__tablename__ = 'Todos'
id = db.Column('id', db.Integer, primary_key=True)
data = db.Column('data', db.Unicode)
def __init__(self, id, data):
self.id = id
self.data = data
def __repr__(self):
return '<Todo %>' % self.id
I get a same err
that err reason for just can operation db in viewfunc
def __init__(self, id, data):
self.id = id
self.data = data
try move that code operation to your viewfunc
In a nutshell, do something like this:
from yourapp import create_app
app = create_app()
app.app_context().push()

Resources