Passing argument to class instantiated by framework? (Python Flask) - python

I have the following setting:
import sys
from flask import Flask
from flask.ext import restful
from model import Model
try:
gModel = Model(int(sys.argv[1]))
except IndexError, pExc:
gModel = Model(100)
def main():
lApp = Flask(__name__)
lApi = restful.Api(lApp)
lApi.add_resource(FetchJob, '/')
lApp.run(debug=True)
class FetchJob(restful.Resource):
def get(self):
lRange = gModel.getRange()
return lRange
if __name__ == '__main__':
main()
Is there a way to instantiate the Model-class inside the main()-function? Here, the Flask framework instantiates the FetchJob-class, so that I cannot provide it the parameters it forwards during the instantiation process.
I don't like to have global variables as this messes up the whole design ...

I think this should work, although I'm not familiar with Flask:
import functools
def main():
try:
gModel = Model(int(sys.argv[1]))
except IndexError as pExc:
gModel = Model(100)
lApp = Flask(__name__)
lApi = restful.Api(lApp)
lApi.add_resource(functools.partial(FetchJob, gModel), '/')
lApp.run(debug=True)
class FetchJob(restful.Resource):
def __init__(self, obj, *args, **kwargs):
restfult.Resource.__init__(self, *args, **kwargs)
self.obj = obj
def get(self):
lRange = self.obj.getRange()
return lRange

Related

Using APscheduler with Textual in Python

i need a scheduler in a Textual application to periodically query an external data source. As a test i've tried to use APscheduler to call a tick() function every second.
However nothing happens although the scheduler should be started.
What is going on and how to debug this?
from textual.app import App, ComposeResult
from textual.containers import Horizontal, Vertical
from textual.widgets import *
from apscheduler.schedulers.background import BackgroundScheduler
class HeaderApp(App):
def __init__(self, *args, **kwargs):
self.sched = BackgroundScheduler()
self.sched.add_job(self.tick,'interval', seconds=1)
self.sched.start()
super(HeaderApp, self).__init__(*args, **kwargs)
def compose(self) -> ComposeResult:
yield Header()
yield TextLog()
def tick(self):
text_log = self.query_one(TextLog)
text_log.write("tick")
def on_mount(self):
text_log = self.query_one(TextLog)
text_log.write(self.sched.running)
if __name__ == "__main__":
app = HeaderApp()
app.run()
I'm not familiar with apscheduler, but since you haven't had a response, could you use the builtin set_interval which will call a method at regular intervals?
from textual.app import App, ComposeResult
from textual.containers import Horizontal, Vertical
from textual.widgets import *
class HeaderApp(App):
def compose(self) -> ComposeResult:
yield Header()
yield TextLog()
def tick(self):
text_log = self.query_one(TextLog)
text_log.write("tick")
def on_mount(self):
self.set_interval(1, self.tick)
if __name__ == "__main__":
app = HeaderApp()
app.run()

How can I use jinja2 in python sanic?

According to my search.
There are two main views:
Install and use the sanic_jinja2
Just use the jinja2
But above two methods didn't work to me(Maybe it's my fault).
Could anyone give me some example code?
tool/tmp.py
from jinja2 import Environment, PackageLoader
from functools import wraps
from sanic.response import html
# print(__name__) # 当前文件路径
# ★package_path设置templates文件夹的相对路径(对于tmp.py来说)
env = Environment(loader=PackageLoader(__name__, package_path='../templates'), enable_async=True)
class Tmp:
#staticmethod
def template(template_name):
def warapper(func):
#wraps(func)
async def inner(request, *args, **kwargs):
temp = env.get_template(template_name)
context = await func(request, *args, **kwargs)
return html(await temp.render_async(context))
return inner
return warapper
app.py
from sanic import Sanic
from tool.tmp import Tmp
app = Sanic(__name__)
app.static("static", "./static")
# 实例化Tmp
br = Tmp()
#app.route('/dag/<br>/<status>', methods=["GET"])
#br.template('dag.html') # 会自动去templates下查找文件html文件
async def search_branch(request, br, status):
_branch = br
_status = status
_time = request.args.get('time')
return {'request': request, '_branch': _branch, '_status': _status, "_time": _time}

Python Decorator Log file not generating

