{ "info": { "author": "Frederico V Lima", "author_email": "frederico.vieira@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Testing" ], "description": "[![PyPI latest](https://img.shields.io/pypi/v/drf-viewset-profiler.svg)](https://pypi.python.org/pypi/drf-viewset-profiler)\n[![Build Status](https://travis-ci.org/fvlima/drf-viewset-profiler.svg?branch=master)](https://travis-ci.org/fvlima/drf-viewset-profiler)\n\n# drf-viewset-profiler\n\nDecorator to profile all methods from a viewset (and its serializer) line by line. For all methods that were called during a request, an output\nwill be generated showing the number of hits, time (in seconds), lines and the content of each line of a method that was executed\n\n## Installation\n\n`pip install drf-viewset-profiler`\n\nNote: due to a problem with `line_profiler` installation, it's necessary to follow these instructions [1] to install, or just do `pip install Cython` and force to install this lib again\n\n1 - https://github.com/rkern/line_profiler#installation\n\n## Usage\n\nDecorate the viewset that will be profiled\n\n```python\nfrom drf_viewset_profiler import line_profiler_viewset\n\n@line_profiler_viewset\nclass SomeViewSet(ViewSet):\n queryset = Model.objects.all()\n```\n\nSet the middleware config in settings.py\n\n```python\nMIDDLEWARE = [\n ...\n \"drf_viewset_profiler.middleware.LineProfilerViewSetMiddleware\"\n]\n```\n\nMake requests in this viewset to profile and measure the time in seconds wasted\n\n## Configuration\n\n```python\nDRF_VIEWSET_PROFILER = {\n \"DEFAULT_OUTPUT_GENERATION_TYPE\": \"drf_viewset_profiler.output.FileOutput\",\n \"DEFAULT_OUTPUT_LOCATION\": \"\",\n \"ENABLE_SERIALIZER_PROFILER\": True\n}\n```\n\n#### DEFAULT_OUTPUT_GENERATION_TYPE\n- drf_viewset_profiler.output.FileOutput: generates the output in a txt file with the name of the profiled viewset\n- drf_viewset_profiler.output.StdOutput: generates the output in the console (default)\n\nIt's possible to customize by extending the BaseOuput class\n\n#### DEFAULT_OUTPUT_LOCATION\n- the location to generate the output file with the name of the view that will profiled (default is empty)\n\n#### ENABLE_SERIALIZER_PROFILER\n- profile the methods from the serializer vinculated with the viewset (default is True)\n\n#### Output example\n\n```\nTotal time: 1.7e-05 s\nFile: /.pyenv/versions/3.7.4/envs/drf-viewset-profiler/lib/python3.7/site-packages/django/views/generic/base.py\nFunction: _allowed_methods at line 113\n\nLine # Hits Time Per Hit % Time Line Contents\n==============================================================\n113 def _allowed_methods(self):\n114 1 17.0 17.0 100.0 return [m.upper() for m in self.http_method_names if hasattr(self, m)]\n\nTotal time: 0.000158 s\nFile: /.pyenv/versions/3.7.4/envs/drf-viewset-profiler/lib/python3.7/site-packages/rest_framework/generics.py\nFunction: get_serializer at line 103\n\nLine # Hits Time Per Hit % Time Line Contents\n==============================================================\n103 def get_serializer(self, *args, **kwargs):\n104 \"\"\"\n105 Return the serializer instance that should be used for validating and\n106 deserializing input, and for serializing output.\n107 \"\"\"\n108 1 15.0 15.0 9.5 serializer_class = self.get_serializer_class()\n109 1 12.0 12.0 7.6 kwargs['context'] = self.get_serializer_context()\n110 1 131.0 131.0 82.9 return serializer_class(*args, **kwargs)\n\nTotal time: 4e-06 s\nFile: /.pyenv/versions/3.7.4/envs/drf-viewset-profiler/lib/python3.7/site-packages/rest_framework/generics.py\nFunction: get_serializer_class at line 112\n\nLine # Hits Time Per Hit % Time Line Contents\n==============================================================\n112 def get_serializer_class(self):\n113 \"\"\"\n114 Return the class to use for the serializer.\n115 Defaults to using `self.serializer_class`.\n116 \n117 You may want to override this if you need to provide different\n118 serializations depending on the incoming request.\n119 \n120 (Eg. admins get full serialization, others get basic serialization)\n121 \"\"\"\n122 1 3.0 3.0 75.0 assert self.serializer_class is not None, (\n123 \"'%s' should either include a `serializer_class` attribute, \"\n124 \"or override the `get_serializer_class()` method.\"\n125 % self.__class__.__name__\n126 )\n127 \n128 1 1.0 1.0 25.0 return self.serializer_class \n\n...\n\nTotal time: 1.5491 s\nFile: /drf-viewset-profiler/test-drf-project/testapp/views.py\nFunction: create at line 52\n\nLine # Hits Time Per Hit % Time Line Contents\n==============================================================\n 52 def create(self, request):\n 53 1 4.0 4.0 0.0 import time\n 54 1 1505235.0 1505235.0 97.2 time.sleep(1.5)\n 55 1 43866.0 43866.0 2.8 return super().create(request) \n``` \n\n## Contribute\n\n- Clone this repository\n- Install poetry (pip install poetry)\n- run `poetry install`\n- run `pre-commit install`\n- Create your branch, make changes and open the pull request\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/fvlima/drf-viewset-profiler", "keywords": "django rest framework,drf,drf viewset,viewset line profiler,profiler", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "drf-viewset-profiler", "package_url": "https://pypi.org/project/drf-viewset-profiler/", "platform": "", "project_url": "https://pypi.org/project/drf-viewset-profiler/", "project_urls": { "Homepage": "https://github.com/fvlima/drf-viewset-profiler", "Repository": "https://github.com/fvlima/drf-viewset-profiler" }, "release_url": "https://pypi.org/project/drf-viewset-profiler/0.2.0/", "requires_dist": [ "Cython (>=0.29,<0.30)", "line_profiler (>=2.1,<3.0)" ], "requires_python": ">=3.6,<4.0", "summary": "Lib to profile all methods from a viewset line by line", "version": "0.2.0" }, "last_serial": 5980932, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "1da4f81e86efe237f37467e2c931bf1e", "sha256": "0e18c521e44962340b76c8c55db85e7b6262e5525061b28f4edd6751508a7b1f" }, "downloads": -1, "filename": "drf_viewset_profiler-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "1da4f81e86efe237f37467e2c931bf1e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 7290, "upload_time": "2019-10-14T23:45:03", "url": "https://files.pythonhosted.org/packages/8e/8a/0e70f2d8d11fb3128baca9a0db15a5ed7c4389ed01f21a97f33f38c40e93/drf_viewset_profiler-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4b50dfde5954c23f2cd845d6ed42cc4e", "sha256": "b25778ccc7d100eb41f5d067ec00d4d210fc9492a293a2158c813058f31fc09e" }, "downloads": -1, "filename": "drf-viewset-profiler-0.1.0.tar.gz", "has_sig": false, "md5_digest": "4b50dfde5954c23f2cd845d6ed42cc4e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 5215, "upload_time": "2019-10-14T23:45:00", "url": "https://files.pythonhosted.org/packages/7f/19/9383c4b52878bd3563a6fca2809d2e8078731c5e90e9629ff44b8b428e39/drf-viewset-profiler-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "39c3807ab7939d0ac9c5f8ccbb66d390", "sha256": "816e430944721780845f8dbb6a92a938c9dc08f84a909d79a5f6844333ac4720" }, "downloads": -1, "filename": "drf_viewset_profiler-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "39c3807ab7939d0ac9c5f8ccbb66d390", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 11576, "upload_time": "2019-10-16T02:58:18", "url": "https://files.pythonhosted.org/packages/3c/6e/ddb57c3321443437b34e1d6e910b4c07935794eb441f5892ee99b55b8ce6/drf_viewset_profiler-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ae0c8eeba39506b4d79f8f72f113316b", "sha256": "d9c6b178d67325cf2604eb5b6217ce2a3241c261fc438ce4c5baace460ce01aa" }, "downloads": -1, "filename": "drf-viewset-profiler-0.2.0.tar.gz", "has_sig": false, "md5_digest": "ae0c8eeba39506b4d79f8f72f113316b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 6329, "upload_time": "2019-10-16T02:58:16", "url": "https://files.pythonhosted.org/packages/7e/1d/6a9441c7140c1b2c439351f37d10653c8759932d7f43d3d673b2dfa4f63a/drf-viewset-profiler-0.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "39c3807ab7939d0ac9c5f8ccbb66d390", "sha256": "816e430944721780845f8dbb6a92a938c9dc08f84a909d79a5f6844333ac4720" }, "downloads": -1, "filename": "drf_viewset_profiler-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "39c3807ab7939d0ac9c5f8ccbb66d390", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 11576, "upload_time": "2019-10-16T02:58:18", "url": "https://files.pythonhosted.org/packages/3c/6e/ddb57c3321443437b34e1d6e910b4c07935794eb441f5892ee99b55b8ce6/drf_viewset_profiler-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ae0c8eeba39506b4d79f8f72f113316b", "sha256": "d9c6b178d67325cf2604eb5b6217ce2a3241c261fc438ce4c5baace460ce01aa" }, "downloads": -1, "filename": "drf-viewset-profiler-0.2.0.tar.gz", "has_sig": false, "md5_digest": "ae0c8eeba39506b4d79f8f72f113316b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 6329, "upload_time": "2019-10-16T02:58:16", "url": "https://files.pythonhosted.org/packages/7e/1d/6a9441c7140c1b2c439351f37d10653c8759932d7f43d3d673b2dfa4f63a/drf-viewset-profiler-0.2.0.tar.gz" } ] }