Running Flask in Pycharm but can't enter custom commands [duplicate] - flask

I created new flask project in PyCharm but I can't see how to run flask shell in integrated PyCharm python console window.
Name app is not defined when start console:
I still can run command "flask shell" in integrated PyCharm terminal but it will start without code completion, hints, syntax checks, etc.
Flask app is defined in terminal:
Is there any way to start flask shell in integrated PyCharm python console?

You can use a combination of creating a request context for the Shell (which flask shell does) and a custom starting script for the PyCharm console.
# Step 1: acquire a reference to your Flask App instance
import app
app_instance = app.create_app()
# I return app instance from a factory method here, but might be be `app.app` for basic Flask projects
# Step 2: push test request context so that you can do stuff that needs App, like SQLAlchemy
ctx = app_instance.test_request_context()
ctx.push()
Now you should have the benefits of flask shell alongside the code completion and other benefits that IPython Shell provides, all from the default PyCharm Python Shell.

In my case (in my server.py I had app=Flask(__name__)) I used
from server import app
ctx = app.app_context()
ctx.push()
Then added this to File | Settings | Build, Execution, Deployment | Console | Python Console starting script

This also works:
from app import app
ctx = app.test_request_context()
ctx.push()
more on the Flask docs page

Running a Shell
To run an interactive Python shell you can use the shell command:
flask shell
This will start up an interactive Python shell, setup the correct
application context and setup the local variables in the shell. This
is done by invoking the Flask.make_shell_context() method of the
application. By default you have access to your app and g.
It's just a normal interactive Python shell with some local variables already setup for you, not an IDE editor with code completion, hints, syntax checks, etc.

Related

How I can run a telegram bot with the Django project?

Now, to run the bot through Django, I first use the python manage.py runserver command and then follow the link to launch a view with my bot. Can you tell me if there is an easier way to start my bot automatically when starting a Django project?
Actually, you can use a management command to run your bot with something like
python manage.py runbot
All Django context, including DB and settings, will be available
Reference to management command page:
https://simpleisbetterthancomplex.com/tutorial/2018/08/27/how-to-create-custom-django-management-commands.html
Maybe is a little late but you can do the following:
create the bot.py file in the same folder where manage.py is.
inside the bot.py make sure you import the following:
import django
import os
os.environ['DJANGO_SETTINGS_MODULE'] = '{Folder where your settings are}.settings'
django.setup()
and in order to run you just type python bot.py

Flask not displaying debug mode [duplicate]

