Complex Python Bottle App + WSGI - python

I have a python bottle application inside of a single folder that's been organized by function and I would like to convert my existing cherrypy usage over to apache mod_wsgi.
The folder structure looks like the following:
- project
-- app.py (loads the webserver class and runs it)
-- app
--- common
--- logs
--- modules
--- tools
--- web
---- webserver.py
The reason for this structure was so code from common could be used within tools and web without any issue. Imports are all done in a style of "from app.common.blah import utility". When trying to setup mod_wsgi, it expects to load up a simple application.
Is it possible to run mod_wsgi with a folder structure like this? If not, are there any recommendations for setting up a structure that will allow for mod_wsgi, but also the sharing of common utilities between folders like tools and web?

From the Bottle deployment docs on Deployment:
All you need is an app.wsgi file that provides an application object. This object is used by mod_wsgi to start your application and should be a WSGI-compatible Python callable.
File /var/www/yourapp/app.wsgi:
import os
# Change working directory so relative paths (and template lookup) work again
os.chdir(os.path.dirname(__file__))
import bottle
# ... build or import your bottle application here ...
# Do NOT use bottle.run() with mod_wsgi
application = bottle.default_app()
In your case, edit the snippet above to import the application object that is presumably defined in your app.py

Related

Can a Python script use a Django database while not being in the same folder?

