The OWNER_ID bypasses all authorization checks and has access to admin commands:
/auth - Grant temporary access
/unauth - Revoke temporary access
/unauthall - Clear all temporary authorizations
Best practices:
Set this to your personal Telegram user ID
Never share your owner credentials
Keep this separate from chat/group IDs
Check in source:jackett_bot/handlers/commands.py:279
Understand Authorization Layers
Authorization is checked in this order:
Owner ID - Configured via OWNER_ID, permanent
Configured Chat IDs - From AUTHORIZED_CHAT_IDS, permanent
Temporary IDs - Added via /auth, cleared on restart
def _is_authorized(self, user_id: int, chat_id: int) -> bool: if self._is_owner(user_id): return True if self.auth_service.is_configured_id_authorized(chat_id): return True if self.auth_service.is_temporary_id_authorized(chat_id): return True if user_id and self.auth_service.is_configured_id_authorized(user_id): return True if user_id and self.auth_service.is_temporary_id_authorized(user_id): return True return False
Source:jackett_bot/handlers/commands.py:266
Because authorization checks multiple layers, removing one grant may still leave another active. Use /unauthall to clear all temporary grants.
Use Docker volumes for logs to persist across container restarts.
Handle Database Lock Errors
The bot uses Pyrogram’s session database. If you see “database is locked” errors:Cause: Another bot instance is running or a stale lock exists.Solution:
The project uses uv for faster, more reliable dependency management:Benefits:
10-100× faster than pip
Automatic virtual environment management
Lock file for reproducible installs
Built-in workspace support
Compatible with pip/requirements.txt
Key commands:
# Install dependencies (creates .venv automatically)uv sync# Add a new dependencyuv add package-name# Update lock file after manual pyproject.toml editsuv lock# Run without activating venvuv run python main.py
Source: Mentioned in README.md:21
Dependency Files
The project uses modern Python packaging with pyproject.toml:pyproject.toml (project metadata + dependencies)
Defines project metadata
Lists runtime dependencies
Conditional dependencies (e.g., tgcrypto only on Python < 3.13)
uv.lock (locked versions)
Generated by uv lock
Contains exact versions and hashes
Ensures reproducible installs across environments
Commit this file to version control
requirements.txt (pip compatibility)
Human-readable dependency list
Used for documentation
Can be used with pip if needed
Always run uv lock after manually editing pyproject.toml to update the lock file.
Optional tgcrypto
The bot includes tgcrypto for faster encryption, but it’s optional:
[project.dependencies]tgcrypto = { version = "*", python = "<3.13" }
Why conditional?
Requires C++ build tools to compile
Python 3.13+ has compatibility issues
Bot works fine without it (just slightly slower encryption)
If installation fails:
# Remove from pyproject.toml or install build toolssudo apt-get install build-essential python3-dev
Search results use in-memory pagination with automatic cleanup:Session TTL
Default: 3600 seconds (1 hour)
Automatically pruned on new searches or page requests
Prevents memory leaks from abandoned sessions
Implementation:
def _prune_expired_sessions(self): now = time.time() expired_session_ids = [ session_id for session_id, session in self._pagination_sessions.items() if now - session.created_at > self._pagination_ttl_seconds ] for session_id in expired_session_ids: self._pagination_sessions.pop(session_id, None)
Detailed errors are logged but not shown to users. This prevents information leakage while maintaining debuggability.
Startup Validation
The bot validates configuration before starting:
if __name__ == "__main__": try: bot = JackettSearchBot.initialize("config.env") except ValueError as exc: print(f"Initialization failed: {exc}") print("Please fill the missing values in config.env and start again.") raise SystemExit(1) from exc bot.run()
Validation checks:
All required environment variables present
Numeric values parseable as integers
Log levels valid
Chat IDs valid integers
Source:main.py:4, jackett_bot/config.py:53
Fast-fail on startup prevents runtime errors from missing configuration.
Graceful Shutdown
The bot handles shutdown signals cleanly:
def run(self): self.logger.info("Starting bot runtime.") try: self.app.run() except KeyboardInterrupt: self.logger.info("Stop signal received (KeyboardInterrupt). Exiting gracefully.") except sqlite3.OperationalError as exc: if "database is locked" in str(exc).lower(): self.logger.error( "Session database is locked. This usually means another bot instance is still running " "or a stale session lock exists." ) raise SystemExit(2) from exc self.logger.exception("SQLite operational error while starting bot.") raise except Exception: self.logger.exception("Fatal runtime error. Bot stopped unexpectedly.") raise finally: self._shutdown_services() self.logger.info("Bot shutdown complete.")