hikari-atsume


Namehikari-atsume JSON
Version 0.5.1 PyPI version JSON
download
home_pagehttps://github.com/pmdevita/hikari-atsume
SummaryAn opinionated, Django-like Discord bot framework for Hikari, Tanjun, and Ormar
upload_time2023-11-29 21:23:14
maintainer
docs_urlNone
authorPeter DeVita
requires_python>=3.10,<3.12
licenseMIT
keywords hikari discord ormar tanjun framework
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # hikari-atsume

[![ci](https://github.com/pmdevita/hikari-atsume/actions/workflows/ci.yml/badge.svg)](https://github.com/pmdevita/hikari-atsume/actions/workflows/ci.yml)
[![docs](https://github.com/pmdevita/hikari-atsume/actions/workflows/docs.yml/badge.svg)](https://pmdevita.github.io/hikari-atsume/)
![mypy](https://badgen.net/badge/mypy/checked/2A6DB2)
![code-style-black](https://img.shields.io/badge/code%20style-black-black)


[Documentation](https://pmdevita.github.io/hikari-atsume/)

An opinionated Discord bot framework inspired by Django and built on 
top of [Hikari](https://github.com/hikari-py/hikari), [Tanjun](https://github.com/FasterSpeeding/Tanjun), 
[Ormar](https://github.com/collerek/ormar), and [Alembic](https://alembic.sqlalchemy.org/en/latest/).

Atsume is in alpha and breaking changes should be expected. If you have any feedback or advice, feel free 
to find me in the [Hikari Discord](https://discord.gg/Jx4cNGG).


## Features

- Automatic project scaffolding/file-based organization
- Configuration instead of boilerplate
- Functionality split into modular, independent components
- Automatically restart the bot on changes during development
- Configure which components run in which servers
- Database ORM with Ormar
- Automatic database migrations with Alembic

## Quick Start

### Installation

Create a new project directory and install hikari-atsume 
(make sure you are using Python 3.10+. If you are using Poetry, 
your Python dependency should be `python = "^3.10,<3.12"`)

```shell
# Install with your preferred database backend, SQLite recommended for beginners

pip install hikari-atsume[sqlite]

pip install hikari-atsume[mysql]

pip install hikari-atsume[postgresql]
```

### Start a new project

Now to start your new project, run 

```shell
atsume startproject my_bot
```

which should generate some files for your project. In `my_bot/local.py`, add your
Discord bot token in. If you want to use message commands, make sure to set your 
`MESSAGE_PREFIX` and add `hikari.Intents.MESSAGE_CONTENT` to your `INTENTS`.

```python
# my_bot/settings.py

INTENTS = hikari.Intents.ALL_UNPRIVILEGED | hikari.Intents.MESSAGE_CONTENT
```

### Start a component

In your project directory run

```shell
python manage.py startapp basic
```
which should generate a new directory called `basic`.

In `basic/commands.py`, write your commands using [Tanjun](https://tanjun.cursed.solutions/usage/#declaring-commands).
Commands are declared without explicitly attaching to a Component object 
(Atsume takes care of that using `load_from_scope`).

This is an example of a hybrid slash/message command that takes one 
optional positional argument, the user to say hi to.

```python
# basic/commands.py

@tanjun.annotations.with_annotated_args(follow_wrapped=True)
@tanjun.as_message_command("hi", "hello", "hey", "howdy")
@tanjun.as_slash_command("hi", "The bot says hi.")
async def hello(
    ctx: atsume.Context,
    member: Annotated[Optional[Member], "The user to say hi to.", Positional()] = None,
) -> None:
    member = member if member else ctx.member
    if member:
        await ctx.respond(f"Hi {member.display_name}!")
```

Now with our new component ready, register it in the bot's settings.

```python
# my_bot/settings.py

COMPONENTS = [
  "basic"
]

```

### Working with the database

Let's say we want to track how many times each member of a guild has said 
hi to the bot. In our `models.py` file, let's create a new database model 
to keep track of this. Atsume uses [Ormar](https://collerek.github.io/ormar/)
for its database models and queries.

```python
# basic/models.py
from atsume.db import Model
import ormar

class HiCounter(Model):
  user: int = ormar.BigInteger(primary_key=True)  # Discord User IDs need to be stored as big integers
  count: int = ormar.Integer(default=0)

```

Now in our `commands.py`, let's increment a user's count every time they say hi.

```python
# basic/models.py

# Skipping the decorators
async def hello(
    ctx: atsume.Context,
    member: Annotated[Optional[Member], "The user to say hi to.", Positional()] = None,
) -> None:
    member = member if member else ctx.member
    if member:
        count_model, _ = await HiCounter.objects.get_or_create(user=member.user.id, _defaults={"count": 0})
        count_model.count = count_model.count + 1
        await count_model.upsert()
        await ctx.respond(f"Hi {member.display_name}! (You've said hi {count_model.count} time[s]!)")
```

### Migrating the database

Before we run this though, we need to add our HiCounter model to the database! To do this, 
we can generate a database migration that will migrate the database from it's current 
state (nothing) to the state we want (a database with a table for HiCounter). Atsume 
can generate migrations automatically in most cases so we'll use it's tool for that here.

Run this command to generate migrations.

```shell
python manage.py makemigrations
```

You should see something like

```
Migrating ComponentConfig(name"basic")...
  Create model hicounter...
```

Once that's done, your migration is ready to go! Run it on the database with 

```shell
python manage.py upgrade
```

#### Note about Atsume Migrations

Atsume's migrations are still very much a work in progress (you can track it 
[here](https://github.com/pmdevita/hikari-atsume/issues/2)).
As a general rule of thumb, Atsume is good at migrations that create and delete 
models and fields, but currently struggles with renames. You can always review 
a migration and make any needed changes by looking in the component's 
generated migration folder. Atsume uses 
[Alembic](https://alembic.sqlalchemy.org/en/latest/) 
for migrations, so you can look at the 
[Alembic operations docs](https://alembic.sqlalchemy.org/en/latest/ops.html#alembic.operations.Operations)
to figure out how to write migrations manually.


### Run the bot

Finally, with the bot configured and our component's commands and models ready , 
it's time to run it!


```shell
python manage.py run
```

![docs/img/hi_bot.png](./docs/img/hi_bot.png)

## Special thanks to
- The Hikari Discord for help and feedback
- FasterSpeeding for [Tanjun](https://github.com/FasterSpeeding/Tanjun)
- Lunarmagpie for help with the CI and linting
- The [Django](https://www.djangoproject.com/) and [django-stubs](https://github.com/typeddjango/django-stubs) projects for their amazing work and some 
code that I borrowed.



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/pmdevita/hikari-atsume",
    "name": "hikari-atsume",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.10,<3.12",
    "maintainer_email": "",
    "keywords": "hikari,discord,ormar,tanjun,framework",
    "author": "Peter DeVita",
    "author_email": "mewtwo2643@yahoo.com",
    "download_url": "https://files.pythonhosted.org/packages/60/38/daf016ffa74d85105fe6137475dba2392c4d8b4eff21431943a40aa9f713/hikari_atsume-0.5.1.tar.gz",
    "platform": null,
    "description": "# hikari-atsume\n\n[![ci](https://github.com/pmdevita/hikari-atsume/actions/workflows/ci.yml/badge.svg)](https://github.com/pmdevita/hikari-atsume/actions/workflows/ci.yml)\n[![docs](https://github.com/pmdevita/hikari-atsume/actions/workflows/docs.yml/badge.svg)](https://pmdevita.github.io/hikari-atsume/)\n![mypy](https://badgen.net/badge/mypy/checked/2A6DB2)\n![code-style-black](https://img.shields.io/badge/code%20style-black-black)\n\n\n[Documentation](https://pmdevita.github.io/hikari-atsume/)\n\nAn opinionated Discord bot framework inspired by Django and built on \ntop of [Hikari](https://github.com/hikari-py/hikari), [Tanjun](https://github.com/FasterSpeeding/Tanjun), \n[Ormar](https://github.com/collerek/ormar), and [Alembic](https://alembic.sqlalchemy.org/en/latest/).\n\nAtsume is in alpha and breaking changes should be expected. If you have any feedback or advice, feel free \nto find me in the [Hikari Discord](https://discord.gg/Jx4cNGG).\n\n\n## Features\n\n- Automatic project scaffolding/file-based organization\n- Configuration instead of boilerplate\n- Functionality split into modular, independent components\n- Automatically restart the bot on changes during development\n- Configure which components run in which servers\n- Database ORM with Ormar\n- Automatic database migrations with Alembic\n\n## Quick Start\n\n### Installation\n\nCreate a new project directory and install hikari-atsume \n(make sure you are using Python 3.10+. If you are using Poetry, \nyour Python dependency should be `python = \"^3.10,<3.12\"`)\n\n```shell\n# Install with your preferred database backend, SQLite recommended for beginners\n\npip install hikari-atsume[sqlite]\n\npip install hikari-atsume[mysql]\n\npip install hikari-atsume[postgresql]\n```\n\n### Start a new project\n\nNow to start your new project, run \n\n```shell\natsume startproject my_bot\n```\n\nwhich should generate some files for your project. In `my_bot/local.py`, add your\nDiscord bot token in. If you want to use message commands, make sure to set your \n`MESSAGE_PREFIX` and add `hikari.Intents.MESSAGE_CONTENT` to your `INTENTS`.\n\n```python\n# my_bot/settings.py\n\nINTENTS = hikari.Intents.ALL_UNPRIVILEGED | hikari.Intents.MESSAGE_CONTENT\n```\n\n### Start a component\n\nIn your project directory run\n\n```shell\npython manage.py startapp basic\n```\nwhich should generate a new directory called `basic`.\n\nIn `basic/commands.py`, write your commands using [Tanjun](https://tanjun.cursed.solutions/usage/#declaring-commands).\nCommands are declared without explicitly attaching to a Component object \n(Atsume takes care of that using `load_from_scope`).\n\nThis is an example of a hybrid slash/message command that takes one \noptional positional argument, the user to say hi to.\n\n```python\n# basic/commands.py\n\n@tanjun.annotations.with_annotated_args(follow_wrapped=True)\n@tanjun.as_message_command(\"hi\", \"hello\", \"hey\", \"howdy\")\n@tanjun.as_slash_command(\"hi\", \"The bot says hi.\")\nasync def hello(\n    ctx: atsume.Context,\n    member: Annotated[Optional[Member], \"The user to say hi to.\", Positional()] = None,\n) -> None:\n    member = member if member else ctx.member\n    if member:\n        await ctx.respond(f\"Hi {member.display_name}!\")\n```\n\nNow with our new component ready, register it in the bot's settings.\n\n```python\n# my_bot/settings.py\n\nCOMPONENTS = [\n  \"basic\"\n]\n\n```\n\n### Working with the database\n\nLet's say we want to track how many times each member of a guild has said \nhi to the bot. In our `models.py` file, let's create a new database model \nto keep track of this. Atsume uses [Ormar](https://collerek.github.io/ormar/)\nfor its database models and queries.\n\n```python\n# basic/models.py\nfrom atsume.db import Model\nimport ormar\n\nclass HiCounter(Model):\n  user: int = ormar.BigInteger(primary_key=True)  # Discord User IDs need to be stored as big integers\n  count: int = ormar.Integer(default=0)\n\n```\n\nNow in our `commands.py`, let's increment a user's count every time they say hi.\n\n```python\n# basic/models.py\n\n# Skipping the decorators\nasync def hello(\n    ctx: atsume.Context,\n    member: Annotated[Optional[Member], \"The user to say hi to.\", Positional()] = None,\n) -> None:\n    member = member if member else ctx.member\n    if member:\n        count_model, _ = await HiCounter.objects.get_or_create(user=member.user.id, _defaults={\"count\": 0})\n        count_model.count = count_model.count + 1\n        await count_model.upsert()\n        await ctx.respond(f\"Hi {member.display_name}! (You've said hi {count_model.count} time[s]!)\")\n```\n\n### Migrating the database\n\nBefore we run this though, we need to add our HiCounter model to the database! To do this, \nwe can generate a database migration that will migrate the database from it's current \nstate (nothing) to the state we want (a database with a table for HiCounter). Atsume \ncan generate migrations automatically in most cases so we'll use it's tool for that here.\n\nRun this command to generate migrations.\n\n```shell\npython manage.py makemigrations\n```\n\nYou should see something like\n\n```\nMigrating ComponentConfig(name\"basic\")...\n  Create model hicounter...\n```\n\nOnce that's done, your migration is ready to go! Run it on the database with \n\n```shell\npython manage.py upgrade\n```\n\n#### Note about Atsume Migrations\n\nAtsume's migrations are still very much a work in progress (you can track it \n[here](https://github.com/pmdevita/hikari-atsume/issues/2)).\nAs a general rule of thumb, Atsume is good at migrations that create and delete \nmodels and fields, but currently struggles with renames. You can always review \na migration and make any needed changes by looking in the component's \ngenerated migration folder. Atsume uses \n[Alembic](https://alembic.sqlalchemy.org/en/latest/) \nfor migrations, so you can look at the \n[Alembic operations docs](https://alembic.sqlalchemy.org/en/latest/ops.html#alembic.operations.Operations)\nto figure out how to write migrations manually.\n\n\n### Run the bot\n\nFinally, with the bot configured and our component's commands and models ready , \nit's time to run it!\n\n\n```shell\npython manage.py run\n```\n\n![docs/img/hi_bot.png](./docs/img/hi_bot.png)\n\n## Special thanks to\n- The Hikari Discord for help and feedback\n- FasterSpeeding for [Tanjun](https://github.com/FasterSpeeding/Tanjun)\n- Lunarmagpie for help with the CI and linting\n- The [Django](https://www.djangoproject.com/) and [django-stubs](https://github.com/typeddjango/django-stubs) projects for their amazing work and some \ncode that I borrowed.\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "An opinionated, Django-like Discord bot framework for Hikari, Tanjun, and Ormar",
    "version": "0.5.1",
    "project_urls": {
        "Documentation": "https://pmdevita.github.io/hikari-atsume/",
        "Homepage": "https://github.com/pmdevita/hikari-atsume",
        "Repository": "https://github.com/pmdevita/hikari-atsume"
    },
    "split_keywords": [
        "hikari",
        "discord",
        "ormar",
        "tanjun",
        "framework"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fed99cbbe8e9b6197bc65fcfb586eb6c0f9762ae23e87a85aeccff0b42d95c95",
                "md5": "4ab0098ad03529a3ad9b9fe620b3ca4f",
                "sha256": "f556d80f61eb5249afd26fe313caac4a477d76df58507bd99394da909f424c24"
            },
            "downloads": -1,
            "filename": "hikari_atsume-0.5.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "4ab0098ad03529a3ad9b9fe620b3ca4f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10,<3.12",
            "size": 40759,
            "upload_time": "2023-11-29T21:23:13",
            "upload_time_iso_8601": "2023-11-29T21:23:13.208184Z",
            "url": "https://files.pythonhosted.org/packages/fe/d9/9cbbe8e9b6197bc65fcfb586eb6c0f9762ae23e87a85aeccff0b42d95c95/hikari_atsume-0.5.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6038daf016ffa74d85105fe6137475dba2392c4d8b4eff21431943a40aa9f713",
                "md5": "629a16e33a891737d5f18c7990022c24",
                "sha256": "17b1a1d9dbaac9a94d76c7775f19ba524e2786f54c0de6f4e0d42759af970c20"
            },
            "downloads": -1,
            "filename": "hikari_atsume-0.5.1.tar.gz",
            "has_sig": false,
            "md5_digest": "629a16e33a891737d5f18c7990022c24",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10,<3.12",
            "size": 30123,
            "upload_time": "2023-11-29T21:23:14",
            "upload_time_iso_8601": "2023-11-29T21:23:14.647228Z",
            "url": "https://files.pythonhosted.org/packages/60/38/daf016ffa74d85105fe6137475dba2392c4d8b4eff21431943a40aa9f713/hikari_atsume-0.5.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-29 21:23:14",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "pmdevita",
    "github_project": "hikari-atsume",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "hikari-atsume"
}
        
Elapsed time: 0.15731s