I have a python application (which we'll call app) I'd like to have a web front for. The application has many files and it's important the folder tree structure stays the way it is.
I've built a Django project and put it in a folder named "Web" in the app's folder, so now the folder tree looks like so:
[Data]
[Resources]
[Web]
[WebFront]
normal django app files
[Web]
__init__.py
settings.py
urls.py
wsgi.py
__init__.py
manage.py
main.py
Here's the code on the app's main.py:
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Web.Web.settings")
django.setup()
This code causes an exception on the django.setup() line as (I think) django does not find the project modules: ImportError: No module named WebFront (WebFront is the name of the django app)
I suspect this is caused because django runs in the directory of python app, and therefore cannot find the folder WebFront - Which should actually be Web/WebFront
Can this be done? Or should I reverse the order and put the python app in the django app?
This is not a duplicate of the following questions as the folder nesting causes a different problem (I think)
Django 1.7 throws django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet
Easiest way to write a Python program with access to Django database functionality
Using only the DB part of Django
You can locate your main.py script where you like. However, if it is outside of the Web folder, then you will have to add Web to the Python path, otherwise imports like import Webfront are going to fail.
import sys
sys.path.append('/path/to/Web/')
Once you have done that, you can change the DJANGO_SETTINGS_MODULE to
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Web.settings")

Initial setup of Flask Mega Tutorial on pythonanywhere

After successfully completing the pythonanywhere flask tutorial (pa.com), Miguel Grinberg's the "Flask Mega Tutorial" (fmt) beckoned. Sadly, I've not even made it to "Hello, World". Here's what I have done:
In pa.com attempting to follow fmt verbatim is a no go:
python3 -m venv flask
leads to an error of
ensurepip is not available
and we do not have sudo access.
Undeterred, I reasoned that all Miguel is asking us to do is distribute the functionality we see in one file in the pa.com tutorial (flask_app.py) into a few files that will make the building of a full app easier. Since pa.com is already setting up my base web app with flask and python 3.4, not being able to set up the virtual env. did not seem to be a block, at least not at first.
Per the fmt, in the base dir of the pa.com (pwd -> home/{username}/microblog) -- which is where the flask_app.py file that successfully generates the pa.com tutorial page lives -- I set up app and tmp directories, and create app/__init__.py, app/views.py and the run.py files as directed by fmt
Hitting the app page (run.py the only file in the main directory) generates an Unhandled Exception on the page.
Changing the name to flask_app.py (which seems to be what pa.com expects on flask installations) generates the same error.
Modifying the content of the flask_app.py code to:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return "working from flask_app.py"
Generates a successful output from the app, whereas having the same code in a file named run.py generates the same Unhandled Exception error.
the lines:
from app import app in both run.py and views.py and
from app import views in __init__.py
all make me wonder... where is this "app" module coming from? But aside from being puzzled by that question, no other ideas on how to proceed from here. Any suggestions? Would really like to get set up on pa.com and work through this tutorial/book.
Feel like I am missing something basic, but not sure what.
First rule is: don't use app.run() on PythonAnywhere - that's what run.py is trying to do. That's fine for your own PC, but on PA it will cause an error. It's fine to have the file there, but don't try and import from that file in your wsgi config.
Instead, you just need to import the flask app variable, which Miguel gets you to put in app/__init__.py (that's slightly confusing, a variable called app, and a folder called app, but we can deal with it!)
To do that, you'll want to add the folder that contains the app folder to your sys.path. You also need to "rename" the app variable to application as you import it:
# assuming we have /home/myusername/microblog/app/__init__.py:
path = '/home/myusername/microblog'
if path not in sys.path:
sys.path.append(path)
# now we can import the app variable from the app folder's __init__
# and rename it to application
from app import app as application
More info: a brief guide to flask on pythonanywhere and a guide to debugging imports and sys.path problems in your pythonanywhere wsgi file
from microblog import app as application
This is fixed my solution.
Best Regards

Import a Python module when using WSGI

I just installed WSGI on Apache to start using Python as a web programming language. I only added this line to my Apache config (except for the loading of the mod_wsgi module)
WSGIScriptAlias MyApp/ /path/to/app.wsgi
I have my app.wsgi running fine, but I want to use separate files for separate functionality. So, I created an extras.py in the same dir as app.wsgi, with not much in it:
class MyClass:
pass
and put a
from extras import MyClass
on the top of my app.wsgi. But, unfortunately, I get this error:
ImportError: cannot import name MyClass
Am I missing something?
use the WSGIPythonPath to specify the modules which are to be searched while running ur wsgi application.
more about it could be found here

GAE - Flask can't import Jinja2 from subdirectory?

I'm working on a Google App Engine project using Flask. Flask is then using Jinja2. When I put Flask and all its required modules into the root folder of my project, the server started up just fine. However, I wanted to clean up the directory a bit so I moved Flask and other modules (including Jinja2) to a subdirectory called 'lib'. So my project looks like:
app.yaml
main.py
myapp
__init__.py
view.py
blahblah.py
lib
flask
jinja2
OtherModules
Then in the main.py file of the app I add the directory using sys.path.insert(0, 'lib'). Flask seems to import fine using this method, but Flask does not seem to be able to find Jinja2 with them both in the lib folder. When attempting to access a view on my running dev_appserver test I get:
File "lib/flask/__init__.py", line 19, in <module>
from jinja2 import Markup, escape
ImportError: No module named jinja2
How can I allow Flask to find Jinja2 (and allow other modules to find their requirements) while keeping them in the lib directory and not having to edit the modules to adjust paths?
Below is my main.py file in case something in there would be useful to know:
import sys
sys.path.insert(0, 'lib')
from google.appengine.ext.webapp.util import run_wsgi_app
from myapp import app
run_wsgi_app(app)
In order to include Jinja in you app engine application in your app.yaml file add these lines
libraries:
- name: jinja2
version: latest
Documentation for including more of the available libraries.
In order to use it for your local server you should install these also to your system. In a unix like system it would be
sudo easy_install jinja2
Additional information: there is an open source framework called gae-init, which combines your tech stack and provides a series of automations and good practices for app engine web services. Maybe worth having a look at it.

Sys.path modification or more complex issue?

I have problems with importing correctly a module on appengine. My app generally uses django with app-engine-patch, but this part is task queues using only the webapp framework.
I need to import django settings for the app to work properly.
My script starts with:
import os
import sys
sys.path.append('common/')
# Force Django to reload its settings.
from django.conf import settings
settings._target = None
# Must set this env var before importing any part of Django
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
I always get this error, or something related:
<type 'exceptions.ImportError'>: No module named ragendja.settings_pre
because the settings.py file starts with
from ragendja.settings_pre import *
I think I need to add ragendja to sys.path again but I had several tries that didn't work.
Here is my directory:
project/
app.yaml
setting.py
common/
appenginepatch/
ragendja/
setting_pre.py
myapp/
script.py
Is it only a sys.path problem and how do I need to modify it with the correct syntax?
Thanks
App engine patch manipulates sys.path internally. Background tasks bypass that code, so your path will not be ready for Django calls. You have two choices:
Fix the paths manually. The app engine documentation (see the sub-section called "Handling import path manipulation") suggests factoring the path manipulation code into a module that can be imported by your task script.
Eliminate dependencies on django code, if possible. If you can write your task to be pure python and/or google api calls, you're good to go. In your case, this might mean refactoring your settings code.
Why not:
sys.path.append('common/appenginepatch')
since the ragendja is in this directory?

Categories