Why I see no Django log in git-bash? - django

I am using Python 3's print to log from Django dev server. I should mention that I also tried to configure Django to use the Python logger but without much luck. I am using pipenv run but the same happens when I activate the virtual env using pipenv shell.
I have a very simple view:
from django.shortcuts import render
def index(request):
print('Printing to the console from myapp.views.index')
return render(request, 'myapp/index.html', {
'message': 'Hello, World!'
})
While everything works perfectly fine in cmd.exe, git-bash does not display any output from my custom logging. See image below.
Why is that? Does it have to deal with the fact that one console is considered a terminal (tty) and the other is not?

Related

Internal Error when using PyInstaller to make an standalone app using Flask + FlaskWebGui

Ok so I've been trying to make a standalone python app using Flask and FlaskWebGUI, it works just fine when I'm running it on VScode, print of an example program below:
Working just fine, ok. But when I use the PyInstaller command pyinstaller server.py to create the desktop app for some reason this following error occurs:
that's my server.py code:
from flask import Flask, render_template, request, redirect, url_for
#importa o Web GUI
from flaskwebgui import FlaskUI
app = Flask(__name__)
app.static_folder = 'static'
ui = FlaskUI(app, width=1150, height=700)
# A decorator used to tell the application
# which URL is associated function
#app.route('/', methods =["GET", "POST"])
def gfg():
if request.method == "POST":
# getting input with name = fname in HTML form
first_name = request.form.get("fname")
# getting input with name = lname in HTML form
last_name = request.form.get("lname")
return "Your name is "+first_name + last_name
return render_template("index.html")
# runs app
if __name__ == "__main__":
# app.run(debug=True)
# Default start flask
FlaskUI(
app=app,
server="flask",
width=1150,
height=700,
).run()
I have no idea why it isn't working.
In case it's useful, here's the PyInstaller log after running the command: https://pastebin.com/6dC6fTBs
==========
I also have tried using the following PyInstaller commands:
pyinstaller --name myapp --onefile server.py -> still not working
pyinstaller --name myapp --onefile --add-data "templates;." server.py -> also not working
It was a dependent files issue, PyInstaller you need to specify the dependency files to PyInstaller and I just wasn't managing to do it.
I then instead of typing the PyInstaller command by myself, i used it's GUI (by running "auto-py-to-exe" on a terminal in the script folder) then i used the GUI to select the dependency files (I did not had to select libraries manually, just files like .html, .png) and it worked just fine.
There's also a lot of other configs you can set using the GUI, but that's all i needed to make the program run properly.

Webhook from Django 4.1 to python-telegram-bot 20.0a2

I use the python-telegram-bot 20.0a2 library and Django 4.1
The bot runs by main.py script:
if __name__ == "__main__":
asyncio.run(main())
Inside of the main script I also run uvicorn in the same ascynhronous context as Application instance
# Run application and webserver together
async with application_tg:
await application_tg.start()
await server.serve() # uvicorn
await application_tg.stop()
What is the problem?
I use webhook for my bot
Django's url.py calls async view but the view can't get initalized Application instance of the bot.
so the question is:
How can to rearrange a scheme of interaction between python-telegram-bot 20 and Django 4.1 in a way that I can access Application instance from a Django hook?
Addition:
It's easy to achieve by using other frameworks such as starlette as it mentioned on the official wiki page of PTB library: https://docs.python-telegram-bot.org/en/v20.0a2/examples.customwebhookbot.html
My main script:
https://gist.github.com/SergSm/6843fadf505b826f83a10bf7eebc3fa0
my view:
import json
from django.views import View
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from telegram import Update
from bot.tgbot.main import application_tg
async def telegram_handle(request):
if request.method == 'POST':
await application_tg.update_queue.put(
Update.de_json(data=json.loads(request.body), bot=application_tg.bot)
)
return JsonResponse({"ok": "POST processed"})
else:
return JsonResponse({"ok": "GET processed"})
UPDATE 1
I was desperate to make it run this way.
I tried to use contextvars module and read a lot of asyncio related stuff/
In the end I made an awful assumption that if I put my python-telegram-bot code into the Django view async function it's gonna work. But it does work!
And now I will try to wrap it using middleware to make my code cleaner
UPDATE 2
If you want to use Django orm with sync functions you need to use #sync_to_async(thread_sensitive=False)
the thread_sensitive=False parameter is important in this case otherwise you will never get the result of awaitables

Django Selenium LiveServerTestCase not loading the page in browser (error 500)

I have a test Django project called MyApp, running over WSGI on port 8083. When I go to http://myapp:8083, I see the standard Django "it's working" page. I wrote a functional test using selenium bindings in Django to launch a browser and load the above mentioned page. When I run the test, though, I get an error message "Address already in use". So I run the test using another port like this: python manage.py test --liveserver=myapp:8084
This opens the browser, but shows "Page not found" error instead of the default Django page. What am I doing wrong? Any ideas? Thank you!
The test.py file content:
class CoreSeleniumTestCase(LiveServerTestCase):
#classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.driver.maximize_window()
super(CoreSeleniumTestCase, cls).setUpClass()
#classmethod
def tearDownClass(cls):
cls.driver.quit()
super(CoreSeleniumTestCase, cls).tearDownClass()
def testIndexShouldLoad(self):
self.driver.get('%s%s' % (self.live_server_url, '/'))
I finally found the problem. At some point, Django removed MEDIA_ROOT from the settings.py file by default. It turns out that this setting must be in the file for Selenium tests to work properly. Once I reintroduced the setting and assigned a directory to it, the Selenium tests started to work as expected.