I am new to Python and learning logging technique with Decorator.
For me the below code is not generating required log file. Debugged the code, getting correct message to logger statement but the file is not generating. From Test method i am call the required function where i have implemented Decorator. Please guide where i am doing mistake.
try:
import csv
import requests
import datetime
import os
import sys
import logging
except Exception as e:
print("Some Modules are missing {}".format(e))
class Meta(type):
""" Meta class"""
def __call__(cls, *args, **kwargs):
instance = super(Meta, cls).__call__(*args, **kwargs)
return instance
def __init__(cls, name, base, attr):
super(Meta, cls).__init__(name, base, attr)
class log(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
""" Wrapper Function"""
start = datetime.datetime.now() #start time
Tem = self.func(*args) #call Function
Argument = args
FunName = self.func.__name__ #get Function name
end = datetime.datetime.now() #end Time
message = """
Function : {}
Execustion Time : {}
Argument : {}
Memory : {} Bytes
Date : {}
""".format(FunName,
end-start,
Argument,
sys.getsizeof(self.func),
start
)
cwd = os.getcwd();
folder = 'Logs'
newPath = os.path.join(cwd, folder)
try:
"""Try to create a folder """
os.mkdir(newPath)
except:
"""Folder already exist """
logging.basicConfig(filename='apiRun.log'.format(newPath), level=logging.DEBUG)
logging.debug(message)
return Tem
class APIHelper(metaclass=Meta):
def __init__(self, *args, **kwargs):
pass
#log
def star_wars_characters(url):
#self.url = url
api_response = requests.get(url)
people = []
if api_response.status_code == 200:
data = api_response.json()
for d in data['results']:
character = []
character.append(d['name'])
character.append(d['height'])
character.append(d['gender'])
people.append(character)
return people
else:
return "Bad Request"
My Test Method:
import unittest
import csv
from com.Script.APIHelper import APIHelper
class TestAPI(unittest.TestCase):
def _setUp(self, file_name):
self.api = APIHelper()
with open(file_name, "w") as self.fd:
self.csvfile = csv.writer(self.fd, delimiter = ',')
self.csvfile.writerow(['Name','Height','Gender'])
def tearDown(self):
self.fd.close()
def test_responseNotEmpty(self):
file_name = 'SWAPI.csv'
self._setUp(file_name)
people = self.api.star_wars_characters("https://swapi.dev/api/people/")
assert type(people) is list
Thanks you in Advance.
Add finally
Change filename='apiRun.log' to filename='{}/apiRun.log'
try:
"""Try to create a folder """
os.mkdir(newPath)
except:
"""Folder already exist """
finally:
logging.basicConfig(filename='{}/apiRun.log'.format(newPath), level=logging.DEBUG)
logging.debug(message)
except is executed only when an exception is raised from try.
finally is always executed.

can't initialize values before starting App in Flask

I'm playing with Flask a little, for my application I would require a global storage which is updated by a Thread running in the background on the server. I found this question about global context and the answer from Johan Gov seems to work if I init the server using /create explicitly:
from flask import Flask
from flask.json import jsonify
app = Flask(__name__)
cache = {}
#app.route("/create")
def create():
cache['foo'] = 0
return jsonify(cache['foo'])
#app.route("/increment")
def increment():
cache['foo'] = cache['foo'] + 1
return jsonify(cache['foo'])
#app.route("/read")
def read():
return jsonify(cache['foo'])
if __name__ == '__main__':
app.run()
If I try to call the init automaticaly however, it fails as apparently no cache["foo"] is known.
from flask import Flask
from flask.json import jsonify
app = Flask(__name__)
cache = {}
def create(): #create does not have a route anymore
cache['foo'] = 0
#app.route("/increment")
def increment():
cache['foo'] = cache['foo'] + 1
return jsonify(cache['foo'])
#app.route("/read")
def read():
return jsonify(cache['foo'])
if __name__ == '__main__':
create() #initialize by default
app.run()
Why is this happening? How can I initialize global state before starting the Application?
You can use the Cache as your app property, i always use this when i want to avoid awkward global definitions, just define the cache like this:
# here u create a "cache" attribute for the app.
app.cache = {}
app.cache['foo'] = 0
# then after that when calling in a route:
# notice that we don't need the global keyword since we are using the app.
#app.route("/increment")
def increment():
app.cache = app.cache + 1
return jsonify(app.cache)
I even used relatively big objects like deep learning models using this method and had not problems at all.
tbh, the above code work for me without any change and I'm able to read and increment counter.
Try below code with global variable
from flask import Flask
from flask.json import jsonify
app = Flask(__name__)
cache = {}
def create(): # create does not have a route anymore
global cache
cache['foo'] = 0
#app.route("/increment")
def increment():
global cache
cache['foo'] = cache['foo'] + 1
return jsonify(cache['foo'])
#app.route("/read")
def read():
return jsonify(cache['foo'])
if __name__ == '__main__':
create() # initialize by default
app.run()

initialize logger in class to use in retry decorator

Iam writing a database client and i want use a specific logger in the retry decorator:
import pandas as pd
from retry import retry
from set_up.SetUp import set_logging, set_up_environment, get_retry_parameters
class DBClient:
def __init__(self):
self.log = set_logging()
self.connection = set_up_environment()
self.tries,self.delay = get_retry_parameters()
#retry(tries=tries, delay=delay, logger=log)
def get_artist_table(self):
Is there a possibility to use the variables that i instantiate the class with in the retry decorator (it's an external library).
Using retry_call instead of retry. This should be sufficient for your requirement. https://github.com/invl/retry/blob/master/retry/api.py#L79
import pandas as pd
from set_up.SetUp import set_logging, set_up_environment, get_retry_parameters
from retry.api import retry_call
def retrydecorator(func):
def inner(self, *fargs, **fkwargs):
result = retry_call(func, fargs=(self,)+fargs, fkwargs=fkwargs, tries=self.tries, delay=self.delay, logger=self.log)
return result
return inner
class DBClient:
def __init__(self):
self.log = set_logging()
self.connection = set_up_environment()
self.tries,self.delay = get_retry_parameters()
#retrydecorator
def get_artist_table(self):
pass

Categories

Resources