Package: hmus
Hummus.py (aka hmus)This is an asynchronous wrapper currently in version 0.5.1!Hmus is the mirror package toHummus.py, because the name to install that ishummus2016.py, so to shorten it, hmus exists as a mirror package.Why "hmus"? It is in reference tohttps://hmus.sys42.net, Ziad87's (owner of Hummus) mirror site toHummus.InstallationYou can dopip install hummus2016.pyto install Hummus.py as a package, or you can import it manually by downloading the files atthe GitLab repositoryGetting startedYou can use the following code in the main file to connect to Hummus:importhummusfromhummusimportClientimportasyncioclassCommands(Client):asyncdeftest(self,ctx:hummus.Message):print(ctx.content)awaitctx.reply(f"<@{ctx.author.id}> activated test!")Client=Commands(prefix="!",bottoken="INSERT TOKEN HERE",status="online",game="!test")asyncio.run(Client.RUN())Adding new commands is as simple as creating new functions under theCommandsclass. No need for decorators, just because. Adding custom arguments is as simple as adding parameters in a function, as seen below (remember: In every function, you must have theselfandctxargs!):classCommands(Client):asyncdeftest(self,ctx:hummus.Message,test=None):#extra "test" argprint(test)print(ctx.content)awaitctx.reply(f"{ctx.author.mention}activated test! Arg 1:{test}")#you can also do "<@{ctx.author.id}>" if you wantYou can make these parameters have annotations (test: strormention: hummus.User) or have default values (test=None).ArgumentsThere are 2 ways to have arguments in a Hummus.py command:Add extra arguments to your functionUse.split(" ")to split words in a command into different items on a listCustom arguments in a function will function differently than using.split(" "). The argument system looks for quotation marks in a message, and if there is text within quotation marks, no matter if there are spaces, the entire text (within the quotations!) will be considered as asingleargument. This allows for easier usage of commands like!nicknamewhere you can specify a nickname with spaces, as long as the nickname is within quotation marks.Quotation marks are not necessary for arguments with no spaces!UsageCommandsHummus.py is in development, so it will not have all the functions existing. Also, please note that the Hummus API itself is unfinished and is missing endpoints, so I cannot have every function either.Here's an example on how to use thectx.getUser()function where you can get any user with their ID:Without parameter and annotation:classCommands(Client):asyncdefavatar(self,ctx:hummus.Message):iflen(ctx.mentions)>0:member=ctx.getUser(ctx.mentions[0].id)awaitctx.reply(member.avatar.url)else:awaitctx.reply(ctx.author.avatar.url)With parameter and annotation:classCommands(Client):asyncdefavatar(self,ctx:hummus.Message,mention:hummus.User=None):ifmention:#"None" is equivalent to "False"awaitctx.reply(mention.avatar.url)else:awaitctx.reply(ctx.author.avatar.url)As you can see, the above code fetches a member based on the first mention that is in the recieved command, and uses the Member object to get their avatar url.Moderation Commands (or commands requiring permissions)You can get access to Hummus.py's permissions checking feature withfrom hummus.funcs import fullPermsCheck. Its arguments are theMessageobject you recieve on command, your class instance akaself, the permission you want to check, andoptionally,the target user ID to compare permissions with. What thefullPermsCheck()function does is that it checks to see if the user has the required permission, and it also checks whether it has a higher role than the target ID when specified (permissions comparing). You would use the function like this:perms=awaitfullPermsCheck(ctx,self,"kick_members",ctx.mentions[0])#assume this is in a command functionThe code would return aboolobject which you could use to verify that the user executing the command has the required permissions.So, for commands that require permissions such as kicking members, theoptimalcode would be the following:classCommands(Client):asyncdefkick(self,ctx:hummus.Message,mention:hummus.User=None):ifnotmention:awaitctx.reply("Please mention a user to kick them.")returnperms=awaitfullPermsCheck(ctx,self,"kick_members",mention)member=awaitctx.getUser(mention)ifperms:e=awaitmember.kick()ife.staus_code==200ore.status_code==204:#i dont remember which status code it is lolawaitctx.reply(f"i have kicked <@{member.id}>!")else:awaitctx.reply(f"Error kicking user. Status code:{e.status_code}")else:awaitctx.reply(f"You do not have the perms to kick{member.user.username}!")Existing moderation commands you can use:member.kick()member.nick()ctx.deleteMessage()ctx.bulkDelete()ctx.delete()Hummus's API is very unfinished, which means fetching a guild member with the endpoint doesn't exist, as is with many other endpoints. Therefore, Hummus.py has to rely on login information for necessary info such as role permissions. Because I am lazy and don't know how Hummus/Discord's permissions integers works, Hummus.py now uses Discord.py as a dependency (it has a needed permissions function). However, this is mainly a package process, which means you don't need to manually import Discord.py in your main bot code, you just need to have it installed.EventsYou can use events to execute code, as demonstrated below.fromhummusimportEventsclassEvents(Events):asyncdefon_message_create(self,message):#activates every time a message is sent in a channel a bot can seeifmessage.content.startswith("ping"):awaitmessage.reply("pong")Make sure to put this in your main file, before yourClientclass. You will also want to "listen" for this class before running theClientclass, as shown below:Client=Commands(prefix="!",bottoken=token,status="online",game="!test")asyncdefbot():awaitClient.LISTEN(Events())awaitClient.RUN()asyncio.run(bot())Events are a WIP, expect some bugs and alotof missing events.EmbedsYou can create an embed object by importing theEmbedclass fromhummus.fromhummusimportEmbedclassCommands(Client):asyncdeftest(self,ctx:hummus.Message):embed=Embed(title="Test",description="something")TheEmbedclass supports 4 parameters:title,description,color, andtimestamp. Thecolorparameter uses Discord's integer colors, view the listhere.Thetimestampparameter uses the ISO8601 format (what Hummus accepts), so here's the code to get the current time in that format.fromdatetimeimportdatetime,timezonecurrent_time_utc=datetime.now(timezone.utc)formatted_timestamp=current_time_utc.isoformat()You can add attributes to the embed such as fields, footers, a thumbnail, an image, or an author like this:classCommands(Client):asyncdeftest(self,ctx:hummus.Message):embed=Embed(title="Test",description="something")awaitembed.addField(name="field title",value="field value")awaitembed.addAuthor(name="author",url="https://google.com/",icon_url="https://www.google.com/favicon.ico")awaitembed.addFooter(text="foot",icon_url="https://www.google.com/favicon.ico")awaitembed.addThumbnail(url="https://google.com/favicon.ico")Sending an embed is as expected, you would include it in thectx.send()orctx.reply()function like this:classCommands(Client):asyncdeftest(self,ctx:hummus.Message):embed=Embed(title="Test",description="something")awaitembed.addField(name="field title",value="field value")awaitctx.reply("its an embed!",embed=embed)Note:Embeds will be ignored if an attachment is also passed!AttachmentsAttachments are quite simple. Create aFileobject instance, and pass it through thefileparameter inctx.send()orctx.reply().AFileobject can take 4 different types of parameters. Here is a list of them and their examples:str:file = hummus.File("path/to/file.here")io.BufferedReader:file = hummus.File(open("file.png","rb"))bytes:file = hummus.File(open("file.png","rb").read())(.read()returns abytesobject)BytesIO:file = hummus.File(BytesIO(b""))(BytesIO accepts abytesobject,Filegets it)A use case is the following:classCommands(Client):asyncdeftest(self,ctx:hummus.Message):awaitctx.reply("its an image!",file=hummus.File("image.png"))Note:Embeds will be ignored if an attachment is passed!SupportI am LG125YT#2241 on Hummus, @ytlg on Discord, LG125YT#3014 on Oldground, and @lg125yt on Replit. My email islg125yt@gmail.com, but you might want to let me know somewhere else that you sent me an email.RoadmapCurrently attempting to add all endpoints from theHummus API docsbeginning with most important for bot development.ChangelogVersion 0.5.1:No real changes, I'm just trying to fix the pypi issue whereimport hummusdoesnt work. Also updating this file a little to be more up-to-date.Version 0.5.0:You now need to upload files by creating aFileobject with your file in it. This allows for less cluttering inmessage.pyfor thesendfunction, and it allows me to easily add more freedom to uploading files.Continuation of above note, you can now provide a file path,bytesobject,BytesIOobject, or anio.BufferedReaderobject (the object you get when you assign a variable toopen("name.ext","rb"))AllMessageobjects now have adelete()function, which sends a request to delete that message on Hummus. (Previously, we only haddeleteMessage(id), where you needed to provide a message ID to delete.)For some reason, the v0.4.x versions have not been updating thehummusfolder, and only thehummus2016folder. If it persists, consider switching allfrom hummus import *andimport hummustofrom hummus2016 import *andimport hummus2016. This may also require changing some other lines, or you can useimport hummus2016 as hummus.Version 0.4.1:Updates in 0.4.0 didn't push for some reason lol. Here they are (again).Turns out that the Image and Thumbnail objectsdowork, they just requirewidthandheightparameters that Hummus.py will automatically take care for you. Nothing has changed, you can continue uploading files as before.Fixed bug not letting Hummus.py work, its just me forgetting to include headers when making the request to get the websocket url.Version 0.4.0:Added embed support (Image and Thumbnail objects to not work on Hummus, so they are not included in Hummus.py)Added attachment support (You only have to include the filepath)Version 0.3.4:Fixedctx.edit()so that it edits only the "content" section of the "reply" fromctx.reply()(basically it doesn't edit the whole message)Added a newis_reply(boolean),original_reply(content of the message being replied to), andoriginal_author(Userclass) attributes to theMessageobjectis_replyis entirely local, it is only true for a message object where thectx.reply()function is used, and cannot detect replies outside ofctx.reply()Errors caught by the package exception handler now print out the tracebackMinor changes to the READMEVersion 0.3.3:Updated the README (this thingy you're reading!) to not have the wackiest indents (frick you replit)Version 0.3.2:Fixed hummus.py not working when you didn't manually register anEventsclass to listen.Version 0.3.1:Quick update just addedctx.deleteMessage(id)because i forgor to add it before :sku:Version 0.3.0:More events in theEventsclass work now, alsoself.allGuildsin theClientclass now updates on related events like guild member join/leave and guild add/removeClientclass initialization redone a little, see the "Getting Started" and "Events" section in this READMECommand args should now fully work, you do not need to add a default value to parameters and some annotations (namelystr,int, andhummus.member.User) now workTheAuthorclass has been renamed to theUserclass because most use cases within the package do not reflect the "Author" status of a user (this should not affect much of anything since annotations did not work before this update)Too lazy to like do anything from before, if you want to do it for me, go for it.ContributingContribute if you want, you can make a pull request on theGitLab repository, comment on theReplit project.Note that the Replit project is the most recent version of Hummus.py, because it is where I test new features. You can see upcoming features on the Replit project if you want.AuthorsThis wrapper was made by LG125YT. Contact me on Hummus (LG125YT#2241) or Discord (@ytlg)