An optional component handler for hikari, inspired by discord.py's views.

Overview

hikari-miru

An optional component handler for hikari, inspired by discord.py's views.

Installation

pip install git+https://github.com/HyperGH/hikari-miru.git

Usage

None: if event.is_bot or not event.content: return if event.content.startswith("hm.buttons"): view = MyView(bot, timeout=60) # Create a new view message = await event.message.respond("Rock Paper Scissors!", components=view.build()) view.start(message) # Start listening for interactions await view.wait() # Wait until the view times out or gets stopped await event.message.respond("Thank you for playing!") bot.run()">
import hikari
import hikari_miru as miru


class MyView(miru.View):

    @miru.button(label="Rock", emoji="🪨", style=hikari.ButtonStyle.PRIMARY)
    async def rock_button(self, button: miru.Button, interaction: hikari.ComponentInteraction):
        await interaction.create_initial_response(hikari.ResponseType.MESSAGE_CREATE, content=f"Paper!")

    @miru.button(label="Paper", emoji="📜", style=hikari.ButtonStyle.PRIMARY)
    async def paper_button(self, button: miru.Button, interaction: hikari.ComponentInteraction):
        await interaction.create_initial_response(hikari.ResponseType.MESSAGE_CREATE, content=f"Scissors!")

    @miru.button(label="Scissors", emoji="✂️", style=hikari.ButtonStyle.PRIMARY)
    async def scissors_button(self, button: miru.Button, interaction: hikari.ComponentInteraction):
        await interaction.create_initial_response(hikari.ResponseType.MESSAGE_CREATE, content=f"Rock!")

    @miru.button(emoji="⏹️", style=hikari.ButtonStyle.DANGER, row=2)
    async def stop_button(self, button: miru.Button, interaction: hikari.ComponentInteraction):
        await interaction.create_initial_response(hikari.ResponseType.DEFERRED_MESSAGE_UPDATE)
        self.stop() # Stop listening for interactions


bot = hikari.GatewayBot(token="...")


@bot.listen()
async def buttons(event: hikari.GuildMessageCreateEvent) -> None:

    if event.is_bot or not event.content:
        return

    if event.content.startswith("hm.buttons"):
        view = MyView(bot, timeout=60)  # Create a new view
        message = await event.message.respond("Rock Paper Scissors!", components=view.build())
        view.start(message)  # Start listening for interactions
        await view.wait() # Wait until the view times out or gets stopped
        await event.message.respond("Thank you for playing!")

bot.run()

Issues and support

For general usage help or questions, ping Hyper#0001 in the hikari discord, if you have found a bug or have a feature request, feel free to open an issue!

Contributing

If you wish to contribute, be sure to first enable the formatting pre-commit hook via git config core.hooksPath .githooks, then make your changes.

