Heroku python console app module ImportError - python

I've encountered an issue while trying to access PostgreSQL from heroku python console (first attempt).
First up, I launch python using $ heroku run python
Then I try to load up the db module with >>> from app import db, this action returns:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named app
I have one web dyno running python which has app = Flask(__name__), apart from that, I don't know what other details should I provide in order to shed more light into the issue.

After experimenting with the terminal, it became clear, that there really is no way for it to know what variables do I have in my main.py, so what I did then was load the main parts of the app through the terminal like so:
>>> import os
>>> from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
>>> from flask.ext.sqlalchemy import SQLAlchemy
>>> # create the application
>>> app = Flask(__name__)
>>> app.config.from_object(__name__)
>>> app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'some-url.com')
>>> db = SQLAlchemy(app)
And from then on I was able to access the db object as intended.
EDIT - the issue completely resolved below.
So the reason I was having an error while trying to import my apps code into the python shell was two fold:
The *.py that was the target of my import was not at the root directory, I was telling the shell to look in the wrong place.
Since the *.py I was importing was not named app.py (and I was asking to from app import db), I was also telling the shell to look for the wrong file.
The way to solve this issue was to append the path of my *.py file to the sys.path and instead of from app import db, us from my_filename_without_the_extenssion import db. For a summary, the shell received these instructions:
>>> import sys
>>> sys.path.append('path/to/my/file')
>>> from my_filename_without_the_extenssion import db
>>> # to test if everythings ok
>>> db

Related

Trying to reuse code across multiple Flask servers, stuck on importing with errors "ModuleNotFoundError" or "ImportError"

My goal is to import code into three separate Flask servers. It's not going well. I am on python 3.10.4. I have read perhaps 10 different posts that say things like "put a __init__.py file in your folders" which I have done.
For context I'm not exactly new to Python but I've never learned the importing/module system properly.
I have three Flask servers that run scraping operations on different (but similar) websites. I need them to be separate for various reasons. Anyway, all three need to run the same procedure of getting an IP for a proxy from my proxy provider. For this I have some code:
# we don't need the details here so I snip it to save space
def get_proxy_ip(choice):
r = requests.get(download_list, headers={"Authorization": "Token " + token})
selected_proxy_ip = r.json()["results"][choice]["proxy_address"]
selected_proxy_port = r.json()["results"][choice]["port"]
print(selected_proxy_ip)
return selected_proxy_ip, selected_proxy_port
I want to use this function across all 3 of my Flask servers. Here are some various ways I've tried to import the code into one of the Flask servers:
scrapers/rentCanada/app.py
import requests
from flask import Flask, request, make_response
print("cats")
app = Flask(__name__)
print(__name__, __package__)
# from ..shared.ipgetter import get_proxy_ip
# from ..shared.checker import check_public_ip
# from scrapers.shared.ipgetter import get_proxy_ip
# from scrapers.shared.checker import check_public_ip
import shared.ipgetter as ipgetter
import shared.checker as checker
None of them work.
import shared.ipgetter as ipgetter yields:
cats
__main__ None
Traceback (most recent call last):
File "/home/rlm/Code/canadaAps/scrapers/rentCanada/app.py", line 10, in <module>
import shared.ipgetter as ipgetter
ModuleNotFoundError: No module named 'shared'
ModuleNotFoundError: No module named 'scrapers' yields: ModuleNotFoundError: No module named 'scrapers'
from ..shared.ipgetter import get_proxy_ip yields: ImportError: attempted relative import with no known parent package
At this point you need to see my folder structure.
/scrapers
..__init__.py
..setup.py
../rentCanada
.....__init__.py
.....app.py
../rentFaster
.....__init__.py
.....app.py
../rentSeeker
.....__init__.py
.....app.py
../shared
.....__init__.py
.....ipgetter.py
.....checker.py
I need to be able to use any of the app.py files as entry points.
I also tried setup.py with this:
from setuptools import setup, find_packages
setup(
name = 'tools',
packages = find_packages(),
)
followed by python setup.py install but that didn't make a "tools" import available in app.py like I wanted.
As a final note I suspect someone will tell me to use a blueprint. To me those look like a tool I'd use if I was adding a route. I'm not sure they're right for a simple function, but maybe I'm wrong.
My solution for now is to run Flask with python rentCanada/app.py from the /scrapers folder and use this code
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).parent.parent)) # necessary so util folder is available
import requests
from flask import Flask, request, make_response
print("cats")
app = Flask(__name__)
print(__name__, __package__)
from util.ipgetter import get_proxy_ip
from util.checker import check_public_ip
So the program appends the app.py file folder's parent folder to the path. That makes the util folder (which used to be shared but had a naming conflict) available within the app.py file.

