FastAPI - Error loading ASGI app. Could not import module "main" - python-3.x

I have this structure in FastAPI.
project_folder/
project_folder/app/
project_folder/app/main.py (with app object of FastAPI)
project_folder/app/rest/panel.py (here I try import app object from main)
In panel.py I import by:
from ..main import app
or
from app.main import app
Its works with other files... like "from app.models import XYZModel".
I run by command:
bash -c "uvicorn main:app --host 0.0.0.0 --port 8000 --reload"
and I try this:
bash -c "uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload"
It works. All paths and imports to multiple files inside different directories work fine. The problem is only when I try to import the app object from main.
I got error like this:
Error loading ASGI app. Could not import module "main".

Notice that there are many confusing things in your solution:
conflicting name between package name and object name : app
what the root source path for your project
I suggest:
rename the directory app into src, and consider it your source root
when you import, try to use abs import: from main import app
run server inside src folder and user uvicorn main:app

Related

paths for deploying flask/wsgi differ from development

I am developing an app and the development setup was really easy.
I run it locally with:
$ . .venv/bin/activate
(.venv) $
(.venv) $ python -m flask run
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:8080
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: -###-###
and I have configured apache2 on my (ubuntu) laptop with:
ProxyPass / http://127.0.0.1:8080
My code is structured like:
app.py
pages/scc_main/scc.html
...
The code has this:
import re
import jinja2
from flask import Flask
from flask import request
import data
app = Flask(__name__)
env = jinja2.Environment(loader=jinja2.FileSystemLoader("pages"))
#app.route('/')
def hello_world():
return '<h2>Hello, World!</h2>'
#app.route('/contracts/scc')
#app.route('/contracts/scc/')
def contracts_main():
main = env.get_template('scc_main/scc.html')
context = data.build('scc_main')
return main.render(**context)
And everything works great. As in:
$ curl 'http://localhost/'
<h2>Hello, World!</h2>$
But when I deploy. Wow. I set my site's root to point to the app. That is actually working. I can hit https://opencalaccess.org/ and it gets my static content.
I have:
import sys
import logging
logging.basicConfig(
level=logging.DEBUG,
filename='/var/www/<full-path>/logs/contracts_scc.log',
format='^(asctime)s %(message)s')
sys.path.insert(0, '/var/www/<full-path>')
sys.path.insert(0, '/var/www/<full-path>/.venv/lib/python3.8/site-packages')
And https://opencalaccess.org/contracts/scc works. But only after I change the Environment call above to:
env = jinja2.Environment(loader=jinja2.FileSystemLoader("/var/www/full-path>/pages"))
Now, any link which is just a link is fine. But anything that looks at the flask.request.path gives me:
The browser (or proxy) sent a request that this server could not understand.
What the heck? Setting up the dev environment was so easy. What do you have to do to get this working in deployment? Any suggestions?
ADDED:
Well, it seems clear that it is the WSGI part that is having the problem. My script is not receiving the request structure and so it cannot read any parameters. I have all my parameters on the URL, so my data building method reads the request.path to see what to do.
So, where to go from here. We will see.
I am no longer able to reproduce this.

Flask error = Error: Could not import "web_app"

This error is something that repeatedly and seemingly randomly occurs and I always have difficulty fixing it. I have read all the other posts on this issue and I still can't fix it.
My directory layout is the following
> /data
> .gitignore
> Pipfile
> Pipfile.lock
> README.md
> run.py
> /web_app
> /models
> /routes
> /templates
> init.py
Here is init.py
from flask import Flask
from web_app.routes.home_routes import home_routes
from web_app.routes.json_routes import json_routes
from web_app.routes.insert_routes import insert_routes
app = Flask(__name__)
app.register_blueprint(home_routes)
app.register_blueprint(json_routes)
app.register_blueprint(insert_routes)
app.run(debug=True)
Here is run.py
from web_app import app
I open /data
I execute: set FLASK_APP=web_app
I execute: run flask
I receive this common error:
Error: Could not import "web_app".
I thought I had perfectly fulfilled the necessary directory design for flask yet it still occurs.
Try renaming
init.py
file in /data/web_app directory to
__init__.py
I think I figured out whats wrong. When I ran flask run in web_app directory, THEN it worked. Though I still don't understand the logic of how flask reads/runs flask directories, so I'm worried it will happen again.
Try renaming init.py to __init__.py and import as
from .web_app import app

