Problems deploying Flask app on Google App Engine - python

I'm trying to deploy a Flask app on GAE using Windows. It runs fine locally but runs into problems when I try to run it on GAE.
First I get this error in flask\json.py:
from itsdangerous import json as _json
ImportError: No module named itsdangerous
Downloading and unpacking https://pypi.python.org/pypi/itsdangerous in the same directory doesn't fix the issue. If I just grab itsdangerous.py and put it in the flask directory, I get:
_slash_escape = '\\/' not in _json.dumps('/')
AttributeError: 'module' object has no attribute 'dumps'
I've read that it may be due to conflicting json.py files but I've also tried using absolute paths for the import json and it doesn't seem to make a difference.

You put the itsdangerous.py in the wrong directory. Because json.py and itsdangerous.py both exist in the /flask directory, itsdangerous.py will import /flask/json.py intead of the right one.
The GAE official doc mentioned a way to include 3rd-party libraries:
You can include other pure Python libraries with your application by
putting the code in your application directory. If you make a symbolic
link to a module's directory in your application directory, appcfg.py
will follow the link and include the module in your app.
Obviously, it's a poor solution because we don't want to mix the libraries we used with the code we write. The community have found better ways.
I suggest you to use a gae-flask project template(e.g. flask-appengine-template) or at least follow some of its project structure. You can put all these 3rd-party libraries under a directory like /lib and add '/lib' to sys.path. Actually flask-appengine-template include common flask modules like itsdangerous for you by default.
sample code:
import os
import sys
sys.path.insert(1, os.path.join(os.path.abspath('.'), 'lib'))
import application

Google now makes it super-easy:
https://console.developers.google.com/start/appengine

Related

Importing a module in resources/ into an XBMC plugin

I'm working on an XBMC plugin which requires a few Python modules not available via a requires tag in addon.xml (they are not in the XBMC repository as far as I'm aware). The documentation for plugin development seems to indicate that you can do this by adding the module(s) to the resources/lib/ subdirectory of your plugin directory.
I've done this and when testing it in XBMC I get an import error trying to import this module because it cannot be found.
I've read the other question I found on SO regarding this topic entitled Importing a python module into XBMC for use within an addon but the proposed solution there, of adding the module directory to the path before importing, doesn't work for me either. I get the same import error.
In fact I don't think that answer is correct because os.getcwd() in XBMC does not return your plugin directory path when called from within your plugin; so concatenating the path it gives with /resources/lib as the answer suggests won't yield a valid path. I modified the example to use getAddonInfo to find the plugin path from an Addon object via the xbmcaddon module and added that to the path concatenated with /resources/lib but it still did not work.
Putting the modules into the root of the plugin directory also doesn't work. I haven't been able to find specific documentation about how to do this correctly beyond the initial tutorial saying that I should add it to the resources/lib subdirectory.
So does anyone know how to do this or have an example of this being done successfully in another XBMC plugin?
Figured out my mistake. I wasn't paying attention to the path I was adding. I was adding the addon profile directory to sys.path using getAddonInfo('profile') when I should have been using getAddonInfo('path')
For future reference, if you want to add a subdirectory of your addon to the path, this is what I did:
import xbmcaddon
import os
...
my_addon = xbmcaddon.Addon('plugin.video.my_plugin')
addon_dir = xbmc.translatePath( my_addon.getAddonInfo('path') )
sys.path.append(os.path.join( addon_dir, 'resources', 'lib' ) )
import <whatever modules you want>
I guess that's yet another lesson in paying close attention to the content of an error message.

Installing icalendar (or other Python modules) in Google App Engine project

I'm trying to install the icalendar Python module for use in my Google App Engine project. I have created a Python virtual environment in my project folder, and installed the icalendar package in it. If I run the Python interpreter from the venv, I can import icalendar and use it just fine (help(icalendar) shows it's getting the module from the correct path: venv/lib/python2.7/site-packages/icalendar). I have created a symlink called icalendar pointing to that directory in my project root (same place as app.yaml). The project can deploy and run on GAE, but anytime it tries to use icalendar, I get "Cannot import module 'icalendar'".
I used the exact same steps to install the Twilio library in my app, which worked fine. If I don't include the symlink to the Twilio module, the error message is actually 'No module named twilio', instead of "Cannot import..". Not sure if that's relevant.
I've seen this: https://groups.google.com/forum/?fromgroups=#!topic/google-appengine/FM_NXd9cbus, which is exactly my problem, but there was no solution!
What am I doing wrong?
Edit: I also tried just putting the icalendar module directory in the project root, w/o the symlink. No difference.
You need to check how to use python libraries in GAE.
Pay attention as the docs are a bit confusing, you need to pick one (and only one) solution for a library, you can't mix both (they're both chapters on the above-mentioned page):
Requesting a library - for libs supplied by GAE - for these check notes for what you may need to do for your local development server
Installing a library - for additional libraries you need to include in your app - for these check also the restrictions the library needs to meet