Attempting to import methods into cucumber test results in "No module named 'blueprints' " error - Cucumber Test, Python, Behave

I know this question is a duplicate but I seriously need some help on it. I have searched everywhere for a solution and none of the ones I found helped solved the issue. I would REALLY appreciate some input.
I am working on a project with the following tree structure:
Project
- Source
- Web
- test
- features
testing.features
- steps
testing.py
- app
- __init__.py
- blueprints
communication_bp.py
I am working on a cucumber test code using the behave module and the folder I am working on is the test folder, which include features and steps.
What I am trying to do is to import some methods found in communication_bp.py from the app folder into the cucumber test file "testing.py" in python.
So Line 3 is what I am trying to achieve.
testing.py:
from behave_restful import *
import requests
from blueprints.communication_bp import client_comm
but I keep getting this error.
File "../steps/testing.py", line 3, in <module>
from blueprints.communication_bp import client_comm
ModuleNotFoundError: No module named 'blueprints'
Based on what I have read, the app folder is supposed to have __init__.py, which it does.
I will include what both this file and communication_bp.py file here as well.
init.py
from flask import Flask
from flask_cors import CORS
from flask_jwt_extended import JWTManager
from flask_socketio import SocketIO
# Create the Flask application
rest = Flask(__name__)
...
...
from app.blueprints.communication_bp import communication_bp
...
...
rest.register_blueprint(communication_bp, url_prefix = Config.API_PREFIX)
...
...
communication_bp.py
import sys
import json
from flask import Blueprint, request
...
...
So what exactly does this program wants? What am I missing here?

Flask: 'NoneType' object has no attribute 'drivername' when querying a table from Python terminal

EDIT: I added the following lines to config.py:
print(type(SECRET_KEY), SECRET_KEY)
print(type(SQLALCHEMY_DATABASE_URI), SQLALCHEMY_DATABASE_URI)
print(SQLALCHEMY_DATABASE_URI == "sqlite:///site.db")
And then when I start the flask app with python run.py, I get the output
<class 'str'> secret
<class 'str'> sqlite:///site.db
True
Now in the python terminal when I run the following command
>>> from main import create_app, db
I'm getting output
<class 'NoneType'> None
<class 'NoneType'> None
False
So it seems like the values are not getting loaded from the .env file. Am I missing any imports? Because if hardcode the value of the SQLALCHEMY_DATABASE_URI to sqlite:///site.db the output becomes:
<class 'NoneType'> None
<class 'str'> sqlite:///site.db
True
I'm working on a Flask application and I restructured it using Blueprints. After this change when I try to interact with tables in my database the following error gets thrown:
'NoneType' object has no attribute 'drivername'
I'm loading any secret values or database URI's from a .env file using the dotenv package. In fact, in the front end the application is working because when I make changes they are saved and being rendered on the page. However, I want to work with tables through the table to create dummy data quickly, but for some reason I'm not.
__ init __.py
This file is part of the main package called main
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from main.config import Config
db = SQLAlchemy()
bcrypt = Bcrypt()
login = LoginManager()
login.login_view = 'users.login'
def create_app(config_class=Config):
# Create app and setup config
app = Flask(__name__)
app.config.from_object(Config)
# Link extensions to the app
db.init_app(app)
bcrypt.init_app(app)
login.init_app(app)
# Add route imports
from main.users.routes import users
from main.decks.routes import decks
from main.cards.routes import cards
from main.errors.handlers import errors
# Register blueprints
app.register_blueprint(users)
app.register_blueprint(decks)
app.register_blueprint(cards)
app.register_blueprint(errors)
return app
config.py
from dotenv import load_dotenv
import os
load_dotenv()
class Config():
SECRET_KEY = os.getenv('SECRET_KEY')
SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI')
.env
SECRET_KEY="secret"
SQLALCHEMY_DATABASE_URI="sqlite:///site.db"
This is how I'm trying to interact with tables from the python terminal
>> from main import db, create_app
>> from main.models import Card
>> app = create_app()
>> with app.app_context():
Card.query.first()
AttributeError: 'NoneType' object has no attribute 'drivername'
This is quite a generic error, because all it means is that somewhere along the line you have an object with type NoneType, and None has no attributes as far as I know, so it will raise an AttributeError. Looking at the question context, I think the most likely error is referring to a database query that is returning None.
So look for a point in your code when you do something like this:
x = Card.query.get(65) # let's say there are only 52 cards, so this is None
return x.drivername
This will cause an AttributeError and has clearly crashed your code. So it will be in any file that is imported by the create_app, and any files they import themselves (if this is quite a lot, think about where you use database queries the most).
Yeah all I had to do in the python terminal was the load the .env file using the load_dotenv() and find_dotenv() functions. In essence, before you call create_app you need to load your environment variables in, which I wasn't entering as a command in my Python terminal, but was automatically getting ran in my script.

