what file structure should I use for django app on google app engine - django

I can't get my django app to run on google app engine.
It deploys successfully but throws an error when I try connect to it in my browser.
main.py throws the following error: from wsgi import application as app ModuleNotFoundError: No module named 'wsgi'
I've looked at the question here:
ModuleNotFoundError - No module named 'main' when attempting to start service
I don't know what file structure is 'expected' for my main.py to run without errors.
This is the current structure
--static root file--main.py, app.yaml, etc.
|
voting------------
|
--voting-----------settings.py, wsgi.py, etc.
|
other stuff
my main.py currently reads (voting is the name of my project)
from voting.wsgi import application as app
I have tried voting.voting.wsgi and wsgi also. Please help

Fixed the issue by moving the static root.
Look at this for an example of how to set out the folder structure and where to place the static root: https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/standard_python37/django

Related

Upload Django app to Heroku. ModuleNotFoundError:No Module named 'Name of Project"

I can not upload Django App to Heroku by command: git push heroku master. After uploading I have error: ModuleNotFoundError: No module named 'bot_diller'
Procfile:
web: gunicorn bot_diller.wsgi --log-file -
enter image description here
From the directory structure the root of your Git project is not entirely clear to me.
It seems you reference bot_diller as python module probably in an import statement in one of your Python files, which is outside of the scope of the code you push to Heroku.
The Django project seems to be inside bot_diller/new_project, where you have the top-level files like Procfile, requirements.txt and manage.py.
The Django app you created seems to be called main, which is also a Python module and beside that you have a module named new_project, which probably contains the Django settings.
So inside your Django project you can write import statements like
from main.models import MyModel
and the import error probably originates from a statement like
from bot_diller.new_project.main.models import MyModel

While importing 'myapp.app' an import error was raised

I'm building a flask application, located in a subdirectory within my project called myapp. Running gunicorn --bind 0.0.0.0:$PORT myapp.app:app works fine, no errors, regardless of what FLASK_APP is set to. When I try to use Flask's CLI, however, it fails to find my app (reasonable), but when I set FLASK_APP to myapp.app., it appears to be doubling up the import path, resulting in an import error:
FLASK_APP=myapp.app flask run
* Serving Flask app 'myapp.app' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
Usage: flask run [OPTIONS]
Try 'flask run --help' for help.
Error: While importing 'myapp.myapp.app', an ImportError was raised.
How can I solve this? Is this a bug in Flask?
There was a __init__.py in my project directory that was causing this.
I dug into the source code of flask in cli.py and found the following code in prepare_import:
# move up until outside package structure (no __init__.py)
while True:
path, name = os.path.split(path)
module_name.append(name)
if not os.path.exists(os.path.join(path, "__init__.py")):
break
Because I had an __init__.py in my project directory (also called myapp), this made flask try to import myapp.app from the ancestor of my project, resulting in myapp.myapp.app.

ImportError: no module named [directory] Google App Engine

