Django ASGI New Relic getting a CORS Error Heroku - django

I am running a Django Application using Django channels and a daphne server (ASGI) instead of the typical gunicorn (WSGI) server. So I had to modify my application to this:
# asgi.py
import os
import django
from channels.routing import get_default_application
from asgiref.wsgi import WsgiToAsgi
from django.core.wsgi import get_wsgi_application
from newrelic import agent
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
django.setup()
application = agent.WSGIApplicationWrapper(get_wsgi_application())
application = WsgiToAsgi(application)
To my surprise this actually works. When I access my django api from a browser or postman it works properly and the data shows up in New Relic. However, I also have a client-side Angular web app which makes REST API calls to the django server and I am getting CORS errors.
Please note that this is not a regular CORS issue as when I remove the new relic wrapper I am able to access my API properly from Angular.
Failed to load https://my-app.herokuapp.com/api/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin https://frontend.com is therefore not allowed access.

Change your asgi.py file something like this
from django.core.asgi import get_asgi_application
import newrelic.agent #import newrelic agent
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
django_asgi_app = get_asgi_application()
from django.conf import settings
newrelic_config_file = settings.BASE_DIR + "/newrelic.ini" #location of your newrelic.ini file
newrelic.agent.initialize(newrelic_config_file) #initialise agent
application = newrelic.agent.ASGIApplicationWrapper(django_asgi_app)

Related

Problem connecting Cloud Run Flask app with Cloud SQL Postgress

I'm very new on GCP and I've tried everything around to achieve this connection, my app connects to any other postgress service but not to Cloud SQL.
I've started to think that is a problem with my code in flask.
So far I have followed this guide:
https://cloud.google.com/sql/docs/postgres/connect-run#public-ip-default
and watched some Youtube Tutorials.
Maybe my problem is in the Cloud Proxy Auth.
MyCode looks like this:
import os
from os.path import join, dirname
from flask import Flask
from flask_cors import CORS
from flask_restful import Api
from flask_jwt_extended import JWTManager
from flask_bcrypt import Bcrypt
from flask_migrate import Migrate
from constants import ACTIVE_SCHEDULER
from db import db
from ma import ma
from resources.routes import initialize_routes, initialize_errors, initialize_cli
from sched import init_scheduler
app = Flask(__name__)
db_user = os.environ.get("DB_USER")
db_pass = os.environ.get("DB_PASS")
db_name = os.environ.get("DB_NAME")
unix_socket_path = os.environ.get("INSTANCE_UNIX_SOCKET")
db_url = 'postgresql+pg8000://{user}:{pw}#/{db}?unix_sock={path}/.s.PGSQL.5432'.format(user=db_user,pw=db_pass,db=db_name, path=unix_socket_path)
app.config["SQLALCHEMY_DATABASE_URI"] = db_url
app.config["SECRET_KEY"] = os.environ.get('JWT_SECRET_KEY', '')
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["PROPAGATE_EXCEPTIONS"] = True
and the error that I always get is:
"error": "(pg8000.exceptions.InterfaceError) Can't create a connection to host 172.17.0.1 and port 5432 (timeout is None and source_address is None). (Background on this error at: https://sqlalche.me/e/14/rvf5)"
I'm out of ideas, I hope anyone knows any guide or solution to my problem, Maybe I'm missing some access to the service account, but I think I follow correctly the instructions I even try to connect Privately with the TCP instructions and is almost the same.

setting up Django app to work on google app engine GAE (app.yaml & main.py)

I have a working Django app that I was able to get functioning on Heroku. The structure is project named 'untitled' and an app named 'web' such that the structure is:
project_root
static
templates
untitled
--->init.py
--->settings.py
--->urls.py
--->wsgi.py
web
--->init.py
--->admin.py
--->apps.py
--->models.py
--->tests.py
--->urls.py
--->views.py
This is a fairly basic app that I can get working outside of GAE (local and on Heroku), however, I'm getting stuck on the app.yaml and main.py requirements for GAE.
My app.yaml is:
application: seismic-interpretation-institute-py27
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: main.app
libraries:
- name: django
version: "latest"
and my main.py (generated from PyCharm) is
import os,sys
import django.core.handlers.wsgi
import django.core.signals
import django.db
import django.dispatch.dispatcher
# Google App Engine imports.
from google.appengine.ext.webapp import util
# Force Django to reload its settings.
from django.conf import settings
settings._target = None
os.environ['DJANGO_SETTINGS_MODULE'] = 'untitled.settings'
# Unregister the rollback event handler.
django.dispatch.dispatcher.disconnect(
django.db._rollback_on_exception,
django.core.signals.got_request_exception)
def main():
# Create a Django application for WSGI.
application = django.core.handlers.wsgi.WSGIHandler()
# Run the WSGI CGI handler with that application.
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
Finally, the output that is reported when running locally is
It seems that the error,
ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.
is causing my problems. I am not exactly sure how to fix it.
try replace
from django.conf import settings
settings._target = None
os.environ['DJANGO_SETTINGS_MODULE'] = 'untitled.settings'
to
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled.settings")
from django.conf import settings
settings._target = None