How do you set DEBUG to True when running a Django test?

I'm currently running some Django tests and it looks that DEBUG=False by default. Is there a way to run a specific test where I can set DEBUG=True at the command line or in code?
For a specific test inside a test case, you can use the override_settings decorator:
from django.test.utils import override_settings
from django.conf import settings
class TestSomething(TestCase):
#override_settings(DEBUG=True)
def test_debug(self):
assert settings.DEBUG
Starting with Django 1.11 you can use --debug-mode to set the DEBUG setting to True prior to running tests.
The accepted answer didn't work for me. I use Selenium for testing, and setting #override_settings(DEBUG=True) makes the test browser always display 404 error on every page. And DEBUG=False does not show exception tracebacks. So I found a workaround.
The idea is to emulate DEBUG=True behaviour, using custom 500 handler and built-in django 500 error handler.
Add this to myapp.views:
import sys
from django import http
from django.views.debug import ExceptionReporter
def show_server_error(request):
"""
500 error handler to show Django default 500 template
with nice error information and traceback.
Useful in testing, if you can't set DEBUG=True.
Templates: `500.html`
Context: sys.exc_info() results
"""
exc_type, exc_value, exc_traceback = sys.exc_info()
error = ExceptionReporter(request, exc_type, exc_value, exc_traceback)
return http.HttpResponseServerError(error.get_traceback_html())
urls.py:
from django.conf import settings
if settings.TESTING_MODE:
# enable this handler only for testing,
# so that if DEBUG=False and we're not testing,
# the default handler is used
handler500 = 'myapp.views.show_server_error'
settings.py:
# detect testing mode
import sys
TESTING_MODE = 'test' in sys.argv
Now if any of your Selenium tests encounters 500 error, you'll see a nice error page with traceback and everything. If you run a normal non-testing environment, default 500 handler is used.
Inspired by:
Where in django is the default 500 traceback rendered so that I can use it to create my own logs?
django - how to detect test environment
Okay let's say you want to write tests for error testcase for which the urls are :-
urls.py
if settings.DEBUG:
urlpatterns += [
url(r'^404/$', page_not_found_view),
url(r'^500/$', my_custom_error_view),
url(r'^400/$', bad_request_view),
url(r'^403/$', permission_denied_view),
]
test_urls.py:-
from django.conf import settings
class ErroCodeUrl(TestCase):
def setUp(self):
settings.DEBUG = True
def test_400_error(self):
response = self.client.get('/400/')
self.assertEqual(response.status_code, 500)
Hope you got some idea!
Nothing worked for me except https://stackoverflow.com/a/1118271/5750078
Use Python 3.7
breakpoint()
method.
Works fine on pycharm
You can't see the results of DEBUG=True when running a unit test. The pages don't display anywhere. No browser.
Changing DEBUG has no effect, since the web pages (with the debugging output) are not visible anywhere.
If you want to see a debugging web page related to a failing unit test, then do this.
Drop your development database.
Rerun syncdb to build an empty development database.
Run the various loaddata scripts to rebuild the fixtures for that test in your development database.
Run the server and browse the page.
Now you can see the debug output.

django: debugging code in the view layer

I am developing my first django website.
I have written code in my view layer (the handlers that return an HttpResponse object to the view template (hope I am using the correct terminology).
In any case, I want to put print statements in my views.py file, so that I can debug it. However, it looks like stdout has been redirect to another stream, so I am not seeing anything printed out on my console (or even the browser).
What is the recommended way (best practice) for debugging django view layer scripts?
there are more advanced ways of doing it, but i find dropping
import pdb
pdb.set_trace()
does the job.
Use the Python logging module. Then use the Django debug toolbar, which will catch and display all the things you send to the log.
I'd upvote dysmsyd, but I don't have the reputation.
pdb is good because it lets you step thru your procedure and follow the control flow.
If you are using the django runserver, you can print to stdout or stderr.
If you are using the mod_wsgi, you can print to stderr.
The pprint module is also useful:
import sys
from pprint import pprint
def myview(request):
pprint (request, sys.stderr)
Try django-sentry. Especially if your project is in production stage.
Configure django debug toolbar: pip install django-debug-toolbar and follow the instructions to configure it in: https://github.com/django-debug-toolbar/django-debug-toolbar
import logging
Use the logging to debug: logging.debug('My DEBUG message')
Here is how it works on my class view:
from django.views.generic import TemplateView
import logging
class ProfileView(TemplateView):
template_name = 'profile.html'
def get(self, request, *args, **kwargs):
logging.debug(kwargs)
return render(request, self.template_name)