fastapi-telescope


Namefastapi-telescope JSON
Version 0.0.14 PyPI version JSON
download
home_pageNone
SummaryMiddleware and tool for FastApi HTTP requests and DB queries debugging
upload_time2025-08-14 13:37:15
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords debugging fastapi
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # FAST API TELESCOPE

This is a FastAPI middleware with UI dashboard for monitoring and debugging your FastAPI applications. It provides a set of tools to help you visualize and analyze the performance of your API endpoints, including request/response times, error rates, and more.

## Requirements
- FastAPI
- PostgreSQL
- SQLAlchemy

## Setup

1. Install the package using pip.
2. Create main.py file with a FastAPI application, include the middleware and mount components like this:
```python
from dotenv import load_dotenv

load_dotenv()

from fastapi.staticfiles import StaticFiles
import uvicorn
from fastapi import FastAPI, Request, status
from fastapi.responses import JSONResponse
from fastapi_telescope import TelescopeMiddleware
from fastapi_telescope import TELESCOPE_COMPONENTS_DIR
from fastapi_pagination import add_pagination
from .router import router

app = FastAPI()

app.add_middleware(TelescopeMiddleware)  # add telescope middleware

app.include_router(router) # optionally add admin auth dependency here

add_pagination(app)  # add pagination to your app

app.mount("/components", StaticFiles(directory=TELESCOPE_COMPONENTS_DIR),
          name="components")  # mount Vue components directory


@app.exception_handler(Exception)  # global exception handler, you can add your own
def global_exception_handler(request: Request, exc: Exception):
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={'message': 'An unexpected error occurred'},
    )


if __name__ == '__main__':
    uvicorn.run(
        'main.cmd.main:app', host='0.0.0.0', port=8000, reload=True
    )  # use for debugging
```
3. Create router.py file and include the Telescope router and optionally add the authenticated user ID in requests using custom dependency like this:
```python
from starlette.requests import Request
from fastapi import APIRouter, Depends
from fastapi_telescope import router as telescope_router

async def get_user_id(
    request: Request,
) -> str:
    user_id = '111' # this is just an example, you can get user id from your auth system
    request.state.user_id = user_id # this user_id will be used in logs
    return user_id

router = APIRouter(dependencies=[Depends(get_user_id)])
router.include_router(telescope_router)

__all__ = ['router']
```
4. Add creds (DB_USER,DB_PASSWORD,DB_HOST,DB_PORT,DB_NAME) to POSTGRES db, SITE_URL (f.e. http://localhost:8000) and API_PREFIX (f.e. '/api') to your .env file.
5. To allow middleware use hooks to intercept database calls and log them, use the session maker from the package to create an asynchronous session:
```python
from fastapi_telescope.db import get_async_sessionmaker
from typing import AsyncGenerator, Callable

from fastapi import Depends
from sqlalchemy.ext.asyncio import (
    AsyncSession,
)

async def get_async_session(
    sessionmaker: Callable[..., AsyncSession] = Depends(get_async_sessionmaker),
) -> AsyncGenerator[AsyncSession, None]:
    async with sessionmaker() as session:
        yield session
```
6. Add migration with such methods to your migrations folder and run it (or you can use raw sql query for your db).
```python
def upgrade():
    op.create_table('log_http_requests',
                    sa.Column('id', sa.Integer(), nullable=False),
                    sa.Column('level', sa.String(), nullable=False),
                    sa.Column('request_method', sa.String(), nullable=False),
                    sa.Column('request_url', sa.String(), nullable=False),
                    sa.Column('path_params', sa.String(), nullable=False),
                    sa.Column('query_params', sa.String(), nullable=False),
                    sa.Column('headers', sa.String(), nullable=False),
                    sa.Column('request_body', sa.String(), nullable=False),
                    sa.Column('status_code', sa.Integer(), nullable=False),
                    sa.Column('response_time', sa.Float(), nullable=False),
                    sa.Column('response_body', sa.String(), nullable=False),
                    sa.Column('exception_message', sa.String(), nullable=True),
                    sa.Column('stack_trace', sa.String(), nullable=True),
                    sa.Column('user_id', sa.String(), nullable=True),
                    sa.Column('created_at', sa.DateTime(), nullable=False),
                    sa.Column('updated_at', sa.DateTime(), nullable=False),
                    sa.PrimaryKeyConstraint('id')
                    )
    op.create_table('log_db_queries',
                    sa.Column('id', sa.Integer(), nullable=False),
                    sa.Column('log_http_request_id', sa.Integer(), nullable=False),
                    sa.Column('level', sa.String(), nullable=False),
                    sa.Column('db_query', sa.String(), nullable=False),
                    sa.Column('db_query_time', sa.Float(), nullable=False),
                    sa.Column('created_at', sa.DateTime(), nullable=False),
                    sa.Column('updated_at', sa.DateTime(), nullable=False),
                    sa.ForeignKeyConstraint(['log_http_request_id'], ['log_http_requests.id'], ),
                    sa.PrimaryKeyConstraint('id')
                    )
    op.create_index(op.f('ix_log_db_queries_log_http_request_id'), 'log_db_queries', ['log_http_request_id'],
                    unique=False)


def downgrade() -> None:
    op.drop_index(op.f('ix_log_db_queries_log_http_request_id'), table_name='log_db_queries')
    op.drop_table('log_db_queries')
    op.drop_table('log_http_requests')
```
7. Run your FastAPI app and open docs page http://localhost:8000/docs.
8. Open your browser and go to `<SITE_URL><API_PREFIX>/telescope/dashboard` to see the dashboard. It should look like this:<br><br>
![Dashboard](https://github.com/AlisaZobova/fastapi-telescope-pip/blob/master/dashboard.png?raw=true)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "fastapi-telescope",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "debugging, fastapi",
    "author": null,
    "author_email": "Alisa Zobova <zobovaalice@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/0d/38/f7556d6f0a30d2f7a3812209d93deea7a05461c4c3542078d8155c7bad01/fastapi_telescope-0.0.14.tar.gz",
    "platform": null,
    "description": "# FAST API TELESCOPE\n\nThis is a FastAPI middleware with UI dashboard for monitoring and debugging your FastAPI applications. It provides a set of tools to help you visualize and analyze the performance of your API endpoints, including request/response times, error rates, and more.\n\n## Requirements\n- FastAPI\n- PostgreSQL\n- SQLAlchemy\n\n## Setup\n\n1. Install the package using pip.\n2. Create main.py file with a FastAPI application, include the middleware and mount components like this:\n```python\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nfrom fastapi.staticfiles import StaticFiles\nimport uvicorn\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import JSONResponse\nfrom fastapi_telescope import TelescopeMiddleware\nfrom fastapi_telescope import TELESCOPE_COMPONENTS_DIR\nfrom fastapi_pagination import add_pagination\nfrom .router import router\n\napp = FastAPI()\n\napp.add_middleware(TelescopeMiddleware)  # add telescope middleware\n\napp.include_router(router) # optionally add admin auth dependency here\n\nadd_pagination(app)  # add pagination to your app\n\napp.mount(\"/components\", StaticFiles(directory=TELESCOPE_COMPONENTS_DIR),\n          name=\"components\")  # mount Vue components directory\n\n\n@app.exception_handler(Exception)  # global exception handler, you can add your own\ndef global_exception_handler(request: Request, exc: Exception):\n    return JSONResponse(\n        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,\n        content={'message': 'An unexpected error occurred'},\n    )\n\n\nif __name__ == '__main__':\n    uvicorn.run(\n        'main.cmd.main:app', host='0.0.0.0', port=8000, reload=True\n    )  # use for debugging\n```\n3. Create router.py file and include the Telescope router and optionally add the authenticated user ID in requests using custom dependency like this:\n```python\nfrom starlette.requests import Request\nfrom fastapi import APIRouter, Depends\nfrom fastapi_telescope import router as telescope_router\n\nasync def get_user_id(\n    request: Request,\n) -> str:\n    user_id = '111' # this is just an example, you can get user id from your auth system\n    request.state.user_id = user_id # this user_id will be used in logs\n    return user_id\n\nrouter = APIRouter(dependencies=[Depends(get_user_id)])\nrouter.include_router(telescope_router)\n\n__all__ = ['router']\n```\n4. Add creds (DB_USER,DB_PASSWORD,DB_HOST,DB_PORT,DB_NAME) to POSTGRES db, SITE_URL (f.e. http://localhost:8000) and API_PREFIX (f.e. '/api') to your .env file.\n5. To allow middleware use hooks to intercept database calls and log them, use the session maker from the package to create an asynchronous session:\n```python\nfrom fastapi_telescope.db import get_async_sessionmaker\nfrom typing import AsyncGenerator, Callable\n\nfrom fastapi import Depends\nfrom sqlalchemy.ext.asyncio import (\n    AsyncSession,\n)\n\nasync def get_async_session(\n    sessionmaker: Callable[..., AsyncSession] = Depends(get_async_sessionmaker),\n) -> AsyncGenerator[AsyncSession, None]:\n    async with sessionmaker() as session:\n        yield session\n```\n6. Add migration with such methods to your migrations folder and run it (or you can use raw sql query for your db).\n```python\ndef upgrade():\n    op.create_table('log_http_requests',\n                    sa.Column('id', sa.Integer(), nullable=False),\n                    sa.Column('level', sa.String(), nullable=False),\n                    sa.Column('request_method', sa.String(), nullable=False),\n                    sa.Column('request_url', sa.String(), nullable=False),\n                    sa.Column('path_params', sa.String(), nullable=False),\n                    sa.Column('query_params', sa.String(), nullable=False),\n                    sa.Column('headers', sa.String(), nullable=False),\n                    sa.Column('request_body', sa.String(), nullable=False),\n                    sa.Column('status_code', sa.Integer(), nullable=False),\n                    sa.Column('response_time', sa.Float(), nullable=False),\n                    sa.Column('response_body', sa.String(), nullable=False),\n                    sa.Column('exception_message', sa.String(), nullable=True),\n                    sa.Column('stack_trace', sa.String(), nullable=True),\n                    sa.Column('user_id', sa.String(), nullable=True),\n                    sa.Column('created_at', sa.DateTime(), nullable=False),\n                    sa.Column('updated_at', sa.DateTime(), nullable=False),\n                    sa.PrimaryKeyConstraint('id')\n                    )\n    op.create_table('log_db_queries',\n                    sa.Column('id', sa.Integer(), nullable=False),\n                    sa.Column('log_http_request_id', sa.Integer(), nullable=False),\n                    sa.Column('level', sa.String(), nullable=False),\n                    sa.Column('db_query', sa.String(), nullable=False),\n                    sa.Column('db_query_time', sa.Float(), nullable=False),\n                    sa.Column('created_at', sa.DateTime(), nullable=False),\n                    sa.Column('updated_at', sa.DateTime(), nullable=False),\n                    sa.ForeignKeyConstraint(['log_http_request_id'], ['log_http_requests.id'], ),\n                    sa.PrimaryKeyConstraint('id')\n                    )\n    op.create_index(op.f('ix_log_db_queries_log_http_request_id'), 'log_db_queries', ['log_http_request_id'],\n                    unique=False)\n\n\ndef downgrade() -> None:\n    op.drop_index(op.f('ix_log_db_queries_log_http_request_id'), table_name='log_db_queries')\n    op.drop_table('log_db_queries')\n    op.drop_table('log_http_requests')\n```\n7. Run your FastAPI app and open docs page http://localhost:8000/docs.\n8. Open your browser and go to `<SITE_URL><API_PREFIX>/telescope/dashboard` to see the dashboard. It should look like this:<br><br>\n![Dashboard](https://github.com/AlisaZobova/fastapi-telescope-pip/blob/master/dashboard.png?raw=true)\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Middleware and tool for FastApi HTTP requests and DB queries debugging",
    "version": "0.0.14",
    "project_urls": {
        "Homepage": "https://github.com/AlisaZobova/fastapi-telescope-pip"
    },
    "split_keywords": [
        "debugging",
        " fastapi"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6db17d96ba3430bc2fd4af9cd60594208796ab7d210d353672c944c116d0af7b",
                "md5": "6531b07b18e3401f09c1b30729377f8f",
                "sha256": "f9e6c6ad161b92bb961972c22bd2dcf75da01b7b4e04af25170be7aad438db74"
            },
            "downloads": -1,
            "filename": "fastapi_telescope-0.0.14-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6531b07b18e3401f09c1b30729377f8f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 23981,
            "upload_time": "2025-08-14T13:37:14",
            "upload_time_iso_8601": "2025-08-14T13:37:14.350840Z",
            "url": "https://files.pythonhosted.org/packages/6d/b1/7d96ba3430bc2fd4af9cd60594208796ab7d210d353672c944c116d0af7b/fastapi_telescope-0.0.14-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0d38f7556d6f0a30d2f7a3812209d93deea7a05461c4c3542078d8155c7bad01",
                "md5": "4274c58cc6aef1852014a9a3ca5655f1",
                "sha256": "d9af4eb444444fde0c3addd1da427f3ceec080c691d4fe1ccbb1f352d93fd877"
            },
            "downloads": -1,
            "filename": "fastapi_telescope-0.0.14.tar.gz",
            "has_sig": false,
            "md5_digest": "4274c58cc6aef1852014a9a3ca5655f1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 64199,
            "upload_time": "2025-08-14T13:37:15",
            "upload_time_iso_8601": "2025-08-14T13:37:15.624650Z",
            "url": "https://files.pythonhosted.org/packages/0d/38/f7556d6f0a30d2f7a3812209d93deea7a05461c4c3542078d8155c7bad01/fastapi_telescope-0.0.14.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-14 13:37:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "AlisaZobova",
    "github_project": "fastapi-telescope-pip",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "fastapi-telescope"
}
        
Elapsed time: 0.78708s