How to manually install Flask extensions?

I have a Flask project which I've put the flask module (version 0.9) directly beside my app.py file. I've done this so that I can bundle everything into a version control repository that won't require anyone else using it to install additional Python modules.
I want to use flask-login so I've tried to manually install it by downloading the latest version and putting the flask_login.py file in my "local" flask/ext/ directory. However, while I can import flask and import flask.ext, I am unable to import flask.ext.login with Python throwing ImportError: No module named flask.ext.login. import flask.ext.flask_login throws an import error as well.
Is there something I have to do differently if Flask and it's extensions are local to the app.py?
The solution is to put the flask_login.py file in the same directory as my app.py file. No modification of the flask/ext/__init__.py file is necessary.
The flask.ext module is intended only as a an extension importer, not a repository for installed extensions. Based on the import path, I thought the flask/ext folder was where extensions were to be copied. This was incorrect. Extensions simply need to be somewhere on the python path.
Python doesn't throw the exception in your case, this Flask module is responsible for modifying the standard import hook in the ext folder:
https://github.com/mitsuhiko/flask/blob/master/flask/exthook.py
So, I don't think putting flask_login.py into flask/ext is the right way to use extensions in Flask. The documentation recommends to use pip install flask-login or python setup.py install. After that you can do:
import flask_login
If you still want to do it manually, remove the setup() call from ext/__ init__.py.
It probably has a good reason why the Flask guys did it this way though :-)
Right, but the point was to manually install everything so it could be self-contained in a version control repository that won't require additional installs. I've looked at the setup.py file but can't determine how it achieves the installation. – Soviut Oct 25 at 10:06
Why not use virtualenv to achieve this? You can push your env to source control as well, although that's not normal usage.
See: http://www.virtualenv.org/en/latest/

GoogleAppEngine and latest Python2.7: location of "google" directory

The latest Python2.7 has a google directory within dist-packages, making it impossible to import the google directory which contains appengine and other packages from another location. Such directory is required to work to effect imports from GoogleAppEngine (GAE) code on the dev_server. Otherwise such imports fail. An example of such import is:
from google.appengine.api import mail
which yields
ImportError: No module named appengine.api
This issue is similar to the one in here and indeed following Alex Martelli's reply the location of my google import is
In [1]: import google
In [2]: google.__file__
Out[2]: '/usr/lib/python2.7/dist-packages/google/__init__.pyc'
rather than the one where I placed the GAE unzipped files.
Any recommended way to fix this? I already thought about dirty hacks to fix this, such as putting soft links in the dist-packages google directory, but again, that's dirty.
Packages have a special attribute, __path__, which tells the Python interpreter where to look for modules and subpackages. By modifying this, you can let Python find contents from both google directories. Using the pkgutil module, this ought to work (untested):
import pkgutil
import google
google.__path__ = pkgutil.extend_path(google.__path__, google.__name__)
Are you sure this google directory came with Python 2.7? I've seen it too, but it appeared for the first time when I installed some utility from Google (I think it was Google Storage for Developers). I also think there's a .pth file related to this.

The difference between 'from pylons import config' and 'import pylons.config'

Im trying to import a company module into my software and I get the error:
ImportError: No module named config
from:
from pylons.config import config
So obviously, the module that im importing requires pylons.config but cant find it in my virtual environment.
If I go to the terminal and try some Python scripts I can seem to find the config file if I try:
from pylons import config
but will error if I try:
import pylons.config
Why is this?
And does anybody how or where I can get:
from pylons.config import config
to work. Bearing in mind that I cannot change the code for this module, only mine which is importing it or my own system files.
UPDATE
If anyone finding this page has a similar problem you may find that you are trying to run two modules with different versions of Pylons.
For example, you are creating a login application called myApp. You have some Python modules which help with login handling called pyLogin.
First you install pyLogin with python setup.py install. This adds the libraries to your site packages and updates any libraries it depends on, such as SqlAlchemy.
Next you install myApp in the same way which again updates libraries and dependencies.
This problem will occur if pyLogin and myApp are using different versions of Pylons. If pyLogin is using Pylons 0.9.6 and myApp is using Pylons 1.0 for example, then the pyLogin code will be called from myApp but it will be running in the wrong Pylons framework and hence will require EITHER from pylons import config or from pylons.config import config, but will only work with one. If it is using the wrong call for Pylons then you will find yourself with this error message.
So the only solution to this error is to either find earlier or later libraries which use the same Pylons version as your application or to convert your application to the same Pylons version as the libraries you are using.
There is a diffrence between two usages...
import loads a Python module into its own namespace, while from loads a Python module into the current namespace.
So, using from pylons import config imports config to to your current namespace. But trying to import a class or function using import is not possible since there is no namespace to keep them... You can only import modules, and use functions or classes via calling them with their own namespace like
import pylons
....
pylons.config #to retreive config
More about import in Python

Categories

Resources