Reuse node_module across different react apps

I have setup react using NodeJS according to Link
Since I am learning React, I have to create multiple small projects. I am using create-react-app. This is causing:
Delay in creation of the app (Even when we have node installed while creating a previous app(s).
Allocation of ~200 MB for node_modules folder
Is it possible to reuse the dependencies created for one project, to be used in another?
I have tried copying node_modules from earlier projects to this one but I get following error while executing npm start
> products#0.1.0 start /Users/Deven/playground/React/test
> react-scripts start
internal/modules/cjs/loader.js:783
throw err;
^
Error: Cannot find module '../scripts/start'
in essence the softlinks to files are broken. Also copying node_modules is consuming space so I would like to reuse it.
I am able to get workaround using node_modules in the main app and reusing the same by creating sub-directories for each app in main. In the example I created app called mouseover
Create a main app using create-react-app command.
create-react-app main
It will have node_modules, public and src folders. The public and the src folders are small in size and we can create these for individual apps.
For new app, create a folder for app inside src directory of main.
cd main/src/
mkdir mouseover
Copy Sample public and src to the new folder.
cp -r ../../sample/src ./mouseover/
cp -r ../../sample/public ./mouseover/
Modify App.js to import App from `src/App' from new app folder and return it (index.js of main to consume)
sed -i '' 's/import App1 from .*/import App1 from \".\/mouseover\/src\/App\"/g' App.js
The App.js in main will look like following after importing App from new app and returning it.
import React from "react"
import "./App.css"
import App1 from "./mousehover/src/App"
function App() {
return (
<App1 />
)
}
export default App

Not able to import module server from my testing folder

I am writing a flask app which follows the following folder structure.
backend
server.py
__init__.py
test
__init__.py
servertest.py
"""Server ping test for flask"""
import flask
import pytest
from server import app
#pytest.fixture()
def client():
yield testing.TestClient(app)
def test_ping_resource(client):
doc = "Flask GET service is working"
result = client.simulate_get("/api/ping")
assert result.status_code == 200
assert result.json == doc
And this is my test file. When I am running the file. it gives
from server import app
E ImportError: No module named 'server'
What am I doing wrong, which is making the server module invisible to test module?
When you run a python file, its parent folder is added to the python path, but the parent of its parent (here, your root folder) is not!
What you could do is:
running your tests from the root folder (preferred)
Using relative imports, here: from ..server import app
Modify your python path (not advised)
Python imports modules from a list of path:
import sys
sys.path
You have to provide Python a way to find server.py:
you can run your code from the backend directory, because the current path is automatically happened to sys.path (cd backend; pytest)
you can add the full path to backend to PYTHONPATH
At some point, you will need to read the doc about import.
Also, to use pytest naturally, your test files must start with test.

Flask uWSGI application structure and python3 imports

I have a basic flask-restful application with a structure that looks like this as recommended on the flask website.
/application
/application
/config.py
/__init__.py
/wsgi.ini
Slightly irrelevant, but config.py is generated by our CD server.
wsgi.ini looks likes this
[uwsgi]
module = application:app
master = true
processes =5
socket = /tmp/application.sock
chmod-socket = 660
vacuum = true
die-on-term = true
and __init__.py looks something like this
import config
from flask import Flask, request, g
from flask_restful import Resource, Api, abort
app = Flask(__name__)
api = Api(app)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Now when I try to startup the application using uwsgi --ini wsgi.ini I get this error:
File "./application/__init__.py", line 2, in <module>
import config
Originally __init__.py was called main.py and I executed that to debug, which is why the import is now wrong. I'm guess I will need to change the import to be from .config import *
My question is two fold:
Could I have avoided the import problem completely. ie is there a way in python3 to import sibling modules that will work for both approaches
is my wsgi.ini in the correct place, or should it be in the inner application directory?
Python 3.x dropped support for infra-package relative imports. You need to use an absolute import:
from application import config
or the new spelling of relative imports:
from . import config
If you need to also support legacy versions of Python you can enable this behavior with:
from __future__ import absolute_import

Resources