Packaging a python script from another repository into flask - python

I was tasked with creating 2 repositories.. one has a simple python script
the other is a flask application which should use the first script and return the results in a json
so both projects look something like this
main.py
import random
def isPrime(n):
# Corner case
if n <= 1:
return False
# check from 2 to n-1
for i in range(2, n):
if n % i == 0:
return False
return True
# Function to print primes
def printPrime(n):
previous_primes_nb = []
for i in range(2, n + 1):
if isPrime(i):
previous_primes_nb.append(i)
return previous_primes_nb
if __name__ == "__main__":
# randomized number
n = random.randint(2, 100)
# function calling
previous_primes_list = printPrime(n)
print(previous_primes_list)
simpleflask.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello, World!"
if __name__ == "__main__":
app.run(port=8777)

One way to achieve this is by creating a python package for main.py, and import that into your flask app.
Official doc on creating python packages.
Good tutorial on creating a package for internal use.
You can make that internal package available to the simpleflask.py making sure it's on the PythonPath envirnoment variable or you can use a tool like setuptools to distribute the package.

Related

NameError when putting variable declaration in if __name__ == '__main__': [duplicate]

This question already has an answer here:
How to process requests from multiiple users using ML model and FastAPI?
(1 answer)
Closed 15 days ago.
I have a Python file named main.py. I am running it on Python 3.9.13 on Windows.
import uvicorn
from fastapi import FastAPI
app = FastAPI()
#app.post('/c')
async def c(b: str):
print(a)
if __name__ == '__main__':
a = load_embeddings('embeddings')
uvicorn.run('main:app', host='127.0.0.1', port=80)
Running this, then invoking POST /c will cause a 500 error with NameError 'a' is not defined.
However it is obvious that a will be defined first before the server is ran. If I move a outside of the if __name__ == '__main__': then it works, but it causes load_embeddings to be ran multiple times for unknown reasons (3 exact). Since load_embeddings for me takes long time, I do not want the duplicate execution.
I wish to look for either of these as a solution to my issue: stop whatever outside if __name__ == '__main__': from executing multiple times, OR make a defined globally when it is being defined under if __name__ == '__main__':.
Note: variable names are intentionally renamed for ease of reading. Please do not advise me anything on coding style/naming conventions. I know the community is helpful but that's not the point here, thanks.
You can resolve the issue by moving the a variable definition inside the c function. Then, you can add a check inside the function to load the embeddings only if they have not been loaded yet. You can achieve this by using a global variable, which will keep track of whether the embeddings have been loaded or not.
Here is an example:
import uvicorn
from fastapi import FastAPI
app = FastAPI()
EMBEDDINGS_LOADED = False
def load_embeddings(filename):
# Load embeddings code here
...
#app.post('/c')
async def c(b: str):
global EMBEDDINGS_LOADED
if not EMBEDDINGS_LOADED:
load_embeddings('embeddings')
EMBEDDINGS_LOADED = True
print(a)
if __name__ == '__main__':
uvicorn.run('main:app', host='127.0.0.1', port=80)

Dask Multiprocessing

I am trying to run the following code. It works if executed in a shell but crashes if executed as macro (py macro.py). Please could you tell me what's wrong.
Thank you
import os
import sys
import dask
from dask.distributed import Client
def inc(x):
return x + 1
def add(x, y):
return x + y
client = Client(n_workers=2, threads_per_worker=2, memory_limit='1GB')
a = client.submit(inc, 10)
b = client.submit(inc, 20)
print(a.result())
print(b.result())
This is a problem with running scripts that create processes. You need to create your Client object within the if __name__ == "__main__": block
See the answer in where to put freeze_support() in a Python script? for more information.

write unit test for web.py application by using pytest

