0

I'm attempting to break a small app into units and use the Blueprint pattern in Flask. However I seem to have trouble in getting the app running.

Here is my structure:

\myapp
  login.py
  \upload
    __init__.py
    views.py  

Here is login.py:

import sys, os
from flask import Flask, Blueprint, request
from flask import render_template, session
from .upload import views


app = Flask(__name__)
app.register_blueprint(views)

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':  
    print app.url_map
    print app.blueprints
    app.run(debug = True)

for __init__.py

    from flask import Flask
    app.register_blueprint('upload', __name__)

and in views.py

from flask import Flask, Blueprint, request, redirect, url_for, render_template
import views

upload = Blueprint('upload', __name__)

@upload.route('/uploaded', methods=['GET', 'POST'])
def upload_file():
    ...

Looking at the logs on heroku, here is the error:

from .upload import views
2015-09-05T10:59:00.506513+00:00 app[web.1]: ValueError: Attempted relative import in non-package

Have a structured my package and blueprint correctly? I used the documentation, but I think I'm missing something here.

disruptive
  • 5,687
  • 15
  • 71
  • 135

1 Answers1

2

There are three problems with your code:

  • You are using a relative import in login.py to include views, but given the folder structure and the fact that you use login.py as starting point, it cannot work here. Simply use from upload import views instead.
  • The __init__.py references an unknown variable, app. You actually don't need anything in this file, remove everything.
  • You try to register a module as a blueprint via app.register_blueprint(views) in login.py. This cannot work, a module is not a blueprint. Instead, import the upload variable defined in the views module, that is a blueprint: app.register_blueprint(views.upload).

Changing that should get you started. Two side notes:

  • You have an import in views.py that should probably not be there: import views. This should be harmless however.
  • I answered a question about Flask blueprints some days ago, and gave an example about how to use them. Maybe would you find the answer useful in your case as well (in particular the part where the blueprint definition is moved to the __init__.py file defining the blueprint).
Community
  • 1
  • 1
Nicolas
  • 2,151
  • 1
  • 25
  • 29
  • I made those changes, but now I get the problem: if blueprint.name in self.blueprints: AttributeError: 'function' object has no attribute 'name' – disruptive Sep 05 '15 at 14:26
  • It seems the blueprint cannot be same name as module? – disruptive Sep 05 '15 at 14:34
  • 1
    Hmmm, wild guess: don't you have in the `views.py` file (below the section you copied in your question) a function called `upload` that would overwrite the `upload` blueprint defined at the beginning of the file? – Nicolas Sep 05 '15 at 14:36
  • I go round this by making my blueprint a different name to the 'module'. – disruptive Sep 05 '15 at 14:52