importing gaeutilities or any other module by dev_appserver - python

I'm developing a gae application on a windows machine. to have session handling I downloaded gaeutilities and added its path (C:\Python25\Lib\site-packages\gaeutilities-1.2.1) to the registry ("PythonPath" item under python25).
in my code this is how I import the gaeutilities Session class:
from appengine_utilities.sessions import Session
when gae engine (dev_appserver.py) tries to import it, an exception is raised, stating an importerror and "no module named appengine_utilities.sessions"
on the other hand, pyscripter can find the module (autocomplete becomes available for the Session class), and I can import the module within the python interpreter (the same one that dev_appserver uses, python 2.5.4).
for a remedy, I created a PYTHONPATH environmental variable and also added the path to it. nothing changes.
I'm lost. what am I doing wrong?
important edit: I have found myself to be totally unable to import any 3rd party gae modules. PYTHONPATH is correct, sys.path is correct, registry is correct, still dev_appserver complains of importerror.

Strange.
I would start troubleshooting by making 100% sure that the sys.path that dev_appserver.py uses does include C:\Python25\Lib\site-packages\gaeutilities-1.2.1.
I suggest you display sys.path in a HTML view served by dev_appserver.py.
Check permissions on gaeutilities-1.2.1 directory and subdirectories. Perhaps the python interpreter is unable to create *.pyc files or something like that.
Another suggestion:
Put the appengines_utilities folder in your application directory (the directory that contains your app.yaml file). I guess you need all third-party stuff there anyway if you want to upload the code to google's servers.

Related

ModuleNotFoundError - Python3

New to Python and getting errors when importing modules. I have the following structure (not sure if this is a good way to show folder structure):
ecommerce
customer
__init__.py
contact.py
shopping
__init__.py
sales.py
__init__.py
I want to import contact.py from customer into sales.py in shopping but get presented with: ModuleNotFoundError: No module named 'eccommerce'.
I'm using this:
from ecommerce.customer import contact at start of the sales.py file.
Any ideas?
VSCode, MacOS 10.14.6
One thing to pay attention to is where is your current working directory located. If you have the cwd set to be in ecommerce than you should be able to access the contact with the syntax you inputted.
I ran into this issue several times and in the python documentation this setup should technically work, init files being parsed by the python parser as individual packages which you can then access. It seems though that it won't work with the standard python interpreter and I haven't found the answer why. One way to get around this is to do as #Sory suggests, at the beginning of your package entry, add the path to the environment variable. This is a work around though and can lead to problems later on.
Another option is to use a separate python interpreter, i use for example the IPython interpreter from Jupyter which runs with this setup perfectly fine. This will give you another external dependency though.
Be sure though that the current working directory is set to be the root folder though as that is usually the first problem.
from ecommerce.customer import contact would work if 'customer' was a class in the ecommerce.py file, but in your case, those are different files so it doesn't work...
The correct syntax would be:
from customer import contact
but you need to adjust those files.
Another way around would be to import os, navigate to that ecommerce folder like so: os.getcwd('insert dir path here'), and then import customer.

Problems with relative import and Python 3

