Aiohttp routing (aiohttp.web.RouteTableDef) - python

I have a problems with RouteTableDef.
There is some project where routing structure like this:
1) There is file route.py.
routes.py
from aiohttp import web
routes = web.RouteTableDef()
2) There are some handlers in different files, for example:
handler1.py
from aiohttp import web
from routes import routes
#routes.get('/get')
async def handle(request):
name = request.match_info.get('name', "Anonymous")
text = "Hello, " + name
return web.Response(text=text)
and so on.
3) and main file, where app runs:
from aiohttp import web
from routes import routes
if __name__ == '__main__':
app = web.Application()
app.router.add_routes(routes)
web.run_app(app, host='localhost', port=8877)
The idea is:
all routes store at routes variable, when we wanna create new handler we import that variable from routes.py and use it.
In order to register routes to app, we import routes from routes.py.
And how to make it working with aiohttp v3.3.2?
The problem is: it works with aiohttp version 2.3.10.
But there is the real project with this way of routing and it works.
How to create a one place that will store routes?
I suppose that problem is in lib version, because that project doesn't work with the latest version of aiohttp.

The problem here is order of the imports, as already answered. This is one of the reasons why I create one web.RouteTableDef() in each file and then I put them together for app.router:
from .dashboard import routes as dashboard_routes
from .posts import routes as posts_routes
app.router.add_routes([
*dashboard_routes,
*posts_routes,
])

Import request handler handle to file where web.Application creates and runs. Import it before importing routes from routes.py

Related

Flask authentication using htpassword with routes in seperate files

I'm working on updating an existing university department internal website to run using Flask. Before we completely release the project where it will use shibboleth to manage authentication, I've been trying to setup authentication for testing using htpassword using this tutorial. I'm able to get authentication using htpasswords working for a single file, but I can't figure out how to add the authentication to separate files. Currently, the project looks like this:
This is my main file called app.py:
#app.py
from flask import Flask
from flask_htpasswd import HtPasswdAuth
app = Flask(__name__)
app.config['FLASK_HTPASSWD_PATH'] = '.htpasswd'
app.config['FLASK_SECRET'] = "Super secret key that I will change later"
htpasswd = HtPasswdAuth(app)
import exampleRoute
#app.route('/')
#htpasswd.required
def home(user):
return "This is the homepage"
This is an example of one of my route files called exampleRoute.py:
# exampleRoute.py
from app import app
from flask import Flask
#app.route('/exampleRoute')
def exampleRoute():
return "This is an example route in another file"
When I place the #htpassword.required decorator in front of exampleRoute(), I get an error saying that htpassword is not defined (which makes sense). I've tried to import the app configuration a few different ways and at best, I end up with a circular dependency. I know that I could place the authentication code in a separate file and then import that into all my endpoints, but I didn't think this was possible since this method is incorporated into the app configuration.
I ended up getting an answer from the reddit user alexisprince. The solution was to use Blueprints that import htpasswd from another file (called extensions.py).

running multiple multi-route Flask applications

I have a flask app script that has multiple routes...
#app.py
def create_app(Tractor_id=0):
#app.route("/")
def index():
return render_template('index.html')
#app.route("/id")
def start():
return Tractor_id
#app.route("/stop")
def stop():
I'm trying to implement it multiple times with different parameters each time with the help of DispatcherMiddleware but I'm having trouble with it.
Here's the actual implementation:
# multiapp.py
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.serving import run_simple
import start
T1 = start.create_app(Tractor_id='101')
T2 = start.create_app(Tractor_id='102')
# merge
application = DispatcherMiddleware(
None, {
'/{}'.format('T101'): T1,
'/{}'.format('T102'): T2
}
)
if __name__ == '__main__':
run_simple(
hostname='localhost',
port=5000,
application=application,
use_reloader=True,
use_debugger=True,
use_evalex=True)
In the index.html there are buttons that should redirect the user to the /id and /stop routes, but the do not work.
The general question would be, how to run multiple Flask applications which each have multiple routes within them?
I dont know DispatcherMiddleware.
But if you are trying to bind few flask servers, just pick for every process another port and it will work.
When you request them of course pay attention to port.
If you are struggling with actually making a multi route server, heres a good example.

Access flask app endpoints in another python file?