Comments
  • Components break in hikari 2.0.0.dev110

    Components break in hikari 2.0.0.dev110

    Steps to reproduce

    1. Upgrade to hikari 2.0.0.dev110
    2. Send a message with any components
    3. Try to use said components
    4. Observe the components failing

    Expected result

    The bot should've responded to the component interaction.

    Actual result

    The bot didn't respond to any component interactions.

    System information

    hikari-miru - package information
    ----------------------------------
    Miru version: 1.1.1
    Install path: /root/venv/lib/python3.10/site-packages/miru
    Hikari version: 2.0.0.dev110
    Install path: /root/venv/lib/python3.10/site-packages/hikari
    Python: CPython 3.10.5 (GCC 12.1.0)
    System: Linux x86_64 (solar) - 5.18.16-arch1-1
    

    Further information

    No response

    Checklist

    • [X] I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
    • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.
    bug 
    opened by piotr25691 6
  • Allow customization of item and context classes

    Allow customization of item and context classes

    Wake up babe new pr just dropped

    import miru
    
    
    
    class MyButton(miru.Button):
        ...
    
    class MyContext(miru.Context):
        ...
    
    class MyView(miru.View):
        @miru.button(cls=MyButton, context_cls=MyContext, label="label")
        async def foo(self, button: MyButton, context: MyContext):
            ...
        
        @miru.button(label="label")
        async def bar(self, button: MyButton, context: MyContext):
            ...
    
    view = MyView()
    
    enhancement 
    opened by thesadru 4
  • Persistant components between bot restarts

    Persistant components between bot restarts

    Summary

    Miru should replace the current component persistence system to one thats easier to work with/possibly more efficient. I believe a side effect of my implementation will also allow custom timeout responses for buttons.

    Why is this needed?

    I think it is good if bots can still respond to a button after a restart.

    Ideal implementation

    # Internal
    class ComponentInfo:
        """Info used to distinguish miru components from each other."""
        ....
    
    # External
    # The user is expected to implement these functions if they want to use persistence between restarts.
    
    # Called when a component is created
    @miru.persistence.save_component
    async def save(nonce: str, component: miru.ComponentInfo) -> None:
        """Save a ComponentInfo object"""
        ...
    
    # Called when a component nonce is received that isn't in the cachce
    @miru.persistence.load_component
    async def load(nonce: str) -> miru.ComponentInfo | None:
        """Load a ComponentInfo object. Return `None` if the object doesn't exist."""
        ...
    
    # Called when 
    @miru.persistence.delete_component
    async def load(nonce: str) -> None:
        """Delete a component with a specific nonce."""
        ...
    

    The internals will need to be reworked is have "registry/cache" with all the components. The nonce will be used to run the correct callback. This is similar to how crescent works so I can vouch for the system.

    Checklist

    • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.
    enhancement 
    opened by Lunarmagpie 3
  • Change autodefer to auto_defer

    Change autodefer to auto_defer

    This is more of a suggestion, but it might make consistency between different handlers and libs for Hikari more consistent if these references were changed.

    opened by GoogleGenius 1
  • link buttons cannot be added

    link buttons cannot be added

    When I try to add link buttons with the following code, an error is raised and it doesn't work.

    view = miru.View()
    view.add_item(miru.Button(label="View Online", url=str(ctx.options.user.display_avatar_url)))
    return await ctx.respond(e, components=view.build())
    

    The issue lies in https://github.com/HyperGH/hikari-miru/blob/main/miru/button.py#L127 and causes a following error:

    Traceback (most recent call last):
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\app.py", line 994, in handle_message_create_for_prefix_commands
        await self.process_prefix_commands(context)
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\app.py", line 966, in process_prefix_commands
        await context.invoke()
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\context\base.py", line 292, in invoke
        await self.command.invoke(self)
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\commands\prefix.py", line 112, in invoke
        await self(context)
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\commands\base.py", line 435, in __call__
        return await self.callback(context)
      File "D:\Coding\Iodine\cogs\tools.py", line 41, in avatar
        view.add_item(miru.Button(label="View Online", url=str(ctx.options.user.display_avatar_url)))
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\miru\button.py", line 109, in __init__
        self.style = hikari.ButtonStyle.LINK
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\miru\button.py", line 128, in style
        raise ValueError("A link button cannot have it's style changed. Remove the url first.")
    ValueError: A link button cannot have it's style changed. Remove the url first.
    
    bug 
    opened by piotr25691 1
  • Fix typing issues in miru

    Fix typing issues in miru

    Some internal changes had to be made to make miru type-safe

    Changes

    • make items generic (item.view can now be given attributes)
    • make @button and @select be typed to return the same function that was given
      • A possible alternative is returning the actual type, happy to hear your opinions on this one!
    • added all missing typing.Any and None annotations where they were forgotten
    opened by thesadru 1
  • Add readme files to subdirectories

    Add readme files to subdirectories

    Summary

    Add readme files to most important subdirectories with short explainers detailing what can be found in the directory & directing users to helpful resources.

    Why is this needed?

    Because it is fancy.

    Ideal implementation

    Sit down and write them.

    Checklist

    • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.
    enhancement 
    opened by HyperGH 0
  • Fix a few bugs and inconsistencies

    Fix a few bugs and inconsistencies

    See changelog.

    • no longer use explicit submodules unless they're exported
    • no longer use pass where it's not needed
    • ignore when 3rd party libraries are missing stubs
    • for the sake of user experience assume the class is initialized when annotating
    • make the colorama dependency optional (gawd the dependency management is funky)
    • allow for unloading miru and stopping all views
    enhancement 
    opened by thesadru 0
  • Add colorama to requirements

    Add colorama to requirements

    I install hikari-miru and did python3 -m miru and it said no package named colorama, after installing, it worked fine but it didn't install with hikari-miru, so I suggest adding it as a requirement

    bug 
    opened by VG08 0
  • Add exercises to documentation

    Add exercises to documentation

    Summary

    Add short exercises to documentation to facilitate learning the different features of the library.

    Why is this needed?

    It helps people learn the library a lot quicker if there are potentially quick example problems to solve.

    Ideal implementation

    To be decided.

    Checklist

    • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.
    enhancement 
    opened by HyperGH 0