I would like to write unit test for web.py application by using pytest. How to invoke the web.py services in pytest.
Code:
import web
urls = (
'/', 'index'
)
app = web.application(urls, globals())
class index:
def GET(self):
return "Hello, world!"
if __name__ == "__main__":
app.run()
It can be done by using python requests module, when we run the web.py services, it will run http://localhost:8080/. Then import requests module and use get method and in response object, you can verify the result. That's fine.
By using Paste and nose also we can achieve this as per web.py official documentation. http://webpy.org/docs/0.3/tutorial.
Is there any solution in pytest like option in paste and nose.
Yes. Actually the code from the web.py recipe Testing with Paste and Nose could be used with py.test almost as is, just removing the nose.tools import and updating assertions appropriately.
But if you want to know how to write tests for web.py applications in the py.test style, they could look like this:
from paste.fixture import TestApp
# I assume the code from the question is saved in a file named app.py,
# in the same directory as the tests. From this file I'm importing the variable 'app'
from app import app
def test_index():
middleware = []
test_app = TestApp(app.wsgifunc(*middleware))
r = test_app.get('/')
assert r.status == 200
assert 'Hello, world!' in r
As you will add further tests, you will probably refactor creation of the test app out to a fixture:
from pytest import fixture # added
from paste.fixture import TestApp
from app import app
def test_index(test_app):
r = test_app.get('/')
assert r.status == 200
assert 'Hello, world!' in r
#fixture()
def test_app():
middleware = []
return TestApp(app.wsgifunc(*middleware))

modify content of flask page with another python script

I have two Python scripts:
tnk_flask.py: This creates a flask webserver and two pages.
pitoka.py: this creates a random number.
My goal is the following:
When I run pitonka.py, I always generate a random number which I'd like to pass to tnb_flask.py, but, after refreshing those pages nothing changes.
What can be the mistake?
tnb_flask.py:
from flask import Flask # ezzel importáljuk ki
from pitonka import *
app = Flask(__name__)
#app.route('/')
def index():
denis = alma()
return str(denis)
#app.route('/tuna')
def index__():
return str(numbi)
if __name__ == "__main__":
app.run(debug=True)
pitonka.py:
from flask import Flask
# import tnb_flask
import random
numbi = random.randint(10, 100)
print(numbi)
def alma():
return numbi + 17
In pitonka.py you are assigning the random number to a variable. So it will only get the random variable once. Instead return the random number in the function.
def alma():
return random.randint(10, 100) + 17
You could serve static pages via flask and re-render them from templates in pitonka.py

Global variable is None instead of instance - Python

I'm dealing with global variables in Python. The code should work fine, but there is a problem. I have to use global variable for instance of class Back. When I run the application it says that back is None which should be not true because the second line in setup() function - 'back = Back.Back()'
# -*- coding: utf-8 -*-
from flask import Flask
from flask import request
from flask import render_template
import Search
import Back
app = Flask(__name__)
global back
back = None
#app.route('/')
def my_form():
return render_template('my-form.html')
def setup():
global back
back = Back.Back()
def is_ascii(s):
return all(ord(c) < 128 for c in s)
#app.route('/', methods=['POST'])
def search():
from time import time
pattern = request.form['text']
startTime = time()
pattern=pattern.lower()
arr = []
if len(pattern)<1:
arr.append('Incorrect input')
currentTime = time()-startTime
return render_template('my-form.html', arr=arr, time=currentTime)
arr = []
search = Search.Search(pattern,back)
results = search.getResults()
..................
return render_template('my-form.html', arr=arr, time=currentTime, pattern=pattern)
app.debug=True
if __name__ == '__main__':
setup()
app.run()
Why is the back variable None instead of instance of Back class? Thanks
The Flask development server runs your module twice. Once to run the server itself, and another time in a child process so it can reload your whole script each time you make a change to it. It is that second process that won't run the __main__ guarded code and the global is left as None.
You'll get the same problem if you used another WSGI server; it'd import your file as a module, not as the initial script and the __main__ guard is not executed.
Use a #app.before_first_request function instead; it is guaranteed to be executed when the very first request is handled for this process. This also keeps your global working if you moved to a proper WSGI container that used multiple child processes to scale your site:
#app.before_first_request
def setup():
global back
back = Back.Back()

Categories

Resources