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.1.tar.gz (28.1 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.1-py3-none-any.whl (34.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: hazelaura-1.0.1.tar.gz
  • Upload date:
  • Size: 28.1 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.1.tar.gz
Algorithm Hash digest
SHA256 5db10db4f2918772cac046b80788dced45c25d443ea1f89584109d4d598e2624
MD5 6d84ddee4ce58146b72a2bc2dd648762
BLAKE2b-256 544d2872ebb3cbfef032f3806a5c1164ae74e58e2f705138f9b446aa37dbc9c4

See more details on using hashes here.

File details

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

File metadata

  • Download URL: hazelaura-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 34.0 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 12e439f0379861c832e7969278cd27033b59772d7f8d57f64f659e87afffdb17
MD5 2d8bfcc54f3efee1624f6f90dd0a21a5
BLAKE2b-256 5efba7a3d0f3e61012fefda2132ad40815795b712434a7c2ca6b68a1ea480354

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