Releases(v2.0.1)
  • v2.0.1(Dec 6, 2022)

  • v2.0.0(Dec 5, 2022)

    • BREAKING: View.start() is now asynchronous and needs to be awaited.

    • BREAKING: View.start_listener() has been removed. Use View.start() instead.

    • Added support for modals via miru.Modal.

    • Added support for text input fields via miru.TextInput.

    • Added RawComponentContext, RawModalContext, ViewContext, and ModalContext that inherit from Context.

    • Added miru.InteractionResponse, an object representing responses sent out by the application to interactions.

    • Context.respond() and Context.edit_response() now return an InteractionResponse object.

    • Added Context.bot and Context.author as aliases for Context.app and Context.user respectively.

    • Added overloads to Context.defer() to allow use of different deffered response-types.

    • Added miru.abc.ViewItem and miru.abc.ModalItem that inherit from miru.abc.Item.

    • Views now expect items of type ViewItem and provide ViewContext.

    • Button and Select are now subclasses of ViewItem.

    • Added miru.abc.ItemHandler. View and Modal are subclasses of this object.

    • Added miru.abc.ItemHandler.last_context to access the last received context & interaction by the item handler.

    • miru.abc.ItemHandler now implements Sequence[hikari.api.MessageActionRowBuilder], and thus can be treated as a sequence of action rows. This means that calling .build() on item handlers is no longer required.

    • Removed miru.Interaction.

    • Added View.from_message() classmethod to allow creation of views from message components.

    • Added View.wait_for_input() to wait for any component interaction relating to the view.

    • Added timeout parameter to ItemHandler.wait().

    • Added View.get_context() and Modal.get_context() for custom context support.

    • Added two new event types ModalInteractionCreateEvent and ComponentInteractionCreateEvent.

    • These listeners include the corresponding raw context with the event object, along with every field from hikari.InteractionCreateEvent.

    • ItemHandler.add_item(), ItemHandler.remove_item(), and ItemHandler.clear_items() now return the ItemHandler object to allow for method chaining.

    • Added responded kwarg to NavigatorView to have the ability to send navigators on acknowledged interactions.

    • Added start_at kwarg to NavigatorView to define what the first page should be.

    • Added a “Jump to page” modal to built-in ext.nav.IndicatorButton when pressed.

    • Allow passing datetime.timedelta to ItemHandler.timeout upon instantiation.

    • Add delete_after to Context.respond() as a kwarg, and as a method to InteractionResponse.

    • Added miru.ext.nav.utils.Paginator to help pagination of long strings.

    • View.start() now accepts awaitables that return hikari.Message, thus allowing it to function with custom objects that support this behaviour.

    • Fixed selectoption is_default fields being ignored.

    • Deprecate miru.load and miru.unload in favor of miru.install and miru.uninstall.

    Source code(tar.gz)
    Source code(zip)
A log likelihood fit for extracting neutrino oscillation parameters

A-log-likelihood-fit-for-extracting-neutrino-oscillation-parameters Minimised the negative log-likelihood fit to extract neutrino oscillation paramete

Vid Homsak 1 Jan 23, 2022
A PG3D API Made with Python

PG3D Python API A Pixel Gun 3D Python API (Public Ver) Features Count: 29 How To Use? import api as pbn Examples pbn.isBanned(192819483) - True pbn.f

Karim 2 Mar 24, 2022
Gmvault: Backup and restore your gmail account

Gmvault: Backup and restore your gmail account Gmvault is a tool for backing up your gmail account and never lose email correspondence. Gmvault is ope