How to get config params in another module in flask python?

In my main.py have the below code:
app.config.from_object('config.DevelopmentConfig')
In another module I used import main and then used main.app.config['KEY'] to get a parameter, but Python interpreter says that it couldn't load the module in main.py because of the import part. How can I access config parameters in another module in Flask?
Your structure is not really clear but by what I can get, import your configuration object and just pass it to app.config.from_object():
from flask import Flask
from <path_to_config_module>.config import DevelopmentConfig
app = Flask('Project')
app.config.from_object(DevelopmentConfig)
if __name__ == "__main__":
application.run(host="0.0.0.0")
if your your config module is in the same directory where your application module is, you can just use :
from .config import DevelopmentConfig
The solution was to put app initialization in another file (e.g: myapp_init_file.py) in the root:
from flask import Flask
app = Flask(__name__)
# Change this on production environment to: config.ProductionConfig
app.config.from_object('config.DevelopmentConfig')
Now to access config parameters I just need to import this module in different files:
from myapp_init_file import app
Now I have access to my config parameters as below:
app.config['url']
The problem was that I had an import loop an could not run my python app. With this solution everything works like a charm. ;-)

"ImportError: cannot import name mail" in Flask

I have built is a simple web app with Flask and Python, which I intend to upload to Heroku.
When starting my app locally, with the following script:
#!venv/bin/python
from app import app
app.run(debug = True)
I get this error message:
Traceback (most recent call last):
File "./run.py", line 2, in <module>
from app import app, mail
File "/home/ricardo/personalSite/app/__init__.py", line 3, in <module>
from app import index
File "/home/ricardo/personalSite/app/index.py", line 6, in <module>
from emails import send_email
File "/home/ricardo/personalSite/app/emails.py", line 2, in <module>
from app import app, mail
ImportError: cannot import name mail
So, it cannot import mail.
Inside the app directory I have this __init__.py, here is were I create the Mail object that is ginving me trouble to import:
from flask import Flask
app = Flask(__name__)
from app import index
from flask.ext.mail import Mail
mail = Mail(app)
And this is the file emails.py where I call the send_mail function:
from flask.ext.mail import Message
from app import app, mail
from flask import render_template
from config import ADMINS
from decorators import async
So, according to the error message, the error is in this file, in the from app import app, mail.
What is the problem? Why can't it import mail?
Update:
This is my directory listing:
persSite\
venv\
<virtual environment files>
app\
static\
templates\
__init__.py
index.py
emails.py
decorators.oy
tmp\
run.py
You have a circular dependency. You have to realize what Python is doing when it imports a file.
Whenever Python imports a file, Python looks to see if the file has already started being imported before. Thus, if module A imports module B which imports module A, then Python will do the following:
Start running module A.
When module A tries to import module B, temporarily stop running module A, and start running module B.
When module B then tries to import module A, then Python will NOT continue running module A to completion; instead, module B will only be able to import from module A the attributes that were already defined there before module B started running.
Here is app/__init__.py, which is the first file to be imported.
from flask import Flask
app = Flask(__name__)
from app import index # <-- See note below.
from flask.ext.mail import Mail
mail = Mail(app)
When this file is imported, it is just Python running the script. Any global attribute created becomes part of the attributes of the module. So, by the time you hit the third line, the attributes 'Flask' and 'app' have been defined. However, when you hit the third line, Python begins trying to import index from app. So, it starts running the app/index.py file.
This, of course, looks like the following:
from flask.ext.mail import Message
from app import app, mail # <-- Error here
from flask import render_template
from config import ADMINS
from decorators import async
Remember, when this Python file is being imported, you have thus far only defined Flask and app in the app module. Therefore, trying to import mail will not work.
So, you need to rearrange your code so that if app.index relies on an attribute in app, that app defines that attribute before attempting to import app.index.
This is probably the problem:
from app import app, mail
In the file 'app/emails.py' the import is from the current module, not a nested app module. Try:
from . import app, mail
If it doesn't work, you should update your question with a more detailed directory listing.

Categories

Resources