Skip to content

profiling

django_spire.profiling

lock = threading.Lock() module-attribute

__all__ = ['ProfilingMiddleware', 'ProfilingPanel', 'lock'] module-attribute

ProfilingMiddleware

Bases: MiddlewareMixin

Source code in django_spire/profiling/middleware/profiling.py
def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]) -> None:
    super().__init__(get_response)

    configuration = {
        'PROFILING_DIR': os.getenv('PROFILING_DIR', '.profile'),
        'PROFILING_ENABLED': os.getenv('PROFILING_ENABLED', 'False') == 'True',
        'PROFILING_MAX_FILES': int(os.getenv('PROFILING_MAX_FILES', '10')),
        'PROFILE_THRESHOLD': float(os.getenv('PROFILE_THRESHOLD', '0')),
    }

    directory = configuration.get('PROFILING_DIR', '.profile')

    if isinstance(directory, str):
        if not Path(directory).is_absolute():
            current = Path.cwd()
            base = getattr(settings, 'BASE_DIR', current)
            directory = Path(base) / directory
        else:
            directory = Path(directory)

    self.directory = Path(directory)
    self.directory.mkdir(exist_ok=True)

    self.enabled = configuration.get('PROFILING_ENABLED', False)
    self.threshold = configuration.get('PROFILE_THRESHOLD', 0)
    self.maximum = configuration.get('PROFILING_MAX_FILES', 10)

    self.count = 0
    self.lock = threading.Lock()

directory = Path(directory) instance-attribute

enabled = configuration.get('PROFILING_ENABLED', False) instance-attribute

threshold = configuration.get('PROFILE_THRESHOLD', 0) instance-attribute

maximum = configuration.get('PROFILING_MAX_FILES', 10) instance-attribute

count = 0 instance-attribute

lock = threading.Lock() instance-attribute

process_view

Source code in django_spire/profiling/middleware/profiling.py
def process_view(
    self,
    request: HttpRequest,
    view_func: Callable[..., Any],
    args: tuple[Any, ...],
    kwargs: dict[str, Any]
) -> Any:
    if not settings.DEBUG:
        return None

    if not self.enabled:
        return None

    if self._should_skip(request):
        return None

    with self.lock:
        self.count = self.count + 1
        request._profiling_id = self.count

    profiler = Profiler(interval=0.001)
    start = time.time()
    profiler.start()

    try:
        response = view_func(request, *args, **kwargs)

        if hasattr(response, 'render'):
            response.render()
    except Exception:
        profiler.stop()
        duration = (time.time() - start) * 1000
        self._save_profile(profiler, request, duration)

        raise
    else:
        profiler.stop()
        duration = (time.time() - start) * 1000

        if duration >= self.threshold:
            self._save_profile(profiler, request, duration)

        return response

ProfilingPanel

Bases: Panel

Source code in django_spire/profiling/panel.py
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

    self.directory = self._get_directory()

nav_title = 'Profiles' class-attribute instance-attribute

template = 'panel.html' class-attribute instance-attribute

title = 'Profiling' class-attribute instance-attribute

directory = self._get_directory() instance-attribute

nav_subtitle property

delete_file classmethod

Source code in django_spire/profiling/panel.py
@classmethod
def delete_file(cls, request: HttpRequest, filename: str) -> JsonResponse:
    panel = cls(None, None)
    error = panel._validate_filename(filename)

    if error:
        return JsonResponse({'error': error}, status=400)

    location = panel._resolve_location()
    filepath = location / filename

    with lock:
        if not filepath.exists():
            return JsonResponse({'success': True, 'is_deleted': True})

        error = panel._validate_filepath(filepath, location)

        if error:
            return JsonResponse({'error': error}, status=400)

        result = panel._try_delete(filepath)

        if result:
            return result

    return JsonResponse({'error': 'Could not delete file'}, status=500)

generate_stats

Source code in django_spire/profiling/panel.py
def generate_stats(self, request: HttpRequest, response: HttpResponse) -> None:
    profiles = self._get_files()
    profiling = os.getenv('PROFILING_ENABLED', 'False') == 'True'

    stats = ProfileStats(
        profiles=[asdict(profile) for profile in profiles],
        count=len(profiles),
        directory=str(self.directory),
        total_size=self._format_size(self._get_size()),
        enabled=profiling
    )

    self.record_stats(asdict(stats))

get_urls classmethod

Source code in django_spire/profiling/panel.py
@classmethod
def get_urls(cls) -> list:
    return [
        re_path(
            r'^profiling/view/(?P<filename>[^/]+)/$',
            cls.serve_file,
            name='profiling_view'
        ),
        re_path(
            r'^profiling/delete/(?P<filename>[^/]+)/$',
            csrf_exempt(cls.delete_file),
            name='profiling_delete'
        ),
        re_path(
            r'^profiling/list/$',
            cls.list_files,
            name='profiling_list'
        ),
    ]

list_files classmethod

Source code in django_spire/profiling/panel.py
@classmethod
def list_files(cls, request: HttpRequest) -> JsonResponse:
    panel = cls(None, None)
    panel.directory = panel._resolve_location()
    profiles = panel._get_files()

    response = ProfileList(
        profiles=[asdict(profile) for profile in profiles],
        count=len(profiles),
        total_size=panel._format_size(panel._get_size())
    )

    return JsonResponse(asdict(response))

serve_file classmethod

Source code in django_spire/profiling/panel.py
@classmethod
def serve_file(cls, request: HttpRequest, filename: str) -> HttpResponse:
    panel = cls(None, None)
    error = panel._validate_filename(filename)

    if error:
        raise Http404(error)

    location = panel._resolve_location()
    filepath = location / filename

    with lock:
        if not filepath.exists():
            message = 'Profile has been removed'
            raise Http404(message)

        error = panel._validate_filepath(filepath, location)

        if error:
            raise Http404(error)

        with open(filepath, 'r', encoding='utf-8') as handle:
            content = handle.read()

    return HttpResponse(content, content_type='text/html')