ImportError: No module named config on Travis-CI build - python

I'm having an import error on Travis builds, the error is related to the configuration of flask:
from flask import Flask
app = Flask(__name__)
app.config.from_object('config')
On local machine, the flask app run correctly. But on travis here is the error trace
$ nosetests --with-coverage --cover-package=core
E.........................
======================================================================
ERROR: Failure: ImportStringError (import_string() failed for 'config'. Possible reasons are:
- missing __init__.py in a package;
- package or module path not included in sys.path;
- duplicated package or module name taking precedence in sys.path;
- missing module, class, function or variable;
Debugged import:
- 'config' not found.
Original exception:
ImportError: No module named config)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/travis/virtualenv/python2.7_with_system_site_packages/local/lib/python2.7/site-packages/nose/loader.py", line 414, in loadTestsFromName
addr.filename, addr.module)
File "/home/travis/virtualenv/python2.7_with_system_site_packages/local/lib/python2.7/site-packages/nose/importer.py", line 47, in importFromPath
return self.importFromDir(dir_path, fqname)
File "/home/travis/virtualenv/python2.7_with_system_site_packages/local/lib/python2.7/site-packages/nose/importer.py", line 94, in importFromDir
mod = load_module(part_fqname, fh, filename, desc)
File "/home/travis/build/dzlab/sentimentpy/webapp/app/__init__.py", line 6, in <module>
app.config.from_object('config')
File "/home/travis/virtualenv/python2.7_with_system_site_packages/local/lib/python2.7/site-packages/flask/config.py", line 162, in from_object
obj = import_string(obj)
File "/home/travis/virtualenv/python2.7_with_system_site_packages/local/lib/python2.7/site-packages/werkzeug/utils.py", line 426, in import_string
sys.exc_info()[2])
File "/home/travis/virtualenv/python2.7_with_system_site_packages/local/lib/python2.7/site-packages/werkzeug/utils.py", line 408, in import_string
return __import__(import_name)
ImportStringError: import_string() failed for 'config'. Possible reasons are:
- missing __init__.py in a package;
- package or module path not included in sys.path;
- duplicated package or module name taking precedence in sys.path;
- missing module, class, function or variable;
What's wrong with my configuration?

import_string only takes absolute module imports. Since config is not a top-level module, but part of webapp, you need to specify webapp.config. See http://flask.pocoo.org/docs/0.10/config/#configuring-from-files:
app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')

I came across this issue recently and could not figure it out until I had an epiphany after 2nd days by reading Markus's answer.
Just in-case someone out there is looking for a solution to load the configuration from config.py and the flask app is using a package structure then ensure to provide the full classpath to the config class file in app.config.from_object().
For e.g., I had a configuration myproj/app/config.py in my flask project myproj and the class file with the configuration was DevelopmentConfig. You need to provide it as follows:
app.config.from_object('app.config.DevelopmentConfig')
Another example would be if you put the same file under myproj/instance/config.py then, you call it as:
app.config.from_object('instance.config.DevelopmentConfig')
During the development of your app, the easiest way to change your settings would be to put an environment variable in myapp/.env file like so:
FLASK_APP=app
APP_SETTINGS="app.config.DevelopmentConfig"
and use the variable in your app.config.from_object() call:
app.config.from_object(os.environ['APP_SETTINGS'])
But do remember that for the .env to take effect, you need to start your app with flask run instead of running the app directly.

Related

How to rename Flask WSGI App during development?

