I have a Raspberry Pi sitting in a remote location. It is hooked up to a small homemade circuit and a temperature probe. I've set up the Raspberry Pi to do a few things:
- Run
cron
jobs every hour to take a temperature reading and store it locally to a sqlite database - Run an Nginx web server
- Run a uwsgi application server
- Serve a simple Django app
In that Django app, I have a simple view that does the following:
- Hit the DB to get the last 300 temperature recordings
- Put those into a Pandas
DataFrame
- Use Matplotlib to produce a nice SVG graph of the recent temperature history
- Fill out a simple template which displays the SVG and also a small HTML table of the recent temperature readings.
Rendering this view takes ~30 seconds. A very long time. So I wanted to see what was taking so long. My guess is that it's all the work related to generating the graphics. But to find out, I wanted to do some profiling.
I installed django-debug-toolbar
and also django-debug-toolbar-line-profiler
using pip.
I have configured them according to the docs as best I understood. In particular, I've set:
DEBUG = True
TEMPLATE_DEBUG = DEBUG
DEBUG_TOOLBAR_PATCH_SETTINGS = False
MIDDLEWARE_CLASSES = (
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
DEBUG_TOOLBAR_PANELS = (
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
'debug_toolbar_line_profiler.panel.ProfilingPanel',
)
In addition, INTERNAL_IPS
is also set properly.
I have built my view using class-based views. It looks like this:
from django.views.generic import TemplateView
from XXXX.models import TempReading, TempSeries
import numpy as np
import pandas as pd
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import seaborn as sbn
import StringIO
class TestView(TemplateView):
template_name = 'XXXX/test.html'
def get_context_data(self, **kwargs):
upstairs = TempSeries.objects.get(name='Upstairs')
upstairstemps = upstairs.tempreading_set.all().order_by('-timestamp')[:300]
frame = pd.DataFrame(list(upstairstemps.values()))
frame.set_index('timestamp', inplace=True)
# matplotlib.rcParams['svg.fonttype'] = 'none'
fig = Figure()
ax = fig.add_subplot(1,1,1)
frame['value'].plot(ax=ax)
ax.get_xaxis().grid(color='w', linewidth=1)
ax.get_yaxis().grid(color='w', linewidth=1)
fig.set(facecolor='w')
canvas = FigureCanvas(fig)
imgdata = StringIO.StringIO()
canvas.print_svg(imgdata)
imgstr = imgdata.getvalue()
context = super(TestView, self).get_context_data(**kwargs)
context['svgtext'] = imgstr
context['htmltable'] = frame[:5].to_html()
return context
The code I am most interested in profiling is get_context_data
.
When I load the page, the debug-toolbar does in fact show up. And the profiling panel is shown. But all I see is:
{method 'disable' of '_lsprof.Profiler' objects}
Here's a screenshot of the page as it first loads:
And here's how it looks on the profiling page:
It doesn't seem like it's doing any "line-profiling" at all! I was expecting to see timed results for every line within my class-based view. In particular, for each line within the get_context_data
function. What's going on? Any help much appreciated.
Edit on 4/2
Just as a test, I wrote up a dummy view that does not use class-based views. And this seems to work just fine. Here's the new non-class-based-view:
def testview2(request):
df = pd.DataFrame({'a': np.random.randn(10), 'b': np.random.randn(10)})
htmltable = df.to_html()
context = {}
context['htmltable'] = htmltable
return render(request, 'XXXX/test2.html', context)
And that produces the following result in the profiling pane:
So that seems to be working fine. Is there some subtlety I'm missing about how debug-toolbar-line-profiler
works with class-based views? In the docs, it suggests it will profile any method on the class that does not start with an underscore. Is that incorrect?
I have a Raspberry Pi sitting in a remote location. It is hooked up to a small homemade circuit and a temperature probe. I've set up the Raspberry Pi to do a few things:
- Run
cron
jobs every hour to take a temperature reading and store it locally to a sqlite database - Run an Nginx web server
- Run a uwsgi application server
- Serve a simple Django app
In that Django app, I have a simple view that does the following:
- Hit the DB to get the last 300 temperature recordings
- Put those into a Pandas
DataFrame
- Use Matplotlib to produce a nice SVG graph of the recent temperature history
- Fill out a simple template which displays the SVG and also a small HTML table of the recent temperature readings.
Rendering this view takes ~30 seconds. A very long time. So I wanted to see what was taking so long. My guess is that it's all the work related to generating the graphics. But to find out, I wanted to do some profiling.
I installed django-debug-toolbar
and also django-debug-toolbar-line-profiler
using pip.
I have configured them according to the docs as best I understood. In particular, I've set:
DEBUG = True
TEMPLATE_DEBUG = DEBUG
DEBUG_TOOLBAR_PATCH_SETTINGS = False
MIDDLEWARE_CLASSES = (
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
DEBUG_TOOLBAR_PANELS = (
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
'debug_toolbar_line_profiler.panel.ProfilingPanel',
)
In addition, INTERNAL_IPS
is also set properly.
I have built my view using class-based views. It looks like this:
from django.views.generic import TemplateView
from XXXX.models import TempReading, TempSeries
import numpy as np
import pandas as pd
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import seaborn as sbn
import StringIO
class TestView(TemplateView):
template_name = 'XXXX/test.html'
def get_context_data(self, **kwargs):
upstairs = TempSeries.objects.get(name='Upstairs')
upstairstemps = upstairs.tempreading_set.all().order_by('-timestamp')[:300]
frame = pd.DataFrame(list(upstairstemps.values()))
frame.set_index('timestamp', inplace=True)
# matplotlib.rcParams['svg.fonttype'] = 'none'
fig = Figure()
ax = fig.add_subplot(1,1,1)
frame['value'].plot(ax=ax)
ax.get_xaxis().grid(color='w', linewidth=1)
ax.get_yaxis().grid(color='w', linewidth=1)
fig.set(facecolor='w')
canvas = FigureCanvas(fig)
imgdata = StringIO.StringIO()
canvas.print_svg(imgdata)
imgstr = imgdata.getvalue()
context = super(TestView, self).get_context_data(**kwargs)
context['svgtext'] = imgstr
context['htmltable'] = frame[:5].to_html()
return context
The code I am most interested in profiling is get_context_data
.
When I load the page, the debug-toolbar does in fact show up. And the profiling panel is shown. But all I see is:
{method 'disable' of '_lsprof.Profiler' objects}
Here's a screenshot of the page as it first loads:
And here's how it looks on the profiling page:
It doesn't seem like it's doing any "line-profiling" at all! I was expecting to see timed results for every line within my class-based view. In particular, for each line within the get_context_data
function. What's going on? Any help much appreciated.
Edit on 4/2
Just as a test, I wrote up a dummy view that does not use class-based views. And this seems to work just fine. Here's the new non-class-based-view:
def testview2(request):
df = pd.DataFrame({'a': np.random.randn(10), 'b': np.random.randn(10)})
htmltable = df.to_html()
context = {}
context['htmltable'] = htmltable
return render(request, 'XXXX/test2.html', context)
And that produces the following result in the profiling pane:
So that seems to be working fine. Is there some subtlety I'm missing about how debug-toolbar-line-profiler
works with class-based views? In the docs, it suggests it will profile any method on the class that does not start with an underscore. Is that incorrect?
0 commentaires:
Enregistrer un commentaire