{"id":13469204,"url":"https://github.com/vpcarlos/profyle","last_synced_at":"2025-10-05T12:38:34.293Z","repository":{"id":77578933,"uuid":"605525652","full_name":"vpcarlos/profyle","owner":"vpcarlos","description":"Development tool for analysing and managing python traces","archived":false,"fork":false,"pushed_at":"2024-04-19T14:51:52.000Z","size":4049,"stargazers_count":120,"open_issues_count":3,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-26T20:06:33.982Z","etag":null,"topics":["api","asgi","fastapi","flask","http","middleware","perfetto","profile","profyle","python","python3","trace","tracing","viztracer"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vpcarlos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-23T10:46:37.000Z","updated_at":"2025-01-13T13:39:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"83015f16-769a-4254-8480-adecf6260671","html_url":"https://github.com/vpcarlos/profyle","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpcarlos%2Fprofyle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpcarlos%2Fprofyle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpcarlos%2Fprofyle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpcarlos%2Fprofyle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vpcarlos","download_url":"https://codeload.github.com/vpcarlos/profyle/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246922248,"owners_count":20855345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","asgi","fastapi","flask","http","middleware","perfetto","profile","profyle","python","python3","trace","tracing","viztracer"],"created_at":"2024-07-31T15:01:29.131Z","updated_at":"2025-10-05T12:38:29.241Z","avatar_url":"https://github.com/vpcarlos.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n \u003cimg \n    src=\"https://github.com/vpcarlos/profyle/blob/main/docs/img/profyle.png?raw=true\" \n    width=\"300\"\n    alt=\"Profyle\"\n \u003e\n\u003c/p\u003e\n\n### Development tool for analysing and managing python traces\n[![Tests](https://github.com/vpcarlos/profyle/actions/workflows/test.yml/badge.svg)](https://github.com/vpcarlos/profyle/actions/workflows/test.yml)\n\u003ca href=\"https://pypi.org/project/profyle\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/profyle\" alt=\"Package version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/profyle\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/pyversions/profyle.svg?color=%2334D058\" alt=\"Supported Python versions\"\u003e\n\u003c/a\u003e\n\n## Why do you need Profyle?\n### Bottlenecks\nWith Profyle you can easily detect where in your code you have a bottleneck, simply analyze the trace and see what function or operation is taking most of the execution time of the request\n\n### Enhance performace\nAnalyze the traces and decide which parts of your code should be improved\n\n\n## Installation\n\n\u003cdiv class=\"termy\"\u003e\n\n```console\n$ pip install profyle\n\n---\u003e 100%\n```\n\n\u003c/div\u003e\n\n## Example\n\n### 1. Implement\nIn order to track all your API requests you must implement the \u003ccode\u003eProfyleMiddleware\u003c/code\u003e\n#### ProfyleMiddleware\n| Attribute | Required | Default | Description | ENV Variable |\n| --- | --- | --- | --- | --- |\n| `enabled` | No | `True` | Enable or disable Profyle | `PROFYLE_ENABLED` |\n| `pattern` | No | `None` | 0nly trace those paths that match with [pattern](https://en.wikipedia.org/wiki/Glob_(programming))  | `PROFYLE_PATTERN` |\n| `max_stack_depth` | No | `-1` | Limit maximum stack trace depth | `PROFYLE_MAX_STACK_DEPTH` |\n| `min_duration` | No | `0` (milisecons) | Only record traces with a greather duration than the limit. | `PROFYLE_MIN_DURATION` |\n\n\n\u003cdetails markdown=\"1\" open\u003e\n\u003csummary\u003eFastAPI\u003c/summary\u003e\n\n```Python\nfrom fastapi import FastAPI\nfrom profyle.fastapi import ProfyleMiddleware\n\napp = FastAPI()\n# Trace all requests\napp.add_middleware(ProfyleMiddleware)\n\n@app.get(\"/\")\nasync def root():\n    return {\"hello\": \"world\"}\n```\n\n```Python\nfrom fastapi import FastAPI\nfrom profyle.fastapi import ProfyleMiddleware\n\napp = FastAPI()\n# Trace all requests that match that start with /users \n# with a minimum duration of 100ms and a maximum stack depth of 20\napp.add_middleware(\n    ProfyleMiddleware,\n    pattern=\"/users*\",\n    max_stack_depth=20,\n    min_duration=100\n)\n\n@app.get(\"/users/{user_id}\")\nasync def get_user(user_id: int):\n    return {\"hello\": \"user\"}\n```\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\n\u003csummary\u003eFlask\u003c/summary\u003e\n\n```Python\nfrom flask import Flask\nfrom profyle.flask import ProfyleMiddleware\n\napp = Flask(__name__)\n\napp.wsgi_app = ProfyleMiddleware(app.wsgi_app, pattern=\"*/api/products*\")\n\n@app.route(\"/\")\ndef root():\n    return \"\u003cp\u003eHello, World!\u003c/p\u003e\"\n```\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\n\u003csummary\u003eDjango\u003c/summary\u003e\n\n```Python\n# settings.py\n\nMIDDLEWARE = [\n    ...\n    \"profyle.django.ProfyleMiddleware\",\n    ...\n]\n```\n\u003c/details\u003e\n\n### 2. Run\n* Run the web server:\n\n\u003cdiv class=\"termy\"\u003e\n\n```console\n$ profyle start\n\nINFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO:     Started reloader process [28720]\nINFO:     Started server process [28722]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\n```\n\n\u003c/div\u003e\n\n### 3. List\n* List all requests tracing:\n\n![Alt text](https://github.com/vpcarlos/profyle/blob/main/docs/img/traces.png?raw=true \"Traces\")\n\n### 4. Analyze\n* Profyle stands on the shoulder of giants: \u003ca href=\"https://github.com/gaogaotiantian/viztracer\" class=\"external-link\" target=\"_blank\"\u003eViztracer\u003c/a\u003e and  \u003ca href=\"https://github.com/google/perfetto\" class=\"external-link\" target=\"_blank\"\u003ePerfetto\u003c/a\u003e\n* Detailed function entry/exit information on timeline with source code\n* Super easy to use, no source code change for most features, no package dependency\n* Supports threading, multiprocessing, subprocess and async\n* Powerful front-end, able to render GB-level trace smoothly\n* Works on Linux/MacOS/Window\n\n![Alt text](https://github.com/vpcarlos/profyle/blob/main/docs/img/trace1.png?raw=true \"Trace1\")\n\n![Alt text](https://github.com/vpcarlos/profyle/blob/main/docs/img/trace2.png?raw=true \"Trace2\")\n\n\n\n## CLI Commands\n### start\n* Start the web server and view profile traces\n\n| Options | Type | Default | Description |\n| --- | --- | --- | --- |\n| --port | INTEGER | 0 | web server port |                                                                 \n| --host | TEXT | 127.0.0.1 | web server host |                                                                 \n                                                                  \n\n\u003cdiv class=\"termy\"\u003e\n\n```console\n$ profyle start --port 5432\n\nINFO:     Uvicorn running on http://127.0.0.1:5432 (Press CTRL+C to quit)\nINFO:     Started reloader process [28720]\nINFO:     Started server process [28722]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\n```\n\n\u003c/div\u003e\n\n### clean\n* Delete all profile traces\n\u003cdiv class=\"termy\"\u003e\n\n```console\n$ profyle clean\n\n10 traces removed \n```\n\n\u003c/div\u003e\n\n### check\n* Check traces DB size\n\u003cdiv class=\"termy\"\u003e\n\n```console\n$ profyle check\n\nDB size: 30MB\n```\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvpcarlos%2Fprofyle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvpcarlos%2Fprofyle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvpcarlos%2Fprofyle/lists"}