I would like to know how can I change the name of the Flask WSGI App during the development stage.
Using the Flask Mega-Tutorial as reference, I was able to successfully setup a "Hello World" app.
Digressions from the tutorial:
Use pipenv as my Python virtual environment manager (instead of venv)
Name of the app is astronomer.py.
Now, I want to build on top of the existing app and customize the code to my requirements; starting with the app name that I have defined in the .flaskenv file as FLASK_APP env var.
Accordingly, I have updated the name of the root level Python script from astronomer.py (in the tutorial) to galielo.py (for my use). After changing the corresponding value of FLASK_APP and restarting the flask server via $ pipenv run flask run, the app crashes with the following error:
$ pipenv run flask run [12:29:33]
* Serving Flask app "astronomer.py" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 302-012-958
127.0.0.1 - - [09/Oct/2019 12:29:57] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
File "/Users/kshitij10496/.local/share/virtualenvs/galileo-iQPdbs28/lib/python3.7/site-packages/flask/cli.py", line 240, in locate_app
__import__(module_name)
ModuleNotFoundError: No module named 'astronomer'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/kshitij10496/.local/share/virtualenvs/galileo-iQPdbs28/lib/python3.7/site-packages/flask/cli.py", line 338, in __call__
self._flush_bg_loading_exception()
File "/Users/kshitij10496/.local/share/virtualenvs/galileo-iQPdbs28/lib/python3.7/site-packages/flask/cli.py", line 326, in _flush_bg_loading_exception
reraise(*exc_info)
File "/Users/kshitij10496/.local/share/virtualenvs/galileo-iQPdbs28/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/kshitij10496/.local/share/virtualenvs/galileo-iQPdbs28/lib/python3.7/site-packages/flask/cli.py", line 314, in _load_app
self._load_unlocked()
File "/Users/kshitij10496/.local/share/virtualenvs/galileo-iQPdbs28/lib/python3.7/site-packages/flask/cli.py", line 330, in _load_unlocked
self._app = rv = self.loader()
File "/Users/kshitij10496/.local/share/virtualenvs/galileo-iQPdbs28/lib/python3.7/site-packages/flask/cli.py", line 388, in load_app
app = locate_app(self, import_name, name)
File "/Users/kshitij10496/.local/share/virtualenvs/galileo-iQPdbs28/lib/python3.7/site-packages/flask/cli.py", line 250, in locate_app
raise NoAppException('Could not import "{name}".'.format(name=module_name))
flask.cli.NoAppException: Could not import "astronomer".
Debugging
After logging into the virtual env and checking for the value of the env var FLASK_APP, I get the old value of astronomer.py. This explains why the application is not starting. However, I'm not able to understand why this is happening?
I even tried using "eager-loading" the app using: $ pipenv run flask run --eager-loading
Still, the app does not start with the same error message ofcourse.
I was able to solve this manually by unsetting the env var FLASK_APP from within the virtual env and restarting the flask server. I'm curious to know about why the app is not loading the file .flaskenv at initialization and if there is an automated way to do this?
With Pipenv, I think things are a little bit different when it comes to environment variables. As per the documentation, there is a builtin mechanism for loading a .env file:
If a .env file is present in your project, $ pipenv shell and $ pipenv run will automatically load it, for you
So I guess you should rename your file from .flaskenv to .env and then safely remove the python-dotenv dependency.

Cannot get gcloud to work with Python and Pycharm