How are you meant to debug errors in Flask? Print to the console? Flash messages to the page? Or is there a more powerful option available to figure out what's happening when something goes wrong?
Running the app in debug mode will show an interactive traceback and console in the browser when there is an error. As of Flask 2.2, to run in debug mode, pass the --app and --debug options to the flask command.
$ flask --app example --debug run
Prior to Flask 2.2, this was controlled by the FLASK_ENV=development environment variable instead. You can still use FLASK_APP and FLASK_DEBUG=1 instead of the options above.
For Linux, Mac, Linux Subsystem for Windows, Git Bash on Windows, etc.:
$ export FLASK_APP=example
$ export FLASK_DEBUG=1
$ flask run
For Windows CMD, use set instead of export:
set FLASK_DEBUG=1
For PowerShell, use $env:
$env:FLASK_DEBUG = "1"
If you're using the app.run() method instead of the flask run command, pass debug=True to enable debug mode.
Tracebacks are also printed to the terminal running the server, regardless of development mode.
If you're using PyCharm, VS Code, etc., you can take advantage of its debugger to step through the code with breakpoints. The run configuration can point to a script calling app.run(debug=True, use_reloader=False), or point it at the venv/bin/flask script and use it as you would from the command line. You can leave the reloader disabled, but a reload will kill the debugging context and you will have to catch a breakpoint again.
You can also use pdb, pudb, or another terminal debugger by calling set_trace in the view where you want to start debugging.
Be sure not to use too-broad except blocks. Surrounding all your code with a catch-all try... except... will silence the error you want to debug. It's unnecessary in general, since Flask will already handle exceptions by showing the debugger or a 500 error and printing the traceback to the console.
You can use app.run(debug=True) for the Werkzeug Debugger edit as mentioned below, and I should have known.
From the 1.1.x documentation, you can enable debug mode by exporting an environment variable to your shell prompt:
export FLASK_APP=/daemon/api/views.py # path to app
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0
One can also use the Flask Debug Toolbar extension to get more detailed information embedded in rendered pages.
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
import logging
app = Flask(__name__)
app.debug = True
app.secret_key = 'development key'
toolbar = DebugToolbarExtension(app)
#app.route('/')
def index():
logging.warning("See this message in Flask Debug Toolbar!")
return "<html><body></body></html>"
Start the application as follows:
FLASK_APP=main.py FLASK_DEBUG=1 flask run
If you're using Visual Studio Code, replace
app.run(debug=True)
with
app.run()
It appears when turning on the internal debugger disables the VS Code debugger.
If you want to debug your flask app then just go to the folder where flask app is. Don't forget to activate your virtual environment and paste the lines in the console change "mainfilename" to flask main file.
export FLASK_APP="mainfilename.py"
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0
After you enable your debugger for flask app almost every error will be printed on the console or on the browser window.
If you want to figure out what's happening, you can use simple print statements or you can also use console.log() for javascript code.
To activate debug mode in flask you simply type set FLASK_DEBUG=1 on your CMD for windows, or export FLASK_DEBUG=1 on Linux terminal then restart your app and you are good to go!!
Install python-dotenv in your virtual environment.
Create a .flaskenv in your project root. By project root, I mean the folder which has your app.py file
Inside this file write the following:
FLASK_APP=myapp
FLASK_ENV=development
Now issue the following command:
flask run
When running as python app.py instead of the flask command, you can pass debug=True to app.run.
if __name__ == "__main__":
app.run(debug=True)
$ python app.py
with virtual env activate
export FLASK_DEBUG=true
you can configure
export FLASK_APP=app.py # run.py
export FLASK_ENV = "development"
to start
flask run
the result
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: xxx-xxx-xxx
and if you change
export FLASK_DEBUG=false
* Environment: development
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
For Windows users:
Open Powershell and cd into your project directory.
Use these commandos in Powershell, all the other stuff won't work in Powershell.
$env:FLASK_APP = "app"
$env:FLASK_ENV = "development"
If you have PyCharm Professional, you can create a Flask server run configuration and enable the FLASK_DEBUG checkbox. Go to Run > Edit Configurations, select or create a Flask server configuration, and enable the FLASK_DEBUG checkbox. Click OK, then click the run button.
You can install python-dotenv with
pip install python-dotenv then create a .flask_env or a .env file
The contents of the file can be:
FLASK_APP=myapp
FLASK_DEBUG=True
Use loggers and print statements in the Development Environment, you can go for sentry in case of production environments.

How to run a script shell in django

