ImportError: No module named views - python

Im writing a web app in flask that displays bus stops pulled from an api.
i have a form on index.html where a user can input a stop number, that number gets picked up in views.py where the function also runs a task through celery to fetch the api data:
from flask import render_template, request
from app import app
#app.route('/')
def index():
return render_template('index.html')
#app.route('/stopno', methods=['POST'])
def stopno():
stopid = request.form['input']
from app.tasks import apidata
apidata.delay()
return render_template('action.html')
here is my tasks.py:
from celery import Celery
import json
import requests
import time
ac = Celery('tasks', broker='amqp://localhost')
#ac.task(name='tasks.apidata')
def apidata():
from views import stopno
api = '*apiurl*:' + str(stopid)
saveinfo = 'static/stop' + str(stopid)+ '.json'
r = requests.get(api)
jsondata = json.loads(r.text)
with open(saveinfo, 'w') as f:
json.dump(jsondata, f)
I am importing stopno from views into tasks so i can search the api for the specified stop, currently when a user inputs a stop number the action.html loads fine and displays the stop number the user inputs but no new file or data is created for the stop number and celery throws an error saying
ImportError: No module named views
structure of my project is
|____run.py
|____app
| |______init__.py
| |____views.py
| |____tasks.py
| |____static
| | |____json
| |____templates
| | |____action.html
| | |____index.html

You are trying to do a relative import but you are not making it explicitly relative, which may or may not work, and which can cause unexpected errors. You should make your import explicitly relative with:
from .views import stopno
This way you don't have to worry about reproducing the entire path to the module.

from app.views import stopno
??

The import doesn't work for you because you are trying an implicit relative import.
This was supported in python 2 but not supported in python 3.
Try this one : from .views import stopno, this is an explicit relative import which is supported in python 3
If that doesn't work
Try importing all from views like this : from .views import *
Always remember, in python 3, import * is supported only on module level, not inside functions like this:
#ac.task(name='tasks.apidata')
def apidata():
from .views import *
So if you are using : from .views import *, make sure you put it like this:
from celery import Celery
import json
import requests
import time
from .views import *
ac = Celery('tasks', broker='amqp://localhost')
#ac.task(name='tasks.apidata')
def apidata():
api = '*apiurl*:' + str(stopid)
saveinfo = 'static/stop' + str(stopid)+ '.json'
r = requests.get(api)
jsondata = json.loads(r.text)
with open(saveinfo, 'w') as f:
json.dump(jsondata, f)

Related

How to run a specific function upon module selection in flask API?