I am trying to connect to the Google App Engine Datastore from my local machine. I have spent all day digging in to this without any luck.
I have tried the approach here (as well as alot of other suggestions from SO such as Using gcloud-python in GAE and Unable to run dev_appserver.py with gcloud):
How to access a remote datastore when running dev_appserver.py?
I first installed gcloud based on this description from google:
https://cloud.google.com/appengine/docs/python/tools/using-libraries-python-27
According to the description I should add the following to my appengine_config.py:
from google.appengine.ext import vendor
vendor.add('lib')
If I do that I get an error saying ImportError: No module named gcloud
If I then move the code to my main.py it seems to pickup the lib-folder and the modules there. That seems a bit strange to me, since I thought appengine_config was being run first to make sure things were initialised.
But now I am getting the following stack trace:
ERROR 2016-09-23 17:22:30,623 cgi.py:122] Traceback (most recent call last):
File "/Users/thomasd/Documents/github/myapp/main.py", line 10, in <module>
from gcloud import datastore
File "/Users/thomasd/Documents/github/myapp/lib/gcloud/__init__.py", line 17, in <module>
from pkg_resources import get_distribution
File "/Users/thomasd/Documents/github/myapp/lib/pkg_resources/__init__.py", line 2985, in <module>
#_call_aside
File "/Users/thomasd/Documents/github/myapp/lib/pkg_resources/__init__.py", line 2971, in _call_aside
f(*args, **kwargs)
File "/Users/thomasd/Documents/github/myapp/lib/pkg_resources/__init__.py", line 3013, in _initialize_master_working_set
dist.activate(replace=False)
File "/Users/thomasd/Documents/github/myapp/lib/pkg_resources/__init__.py", line 2544, in activate
declare_namespace(pkg)
File "/Users/thomasd/Documents/github/myapp/lib/pkg_resources/__init__.py", line 2118, in declare_namespace
_handle_ns(packageName, path_item)
File "/Users/thomasd/Documents/github/myapp/lib/pkg_resources/__init__.py", line 2057, in _handle_ns
loader.load_module(packageName)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pkgutil.py", line 246, in load_module
mod = imp.load_module(fullname, self.file, self.filename, self.etc)
File "/Library/Python/2.7/site-packages/google/cloud/logging/__init__.py", line 18, in <module>
File "/usr/local/google_appengine/google/appengine/tools/devappserver2/python/sandbox.py", line 999, in load_module
raise ImportError('No module named %s' % fullname)
ImportError: No module named google.cloud.logging.client
What am I doing wrong here?
The google-cloud library is not working on App Engine and most likely you don't even have to since you can use the build in functionality.
From the official docs you can use it like this:
import cloudstorage as gcs
I solved it this way:-
1.) Create a lib folder in your project path.
2.) Install gcloud libraries by running following command into terminal from your project path:-
pip install -t lib gcloud
3.) Create an appengine_config.py module in your project and add following lines of code:-
import sys
import os.path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))
4.) After this, you can import like this:-
from gcloud import datastore
5.) To save data into live google datastore from local:-
client = datastore.Client("project-id")
key = client.key('Person')
entity = datastore.Entity(key=key)
entity['name'] = ashish
entity['age'] = 23
client.put(entity)
It will save an entity named Person having properties name and age. Do not forget to specify your correct project id.
Old question but this may be worth including:
I'm unsure the state of your requirements.txt file but I scrounged mine a bit and noticed setuptools was not included.
pip freeze doesn't export setuptools related question
Assuming you're following the tutorial, you likely installed those libraries EXCEPT for setuptools to lib.
I added setuptools=={verionnumber} to requirements.txt and that fixed this related issue for me.

Python/Django TypeError: relative imports require the 'package' argument