How to understand tornado response request cycle in Django

I want to create a real time twitter streaming application using tornado and Django. The problem is I am not able to understand the role of Tornado here, and how will I use view.py models.py of Django in Tornado Web Server.
Below if the request response cycle of Django, could anybody explain to me how the tornado web server will play its role here.
Few questions:
1- What will be role of urls.py file in Django since we will be routing all the urls from Tornado itself.
2- How will I connect to models.py to fetch rows for my tornado application.
I am looking into this github project link
Tornado fits roughly in the "web server" and "wsgi" parts of this diagram, and adds another section for Tornado RequestHandlers attached to the web server. When you create your tornado.web.Application, you will send some URLs to Tornado RequestHandlers and some to the Django WSGIContainer (which will in turn use the Django urls.py).
Using Django models from Tornado code is more challenging; my code from the last time I tried doing this is at https://gist.github.com/bdarnell/654157 (but note that this is quite old and I don't know if it will work any more)
This is tornado_main.py stored in one level with manage.py ... I've tested it with Django 1.8 ...
# coding=utf-8
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project_dir.settings")
import django
django.setup()
from django.core.urlresolvers import reverse_lazy
from django.contrib.auth.models import User
from tornado.options import options, define, parse_command_line
import logging
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.websocket
import tornado.wsgi
define('port', type=int, default=8004)
# tornado.options.options['log_file_prefix'].set(
# '/var/www/myapp/logs/tornado_server.log')
tornado.options.parse_command_line()
class SomeHandler(tornado.websocket.WebSocketHandler):
pass
def main():
logger = logging.getLogger(__name__)
tornado_app = tornado.web.Application(
[
(r'/some_url/(?P<user_id>[0-9]+)', SomeHandler),
],
debug=True
)
logger.info("Tornado server starting...")
server = tornado.httpserver.HTTPServer(tornado_app)
server.listen(options.port)
try:
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
tornado.ioloop.IOLoop.instance().stop()
logger.info("Tornado server has stopped")
if __name__ == '__main__':
main()

Flask Application returning ImportError: No module named user_auth.views

I'm in the beginning stages of a Flask application. The problems I'm having is that whenever I attempt to run the application I get:
app/application/___init___.py, line 11 in <module>
from user_auth.views import auth
ImportError: No module named user_auth.views
I have no idea what the problem is. The import for the home.view did this as well, then it stopped and worked fine on the local server. Been trying to figure this out for the longest, there aren't that many moving parts in the application as of yet, so not sure why this is happeninng. File structure and code below:
|app
|-application
|--__ init __.py
|--home
|--user_auth
|----forms.py
|----views.py
|----templates
|----static
My application/__ init __.py file:
from flask import Flask
app = Flask(__name__)
app.config.from_object('_config')
from home.views import home
from user_auth.views import auth
app.register_blueprint(home)
app.register_blueprint(auth)
My application/user_auth/views.py
from flask import Blueprint
auth = Blueprint('auth', __name__,
url_prefix='/user_auth',
template_folder='templates',
static_folder='static')
You're missing an __init__.py file under ./user_auth/ to make user_auth a module.
There's more information about modules in the docs.

How do I get django to execute a remote celery task? Seems to ignore BROKER_URL in settings.py

I've got a django app that's trying to call a celery task that will eventually be executed on some remote hosts. The task codebase is completely separate to the django project, so I'm using celery.execute.send_task and calling it from a post_delete model signal. The code looks a bit like this:
class MyModel(models.Model):
#staticmethod
def do_async_thing(sender, instance, **kwargs):
celery.execute.send_task("tasks.do_my_thing", args=[instance.name])
signals.post_delete.connect(MyModel.do_async_thing, sender=MyModel)
I'm using the latest Django (1.6.1) and celery 3.1.7, so I understand that I don't need any extra module or app in my django project for it to be able to talk to celery. I've set BROKER_URL inside my settings.py to be the right url amqp://user:password#host/vhost.
When this method fires, I get a Connection Refused error. There's no indication on the celery broker that any connection was attempted - I guess it's not seeing the BROKER_URL configuration and is trying to connect to localhost.
How do I make this work? What extra configuration does send_task need to know where the broker is?
So I discovered the answer, and it was to do with not reading the tutorial (http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html) closely enough.
Specifically, I had the correct celery.py in place which I would have thought should have loaded the settings, but I'd missed the necessary changes to __init__.py in the django project, which wasn't hooking everything together.
My celery.py should be:
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
app = Celery('mypoject')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
and the __init__.py should be simply:
from __future__ import absolute_import
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app