Python monitoring SDK – automatic log capture and real-time metrics for Django, Flask, FastAPI and any Python project
Project description
Lescopr Python SDK
Lescopr is a zero-configuration Python monitoring SDK that automatically captures logs, errors, and system metrics from any Python project and streams them in real-time to the Lescopr app.
It works out of the box with Django, Flask, FastAPI, and any custom Python architecture — no framework-specific code required.
Table of Contents
- Features
- Installation
- Quick Start
- Framework Integration
- Architecture
- CLI Reference
- Advanced Configuration
- How It Works
- PyPI
- Contributing
- License
Features
- ✅ Automatic log capture — hooks into Python's
loggingmodule without any code changes - ✅ Framework auto-detection — detects Django, Flask, FastAPI, and more from your project files
- ✅ Real-time metrics — streams system and application metrics via gRPC
- ✅ Error tracking — captures exceptions, import errors, and tracebacks
- ✅ Daemon architecture — runs as a background process, completely non-blocking
- ✅ Zero configuration — a single CLI command is enough to get started
- ✅ Works everywhere — Django, Flask, FastAPI, Celery, scripts, custom architectures
Installation
pip install lescopr
Requirements: Python 3.8 or later.
Optional dependency for daemon process detection:
pip install lescopr[psutil]
Quick Start
Step 1 — Initialise the SDK in your project directory:
lescopr init --sdk-key YOUR_SDK_KEY
This auto-detects your framework, registers the project with the Lescopr API, and starts the background daemon.
Step 2 — Import and activate monitoring in your application:
import lescopr
lescopr.logs()
That's it. All subsequent log calls are forwarded to the Lescopr app automatically.
Framework Integration
Django
Add a single line to your settings.py (before any other app-specific imports):
# settings.py
import lescopr
lescopr.logs()
INSTALLED_APPS = [
...
]
The SDK automatically hooks into Django's logging system and reconnects after any hot-reload. It also captures uncaught exceptions via Django's got_request_exception signal.
WSGI/ASGI entry points (wsgi.py / asgi.py) work just as well if you prefer:
# wsgi.py
import lescopr
lescopr.logs()
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Flask
Add monitoring at the top of your application factory or app.py:
# app.py
import lescopr
lescopr.logs()
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World'
Works with Flask's development server, Gunicorn, uWSGI, and any other WSGI server.
FastAPI
Add monitoring in your main.py before instantiating the FastAPI app:
# main.py
import lescopr
lescopr.logs()
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
async def root():
return {'message': 'Hello World'}
Compatible with Uvicorn, Hypercorn, and any other ASGI server.
Generic Python / Custom Architecture
The SDK is framework-agnostic. For scripts, Celery workers, background tasks, or any custom Python architecture, add the same two lines:
import lescopr
lescopr.logs()
# Your existing code continues here
import logging
logger = logging.getLogger(__name__)
logger.info('Application started') # → forwarded to Lescopr
logger.error('Something went wrong') # → forwarded to Lescopr
Because lescopr.logs() patches Python's built-in logging module and builtins.__import__, it captures logs and import errors from any Python code, regardless of the framework in use.
Architecture
Your Python Application
│
│ logging.getLogger(...).info(...)
▼
┌─────────────────────────────┐
│ ResilientLescoprHandler │ (attached to root logger)
│ + import error hooks │
└──────────────┬──────────────┘
│ gRPC stream
▼
┌─────────────────────────────┐
│ Lescopr Daemon │ (background process, .lescopr.pid)
│ lescopr/daemon/main.py │
└──────────────┬──────────────┘
│ gRPC / HTTPS
▼
https://api.lescopr.com
│
▼
Lescopr App
https://app.lescopr.com
Key components:
| Component | Path | Role |
|---|---|---|
Lescopr (core) |
lescopr/core/lescopr.py |
Central SDK object, config management, daemon control |
logs() |
lescopr/__init__.py |
Auto-discovery entry point, installs log handler |
FrameworkAnalyzer |
lescopr/filesystem/analyzers/framework.py |
Detects Django, Flask, FastAPI, etc. |
GrpcClient |
lescopr/network/grpc/client.py |
Streams logs to the daemon via gRPC |
| Daemon | lescopr/daemon/main.py |
Background process that relays data to the API |
| CLI | lescopr/cli.py |
init, start, stop, status, diagnose, reset |
The daemon uses a bidirectional gRPC stream so log delivery is non-blocking and resilient to transient network failures.
CLI Reference
After installation, the lescopr command is available in your terminal:
lescopr [OPTIONS] COMMAND [ARGS]...
| Command | Description |
|---|---|
lescopr init --sdk-key KEY |
Initialise the SDK in the current project |
lescopr start |
Start the monitoring daemon |
lescopr stop |
Stop the monitoring daemon |
lescopr status |
Show daemon status and project info |
lescopr diagnose |
Run a full connectivity diagnostic |
lescopr reset |
Remove SDK configuration and stop daemon |
init
lescopr init --sdk-key YOUR_SDK_KEY [--environment production|development] [--no-start-daemon]
- Auto-detects your project framework (Django, Flask, FastAPI, etc.)
- Registers the project with the Lescopr API
- Saves credentials to
.lescopr.json - Starts the background daemon (pass
--no-start-daemonto skip)
diagnose
lescopr diagnose --verbose --check-server
Prints a full report of the configuration, daemon state, and (optionally) gRPC server connectivity.
Advanced Configuration
lescopr.logs() reads from .lescopr.json automatically. You can also pass parameters directly to Lescopr:
from lescopr import Lescopr
client = Lescopr(
api_key="YOUR_API_KEY", # Required – your account API key
sdk_key="YOUR_SDK_KEY", # Required – your project SDK key
environment="production", # "development" (default) or "production"
auto_logging=True, # Attach to root logger immediately (default: True)
auto_grpc=True, # Connect to daemon immediately (default: True)
)
Environment variables
| Variable | Description |
|---|---|
LESCOPR_DAEMON_MODE=true |
Prevents the SDK from starting inside its own daemon process |
.lescopr.json (generated by lescopr init)
{
"sdk_id": "proj_xxxx",
"sdk_key": "lsk_xxxx",
"api_key": "lak_xxxx",
"environment": "development",
"project_name": "my-app",
"project_stack": ["django"]
}
Security: Add
.lescopr.jsonto your.gitignoreto avoid committing credentials.
Debug mode
import lescopr
lescopr.set_debug_mode() # enables verbose internal prints
lescopr.logs()
How It Works
-
lescopr initscans your project files, detects the framework, and calls the Lescopr API to register the project. It writes.lescopr.jsonand starts a background daemon process. -
lescopr.logs()(called at app startup) checks for.lescopr.jsonand a running daemon, then installs aResilientLescoprHandleron Python's root logger. All existinglogging.getLogger(...)calls in your codebase are captured automatically — no changes required. -
The daemon (
lescopr-daemon) runs as an independent background process and maintains a persistent gRPC connection toapi.lescopr.com. Log entries are batched and streamed in real-time. -
Framework-specific integrations are applied automatically:
- Django: monkey-patches
configure_loggingso the handler survives hot-reloads; connects to thegot_request_exceptionsignal. - Flask / FastAPI: the root-logger hook is sufficient — no extra middleware needed.
- Custom Python: the same root-logger hook works for any framework or plain scripts.
- Django: monkey-patches
PyPI
The package is available on PyPI: lescopr
To publish a new release:
# Build source distribution and wheel
python -m build
# Upload to PyPI
twine upload dist/*
Requires
buildandtwine:pip install build twine
Contributing
- Fork the repository: https://github.com/Lescopr/lescopr-python
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m "Add my feature" - Push and open a Pull Request
Please open an issue before starting significant work so we can discuss the approach.
Support
| Channel | Link |
|---|---|
| 📖 Documentation | https://lescopr.com/docs |
| 🌐 App | https://app.lescopr.com |
| support@lescopr.com | |
| 🐛 Bug reports | https://github.com/Lescopr/lescopr-python/issues |
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lescopr-1.0.2.tar.gz.
File metadata
- Download URL: lescopr-1.0.2.tar.gz
- Upload date:
- Size: 72.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d68a7dad97fc347cdbd53e1327a073502091a91e7f4d579fb7198a87ec39ed2a
|
|
| MD5 |
8968663aa532af1aa1dab8f70d5e8c84
|
|
| BLAKE2b-256 |
59313e45f1f9e0ac5e27dcf8214d060eb5615dbcb4f88c6a66aa66b1976db674
|
File details
Details for the file lescopr-1.0.2-py3-none-any.whl.
File metadata
- Download URL: lescopr-1.0.2-py3-none-any.whl
- Upload date:
- Size: 84.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0ad4c9a86bd618922d48c5a010f821775eab2a7aaf627aedb7dac99d83f717a
|
|
| MD5 |
461efc88285e17e964368786b19e3d88
|
|
| BLAKE2b-256 |
012879006672795daa5ae5a5106641cec1c65f9fdf990bd41cd4dec0f017022e
|