After years of writing in C and C++, I feel a bit of a dunce when it comes to python and django. I can't seem to get something simple to work. I concede that the error has been discussed in a number of posts.
I started going through some django tutorials so I have run 'django-admin startproject mysite' which has created a 'mysite' folder.
I've installed django_extensions so now I'm trying to use its 'runscript'. I have a more complex script that I want to run later but for now, I'm trying to invoke a simple user script which I found online via this mechanism i.e.
mysimplescript.py:
def run(*script_args):
print script_args
It is located in a 'scripts' folder so my structure is as follows, where the outer mysite/ root directory is just a container for my project:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
scripts
__init__.py
mysimplescript.py
When I run the script as follows, I get the relative imports error.
python manage.py runscript .scripts.mysimplescript.py --script-args
Testing 123
/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core
/management/base.py:265: RemovedInDjango110Warning:
OptionParser usage for Django management commands is deprecated, use
ArgumentParser instead
RemovedInDjango110Warning)
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core
/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core
/management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/email_notifications.py", line 63, in
run_from_argv
super(EmailNotificationCommand, self).run_from_argv(argv)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core
/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/email_notifications.py", line 75, in execute
super(EmailNotificationCommand, self).execute(*args, **options)
File "/usr/lib/python2.7/site-packages/Django-1.9.2-py2.7.egg/django/core
/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/utils.py", line 57, in inner
ret = func(self, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/commands/runscript.py", line 163, in handle
modules = find_modules_for_script(script)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/commands/runscript.py", line 146, in
find_modules_for_script
mod = my_import(nn)
File "/usr/lib/python2.7/site-packages/django_extensions-1.6.1-py2.7.egg/
django_extensions/management/commands/runscript.py", line 99, in my_import
importlib.import_module(mod)
File "/usr/lib64/python2.7/importlib/__init__.py", line 30, in import_module
raise TypeError("relative imports require the 'package' argument")
TypeError: relative imports require the 'package' argument
If I include the debug, then I can see the following # runscript.py #99:
Check for .scripts.mysimplescript.scripts.py
Having initially run some django tutorials, the following have been set:
./mysite/wsgi.py:os.environ.setdefault("DJANGO_SETTINGS_MODULE",
"mysite.settings")
./manage.py: os.environ.setdefault("DJANGO_SETTINGS_MODULE",
"mysite.settings")
./mysite/settings.py:ROOT_URLCONF = 'mysite.urls'
Some of the discussions on the topic e.g. [1]:python packaging for relative imports and [2]:How to do relative imports in Python? suggest adding a main.py in the outer mysite/ directory.
In essence, though, I still want to invoke the script via django-extensions using:
python manage.py runscript <some_script>
Just a further point. If I drop the '.' preceding the folder i.e.
python manage.py runscript scripts.mysimplescript.py --script-args Testing
123
then I get the following error:
No (valid) module for script 'scripts.mysimplescript.py' found
yet a 'mysimplescript.pyc' is generated.
Can someone help me please? How can I get python to recognize the package? Thanks in advance.
The example in the docs is to save the script as scripts/delete_all_questions.py, and then run it with
python manage.py runscript delete_all_questions
In your case, your script is scripts/mysimplescript.py, so you run it with
python manage.py runscript mysimplescript --script-args Testing 123
Note that you use the module name mysimplescript, so you shouldn't include .py. The django_extensions app assumes that scripts are in a scripts directory, so don't include that either.
Relative imports can run only from a python package. The directory you use the relative import shoul:
1. Contain an init.py file
2. Available to the PYTHONPATH (declared as a path, or sub-directory of another directory which has init.py and is on the path)
In other words, relative path will not work in a script unless you call the entire package:
$ python -m manage.py runscript mystie.scripts.mysimplescript
This will work..
python manage.py runscript mysimplescript --script-args Testing
123

How to debug ImportError (with sys.path being correct)

I serve django pages via CherryPy. Everything works when CherryPy is started in the foreground. When I daemonize CherryPy with
Daemonizer(cherrypy.engine).subscribe()
I get an ImportError.
sys.path is exactly the same in both cases (daemonized and non-daemonized). How can I debug this, what else than sys.path affects python imports?
Additional Information
Traceback:
[02/Sep/2014:03:08:46] ENGINE ImproperlyConfigured('Error importing module plinth.modules.first_boot.middleware: "No module named middleware"',)
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/cherrypy/wsgiserver/wsgiserver2.py", line 1353, in communicate
req.respond()
File "/usr/lib/python2.7/dist-packages/cherrypy/wsgiserver/wsgiserver2.py", line 868, in respond
self.server.gateway(self).respond()
File "/usr/lib/python2.7/dist-packages/cherrypy/wsgiserver/wsgiserver2.py", line 2267, in respond
response = self.req.server.wsgi_app(self.env, self.start_response)
File "/usr/lib/python2.7/dist-packages/cherrypy/_cptree.py", line 299, in call
return app(environ, start_response)
File "/usr/lib/python2.7/dist-packages/django/core/handlers/wsgi.py", line 187, in call
self.load_middleware()
File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py", line 45, in load_middleware
mw_class = import_by_path(middleware_path)
File "/usr/lib/python2.7/dist-packages/django/utils/module_loading.py", line 26, in import_by_path
sys.exc_info()[2])
File "/usr/lib/python2.7/dist-packages/django/utils/module_loading.py", line 21, in import_by_path
module = import_module(module_path)
File "/usr/lib/python2.7/dist-packages/django/utils/importlib.py", line 40, in import_module
import(name)
ImproperlyConfigured: Error importing module plinth.modules.first_boot.middleware: "No module named middleware"
The file to import: /home/fbx/code/plinth/plinth/modules/first_boot/middleware.py
The relevant sys.path entry (also present when the ImportError occurs): '/home/fbx/code/plinth'
The ImportError occurs in djangos import_module function in https://github.com/django/django/blob/master/django/utils/importlib.py.
The parameter name for import_module is "plinth.modules.first_boot.middleware"
the django MIDDLEWARE_CLASSES setting is 'plinth.modules.first_boot.middleware.FirstBootMiddleware'
One more note:
I run the daemonized server with python -m plinth in the directory /home/fbx/code/plinth.
When I start the daemonized server with /usr/bin/python /home/fbx/code/plinth/plinth/__main__.py everything works! In this case, sys.path has one additional entry: /home/fbx/code/plinth/plinth. But adding this path manually on startup doesn't fix the ImportError when run as python -m plinth.
I'm running this code: https://github.com/freedombox/Plinth/tree/0b5af376102f4210395c15b2366b96a6e56fefb2
update
Thanks #cyraxjoe,os.chdir() in combination with the module missing in __init__.py was the problem. For me this behavior is unexpected and I did not find a lot of useful information/documentation, so I set up a github repo to easier demonstrate the issue: https://github.com/fonfon/ImportError-demo
This is just a theory, but it could be the reason.
Given that:
The Deamonizer plugin changes the directory to the root os.chdir('/').
The package plinth.modules.first_boot is explicitly importing first_boot and not the middleware on the __init__.py of the package.
It could be that before the Daemonizer plugins changes the directory, the module plinth.modules.first_boot is imported but without the middleware, so when django y trying to dynamically import the module it just find the module on the import cache but it can't find the middleware because the path was relative and when the Daemonizer plugin changes the directory then it becomes inaccessible.
Try importing the middleware module on the __init__ of the package.
Basically add a from . import middleware on the __init__