I have a python file which defines some endpoints using flask each doing some computation and return a JSON (POST method). I want to do unit testing on this in order to do this I want to be able to access the app I created in one python file in another file so I can test my endpoints.
I see a lot of this on the internet :
from source.api import app
from unittest import TestCase
class TestIntegrations(TestCase):
def setUp(self):
self.app = app.test_client()
def test_thing(self):
response = self.app.get('/')
assert <make your assertion here>
It doesn't explain how I can define and access my app in another file. This might be a stupid question but I really don't see how.
My app is defined as follows:
from flasgger import Swagger
from flask import Flask, jsonify, request
from flask_cors import CORS
import os
def init_deserializer_restful_api():
# Initiate the Flask app
app = Flask(__name__)
Swagger(app)
CORS(app)
# Handler for deserializer
#app.route("/deserialize", methods=['POST'])
def handle_deserialization_request():
pass
I have many other end points in this fashion. Should i just do:
import my_file_name
Thanks!!
Check out this question: What does if __name__ == "__main__": do?
As long as you have that in your python program, you can both treat it as a module and you can call it directly.

Combining 2 Flask apps using DispatcherMiddleware instance results in 404 for second app

Sorry for ambiguous question, I'm not sure how better I can put it. So let me do the explanation of my problem.
I've the Flask application libindic, which has 2 Flask application one is frontend and other is api. So I've wsgi.py as follows
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
from silpa import api, frontend
import os
conffile = os.path.join(os.path.dirname(__file__), "etc", "silpa.conf")
application = DispatcherMiddleware(frontend.create_app(conffile),
{'/api': api.create_app(conffile)})
if __name__ == "__main__":
run_simple('0.0.0.0', 5000, application,
use_reloader=True, use_debugger=True)
The front end access works properly but when I hit /api/JSONRPC I get 404 error returned. This rule is defined as follows in silpa/api/jsonrpc.py
bp = Blueprint('api_jsonrpc', __name__, url_prefix='/api')
#route(bp, '/JSONRPC', methods=['POST'])
def handle_jsonrpc_call():
...
And when I print value of application and application.app and application.mounts in python interpreter I see folllowing
>>> application.app
<Flask 'silpa.frontend'>
>>> application.mounts
{'/api': <Flask 'silpa.api'>}
I'm unable to figure out why /api/JSONRPC results in 404. I'm not sure how can I debug it. I did check the app.url_map for api application and I can see rule for /api/JSONRPC registered there.
If some one can tell me what I might be doing wrong it would be a great help.
OK after debugging and stepping through Flask code I figured out the reason for the problem. The following line actually caused the problem
bp = Blueprint('api_jsonrpc', __name__, url_prefix='/api')
url_prefix should not be present in code because I'm already mounting this app at /api. Adding a /api url_prefix will result in following url instead /api/api/JSONRPC. Removing the above line fixed the issue.
So if you are mouting your app at different mount point than / using DispatcherMiddleware you should not url_prefix in blueprint.

No response from a Flask application using Apache server

I have created a flask application and am hosting it on a Ubuntu server. I know that my apache config is correct since I am able serve the example flask application. However, this one seems to be giving me trouble. The code is below:
from flask import Flask, render_template, request, url_for
import pickle
import engine
import config
# Initialize the Flask application
app = Flask(__name__)
model = pickle.load(open(config.MODEL_PATH, "rb"))
collection = engine.Collection(config.DATABASE_PATH)
search_engine = engine.SearchEngine(model, collection)
#app.route('/')
def form():
return render_template('index.html')
#app.route('/search/', methods=['POST'])
def search():
query = request.form['query']
results = search_engine.query(query)
return render_template('form_action.html', query=query, results=results)
#app.route('/retrieve/<int:item_number>', methods=['GET'])
def retrieve(item_number):
item = engine.Product(item_number, collection.open_document(str(item_number)))
return render_template('document.html', item=item)
if __name__ == '__main__':
app.run()
When running the file directly through the python interpreter, it works fine and I can access. However, when starting through apache and wsgi, I get no response from the server. It just hangs when making a request and nothing is available on the logs.
I suspect that my issue may have something to do with the three objects I initialize at the beginning of the program. Perhaps it gets stuck running those?
Update: I have tried commenting out certain parts of the code to see what is causing it to stall. Tracing it out to the engine module, importing NearestNeighbors seems to be causing the issue.
import sqlite3
import config
from sklearn.neighbors import NearestNeighbors
from preprocessor import preprocess_document
from collections import namedtuple

Categories

Resources