I'm building a python visualization application. I'm using 2 modules for this:
LUX
Pandas Profiling
The above 2 are auto visualization libraries that take in a csv/xlsx file & give descriptive statistics of the data which includes visualizations.
LUX has a customizable function called 'Intent' which analyzes the relationship among specific variables upon selection.
The visualizations get stored in a HTML file on my local system.
What I have tried:
This is my Python code for the visualization:
# Importing libraries
import csv
from mimetypes import init
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import os
import csv
import json
from pandas_profiling import ProfileReport
import pandas_profiling as pp
import lux
# # Pandas profiling
def pand_prof_fun(eda_file, savepath):
profile = ProfileReport(eda_file)
# Activating the widgets
profile.to_widgets()
profile.to_notebook_iframe()
# Saving & generating the report
pp.ProfileReport(eda_file)
profile.to_file(savepath)
profile = ProfileReport(eda_file, title="My Data Profile Report")
return profile
def lux_vis(eda_file, vis_file_path, vis_file_path_intent, intent_list):
eda_file.save_as_html(vis_file_path)
# Visualizing selected variables
eda_file.intent = intent_list
eda_file.save_as_html(vis_file_path_intent)
def run(csv_filepath, int_list):
csv_dataframe = pd.read_csv(csv_filepath)
os.makedirs(r'templates', exist_ok=True)
pand_prof_path = r'templates\pandas_prof.html'
lux_save_path = r'templates\lux_complete.html'
lux_intent_save_path = r'templates\lux_intent.html'
pand_prof_fun(csv_dataframe, pand_prof_path)
lux_vis(csv_dataframe, lux_save_path, lux_intent_save_path, int_list)
if __name__ == '__main__':
csv_filepath = r'C:\Users\projects\Churn_bank.csv'
I now want to build a Flask API such that the user can choose what they want to display, i.e., -->
Lux - displays the pairwise relationship between all variables. (or)
Lux using intent (Customization)- displays the relationship between specified variables. (or)
Pandas Profiling - displays the descriptive statistics of the entire data.
This is my API code for the 2nd module (Lux using intent):
from flask import Flask, render_template
import requests
from flask import Flask, request, jsonify
import json
import traceback
from visualization_function import run
from visualization_function import lux_vis
from visualization_function import pand_prof_fun
app = Flask(__name__)
#app.route('/visualization_with_us', methods = ['POST'])
def home1():
allowed_extensions = ['csv', 'xlsx']
file = request.json.get('filepath')
filename=file.split("/")[-1]
intents = request.json.get('intents')
file_extension = filename.split('.', 1)[1].lower()
try:
if file_extension in allowed_extensions:
run(file, intents)
return "Successful"
else:
return "File not supported"
except:
return "Exception in file"
if __name__ == '__main__':
app.run()
Entering input via 'Postman'
Entering the 'intents' via postman returns "successful" message & gives the right output. The HTML file gets created & saved in my "templates" folder. But when I try to include the other two modules in my API code - 'Module 1' & 'Module 3', my code doesn't work.
Here's how I've included 'Module 1' & 'Module 3' in my API code. My idea is to create a list of the modules & depending on the module chosen, the respective module/function runs -->
from flask import Flask
from flask import Flask, request
from importlib.util import module_from_spec
from flask import Flask, render_template
import requests
from flask import Flask, request, jsonify
import json
import traceback
from visualization_function import run
from visualization_function import lux_vis
from visualization_function import pand_prof_fun
app = Flask(__name__)
#app.route('/visualization_with_apoorva', methods = ['POST'])
def home1():
allowed_extensions = ['csv', 'xlsx']
available_modules=['pandas_profiling', 'lux_overall', 'lux_intent']
file = request.json.get('filepath')
filename=file.split("/")[-1]
file_extension = filename.split('.', 1)[1].lower()
intents = request.json.get('intents')
module_selection= request.json.get('module')
try:
if file_extension in allowed_extensions:
return lux_vis()
if module_selection=='lux_intent':
intents = request.json.get('intents')
run(file, intents)
if module_selection=='lux_overall':
run(file, lux_vis)
if module_selection=='pandas_profiling':
run(file, pand_prof_fun)
return "Successful"
else:
return "File not supported"
except:
return "Exception in file"
if __name__ == '__main__':
app.run()
Error: When I run the route on postman it returns "Exception in file" message.
Postman output
What is the error in my code? How do I include 'module 1' & 'module 3' in the same Flask API code such that the user can choose any one among the 3 modules & get the desired output?

How do I connect modules in python?

Starting to do some more advanced processes in flask and I'm having a hard time figuring out how to import my error handling file. Code snipets from init and errors. What's wrong?
I cant get the errors module to load. I've tried doing from errors import *, I get an import error, tried moving it out of the factory still get errors. Tried from errors import *, tried import errors. All fail to some degree. Seems to me I'm missing something simple as a comma or something.
here's some code
first file - init
from flask import Flask, render_template
def create_app():
# Instantiate App
app = Flask(__name__)
with app.app_context():
# Import Blueprints
from .foodtracker.routes import foodtracker
from .fitness.routes import fitness
from .bio.routes import bio
from .home.routes import home
# Import models, and error handler
from . import errors
# Register Blue Prints
app.register_blueprint(foodtracker)
app.register_blueprint(fitness)
app.register_blueprint(bio)
app.register_blueprint(home)
return app
and errors.py
from flask import render_template
from . import app
#app.errorhandler(404)
def pagenotfound(error):
return render_template('/errors/404.html'), 404
directory structure
/fitlife
/fitlife
/bio
/home
/fitness
/foodtracker
__init__.py
errors.py
models.py
You have circular imports. Meaning, the app file tries to import the errors file and the errors file tries to import the app file.
The correct way to handle this would be to 'dumb down' the errors.py file, meaning making it only contain the errors themselves without using the decorator to register them. Then, the errors.py file will not need to import app.
The registration can be done using app.register_error_handler from the higher-level file, instead.

Flask Testing in Python -- Building one API in a repo with many to unit test it via import_module