I am developing a web app using django. I've a script shell that runs python codes for image processing. I want to execute this script shell using my web app so that users can apply image processing just by using a button in the web interface.
(for the moment i'm working localy , the django web app and the script shell are in the same folder).
I don't know how to do it. can you help me ?
thank you in advance.
Python standard library has the subprocess module which can be used just for that. For instance, given ./script.sh is your shell script a call to subprocess.call will do the work:
>>> import subprocess
>>> # From your working directory:
>>> subprocess.call(["./script.sh"])

Can manage.py runserver execute npm scripts?

I am developing a web application with React for frontend and Django for backend. I use Webpack to watch for changes and bundle code for React apps.
The problem is that I have to run two commands concurrently, one for React and the other one for Django:
webpack --config webpack.config.js --watch
./manage.py runserver
Is there any way to customize runserver command to execute the npm script, like npm run start:dev? When you use Node.js as a backend platform, you can do the similar job like npm run build:client && npm run start:server.
If you are already using webpack and django, probably you can be interested in using webpack-bundle-tracker and django-webpack-loader.
Basically webpack-bundle-tracker will create an stats.json file each time the bundle is build, and django-webpack-loader will watch for those stats.json file to relaunch the dev server. This stack allows to separate the concerns between the server and the client.
There are a couple of posts out there explaining this pipeline.
I'm two and a half years late, but here's a management command that implements the solution that OP wanted, rather than a redirection to another solution. It inherits from the staticfiles runserver and runs webpack concurrently in a thread.
Create this management command at <some_app>/management/commands/my_runserver.py:
import os
import subprocess
import threading
from django.contrib.staticfiles.management.commands.runserver import (
Command as StaticFilesRunserverCommand,
)
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
class Command(StaticFilesRunserverCommand):
"""This command removes the need for two terminal windows when running runserver."""
help = (
"Starts a lightweight Web server for development and also serves static files. "
"Also runs a webpack build worker in another thread."
)
def add_arguments(self, parser):
super().add_arguments(parser)
parser.add_argument(
"--webpack-command",
dest="wp_command",
default="webpack --config webpack.config.js --watch",
help="This webpack build command will be run in another thread (should probably have --watch).",
)
parser.add_argument(
"--webpack-quiet",
action="store_true",
dest="wp_quiet",
default=False,
help="Suppress the output of the webpack build command.",
)
def run(self, **options):
"""Run the server with webpack in the background."""
if os.environ.get(DJANGO_AUTORELOAD_ENV) != "true":
self.stdout.write("Starting webpack build thread.")
quiet = options["wp_quiet"]
command = options["wp_command"]
kwargs = {"shell": True}
if quiet:
# if --quiet, suppress webpack command's output:
kwargs.update({"stdin": subprocess.PIPE, "stdout": subprocess.PIPE})
wp_thread = threading.Thread(
target=subprocess.run, args=(command,), kwargs=kwargs
)
wp_thread.start()
super(Command, self).run(**options)
For anyone else trying to write a command that inherits from runserver, note that you need to check for the DJANGO_AUTORELOAD_ENV variable to make sure you don't create a new thread every time django notices a .py file change. Webpack should be doing it's own auto-reloading anyway.
Use the --webpack-command argument to change the webpack command that runs (for example, I use --webpack-command 'vue-cli-service build --watch'
Use --webpack-quiet to disable the command's output, as it can get messy.
If you really want to override the default runserver, rename the file to runserver.py and make sure the app it lives in comes before django.contrib.static in your settings module's INSTALLED_APPS.
You shouldn't mess with the built-in management commands but you can make your own: https://docs.djangoproject.com/en/1.10/howto/custom-management-commands/.
On your place I'd leave runserver in place and create one to run your custom (npm in this case) script, i.e. with os.execvp.
In theory you could run two parallel subprocesses one that would execute for example django.core.management.execute_from_command_line and second to run your script. But it would make using tools like pbd impossible (which makes work very hard).
The way I do it is that I leverage Docker and Docker compose. Then when I use docker-compose up -d my database service, npm scripts, redis, etc run in the background (running runserver separately but that's another topic).

Shell script to update DB via flask

I got started with flask and I tried out the Flaskr example. On the execution of a certain python script, I would like to update one row of my database.
I am a newbie here and would like to understand: am I going to update the DB from inside that python script or I am going to wait for a signal from the flask WSGI script:
I have referred to this thread but am not sure how I am going to interact with the external script. Any help or hints are appreciated.
WSGI handles HTTP requests/responses. A script won't be issuing those. Instead, import your Flask app in the script and make an application context:
from my_project import my_app
ctx = my_app.app_context()
ctx.push()
# ... my code
db.session.commit()
ctx.pop()
Relevant docs: http://flask.pocoo.org/docs/appcontext/, http://flask.pocoo.org/docs/shell/
Or consider using Flask-Script to add command line functions to your application, if the function doesn't need to be a separate script.