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.
Related
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)
I'm trying to understand why, how, and if to unit test methods that seem to return nothing. I've read in a couple other threads that:
The point of a unit test is to test something that the function does. If its not returning a value, then what is it actually doing?
unittest for none type in python?
In my example, I am using the XMLSigner and XMLVerifier from the sign_XML library.
def verify_xml(signed_xml: str, cert_file: str) -> None:
with open(cert_file, 'rb') as file:
cert = file.read()
with open(signed_xml, 'rb') as input_file:
input_data = input_file.read()
XMLVerifier().verify(input_data, x509_cert=cert)
I started looking up documentaion I found for SignXML. I read that verify():
class signxml.XMLVerifier Create a new XML Signature Verifier object,
which can be used to hold configuration information and verify
multiple pieces of data. verify(data, require_x509=True,
x509_cert=None, cert_subject_name=None, ca_pem_file=None,
ca_path=None, hmac_key=None, validate_schema=True, parser=None,
uri_resolver=None, id_attribute=None, expect_references=1)
Verify the
XML signature supplied in the data and return the XML node signed by
the signature, or raise an exception if the signature is not valid. By
default, this requires the signature to be generated using a valid
X.509 certificate.
This is my first time working with this and I'm confused even more now. So this apparently does return something.
What I've attempted
For another method which ends up calling verify_xml I've used #patch and just checked that the method I patched was called and with the correct arguments. This also seems like it's not the way to do it, but I didn't know how else to test it.
It feels weird doing something similar with the verify_xml method and just checking that it has been called once.
I've also tried self.assertIsNone... and that passes but that seems weird to me and not like it's a way one does this.
Could someone help me understand why, how, and if to unit test methods that seem to return nothing).
Thanks
to test verify_xml() is to test the Exception triggered by XMLVerifer().verify() if input parameters is not valid
There are a few types of exceptions you can tested.
from signxml import (XMLSigner, XMLVerifier, InvalidInput, InvalidSignature, InvalidCertificate, InvalidDigest)
class TestVerifyXML(unittest.TestCase):
def setUpCls(cls):
cls.signed_xml = from_magic()
cls.cert_file = from_magic2()
cls.ceft_file_bad = from_magic_bad()
def test_verify_xml(self):
# no Exception with correct xml
verify_xml(self.signed_xml, self.cert_file)
with self.assertRaises(InvalidSignature):
verify_xml(self.signed_xml, self.cert_file_bad)
I am working on Django rest framework which specifies a set format for function prototype for detail_route in ModelViewSet. Some background: -
The function takes in request object and lookup_field which can be the primary key for a particular table.
#detail_route(methods=["get"], url_path="get-some-data")
def get_some_data(self, request, id=None):
return Response(get_some_data(id))
Now as you can see, I do not need request object here, So should I keep it like this? or change it to
#detail_route(methods=["get"], url_path="get-some-data")
def get_some_data(self, _, id=None):
return Response(get_some_data(id))
Here I changed request to _ to indicate that I do not need this value.
which approach should be followed? Should I let it remain as a request, or change it to an underscore?
For the method arguments I would always use the proper variable name so that in future whether I work on it or my peers if I provide this code to someone else they don't have to struggle to understand what it is.
For now you might think to ignore it but since it is a method argument it would be better to have a name it stands for.
Or, let's say you are adding a docstring where you are including and defining which parameter is what. You would yourself appreciate it if some one had:
#param request: HTTP request object
instead of:
#param _: HTTP request object
If you leave the parameter exist, then give it a meaningful name always do good, even you do not use it.
In addition, _ has special use in python, check it in the following url.
What is the purpose of the single underscore "_" variable in Python?
I'd leave it with a descriptive name. Changing it to underscore or any other non-descriptive name is not beneficial.
I'm pretty new to python, and currently playing with the zeroconf library.
when I try to register a service on the network, I'm seeing this in the function definition:
def register_service(self, info, ttl=_DNS_TTL):
"""Registers service information to the network with a default TTL
of 60 seconds. Zeroconf will then respond to requests for
information for that service. The name of the service may be
changed if needed to make it unique on the network."""
self.check_service(info)
self.services[info.name.lower()] = info
if info.type in self.servicetypes:
self.servicetypes[info.type] += 1
else:
self.servicetypes[info.type] = 1
now = current_time_millis()
next_time = now
i = 0
while i < 3:
if now < next_time:
self.wait(next_time - now)
now = current_time_millis()
continue
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
out.add_answer_at_time(DNSPointer(info.type, _TYPE_PTR,
_CLASS_IN, ttl, info.name), 0)
out.add_answer_at_time(DNSService(info.name, _TYPE_SRV,
_CLASS_IN, ttl, info.priority, info.weight, info.port,
info.server), 0)
out.add_answer_at_time(DNSText(info.name, _TYPE_TXT, _CLASS_IN,
ttl, info.text), 0)
if info.address:
out.add_answer_at_time(DNSAddress(info.server, _TYPE_A,
_CLASS_IN, ttl, info.address), 0)
self.send(out)
i += 1
next_time += _REGISTER_TIME
Anyone know what type info is meant to be?
EDIT
Thanks for providing the answer that it's a ServiceInfo class. Besides the fact that the docstring provides this answer when one goes searching for it. I'm still unclear on:
the process expert python programmers follow when encountering this sort of situation - what steps to take to find the data type for info say when docstring wasn't available?
how does python interpreter know info is of ServiceInfo class when we don't specify the class type as part of the input param for register_service? How does it know info.type is a valid property, and say info.my_property isn't?
It is an instance of ServiceInfo class.
It can be deduced from reading the code and docstrings. register_service invokes check_service function which, I quote, "checks the network for a unique service name, modifying the ServiceInfo passed in if it is not unique".
It looks like it should be a ServiceInfo. Found in the examples of the repository:
https://github.com/jstasiak/python-zeroconf/blob/master/examples/registration.py
Edit
I'm not really sure what to say besides "any way I have to". In practice I can't really remember a time when the contract of the interface wasn't made perfectly clear, because that's just part of using Python. Documentation is more a requirement for this reason.
The short answer is, "it doesn't". Python uses the concept of "duck typing" in which any object that supports the necessary operations of the contract is valid. You could have given it any value that has all the properties the code uses and it wouldn't know the difference. So, per part 1, worst case you just have to trace every use of the object back as far as it is passed around and provide an object that meets all the requirements, and if you miss a piece, you'll get a runtime error for any code path that uses it.
My preference is for static typing as well. Largely I think documentation and unit tests just become "harder requirements" when working with dynamic typing since the compiler can't do any of that work for you.
What is the best practice?
1) have a function be able to take in None?
2) practice to not to send None to a func
is it just personal preference or are there any pros/cons to this?
I have a func
def parse_path(path):
site = None
site_pattern = re.compile('(fl|ny|wa|tx)')
match = site_pattern.search(path)
if match:
site = match.group(0)
return site
so obviously if i pass in None to parse_path, it will complain.
TypeError: expected string or buffer
so should I always be conscious of what to put in to a func or should a func be flexible so it deals with None?
I'm using None as default sometimes as in:
def dosomething(input1, input2=None):
if not input2:
input2 = compute_default_input2
carry_on()
....
This can be useful in classes that can be used in multiple ways or where certain properties require computationally intense initialisation, so you don't want to do this unless it's requested -- adding None as default makes that possible.
It's also a cheap way to allow users to override an object's properties:
def dosomething(self, property=None):
if not property:
property = self.property
This will use the self.* value by default but allow the user to override it.
It's also something of a hack, so as most things in Python should probably used with care.
... other than that: I think None as an input should only be dealt with in a function if there's a reasonable use case where None is passed to that function, and that very much depends on the environment that it is operating in. If you can reasonably expect everyone to be aware they shouldn't call your function with None then the standard error message from Python should be enough to make clear what the problem is.