We have an ETL data API repo. We do all etl processing inside of it, then spit the data out in API's. These API's are run one at a time from a single command passing the resource class through to the server to build an API. the resource class is in a web directory in an __init__.py.
This is a wonderful convention and quite simple to use, but the problem I am having is coming from trying to get one of the 3 API's available spun up for testing. Our directory stucture is like this (calling the project 'tomato')
tomato
- category_api
- web
- etl
- test
- here is where we are writing some tests (test_category_api.py)
- data
- article_api
- web
- etl
- test
- data
- recommendation_api
- web
- etl
- test
- data
- common
- common shit
Inside this test, I have the following test class. On the seventh line up from the bottom,
you will see a comment on where it breaks. It is the import_module method.
import unittest
import sys
import os
import sys
import json
from importlib import import_module
from flask import Flask
from flask_restful import Api, abort, wraps
from flask_restful.utils import cors
from flask.ext.testing import TestCase
#dir_above_top_level = os.path.join(os.path.abspath(__file__), '../../.. /')
#sys.path.append(os.path.abspath(dir_above_top_level))
_CATEGORY_ENDPOINT = '/v1/category/'
_PACKAGE_NAME = os.environ['RECO_API_PACKAGE_NAME']
_CORS = cors.crossdomain(origin='*',
headers=['Origin', 'X-Requested-With',
'Content-Type', 'Accept'],
methods=['GET', 'HEAD', 'OPTIONS'],
max_age=3600)
class CategoryTests(TestCase):
def __init__(self):
self.app = Flask(__name__)
self._configure_app()
for resource in self.resource_classes:
self.api.add_resource(self.resource,
self.resource.URI_TEMPLATE)
def test_status_code(self):
self.response = self.client.post(_CATEGORY_ENDPOINT,
data=json.dumps(
{'title': 'Enjoy this delicious food'}),
headers=json.dumps(
{'content-type':'application/json'}))
self.assertEqual(self.response.status_code, 200)
def test_version(self):
self.response = self.client.post(_CATEGORY_ENDPOINT,
data=json.dumps(
{"title": "eat some delicious stuff"}),
headers=json.dumps(
{'content-type':'application/json'}))
self.assertEqual(json.dumps(self.response['version']), '1')
def _configure_app(self):
self.app = Flask(__name__)
self.app.config['TESTING'] = True
self.app.debug = True
self.decorators = [_CORS]
self.app.Threaded = True
self.web_package = 'tomato.category.web'
self.package = import_module('.__init__', self.web_package) # WE BREAK HERE
self.resources = package.RESOURCE_NAMES
self.resource_classes = [ getattr(package, resource) for resource in resources ]
self.api = Api(self.app, catch_all_404s=True, decorators=self.decorators)
if __name__ == '__main__':
unittest.main()
we are given an exception when running these tests:
ImportError: No module named tomato.category.web.__init__
yet cd into the main top dir, and ls tomato/category/web gets us __init__.py and its right there with the resource class.
How do I import this class so that I can instantiate the API to run the tests in this class?
Or if I'm completely on the wrong track what should I be doing instead?
You don't need to import __init__, just like you probably wouldn't do from tomato.category.web import __init__. You should be able to import the web package directly.
self.web_package = 'tomato.category.web'
self.package = import_module(self.web_package)
The problem here lies in the directory structure. In the current path, I am not at the top level. It is a module. So What was needed was to uncomment the line two lines at the top, and change the structure to append the path like this.
dir_above_top_level = os.path.join(os.path.abspath(__file__), '../../../..')
sys.path.append(os.path.abspath(dir_above_top_level))
and now, I can import it using
self.web_package = 'tomato.category.web'
self.package = import_module('.__init__', self.web_package)
and now it will import fine and I can grab the resource class to set up the testing API

Python 2.7.3 Flask ImportError: No module named

