Skip to main content

Django-inspired modular framework for Discord bots

Project description

HazelAura

Django-inspired modular framework for Discord bots.

pip install hazelaura
aura create --project mybot
cd mybot && aura run dev

Feature Overview

Feature Description
Settings system core/settings.py — Django-style central config with env-var overrides
Auto-discovery INSTALLED_APPS — zero-import app loading (commands, events, services)
Middleware pipeline Async middleware chain runs before every command
Dependency injection Named services auto-injected into command parameters
Command router Decorator-based router.command() — register anywhere, flush at startup
Superuser system aura createsuperuser + @is_superuser() decorator
Role-based auth @require_roles() / @require_permissions() decorators
Global error handler Clean, structured error responses for all failure modes
Hot-reload aura run dev watches for file changes and reloads extensions
Interactive shell aura shell — IPython/code.interact with full project context
Built-in DB SQLite via DatabaseService (swap engine in settings)
Built-in cache In-memory TTL cache via CacheService

Project Structure

mybot/
├── core/
│   └── settings.py          ← All configuration
├── cogs/
│   └── example/
│       ├── __init__.py
│       ├── commands.py      ← Cog + commands (auto-discovered)
│       ├── events.py        ← Event listeners (auto-discovered)
│       ├── services.py      ← Business logic layer
│       └── models.py        ← Data-access helpers
├── utils/
├── data/                    ← SQLite DB + logs (git-ignored)
├── .env                     ← Secrets (git-ignored)
├── main.py
└── requirements.txt

CLI Reference

aura create --project <n>    Scaffold a new project
aura create --app <n>        Scaffold a new cog/app
aura run dev                    Start bot with hot-reload
aura migrate                    Run DB schema migrations
aura createsuperuser            Register a Discord superuser
aura shell                      Interactive Python shell
aura help                       Show help

Settings

# core/settings.py
from hazelaura.core.settings import BaseSettings

class Settings(BaseSettings):
    TOKEN           = os.getenv("DISCORD_TOKEN")
    PREFIX          = "!"
    DEBUG           = True
    INSTALLED_APPS  = ["cogs.music", "cogs.admin"]
    MIDDLEWARE      = [
        "hazelaura.core.builtin.middleware.logging_middleware",
        "mybot.core.middleware.my_custom_middleware",
    ]
    DATABASE = {"ENGINE": "sqlite", "NAME": "data/db.sqlite3"}

settings = Settings()

Every attribute can be overridden by an environment variable prefixed HAZEL_, e.g. HAZEL_PREFIX=>> overrides PREFIX.


Auto-Discovery

List your app packages in INSTALLED_APPS. HazelAura will automatically import commands.py, events.py, and services.py from each package and register any discord.ext.commands.Cog subclasses with the bot.

INSTALLED_APPS = [
    "cogs.music",
    "cogs.moderation",
    "cogs.economy",
]

Each app follows the convention:

cogs/music/
├── __init__.py
├── commands.py    ← defines MusicCommands(commands.Cog)  + setup()
├── events.py      ← defines MusicEvents(commands.Cog)    + setup()
└── services.py    ← MusicService class

Middleware

# core/settings.py
MIDDLEWARE = [
    "hazelaura.core.builtin.middleware.logging_middleware",
    "mybot.core.middleware.rate_limit_middleware",
]

# mybot/core/middleware.py
async def rate_limit_middleware(ctx, call_next):
    if is_rate_limited(ctx.author.id):
        return await ctx.send("⏳ Slow down!")
    await call_next(ctx)

Dependency Injection

from hazelaura.core.injector import injector

# Register a custom service
injector.register("payments", PaymentService())

# Auto-inject into commands by parameter name
@bot.command()
async def subscribe(ctx, db, cache, payments):
    user = db.fetchone("SELECT * FROM users WHERE id=?", (ctx.author.id,))
    ...

Auth Decorators

from hazelaura import is_superuser, require_roles, require_permissions

@bot.command()
@is_superuser()
async def shutdown(ctx): ...

@bot.command()
@require_roles("Admin", "Moderator")
async def ban(ctx, member): ...

@bot.command()
@require_permissions(manage_guild=True)
async def settings_cmd(ctx): ...

Command Router

Register commands anywhere — in any module — without touching the bot object:

from hazelaura.core.router import router

@router.command("ping")
async def ping(ctx):
    await ctx.send("pong")

@router.group("admin")
async def admin(ctx):
    pass

@router.subcommand("admin", "reload")
async def admin_reload(ctx, extension: str):
    await ctx.bot.reload_extension(extension)
    await ctx.send(f"✅ Reloaded {extension}")

Superuser System

# Register a superuser
aura createsuperuser
# → Enter the Discord user ID

# Or non-interactively
aura createsuperuser --id 123456789012345678
from hazelaura import is_superuser

@bot.command()
@is_superuser()
async def secret(ctx):
    await ctx.send("🔐 Superuser-only command!")

License

MIT — HazelTech

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hazelaura-1.0.0.tar.gz (4.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hazelaura-1.0.0-py3-none-any.whl (4.6 kB view details)

Uploaded Python 3

File details

Details for the file hazelaura-1.0.0.tar.gz.

File metadata

  • Download URL: hazelaura-1.0.0.tar.gz
  • Upload date:
  • Size: 4.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for hazelaura-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7aecec3127dbc3d869080765e8cadb6ede7d641a8cb4745844a37bc37d2f376e
MD5 d4c650273f17be6a4bcf2b85b0471c64
BLAKE2b-256 6f577ad784d9ebf5ab909879ac7151e211996c6ed5dc5a875802939cbb2b6d28

See more details on using hashes here.

File details

Details for the file hazelaura-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: hazelaura-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 4.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for hazelaura-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 74ecb8eb000ecd27d8a585fdd091f7cf87e4b950e6f1d0ba704c7f045fc970d2
MD5 f04a077eee471a4d9cc60cce6c820a84
BLAKE2b-256 4dd0bc697b18d6d9b5a74eb1f108f6c389f756ea10a705968dead6423b644146

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page