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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.