A powerful Python toolkit for building automation, integrations, and bots.
Project description
kroxy
A powerful Python toolkit for building automation, integrations, and bots.
Installation
pip install kroxy
pip install --upgrade kroxy
Import Style
Everything in kroxy is available at the top level — no need to navigate into submodules.
# Import the whole package and use anything directly
import kroxy
antinuke = kroxy.AntiNuke(whitelist=[OWNER_ID])
manager = kroxy.GiveawayManager()
utils = kroxy.Utils()
api = kroxy.DiscordAPI(token="Bot TOKEN")
# Or import exactly what you need
from kroxy import AntiNuke, Checkers, Utils
from kroxy import GiveawayManager, Giveaway
from kroxy import MusicPlayerManager, Track
from kroxy import SlashCommand, PrefixCommand, Option
from kroxy import DiscordAPI
# Submodule access also works if preferred
from kroxy import discord
discord.AntiNuke(...)
discord.Utils.build_embed(...)
Package Structure
kroxy/
├── discord/
│ ├── api.py ← Async Discord REST API client
│ ├── commands.py ← Slash and prefix command builders
│ ├── utils.py ← Embeds, mentions, timestamps, permissions, formatting
│ ├── antinuke.py ← Real-time nuke detection and auto-punishment
│ ├── checkers.py ← Permission, role, and hierarchy validation
│ ├── giveaway.py ← Weighted giveaway engine with scheduling
│ └── music.py ← Multi-guild music queue and player manager
└── website/ ← Coming soon
Module Reference
DiscordAPI — Discord REST API Client
Async HTTP client for the Discord REST API v10.
Constructor: DiscordAPI(token: str, bot: bool = True)
from kroxy import DiscordAPI
api = DiscordAPI(token="Bot YOUR_TOKEN")
guild = await api.get_guild(GUILD_ID)
channel = await api.get_channel(CHANNEL_ID)
user = await api.get_user(USER_ID)
await api.send_message(channel_id=CHANNEL_ID, content="Hello!")
await api.send_message(channel_id=CHANNEL_ID, embed=embed_dict)
await api.ban_member(GUILD_ID, USER_ID, reason="Spam", delete_message_days=1)
await api.unban_member(GUILD_ID, USER_ID)
await api.kick_member(GUILD_ID, USER_ID, reason="AFK")
await api.add_role(GUILD_ID, USER_ID, ROLE_ID)
await api.remove_role(GUILD_ID, USER_ID, ROLE_ID)
await api.create_channel(GUILD_ID, name="general", channel_type=0)
await api.delete_channel(CHANNEL_ID)
await api.get_audit_logs(GUILD_ID, limit=50)
await api.get_invites(GUILD_ID)
await api.delete_invite("invite_code")
await api.get_webhooks(GUILD_ID)
await api.delete_webhook(WEBHOOK_ID)
await api.close()
AntiNuke — Anti-Nuke System
Detects mass destructive actions and triggers automatic punishment.
Constructor: AntiNuke(whitelist: list = [], limits: dict = {})
Default Limits:
| Action | Threshold | Window |
|---|---|---|
ban |
3 | 10s |
kick |
3 | 10s |
channel_delete |
3 | 10s |
channel_create |
5 | 10s |
role_delete |
3 | 10s |
role_create |
5 | 10s |
webhook_create |
3 | 10s |
webhook_delete |
3 | 10s |
bot_add |
2 | 30s |
mass_mention |
5 | 5s |
from kroxy import AntiNuke
antinuke = AntiNuke(
whitelist=[OWNER_ID],
limits={
"ban": (2, 5), # override: 2 bans in 5s triggers
}
)
async def on_nuke(action, user_id, guild):
print(f"[NUKE] {action} by {user_id}")
antinuke.on_trigger = on_nuke
antinuke.punishment = "ban" # "ban" | "kick" | "strip_roles"
# Wire to your event handlers:
await antinuke.on_member_ban(user_id=executor_id, guild=guild)
await antinuke.on_member_kick(user_id=executor_id, guild=guild)
await antinuke.on_channel_delete(user_id=executor_id, guild=guild)
await antinuke.on_channel_create(user_id=executor_id, guild=guild)
await antinuke.on_role_delete(user_id=executor_id, guild=guild)
await antinuke.on_role_create(user_id=executor_id, guild=guild)
await antinuke.on_webhook_create(user_id=executor_id, guild=guild)
await antinuke.on_webhook_delete(user_id=executor_id, guild=guild)
await antinuke.on_bot_add(user_id=executor_id, guild=guild)
await antinuke.on_mass_mention(user_id=executor_id, guild=guild)
# Whitelist management
antinuke.add_whitelist(MOD_ID)
antinuke.remove_whitelist(MOD_ID)
antinuke.reset_user(USER_ID)
# View current config
print(antinuke.get_stats())
Checkers — Permission & Role Validation
Raises CheckFailed on failure, returns True on success.
from kroxy import Checkers, CheckFailed
try:
Checkers.require_admin(member.permissions)
Checkers.require_ban_members(member.permissions)
Checkers.require_manage_guild(member.permissions)
Checkers.require_manage_roles(member.permissions)
Checkers.require_manage_channels(member.permissions)
Checkers.require_manage_messages(member.permissions)
Checkers.require_manage_webhooks(member.permissions)
Checkers.require_role(member.role_ids, MOD_ROLE_ID, "Moderator")
Checkers.require_any_role(member.role_ids, [MOD_ROLE_ID, ADMIN_ROLE_ID])
Checkers.check_hierarchy(
executor_top_role_pos=member.top_role.position,
target_top_role_pos=target.top_role.position,
bot_top_role_pos=bot.top_role.position,
)
Checkers.require_guild_owner(user_id, guild.owner_id)
Checkers.require_guild_only(ctx.guild_id)
Checkers.require_dm_only(ctx.guild_id)
Checkers.block_bots(ctx.author.bot)
Checkers.require_nsfw(channel.nsfw)
except CheckFailed as e:
await ctx.send(f"❌ {e.message}")
Utils — General Utilities
Embed builder, mentions, timestamps, permissions, and text formatters.
from kroxy import Utils
# Embed builder
embed = Utils.build_embed(
title="Title",
description="Description here",
color=0x5865F2,
fields=[
{"name": "Field 1", "value": "Value 1", "inline": True},
{"name": "Field 2", "value": "Value 2", "inline": True},
],
footer="kroxy",
thumbnail="https://example.com/thumb.png",
image="https://example.com/image.png",
author_name="Bot Name",
author_icon="https://example.com/icon.png",
timestamp=True,
)
# Mentions
Utils.mention_user(123456) # <@123456>
Utils.mention_role(654321) # <@&654321>
Utils.mention_channel(999999) # <#999999>
Utils.parse_mention("<@123456>") # 123456
# Timestamps
Utils.discord_timestamp(datetime.now(), style="R") # Relative: "5 minutes ago"
Utils.discord_timestamp(datetime.now(), style="F") # Full: "21 June 2026 12:00"
Utils.time_until(3725) # "1 hour, 2 minutes, 5 seconds"
Utils.snowflake_to_timestamp(snowflake_id)
# Permissions
Utils.has_permission(perms_bitfield, "administrator") # True/False
Utils.has_permission(perms_bitfield, "ban_members")
Utils.permissions_list(perms_bitfield) # ["administrator", "ban_members", ...]
# Text formatting
Utils.truncate(text, max_length=2048)
Utils.code_block("print('hi')", language="python")
Utils.bold("text") # **text**
Utils.italic("text") # *text*
Utils.underline("text") # __text__
Utils.strikethrough("text") # ~~text~~
Utils.spoiler("text") # ||text||
Utils.inline_code("text") # `text`
GiveawayManager / Giveaway — Giveaway Engine
Weighted giveaway system with bonus roles, reroll, and auto-scheduling.
from kroxy import GiveawayManager
manager = GiveawayManager()
async def on_end(giveaway, winners):
print(f"Winners of '{giveaway.prize}': {winners}")
manager.on_end = on_end
# Create
giveaway = await manager.create(
prize="Discord Nitro",
host_id=HOST_USER_ID,
channel_id=CHANNEL_ID,
guild_id=GUILD_ID,
duration=86400, # seconds (24 hours)
winner_count=3,
required_role_id=MEMBER_ROLE_ID,
bonus_roles={
BOOSTER_ROLE_ID: 2, # Boosters: 3 entries
VIP_ROLE_ID: 4, # VIPs: 5 entries
},
)
# Entries
giveaway.add_entry(user_id=555, role_ids=[BOOSTER_ROLE_ID])
giveaway.remove_entry(user_id=555)
# Info
giveaway.is_active # True/False
giveaway.time_remaining # seconds left
giveaway.total_entries # weighted total
giveaway.participant_count # unique users
giveaway.giveaway_id # "A1B2C3D4"
# Control
await manager.end_now(giveaway.giveaway_id) # Force end
await manager.cancel(giveaway.giveaway_id) # Cancel (no winner)
new_winners = giveaway.reroll() # Reroll
# Lookup
manager.get(giveaway_id)
manager.get_by_message(message_id)
manager.all_active()
manager.all_ended()
MusicPlayerManager / MusicPlayer / Track — Music
Multi-guild music queue and player state manager.
from kroxy import MusicPlayerManager, Track, LoopMode
manager = MusicPlayerManager()
# Get or create a guild player
player = manager.get_or_create(
guild_id=GUILD_ID,
channel_id=VOICE_CHANNEL_ID,
text_channel_id=TEXT_CHANNEL_ID,
)
# Create a track
track = Track(
title="Song Name",
url="https://youtube.com/watch?v=...",
stream_url="https://audio.stream/url.mp3",
duration=240, # seconds
requester_id=USER_ID,
thumbnail="https://img.youtube.com/vi/.../0.jpg",
source="youtube",
)
# Queue
player.queue.add(track)
player.queue.add_next(track) # Play next
player.queue.shuffle()
player.queue.remove(index=0)
player.queue.move(from_index=2, to_index=0)
player.queue.clear()
len(player.queue) # queue size
player.queue.total_duration # seconds
player.queue.is_empty # True/False
# Playback
await player.play_next() # Play next track (respects loop)
await player.skip() # Skip current track
player.toggle_pause() # Returns new paused state (True/False)
player.set_volume(0.75) # 0.0 – 2.0
player.set_loop("track") # "none" | "track" | "queue"
player.stop() # Stop + clear queue
# State
player.current # Current Track or None
player.paused # True/False
player.volume # 0.0 – 2.0
player.position # Current position in seconds
player.loop_mode # LoopMode.NONE / TRACK / QUEUE
player.get_state() # Full state dict
# Events
async def now_playing(track, player):
print(f"Now playing: {track.title} [{track.duration_str}]")
async def queue_empty(guild_id):
print("Queue finished.")
player.on_track_start = now_playing
player.on_track_end = None
player.on_queue_empty = queue_empty
# Cleanup
manager.remove(guild_id=GUILD_ID)
SlashCommand / PrefixCommand — Command Builders
from kroxy import SlashCommand, PrefixCommand, Option, CommandRegistry
# Slash command
@SlashCommand.decorator(
name="warn",
description="Warn a member",
options=[
Option("user", "Target member", option_type="user", required=True),
Option("reason", "Reason", required=False),
],
permissions="8", # Administrator
)
async def warn(interaction, user, reason="No reason"):
...
# Prefix command with cooldown + aliases
@PrefixCommand.decorator(
name="ban",
aliases=["b", "yeet"],
description="Ban a member",
cooldown=5,
permissions=["ban_members"],
)
async def ban(ctx, member, *, reason="No reason"):
...
# Slash command export (for registering with Discord API)
warn.to_dict()
# Command registry
registry = CommandRegistry()
registry.add_slash(warn)
registry.add_prefix(ban)
registry.get_slash("warn")
registry.get_prefix("ban")
registry.get_prefix("b") # aliases work too
registry.all_slash()
registry.all_prefix()
Quick Start Example
import kroxy
async def main():
api = kroxy.DiscordAPI(token="Bot YOUR_TOKEN")
antinuke = kroxy.AntiNuke(whitelist=[OWNER_ID])
manager = kroxy.GiveawayManager()
player = kroxy.MusicPlayerManager().get_or_create(GUILD_ID)
embed = kroxy.Utils.build_embed(
title="Bot Ready",
description="kroxy is running.",
color=0x5865F2,
timestamp=True,
)
await api.send_message(LOG_CHANNEL_ID, embed=embed)
giveaway = await manager.create(
prize="Nitro",
host_id=HOST_ID,
channel_id=CHANNEL_ID,
guild_id=GUILD_ID,
duration=3600,
winner_count=1,
)
await api.close()
Requirements
- Python 3.9+
aiohttp >= 3.8.0
License
Proprietary — Copyright © 2026 kroxy. All rights reserved.
Unauthorized copying, redistribution, or modification of this software is strictly prohibited. Contact @kroxy for permissions.
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
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 kroxy-1.0.1.tar.gz.
File metadata
- Download URL: kroxy-1.0.1.tar.gz
- Upload date:
- Size: 22.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bbceb2911cf192527dbc4d00c62fbe5c9fc3ea79f46e1a836edfc076ce16b4f
|
|
| MD5 |
fa0e84b8fae58e21e584965f44929388
|
|
| BLAKE2b-256 |
2d4b0c6018be78e4ce2200c66961598a63f49ca15dc47c46af0e5b75f1fa9936
|
File details
Details for the file kroxy-1.0.1-py3-none-any.whl.
File metadata
- Download URL: kroxy-1.0.1-py3-none-any.whl
- Upload date:
- Size: 21.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2e03ca6a3017d9cf464deb7e4119cc50a51677b3dbe717f531c4758ae771305
|
|
| MD5 |
a5ed30b4ef200e4ecd25339fa6dec97c
|
|
| BLAKE2b-256 |
0209c54c396f8b05eaf1cc2add0eca7b1814c875c7d3edaccff57bce101faf48
|