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.2.tar.gz (28.2 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.2-py3-none-any.whl (34.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: hazelaura-1.0.2.tar.gz
  • Upload date:
  • Size: 28.2 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.2.tar.gz
Algorithm Hash digest
SHA256 ddb3f11c83280056b4f7167dca92a945cf531339776dda3bd78f93de7c92f8ea
MD5 f8b87eae96727e5c0abbfc17019ce454
BLAKE2b-256 86e93c81ddff4579bc1260f90bfd2b258b068c0ef3164db36ab5724c4d8a3270

See more details on using hashes here.

File details

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

File metadata

  • Download URL: hazelaura-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 34.1 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 71b0958762fe20b83d11f198a85858ec064efebf82419ee89ecdb7d681f711bf
MD5 725caa5d9d224b2b6f89e2bedbafee14
BLAKE2b-256 905cd45862933c52e91720b8cbf761bf34ed0b24a39d2b429ad6c9e4ebbaa2f3

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