I have a Flask application with this error:
ImportError: No module named annotaria, referer: http://ltw1413.web.cs.unibo.it/
So, my root in web server is:
/home/web/ltw1413/html
Inside html folder I have:
One folder named "annotaria
One file .wsgi named "wsgi.wsgi"
My file .wsgi is:
import sys
sys.path.insert(0, '/home/web/ltw1413/html')
from annotaria import app as application
Inside my folder "annotaria" I have:
"Static" folder : inside stylesheet and js
"Templates" folder : inside html
"run.py" : file python where I have my application
run.py is this:
from pydoc import html
from annotaria import app
from flask import Flask, render_template, redirect, request
import json
import urllib2
import urlparse
import re
import string
import os
from SPARQLWrapper import SPARQLWrapper, JSON
from rdflib import Graph, BNode, Literal, Namespace
from time import strftime
import urllib2
import BeautifulSoup
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/index.html')
def reloader():
return render_template('index.html')
# other app.route()...
if __name__ == '__main__':
app.run(debug=True)
How can I find a solution? Where is my error?
Lots of errors here...
annotaria is not found on path (that is why it says... well.. exactly that).
In your code you also redefine app: you import it from annotaria and then redefine it in app = Flask(...
Others mentioned individual errors, but it would be helpful to understand the big picture. First of all, let's assume the following structure:
/home/web/ltw1413/html
- wsgi.wsgi
- annotaria/
- __init.py__
- run.py
- static/
- templates
Like Klaus mentioned, you need __init__.py to tell Python that annotaria is a valid package. But then your wsgi.wsgi file needs to import the app from the run module:
from annotaria.run import app as application
You also need to remove this unnecessary import from run.py, since you instantiate a new application:
from annotaria import app
Because there is no application to import, you instantiate a new Flask application.
Finally, make sure that the app runs manually before you start deploying it.

Pyramid Auth error with Persona / Browserid

I want to make pyramid auth in my app with persona or browser id, the problem is that using both of us i see an error.
The console drops me this when i use persona:
Import error: No module named pyramid_persona
and when I use browser ID drops me no modul named browserid
This is my code:
MY VIEW FILE
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.security import authenticated_userid
#from waitress import serve
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.exceptions import Forbidden
def hello_world(request):
userid = authenticated_userid(request)
if userid is None:
raise Forbidden()
return Response('Hello %s!' % (userid,))
MY INIT FILE
from pyramid.config import Configurator
from resources import Root
import views
import pyramid_jinja2
import os
here = os.path.dirname(os.path.abspath(__file__))
settings={
'persona.secret': 'some secret',
'persona.audiences': 'http://localhost:8080'
}
settings['mako.directories'] = os.path.join(here, 'templates')
__here__ = os.path.dirname(os.path.abspath(__file__))
def make_app():
""" This function returns a Pyramid WSGI application.
"""
settings = {}
settings['mako.directories'] = os.path.join(__here__, 'templates')
config = Configurator(root_factory=Root, settings=settings)
config.include('pyramid_persona')////////////////////////THE ERROR AND TROUBLEMAKER
config.add_renderer('.jinja2', pyramid_jinja2.Jinja2Renderer)
config.add_view(views.my_view,
context=Root,
renderer='zodiac1.mako')
#config.add_route( "home", "/home")
#config.add_view(views.home_view, route_name="home", renderer="zodiac1.mako" )
config.add_static_view(name='static',
path=os.path.join(__here__, 'static'))
# config.add_route('zodiac', '/zodiac')
# config.add_view(views.home_view, route_name='zodiac', #renderer='main.mako')
#config.add_route('zodiac1', '/zodiac1')
#config.add_view(views.home_view, route_name='zodiac1', renderer='zodiac1.mako')
config.add_route('zodiac2', '/zodiac2')
config.add_view(views.zodiac2_view, route_name='zodiac2', renderer='zodiac2.mako')
config.add_route('zodiac3', '/zodiac3')
config.add_view(views.guestbook, route_name='zodiac3', renderer='zodiac3.mako')
config.add_route('hello', '/hello')
config.add_view(views.guestbook, route_name='zodiac3', renderer='zodiac3.mako')
return config.make_wsgi_app()
application = make_app()
Please tell me what I am doing wrong, I'm sure that it didn't like how to I import config.include('pyramid_persona')
Thanks
From this error:
Import error: No module named pyramid_persona
You can tell Python cannot find the pyramid_persona module. Perhaps because its not installed. You should install it with pip install pyramid_persona.
You will also need to install pyramid_whoauth to get BrowserID support.
This can get a bit complicated stitching all the parts together, so I recommend having a read of this great writeup by Ryan Kelly (who works at Mozilla) that shows how everything plugs together.

Categories

Resources