Giter VIP home page Giter VIP logo

nextcore's Introduction

Nextcore

A low level Discord API wrapper.

โœจ Features

  • Speed

    We try to make the library as fast as possible, without compromising on readability of the code or features.

    speed-showcase.mp4
  • Modularity

    All the components can easily be swapped out with your own.

  • Control

    Nextcore offers fine-grained control over things most libraries don't support.

    This currently includes:

    • Setting priority for individual requests
    • Swapping out components

Examples

๐Ÿ“ Ping pong

A simple "ping pong" example in nextcore. This will respond with "pong" each time someone sends "ping" in the chat.

import asyncio
from os import environ
from typing import cast

from discord_typings import MessageData

from nextcore.gateway import ShardManager
from nextcore.http import BotAuthentication, HTTPClient, Route

# Constants
AUTHENTICATION = BotAuthentication(environ["TOKEN"])

# Intents are a way to select what intents Discord should send to you.
# For a list of intents see https://discord.dev/topics/gateway#gateway-intents
GUILD_MESSAGES_INTENT = 1 << 9
MESSAGE_CONTENT_INTENT = 1 << 15

INTENTS = GUILD_MESSAGES_INTENT | MESSAGE_CONTENT_INTENT  # Guild messages and message content intents.


# Create a HTTPClient and a ShardManager.
# A ShardManager is just a neat wrapper around Shard objects.
http_client = HTTPClient()
shard_manager = ShardManager(AUTHENTICATION, INTENTS, http_client)


@shard_manager.event_dispatcher.listen("MESSAGE_CREATE")
async def on_message(message: MessageData):
    # This function will be called every time a message is sent.
    if message["content"] == "ping":
        # Send a pong message to respond.
        route = Route("POST", "/channels/{channel_id}/messages", channel_id=message["channel_id"])

        await http_client.request(
            route,
            rate_limit_key=AUTHENTICATION.rate_limit_key,
            json={"content": "pong"},
            headers=AUTHENTICATION.headers,
        )


async def main():
    await http_client.setup()

    # This should return once all shards have started to connect.
    # This does not mean they are connected.
    await shard_manager.connect()

    # Raise a error and exit whenever a critical error occurs
    (error,) = await shard_manager.dispatcher.wait_for(lambda: True, "critical")

    raise cast(Exception, error)


asyncio.run(main())

More examples can be seen in the examples directory.


Contributing

Want to help us out? Please read our contributing docs.

nextcore's People

Contributors

leshaka avatar maskduck avatar ooliver1 avatar tag-epic avatar thegoldenpro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

nextcore's Issues

Add package metadata

PyPi classifiers needs to be added and the project description needs to be updated

Document private functions

While this will not show up in sphinx, this will make understanding what every method does a lot easier

Retry after header missing

Traceback:

Task exception was never retrieved
future: <Task finished name='Task-1093' coro=<HTTPClient.create_message() done, defined at /home/epic/development/pycord/nextcore/nextcore/http/client.py:1104> exception=KeyError('X-RateLimit-Retry-After')>
Traceback (most recent call last):
  File "/home/epic/development/pycord/nextcore/nextcore/http/client.py", line 1220, in create_message
    r = await self._request(
  File "/home/epic/development/pycord/nextcore/nextcore/http/client.py", line 315, in _request
    response.headers["X-RateLimit-Retry-After"],
KeyError: 'X-RateLimit-Retry-After'

Route.bucket changes based on the process

Note: this only happens when python is in debug mode (pass -O to it)

# Expected
route = Route("GET", "/gateway")
route.bucket # asdf

## new process
route.bucket # asdf

# Actual results
route = Route("GET", "/gateway")
route.bucket # asdf

## new process
route.bucket # hfgs

Add clustering support

Currently only one process is supported by most components. This should be changed.

This requires a rate-limiting rewrite, as most the things we currently do is not easily translated.

Also doing everything with websockets seems really painful, is something like redis a good idea? Or is that something we won't use in nextcore

Verify payloads from the discord api (locked behind `__debug__`)

Discord is unreliable with it's changes, and bugs occur.

This should validate all data received from discord to make sure that it is in the correct format.

This would probably need some collaboration with discord_typings to add some typing.Annotated to mark which fields should not be checked (enums for example!)

Use typing.LiteralString for path in Route

This will stop you from accidentally using a f-string or .format

This will unfortunately stop you from loading it via a non-literal, however the use case for that is tiny (and at that point just use a type: ignore comment)

(HTTP) Global ratelimiting not bulking

The global ratelimit seems to spread unloading requests over a few attempts. This should not happen!

Logs: https://paste.nextcord.dev/?id=1654463289134659
Code to reproduce:

    route = Route("POST", "/guilds/{guild_id}/channels", guild_id=message["guild_id"])
    data = {"name": "hmoment", "type": 0}
    results = await gather(
        *[
            http._request(
                route,
                json=data,
                ratelimit_key=authentication.rate_limit_key,
                headers={"Authorization": str(authentication)},
            )
            for _ in range(50)
        ]
    )

    pending = []
    for result in results:
        data = await result.json()
        route = Route("DELETE", "/channels/{channel_id}", channel_id=data["id"])

        pending.append(
            create_task(http._request(
                route, ratelimit_key=authentication.rate_limit_key, headers={"Authorization": str(authentication)}
            ))
        )

    await gather(*pending)
    await http.create_message(authentication, message["channel_id"], content="Done")

Migrate to erlpack instead of json??

erlpack was more efficient last I checked, however it would require significant changes and should be done as early as possible.

WIll also make debugging harder, and erlpack is just a lot more painful to deal with too.

Add scoped priority

This will require some extra thoughts to handle low global priority but high scoped priority

(HTTP) Add a priority queue

Some users may want to change the priority of when their requests get executed.

Concept usage:

await http.create_message(..., global_priority=5, bucket_priority=2)

Add raises to all method docstrings

Theres been some progress for http wrappers, however a lot is missing.

common is missing it for the most part

not quite sure about gateway

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.