I keep getting an error that says no module named backend, this is the directory where my webapp2 application is.
My folder structure:
/project
/backend
/env #python virtual env libraries
main.py #my main entry point where webapp2 app instance is
requirements.txt
app.yaml
My app.yaml:
service: default
handlers:
- url: /dist
static_dir: dist
- url: /.*
script: backend.main.app
libraries:
- name: webapp2
version: latest
- name: jinja2
version: latest
Before my app.yaml was in backend, but I decided to move to root. Now when I run dev_appserver.py in root, I keep getting ImportError: No module named backend
I created the virualenv and installed the requirements.txt packages inside the backend directory.
EDIT: I am unsure if this makes a difference, but I have already deployed my application when the app.yaml was inside the backend folder. I am guessing this should not matter since I am trying to test locally by moving the app.yaml in my project root and running dev_appserver.py app.yaml, but it seems to not work when I do this.
The directory containing the app.yaml file for a GAE service is the service's top-level directory. The content of this directory is what will be uploaded to GAE when you deploy the service. All paths referenced in the service's code or configurations are relative to this top level dir. So moving the app.yaml file around without updating the related code and configurations accordingly will break the app's functionality.
You don't seem to grasp the meaning of the script: statement very well. From Handlers element:
A script: directive must be a python import path, for example,
package.module.app that points to a WSGI application. The last
component of a script: directive using a Python module path is the
name of a global variable in the module: that variable must be a WSGI
app, and is usually called app by convention.
Note: just like for a Python import statement, each subdirectory that
is a package must contain a file named __init__.py
So, assuming your app.yaml file is located in your project dir, the
script: backend.pythonAttack.app
would mean:
having an __init__.py file inside the backend dir, to make backend a package
having a pythonAttack.py file in the backend dir, with an app variable pointing to your webapp2 application
According to your description you don't meet any of these conditions.
My recommendation:
keep the app.yaml inside the backend dir (which doesn't need to be a python package dir)
update its script line to match your code. Assuming the app variable for your webapp2 app is actually in the main.py file the line would be:
script: main.app
run the app locally by explicitly passing the app.yaml file as argument (in general a good habit and also the only way to run apps with multiple services and/or a dispatch.yaml file):
dev_appserver.py backend/app.yaml
store your service python dependencies inside a backend/lib directory (to follow the naming convention), separated from your virtualenv packages
store the env virtualenv package dir outside the backend directory to prevent unnecessarily uploading them to GAE when deploying the service (and potential interference with the app's operation). The goal of the virtualenv is to properly emulate the GAE sandbox locally so that you can run the development server correctly.
Potentially of interest for structuring a multi-service app: Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?

Module 'main' has no attribute application -- Google App Engine Python with Django

I have been running into this problem for a short while now and simply can't find a solution anywhere. I am using Google App Engine to run a default Python 2.7 app with Django 1.5 (via GAE SDK) created through PyCharm. I can upload the app successfully, but upon visiting the actual page, I get a Server Error. Then, checking the logs in Google App Engine, I see this:
ImportError: <module 'main' from '/base/data/home/apps/s~eloquent-ratio-109701/1.388053784931450315/main.pyc'> has no attribute application
After searching the internet for a while, I was able to find a few posts which address this issue, but attempting them never seemed to solve my problem. For example: This problem was solved by replacing "application" with "app" in the following lines:
application = django.core.handlers.wsgi.WSGIHandler()
util.run_wsgi_app(application)
In fact, I had run into this same issue before and this solution provided a fix for me in the past, however at that time I was running a separate app and it was not through the GAE.
I checked the Django documentation for version 1.5 here, but the code and suggestions there don't seem to conflict with what I currently have in my project.
I read a bit more about this type of problem, and saw another post that suggested checking the app's wsgi.py file to ensure that it is named 'application' or 'app' respectively, so that one could then use that same name throughout the rest of the application. However, upon checking those settings I saw that 'application' was used there too:
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
There's even a line in settings.py which uses the same nomenclature to declare the WSGI application:
WSGI_APPLICATION = 'Chimera.wsgi.application'
I'm really having trouble debugging this. I get the feeling it's really dumb and I just can't see it, but unfortunately I'm not particularly good at this kind of stuff -- I'm still a bit of a novice in this field.
Does anyone have any idea what I could try in an attempt to fix this issue?
UPDATE: I started making line by line changes and testing things, and eventually I found that the GAE log changes depending on the input for the "script" under app.yaml. So if I change the script under "handlers" between "main.app" and "main.application", it adjusts the log output to refer to "app" or "application" respectively. So that line in the app.yaml file tells the app what to look for, but I'm still not seeing why it can't be found. Not sure what else I could change to test it out. I wish I knew a bit more about the actual inner workings so that I could figure out why the app is confused about the attribute. Is it trying to run before it even gets instantiated or something?
Source code below:
main.py
import os, sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'Chimera.settings'
from google.appengine.ext.webapp import util
from django.conf import settings
settings._target = None
import django.core.handlers.wsgi
import django.core.signals
import django.db
import django.dispatch.dispatcher
def main():
application = django.core.handlers.wsgi.WSGIHandler()
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
app.yaml
application: eloquent-ratio-109701
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: main.application
libraries:
- name: django
version: 1.5
wsgi.py
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Chimera.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Full log from GAE:
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 240, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 302, in _LoadHandler
raise err
ImportError: <module 'main' from '/base/data/home/apps/s~eloquent-ratio-109701/1.388053784931450315/main.pyc'> has no attribute application
Thanks for helping me out.
In your main.py file (i.e. the main module) application is a variable inside the main() function, not an attribute of the main module. Basically you don't need a main() function.
GAE has some specific support for using Django, I'd strongly suggest going through the Django Support documentation and the Django App example.
Based on the comment made by #DanielRoseman I discovered that declaring the app inside of the main() function caused an issue because the app attribute was then only accessible at the main() function level, as it was a member variable of main() as opposed to a global variable. Although the default application files were structured this way by PyCharm, it seems that it was incorrect. I'm not sure if this is a compatibility issue, but regardless, moving the app declaration outside of the main() function adjusts the scope in a way which allows for other parts of the project to access it, solving my problem.
Thank you #DanielRoseman for the comment.

Google App Engine Interactive Console: ImportError: No module named models

I have a django project running on my local server under the google app engine python SDK 1.9.7.
I want to run a query in the interactive console. I have a model called Flatpage
I put the seemingly appropriate handler in the app.yaml file, namely:
url: /admin/.*
script: google.appengine.ext.admin.application
login: admin
From the docs i understood that when the local development server is running the interactive console on the admin server would be running in the same environment as the a project. Yet:
the interactive console does not recognize any of my model classes and when i try to import models I get an error: ImportError: No module named models
I have tried adding the local path to the models.py file to the directory as well as various names like app.models, appname.models and projectname.models to no avail.
However. when I copy and paste the models file into the interactive console it works.
Would someone explain how to import the models file into the interactive console,
and, secondly, why the interactive console, which seemingly should already have the models defined when the server starts, needs to have the models defined again, anyway, thanks!
I'm not sure why you're adding that handler to use the console locally, but what I do is use the Development Console (available since last year), which by default runs on port 8000, from there (localhost:8000/console most likely) you can import modules from your project.
For example if you have models.py in the same directory as app.yaml, you should be able to do:
import models
entity = models.Flatpage()
with no problem.