Make help command print the commands unsorted - python

Trying to figure out how to use this attribute: sort_commands
Seems like it's there so that I can change its default (True) to False but I can't figure out how to do it.
So far everyone has suggested for me to use bot.remove_command("help") and then implement my own from scratch.
But it seems like it's missing something. This attribute exists for a reason, doesn't it? Must be a better way to use this attribute rather than implement an entire command from scratch.

You're able to create a new instance of a default help command:
from discord.ext import commands
help_command = commands.DefaultHelpCommand(sort_commands=False) # Also set other options here
# And pass in the new help command into the bot so it knows to use it
bot = commands.Bot(command_prefix="!", help_command=help_command)
References:
Bot.help_command
commands.DefaultHelpCommand() - See other options you can edit in here.

I managed to do what I intended in the following way:
I created my own help command which extends (inherits) from DefaultHelpCommand, then I overriden the send_bot_help coroutine and change the sorting to compare by the command description field instead of command name field (I preferred creating my own order field or such, but couldn't find the right way to do it, so I used an existing field).
Then I order my commands like this:
#commands.command(help="A helpful description of cmd1", name="commandName", description='1')
#commands.command(help="A helpful description of cmd2", name="commandName2", description='2')
Following is the class:
class MyHelpCommand(DefaultHelpCommand):
async def send_bot_help(self, mapping):
# ... everything up here copy-pased from original superclass
# This used to be c.name
commands = sorted(commands, key=lambda c: c.description)
# ... The rest is also copy-pasted
Then I use it like suggested:
help_command = MyHelpCommand()
client = commands.Bot(command_prefix=Config.COMMAND_PREFIX, help_command=help_command)

Related

How to reopen a closed Gitlab Projectissue with the python gitlab module

Trying to automate reopening a bunch of issues on a kanban board in Gitlab does not seem to be working as expected. I can edit pretty much everything else: labels, title, description, due date and so on, but changing the state from 'closed' to 'opened' is not doing anything.
Funny enough the save() method, takes some time to complete and is not throwing any error (but it does when I try to update an issue without having changed anything)
import gitlab
gl = gitlab.Gitlab(URL, private_token=TOKEN, api_version = 4)
gl.auth()
Project = gl.projects.get(project_id, lazy=True)
editable_issue = Project.issues.get(issue_id)
I use this to instantiate the gitlab object
This works:
editable_issue.labels.append('some label')
editable_issue.save()
editable_issue.title = title + '\n' + 'edited.'
editable_issue.save()
But this doesn't:
editable_issue.state = 'opened'
editable_issue.save()
I have also tried changing several fields, like so:
editable_issue.state = 'opened'
editable_issue.closed_at = None
editable_issue.save()
But, albeit I receive no error, the task is not being updated.
Is there something I'm overlooking ?
edit
Oh yes, I forgot to mention that the documentation seems to be mentioning state_event as a method, while my object does not know of such a method.
Is this method only there when a projectissue is being created by the api, perhaps ?
As mentioned in the documentation, you must set the state_event attribute, then save. This attribute won't exist at first -- you must create it.
issue.state_event = 'reopen'
issue.save()
Modifying state or closed_at won't work because the issues edit API doesn't accept state or closed_at parameters.
(this is also why state_event doesn't exist on the object at first, because the issue detail API doesn't include state_event in its response -- all the attributes are set dynamically by the response JSON)

In fast api how can I use optional parameters?

I've read through the documentation and this doesn't seem to be working for me. I followed this doc. But I'm not sure if it's related to what I'm trying to do, I think this doc is for passing queries like this - site.com/endpoint?keyword=test
Here's my goal: api.site.com/test/(optional_field)
so if someone goes to the 'test' endpoint then it defaults the optional field to a parameter but if they add something there then it takes that as a input.
With that said, here's my code:
#app.get("/company/{company_ticker}/model/{financialColumn}", dependencies=[Depends(api_counter)])
async def myendpoint(
company_ticker: str,
financialColumn: Optional[str] = 'netincome',
..
myFunction(company_ticker, financialColumn)
what I'm trying to do is if they just go to the endpoint without the optional flag then it defaults to 'netincome' but if they add something then financialColumn is set to that value.
Is there something I can do?
As far as I know, it won't work the way you've set it up. Though you can try something like this:
#app.get("/company/{company_ticker}/model/", dependencies=[Depends(api_counter)])
#app.get("/company/{company_ticker}/model/{financialColumn}", dependencies=[Depends(api_counter)])
async def myendpoint(
company_ticker: str,
financialColumn: Optional[str] = 'netincome'
):
myFunction(company_ticker, financialColumn)
This way, if someone goes to "/company/{company_ticker}/model/" or "/company/{company_ticker}/model/blabla" the function myendpoint will handle the request.
Not sure if it works as you wish, but at the moment I cannot test it. Maybe later. Let me know.

Python: Using string stored in variable to create attribute to class

I am trying to follow syntax of the pyparticleio.ParticleCloud package. Using the following command, my code works correctly "particle_cloud.boron1.led('on')" (hardcoded values)
I want to pass portions of the command, "boron1" and "on" as variable. I'm trying to figure out how to use those variables to act in the same way as if i'd hardcoded the values.
My python level is very beginner.
command_list['boron1','on']
device = command_list[0]
function_1 = command_list[1]
access_token = "ak3bidl3xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
particle_cloud = ParticleCloud(username_or_access_token=access_token)
#particle_cloud.boron1.led('on') #hardcoded example that works
particle_cloud.device.led(function_1) #what i would like to work
If you set device to the actual object, you can call methods on the object. Example:
device = particle_cloud.boron1 # Or whatever you like
arg = 'on' # Also make this whatever you like
device.led(arg) # Same as: particle_cloud.boron1.led('on')
Python has a built in function called exec
It allows you to take a string, and have Python execute it as code.
A basic example based on the code you provided would look like this:
command_list['boron1','on']
device = command_list[0]
function_1 = command_list[1]
exec('particle_cloud.' + device + '.led("' + function_1 + '")')
This is a bit ugly, but there are different ways to compose strings in Python such as using join or format so depending on your real code you may be able to build something nice.
Just be careful not to pass raw user input to exec!
I can cause all kinds of trouble from errors to security issues.
I believe you could use getattr() (in Python3: https://docs.python.org/3/library/functions.html#getattr ) :
pcdevice = getattr(particle_cloud, device)
pcdevice.led(function_1)
(BTW, I woudln't name the string 'on' with the label 'function_1' as the variable name implies that this option is a function when it is a string. Also, the above may now work depending on the properties of your library object ParticleCloud.)

How to get SessionID in QuickFix

I am using QuickFix with Python. On the back of this question, I've explored the SessionID class a bit, but I am mystified by the behavior.
The SessionID class is described here. It is formed of a BeginString, SenderCompID and TargetCompID.
Say my SessionID in string form looks like this: FIX.4.2:LMXTS->TS68.
fix.SessionID().fromString() returns :->
Which if you look, are the three filler characters separating the BeginString, SenderCompID and TargetCompID.
fix.SessionID().getBeginString returns 8=☺ (i.e. the BeginString is nowhere). And the same thing applies to getSenderCompID and getTargetCompID, they return 49=☺ and 56=☺ respectively.
fix.SessionID().getTargetCompID().getValue() returns the empty string ''.
Trying another way, fix.SessionID().fromString('FIX.4.2:LMXTS->TS68') returns None.
I am trying to get these values after the session is created (which I can explicitly see happening when I pass fix.ScreenLogFactory(settings) to the initiator. So I am confused.
The method void onLogon( const SessionID& ) {} in Application.h is fired when the session is logged on, and gives you a reference to a SessionID. You could inspect the SessionID object inside onLogon to see how it behaves.
you can do it any of the quickfix methods after your session is created as the sesionId is one of the parameters.
The first method fired is onCreate so you can potentially store the sesionId in your class var and then reuse if if and when required to retrieve your settings. You can also use the onLogon method as suggested in one of the other answers.
Example below
def onCreate(self, sessionID):
self.session_id = sessionID
target = sessionID.getTargetCompID().getString()
sender = sessionID.getSenderCompID().getString()
It sounds like you're looking at the session directly after creating it, before logging on etc. So that means you're not using a breakpoint in, say, FromApp or ToApp to look at the session properties there. If you do, you get the properties directly i.e. SenderCompID, or TargetCompID.
I cannot find the method SessionID in the objects I use. How do you define your 'fix' object?

Django method same object not saving

This is something I have been trying to solve for 3 days now and I just can't get my head around it why this is not working.
I have a method that creates a new version of an Object. It used to work, that you would pass in the sou obj. and this would be the source from which a new version is created. You can also pass in a destination, which is not really important in this example. Now I wanted to add locking to this method as we want to add multiple users. So I want to be sure that I always have the most current object from which I create a new one. So I added a line that would just get the newest object. If there is no newer object in the database it would be the same anyway.
def createRevision(request, what, sou, destination=None, ignore = [], **args):
...
if "initial" not in args.keys():
source = get_object_or_404(BaseItem, ppk=sou.ppk, project=sou.project, current=True)
print "------------"
print source == sou
print "------------"
# This outputs True
else:
source = sou
further down in the method I do something like
source.current = False
source.save()
Basically the idea is that I pass in BaseItem and if I don't specify the "initial" keyword then I get the current item from that project with the same ppk (Which is a special random pk in conduction with current). I do this just to be on the save side, that I really have the most current object. And if it is the initial version I just use that one, as there can not be another version.
So now the problem is, that everything works fine if I use sou in this method. I can save it etc .. but as soon as I use source and initial is not in the args it just doesn't save it. The print statement tells me they are the same. Everything I print after the save tells me it has been saved but it just doesn't do it.
source.current = False
source.save()
print "SAVED !!!!"
print source.pk
print source.current
rofl = get_object_or_404(BaseItem, pk=source.pk, project=sou.project)
print rofl.pk
print source.current
outputs the same pk and the same current value but somehow it is not properly saved. As soon as I look into django admin or do a select current = True.
I really don't know what to do anymore.
Why does it work without a problem if I pass in the object into the method but starts to fail when I get the exact same object in the method?
Of course I call the method with the same object:
x = get_object_or_404(BaseItem, ppk=sou.ppk, project=sou.project, current=True)
createRevision(request, "", x)
Thank you pztrick for the hint with the caches. I finally solved it. So the problem was that I was doing:
x = get_object_or_404(BaseItem, ppk=sou.ppk, project=sou.project, current=True)
createRevision(request, "", x)
# .... loads of lines of code
unlock(x)
unlock is a method I wrote that just sets a timestamp so I know no other user is editing it. So now the problem was that I was saving x in createRevision with all the correct data but of course unlock(x) still had a reference to an "old" not updated object and of course was saving it again. Hence it was overwriting my changes in createRevision.
Thank you again to everyone who helped with this.
I think you may be running afoul of model manager caching which is intended to limit database queries. However, by invoking the .all() method on the model manager you force it to hit the databse again.
So, try this: Replace your argument from the BaseItem class to the model manager's .all() QuerySet:
source = get_object_or_404(BaseItem.objects.all(), ppk=sou.ppk, project=sou.project, current=True)
# ...
rofl = get_object_or_404(BaseItem.objects.all(), pk=source.pk, project=sou.project)
get_object_or_404 supports mode classes, model managers, or QuerySets as the first parameter so this is valid.

Categories

Resources