django running unittest fail while one of my app named "apps", but "runserver" works

I have a django-project, its apps like this:
In apps/apps, there're views/models/urls as usual.
"runserver" works fine with command
./manage.py runserver --settings=mysettings 0:8000
But when I tried to run unittest with command below, ImportError met.
./manage.py test --settings=mysettings
========================================
Traceback (most recent call last):
File "/Users/lethe/.envs/django/lib/python2.7/site-packages/nose/loader.py", line 413, in loadTestsFromName
addr.filename, addr.module)
File "/Users/lethe/.envs/django/lib/python2.7/site-packages/nose/importer.py", line 47, in importFromPath
return self.importFromDir(dir_path, fqname)
File "/Users/lethe/.envs/django/lib/python2.7/site-packages/nose/importer.py", line 94, in importFromDir
mod = load_module(part_fqname, fh, filename, desc)
File "/Users/lethe/PycharmProjects/phone-buddy-oms/src/apps/downloads/tests/test_downloads_models.py", line 5, in <module>
from apps.models import (AppSource, AppCategory, App, Merchant, Apk)
ImportError: cannot import name Apk
It seems that django unittest frame cannot tell apps or apps/apps, I've tried to use django-nose to run but fail with similar errors.
Is there a solution except change the name of 'apps/apps'? thank you.
Your project home shouldn't have an init.py file, unittest mistakes your project home for a module and tries to load the tests from there but fails (because it has the same name as the app in INSTALLED_APPS).

Categories

Resources