How to run Flask app as a package in PyCharm - python

I was following this documentation on directory management for Flask projects. Now, I'm trying to run my flask application from PyCharm. I have added the below mentioned Environment Variables in Edit Configurations...:
FLASK_DEBUG=true
FLASK_APP=<absolute-path-to-root-directory-of-application>
I add the Script as flask run
The output running this configuration is this:
../red-flask/venv/bin/python "flask run"
../red-flask/venv/bin/python: can't open file 'flask run': [Errno 2] No such file or directory
Process finished with exit code 2
My project directory looks like:
/flask_app
setup.py
/flask_app
__init__.py
views.py
/static
style.css
/templates
layout.html
index.html
login.html
...
I am unable to figure out how to make this work, any help is appreciated.

This is documented in the development build of the docs.
You need to point to the location of the flask command.
Script: /path/to/env/bin/flask
Script parameters: run
Until 1.0 comes out, you need to point FLASK_APP at __init__.py if you don't install your package in your env.
Environment variables: FLASK_APP /path/to/flask_app/__init__.py
Preferably, install the package in the env and point to it using the import name.
From the terminal, in the virtualenv: pip install -e .
Environment variables: FLASK_APP flask_app

Related

When building a Docker container of a webapp, how to import functions from different folders to where the main file (app.py) is located?

My repo has the following structure (simplified):
project
+--x
| +--y
| +--z
| +--app.py
+--util
| +--database.py
In app.py, we import a function from database.py:
from util.database import create_database_connection
I want to deploy app.py as a webapp using Docker, and created a Dockerfile to do so:
FROM felipederodrigues/python37withpyodbc:v1
# Copy required folders and set working directory.
COPY . .
WORKDIR /x/y/z
# Install required packages.
RUN pip install --upgrade pip && pip install gunicorn eventlet==0.30.2
RUN pip install --no-cache-dir -r requirements.txt
# Set Python path.
ENV PYTHONPATH "${PYTHONPATH}:/home/site/wwwroot/"
# Expose port 8050.
EXPOSE 8050
# Start Flask app.
CMD gunicorn -b :8050 -k eventlet -w 1 app:server
Building the image and pushing it to the container registry works as expected, however, the webapp itself does not work because of the following error:
ModuleNotFoundError: No module named 'util'
Obviously, the app is unable to reach the util folder. Strangely enough, when I move app.py to folder x, and changed the WORKDIR in the Dockerfile to /x, the webapp does actually work.
So my question is, how can I make this work using the /x/y/z folder structure instead of only /x?

FLASK_APP variable don't work even it's in .env

I have installed python-dotenv==0.6.5
And I put FLASK_APP in .env file
DEBUG=True
FLASK_ENV=development
FLASK_APP=flasky.py
But it shows this error when I run flask run
Usage: flask run [OPTIONS]
Error: Could not locate Flask application. You did not provide the FLASK_APP environment variable.
For more information see http://flask.pocoo.org/docs/latest/quickstart/
But if I export FLASK_APP=flasky.py , it works well.
I also tried to put FLASK_APP=flasky.py in .flaskenv file, but I didn't work :(
All other env variables are loaded well. Thanks
The problem was FLASK version.
I updated it using pip install --upgrade Flask
Thanks!

"No module named x" for user-defined modules in Python deployment using Dockerfile and docker-compose

I'm trying to deploy a Python app as a Docker container using Dockerfile and docker-compose.
The project structure is this:
ms-request
- src
__init__.py
- exceptions
__init__.py
ms_request_exceptions.py
- messaging
__init__.py
receive_rabbit.py
send_rabbit.py
- request
__init__.py
bsrequest.py
- test
__init__.py
test_bsrequest.py
Dockerfile
requirements.txt
In my receive_rabbit.py script, I am importing functions from the request and messaging packages like so:
from src.request import bsrequest
from src.messaging.send_rabbit import send_message
Executing this using PyCharm works fine. Running it from the command line initially didn't work, until I updated the PYTHONPATH using export PYTHONPATH=${PYTHONPATH}:..
I would like to deploy this as a Docker container, so I created a Dockerfile and an entry in my docker-compose.yml for the project.
Dockerfile:
FROM python:3
WORKDIR /bsreq
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src/ ./src
COPY test/ ./test
RUN export PYTHONPATH=${PYTHONPATH}:.
CMD [ "python", "/bsreq/src/messaging/receive_rabbit.py" ]
docker-compose.yml:
version: "3.3"
services:
rabbitmq: [...]
bs-request:
build: ./ms-request/
depends_on:
- rabbitmq
env_file:
- rabbit.env
[...]
Running this using docker-compose up bs-request always ends in a crash with the error No module named 'src'.
I have tried multiple variations of inputs for the WORKDIR, COPY, PYTHONPATH and CMD lines in the Dockerfile. All lead to the same error. I've tried relative imports, which throw Attempted relative import with no known parent package.
I hope this is an issue others have encountered before. What do I need to do to get this deployment working?
docker layers-way building an image makes your export unusable right after the associated RUN command.
FROM python:3
WORKDIR /bsreq
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src/ ./src
COPY test/ ./test
RUN export PYTHONPATH=${PYTHONPATH}:. #--> exporting
CMD [ "python", "/bsreq/src/messaging/receive_rabbit.py" ] #--> last export is not persistent
as a workaround you set environment variables that will persist through the build AND in the final image with ENV PYTHONPATH=${PYTHONPATH}:. command.
extra read: https://vsupalov.com/docker-build-time-env-values/
any how, suggested method is to write a setup.py file and install your package with python setup.py install so it would be installed as a package and imports would work.
P.S
a better, more updated way would be to use tools such as poetry that uses pyproject.toml (according to PEP 518, 517) which the future way of python!
bonus read: https://python-poetry.org/
good luck!