Guillaume Aubert 3.5k Jan 01, 2023
BlueBorne Dockerized

BlueBorne Dockerized This is the repo to reproduce the BlueBorne kill-chain on Dockerized Android as described here, to fully understand the code you

SecSI 5 Sep 14, 2022
The third home of the bare Programming Language (1st there's my heart, the forest came second and then there's Github :)

The third home of the bare Programming Language (1st there's my heart, the forest came second and then there's Github :)

Garren Souza 7 Dec 24, 2022
Set of scripts that schedules employees for shifts throughout the week based on availability, shift times, and shift necessities

Automatic-Scheduler Set of scripts that schedules employees for shifts throughout the week based on availability, shift times, and shift necessities *

Matthew 1 May 01, 2022
Headless - Wrapper around Ghidra's analyzeHeadless script

Wrapper around Ghidra's analyzeHeadless script, could be helpful to some? Don't tell me anything is wrong with it, it works on my machine.

8 Oct 29, 2022
Run-Your-Own Firefox Sync Server

Run-Your-Own Firefox Sync Server This is an all-in-one package for running a self-hosted Firefox Sync server. It bundles the "tokenserver" project for

Mozilla Services 1.7k Dec 30, 2022
Today I Commit (1일 1커밋) 챌린지 알림 봇

Today I Commit Challenge 1일1커밋 챌린지를 위한 알림 봇 config.py github_token = "github private access key" slack_token = "slack authorization token" channel = "

sunho 4 Nov 08, 2021
A notebook explaining the principle of adversarial attacks and their defences

TL;DR: A notebook explaining the principle of adversarial attacks and their defences Abstract: Deep neural networks models have been wildly successful

1 Jan 22, 2022
This repo holds custom callback plugin, so your Ansible could write everything in the PostgreSQL database.

English What is it? This is callback plugin that dumps most of the Ansible internal state to the external PostgreSQL database. What is this for? If yo

Sergey Pechenko 19 Oct 21, 2022
This is a Python program I wrote to simulate the solar system with 79 lines of code.

Solar System With Python This is a Python program I wrote to simulate the solar system with 79 lines of code. Required modules tkinter, math, time Why

Mehmet Aydoğmuş 1 Oct 26, 2021
Replite - An embeddable REPL powered by JupyterLite

replite An embeddable REPL, powered by JupyterLite. Usage To embed the code cons

Jeremy Tuloup 47 Nov 09, 2022
A fast python implementation of DTU MVS 2014 evaluation

DTUeval-python A python implementation of DTU MVS 2014 evaluation. It only takes 1min for each mesh evaluation. And the gap between the two implementa

82 Dec 27, 2022
a simple proof system I made to learn math without any mistakes

math_up a simple proof system I made to learn math without any mistakes 0. Short Introduction test yourself, enjoy your math! math_up is an NBG-based,

양현우 5 Jun 04, 2021
The best free and open-source automated time tracker. Cross-platform, extensible, privacy-focused.

Records what you do so that you can know how you've spent your time. All in a secure way where you control the data. Website — Forum — Documentation —

ActivityWatch 7.8k Jan 09, 2023
Mpis-ex7 - Implementation of tasks 1, 2, 3 for Metody Probabilistyczne i Statystyka Lista 7

Implementations of task 1, 2 and 3 from here Author: Maciej Bazela Index: 261743 Each task was implemented in Python 3. I've used Cython to speed up e

Maciej Bazela 1 Feb 27, 2022
Adversarial Robustness with Non-uniform Perturbations

Adversarial Robustness with Non-uniform Perturbations This repository hosts the code to replicate experiments of the paper Adversarial Robustness with

5 May 20, 2022
This is a a CSMA/CA simulator written in Python based on simulator of the same type

This is a a CSMA/CA simulator written in Python based on simulator of the same type found the link https://github.com/StevenSLXie/CSMA-Simulator with

M. Ismail 4 Nov 22, 2022
KUIZ is a web application quiz where you can create/take a quiz for learning and sharing knowledge from various subjects, questions and answers.

KUIZ KUIZ is a web application quiz where you can create/take a quiz for learning and sharing knowledge from various subjects, questions and answers.

Thanatibordee Sihaboonthong 3 Sep 12, 2022