First, I need to describe the environment I'm writing for. I'm writing Python code that will be loaded and executed by a Python runtime running within a CAD application. The CAD application uses Python as its scripting engine. As a result, I don't have access to the Python runtime and as a good citizen to all other scripts shouldn't modify any system settings. My script is just one of many that are loaded and running.
This all works fine except when I want to use non-standard libraries. In that case, I need to install a local copy of the library for my script to access. The problem I'm having is that most libraries expect to be installed and added to the sys path which is something I shouldn't do because it could create conflicts with what other scripts are doing. What I'm attempting to do instead is to set up a local copy of the library(s) and then edit their source so their imports are relative and they don't depend on the sys path. That way my program will have its own local copy of the libraries and not depend on anything else and won't disturb any other scripts.
I'm using the -t option of PIP to install Requests and PyOpenSSL into a "Packages" subfolder in my script folder. Here's an abbreviated list of what I have.
RequestsTest/
RequestsTest.py
Packages/
OpenSSL/
cryptography/
x509/
__init__.py
base.py
hazmat/
__init__.py
backends/
__init__.py
interfaces.py
openssl/
__init__.py
backend.py
x509.py
OpenSSL/
__init__.py
SSL.py
Requests/
chardet/
__init__.py
requests/
__init__.py
urllib3/
__init__.py
request.py
contrib/
__init__.py
pyopenssl.py
util/
__init__.py
request.py
ssl_.py
Although it's tedious to track down the various import statements and make then relative, it does seem to work. However, I'm having problems with one particular set of imports.
In Packages/Requests/urllib3/contrib/pyopenssl.py it contains the following imports, which I've modified:
from ....OpenSSL.OpenSSL import SSL
from ....OpenSSL.cryptography import x509
They were originally:
from OpenSSL import OpenSSL.SSL
from cryptography import x509
I get the error "ImportError: No module named 'OpenSSL'" for the first line and "ImportError: No module named 'cryptography'" for the second line. I'm fairly certain the path is correct because if I change the number of dots I get the no module named error but it lists the full path of the what it's trying to load and not just the name of the module.
I would appreciate some help with this specific issue but can also use some overall advice of how to set up and use private copies of libraries. Remember that my program is just one of many that the system is loading changing the system or setting up a virtual environment is not an option.
Check out the localimport module, which seems to be a solution for your particular use case. From the README:
Given your Python script, application or plugin comes with a directory that contains modules for import, you can use localimport to keep the global importer state clean.
app.py
res/modules/
some_package/
__init__.py
# app.py
with localimport('res/modules') as _importer:
import some_package
assert 'some_package' not in sys.modules
The tagline is "Isolated import of Python Modules for embedded applications." so it seems pretty relevant.
When using that module, the following may help keep things neat:
Put your actual script logic into its own file.
Have a wrapper script (which will be the one loaded by the CAD software) which does localimport as mentioned in the README then does a relative import of your module. If your module gets big enough maybe put it into its own package and consume it in the same way as everything else (just do from RequestsTest import * in the body of the with localimport(): ....
Try to have a clear boundary between the source code you write and the final organized set of files required to use that source code in the context of the CAD Python runtime. It is OK to have a build/packaging step that creates the localimport script, downloads the required packages, etc. It's better even because then it is automated and not something that was done manually that someone in the future may have to recreate.

In django 2.0, writing a script to delete models

I have tried every answer on the (Django script to access model objects without using manage.py shell) stack question, and I always get error "no module name 'project_name'".
My project name is called snapbackend.
I have an __init__.py setup. I know I can write django command, but that is somewhat overkill to run one function.
I am using django 2.0, and I wanted to write a script to delete old models.
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "snapbackend.settings.production"
import django
django.setup()
import snapbackend
from snapbackend.models import deleteCapsuleModels
deleteCapsuleModels()
This is because your module isn't installed, and it is not being run from the directory which it is inside of.
If you are using setuptools (a setup.py file), then the proper way to solve this is to symlink your project into your site packages with python setup.py develop. This will make your module available throughout your project.
If you aren't using setuptools then this is a bit trickier. If you are able to choose your current working directory when running the script, you can solve this problem by executing cd YOUR_PROJECT_DIRECTORY before running your script.
In cases where you can't mess with the current working directory, you should se the PYTHONPATH environment variable to the root of your project. This environment variable is used to add additional paths for Python to find modules within.
It's important that you don't use PATH or sys.path for security reasons. Specifically, you don't want to accidentally introdduce any executables into your system which you are unaware of.
Hope this helps!
This is an issue with you PYTHON_PATH which seems simple but is often more tricky to figure out.
Python cannot find your django root so you need to tell python where it can find that module (not sure why it doesn't just work) but you can do this when running the script:
PYTHONPATH=../../. python your_script.py
Or the fly with:
import sys
sys.path.append('../../.')
In your case:
import os
import sys
sys.path.append('../path/to/snapbackend/.')
os.environ["DJANGO_SETTINGS_MODULE"] = "snapbackend.settings.production"
import django
The directory would depend on the relative path to your django root

How to force non-default GAE module to update to new version?

So I have the recommended setup for smaller projects, where you have multiple module YAML files all in the main file, all sharing source. Like here: https://cloud.google.com/appengine/docs/python/modules/#devserver
I only have 2 modules: the default module, and my backend module for running tasks, pipeline, etc.
Default is on version 22, backend is on version 'uno' (the first and only version of this module).
I cannot get backend to update to version 'dos'. Whenever I test things I am getting 404's, like the source files don't exist on the backend module. The requests make it to the correct module, but error out.
I have tried to update using: appcfg.py update main_directory app.yaml backend.yaml
But it always looks like it is only doing a 'default module' update. I never see anything about the backend module. Even when I try the above command minus the app.yaml (which is acting as my default module YAML).
In the developer console I can only see the single version for my backend module. It has not added a 2nd version despite my attempts to add a 'dos' version, and a 'v2' version' - both never "worked".
Anyone else have problems updating a 'backend' module to a new version? Is it the 'all in one directory' setup giving me problems? Am I just not using the right appcfg incantation?
Update 1: My directory structure looks like this
where module1.yaml is app.yaml and module2.yaml is backend.yaml.
Drop the main_directory from the update command:
appcfg.py update app.yaml backend.yaml
Specifying a directory only works for single-module apps, for uploading modules only the respective modules' .yaml files should be specified:
You can also update a single module or a subset of the apps modules by specifying only the .yaml files for the desired module(s).

Import failed when the module is already in the sys.path

It's weird to me that the import fails even when it's in the sys.path.
today, I set up a google app engine django environment on ubuntu in my lab's pc. And it works fine when I checked out the code and ran it in windows(same pc in the lab).
But when I went to the dorm, and checked out the code and start to run, it failed weirdly.
I print the sys.path, like this:
['/home/tower/googlecode/mygae', '/home/tower/googlecode/mygae/.google_appengine', '/home/tower/googlecode/mygae/.google_appengine/lib/antlr3', ...]
and when I ran python complained
from google.appengine.api import apiproxy_stub_map
ImportError: No module named appengine.api
it's easy to know the google module is in the '/home/tower/googlecode/mygae/.google_appengine'
directory, and the__init__.py for each module is present.
So what can be the reason for this weird thing? Or what I messed up probably?
thanks.
Can you import google and google.appengine?
Are you sure interpreter has read and traverse access rights to the module tree?
I had the same problem on Ubuntu when I wanted to play with google.appengine in console. First I tried to fix it by removing the /usr/lib/python2.7/dist-packages/google package altogether but Ubuntu One complained. Finally I resolved it by merging the GAE SDK google package into the package that caused the collision.
The contents of the /usr/lib/python2.7/dist-packages/google dir now look like this:
/google
/appengine
/net
/protobuf
/pyglib
/storage
/__init__.py
/__init__.pyc
Looks like you're getting a module (or package) called 'google' from elsewhere -- perhaps /home/tower/googlecode/mygae -- and THAT google module has no appengine in it. To check, print google.__file__ and if possible google.__path__; that should be informative.
Sometimes you can get an import error for a module when the error is something different, like a syntax error. Try putting
import pdb;pdb.set_trace()
just before the import and then s(tep) into the import, and n(ext) thruogh the module in question to see of you get an error.

Categories