python3: can't find '__main__' module in 'app.py'

I'm trying to create a Docker container to be able to create a GUI with Flask for the utilisation of a tensorflow model.
The thing is that I would like to be able to modify my python files in real time and not have to rebuild my container everytime.
So for now I've created 3 files :
requirement.txt
Flask
tensorflow
keras
Dockerfile
# Use an official Python runtime as a parent image
FROM python:3.5.6-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python3", "app.py"]
app.py
from flask import Flask
import os
import socket
app = Flask(__name__)
#app.route("/")
def test():
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
So after all this I build my container with this command
docker build -t modelgui .
End then I use this command to run my container and make a link between the app file I want to modify on the host and the one in the container
docker run -p 4000:80 -v /home/Documents/modelGUI:/app modelgui
But I get this error and I really don't know why
/usr/local/bin/python3: can't find '__main__' module in 'app.py'
My problem might be dumb to resolve but I'm really stuck here.
Check that /home/Documents/modelGUI in your bind volume mount is the path to where your code files reside and that app.py in that path is not created as a directory rather than a python file with the code you intend to run.
If app.py in /home/Documents/modelGUI is a dir, then the cause of this problem is that are not calling your script app.py at all, you are just giving the Python interpreter a nonexistent script name, which in case a similarly named directory (case-insensitive actually) exists it tries to execute it.
I've tried to replicate:
$ ls -lFs
Dockerfile
app.py/
requirements.txt
Then called the Python interpreter with app.py:
$ python3 app.py
/usr/local/bin/python3: can't find '__main__' module in 'app.py'
Running this locally, it looks like mounting your volume is overwriting your directory:
No volume
docker run -it test_image bash
root#c3870b9845c3:/app# ls
Dockerfile app.py requirements.txt
root#c3870b9845c3:/app# python app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
With volume
docker run -it -v ~/Barings_VSTS/modelGUI:/app test_image bash
root#f6349f899079:/app# ls
somefile.txt
root#f6349f899079:/app#
That could be part of the issue. If you want to mount a filesystem in, I would mount it into a different directory. The default volume behavior is such that whatever you copied into app will be overwritten by the contents of modelGUI

How to run a django project without manage.py

Basically I downloaded django project from SCM, Usually I run the project with with these steps
git clone repository
extract
change directory to project folder
python manage.py runserver
But this project does not contains manage.py , how to run this project in my local machine???
br
You'll have to create a manage.py file manually if you wanted to use its commands in the same way you're accustomed to. You can modify django's manage.py template to include your project's settings.
#!/usr/bin/env python
import os
import sys
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
Most likely, this is not supposed to be a complete project, but a plugin application. You should create your own project in the normal way with django-admin.py startproject and add the downloaded app to INSTALLED_APPS.
You can use uwsgi to run a django project.
First install uwsgi using:
pip install uWSGI
Go to project folder and enter this in terminal:
# Replace server with whatever is your project name
uwsgi --http :8000 --module Server.wsgi
First create a virtual environment and install Django. Now you have django-admin.py available in your system.
django-admin is Django’s command-line utility for administrative tasks.
$ django-admin startproject name [directory] create a Django app directory structure for the given app name in the current directory or the given destination.
You can provide the path to a directory with a custom app template file or a path to a compressed file (.tar.gz, .tar.bz2, .tgz, .tbz, .zip) containing the app template files.
$ django-admin startproject --template=/Users/jezdez/Code/my_app_template myapp
Django will also accept URLs (http, https, ftp) to compressed archives with the app template files, downloading and extracting them on the fly.
For example, taking advantage of GitHub’s feature (or other SCM) to expose repositories as zip files, you can use a URL like:
$ django-admin startproject --template=https://github.com/githubuser/django-app-template/archive/master.zip myapp
$ cd my_proj
$ touch manage.py
Put this content into manage.py like #Sayse said:
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
# CHANGED manage.py will use development settings by
# default. Change the DJANGO_SETTINGS_MODULE environment variable
# for using the environment specific settings file.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings.development")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
Install dependencies and run migrations.
$ pip install -r requirements.txt
$ python manage.py migrate
$ python manage.py runserver
Hope I help!

Categories