I have a simple spyne service:
class JiraAdapter(ServiceBase):
#srpc(Unicode, String, Unicode, _returns=Status)
def CreateJiraIssueWithBase64Attachment(summary, base64attachment, attachment_filename):
status = Status
try:
newkey = jira_client.createWithBase64Attachment(summary, base64attachment, attachment_filename)
status.Code = StatusCodes.IssueCreated
status.Message = unicode(newkey)
except Exception as e:
status.Code = StatusCodes.InternalError
status.Message = u'Internal Exception: %s' % e.message
return status
The problem is that some programs will insert '\n' into generated base64string, after every 60th character or so and it will come into the services' method escaped ('\\n') causing things to behave oddly. Is there a setting or something to avoid this?
First, some comments about the code you posted:
You must instantiate your types (i.e. status = Status() instead of status = Status). As it is, you're setting class attributes on the Status class. Not only this is just wrong, you're also creating race conditions by altering global state without proper locking.
Does Jira have a way of creating issues with binary data? You can use ByteArray that handles base64 encoding/decoding for you. Note that ByteArray gets deserialized as a sequence of strings.
You can define a custom base64 type:
Base64String = String(pattern='[0-9a-zA-Z/+=]+')
... and use it instead of plain String together with validation to effortlessly reject invalid input.
Instead of returning a "Status" object, I'd return nothing but raise an exception when needed (or you can just let the original exception bubble up). Exceptions also get serialized just like normal objects. But that's your decision to make as it depends on how you want your API to be consumed.
Now for your original question:
You'll agree that the right thing to do here is to fix whatever's escaping '\n' (i.e. 0x0a) as r"\n" (i.e. 0x5c 0x6e).
If you want to deal with it though, I guess the solution in your comment (i.e. base64attachment = base64attachment.decode('string-escape') would be the best solution.
I hope that helps.
Best regards,
Related
I'm using Python with the Django Rest framework and am trying to receive webhook events correctly from stripe.
However I constantly get this error:
stripe.error.SignatureVerificationError: No signatures found matching the expected signature for payload
This is the code:
WEBHOOK_SECRET = settings.STRIPE_WEBHOOK_SK
#csrf_exempt
def webhook(request):
sig_header = request.headers.get('Stripe-Signature', None)
payload = request.body
try:
event = stripe.Webhook.construct_event(
payload=payload,
sig_header=sig_header,
secret=WEBHOOK_SECRET
)
except ValueError as e:
raise e
except stripe.error.SignatureVerificationError as e:
raise e
return HttpResponse(status=200)
I have also tried modifying the request body format like so:
payload = request.body.decode('utf-8')
# and also
payload = json.loads(request.body)
And yet no luck.
The error is coming from the verify_header() class method inside the WebhookSignature class.
This is the part of the method where it fails:
if not any(util.secure_compare(expected_sig, s) for s in signatures):
raise error.SignatureVerificationError(
"No signatures found matching the expected signature for payload",
header,
payload,
)
So I printed out exptected_sig and signatures before this line and found that regardless of what format request.body is in, signatures is always there (which is good), but they never match the signature from the header.
Why is this?
When Stripe calculates the signature for the Event it sends you, it uses a specific "payload" representing the entire Event's content. The signature is done on that exact payload and any change to it such as adding a new line, removing a space or changing the order of the properties will change the payload and the corresponding signature.
When you verify the signature, you need to make sure that you pass the exact raw payload that Stripe sent you, otherwise the signature you calculate won't match the Stripe one.
Frameworks can sometimes try to be helpful when receiving a request and they detect JSON and automatically parse it for you. This means that you think you are getting the "raw payload/body" but really you get an alternate version. It has the same content but it doesn't match what Stripe sent you.
This is fairly common with Express in Node.js for example. So, as the developer, you have to explicitly request the exact raw/original payload Stripe sent you. And how to do this can differ based on a variety of factors. There are 2 issues on the stripe-node github with numerous potential fixes here and here.
With Django, the same can happen and you need to make sure that your code requests the raw payload. You seem to use request.body as expected but that's one thing you want to dig into further.
Additionally, another common mistake is using the wrong Webhook secret. If you use the Stripe CLI for example, it creates a new secret for you that is different from the one you see in the Dashboard for this Webhook Endpoint. You need to make sure you use the correct secret based on the environment you're in.
I'm working with Stripe API to cancel a subscription using the subscription ID. In all the tests, the stripe.Subscription.delete works fine but in some (very few) cases, it just gives this error unbound method delete() must be called with Subscription instance as the first argument.
First I thought that the Stripe object wasn't defined correctly but in the same function, I'm making another Stripe API call to get the subscription list (stripe.Subscription.list). This works every time.
This is a bit confusing scenario so any help would be great.
try:
sub_id = <sub_id from the API call>
logging.info('sub_id = %s', sub_id)
logging.info('isinstance(sub_id, unicode) = %s', isinstance(sub_id, unicode))
if isinstance(sub_id, unicode):
sub_id = sub_id.encode('ascii', 'ignore')
logging.info('sub_id is unicode. Converting to ascii = %s', sub_id)
else:
logging.info('sub_id is _not_ a unicode string')
except Exception as e:
subject_str = 'hit exception when canceling subcription in stripe. Error = %s'%e
logging.error(subject_str)
stripe.Subscription.delete(sub_id)
return True
Added try-except just to make sure I'm always passing string argument.
Thank you!
If I had to guess, it's happening because the Subscription ID is for a sub that doesn't exist. You might want to file this as an issue in Github - along with details of the version you're using - as there may be something odd going on under the hood. https://github.com/stripe/stripe-python/
Each time I write a function which has (one ore more) parameters, the first thing I do in the function body is to check that the received value of each parameter is valid.
For example:
def turn_on_or_off_power_supplies (engine, power_supply, switch_on_or_off = RemoteRebootConst.OFF):
'''
#summary:
The function turns off or turns on the switch.
#param engine:
SSH connection to the switch
#param switch_on_or_off:
This sets whether to turn off, or turn on the switch.
Use the following constants in infra_constants.py:
RemoteRebootConst.OFF = off
RemoteRebootConst.ON = on
'''
if switch_on_or_off != RemoteRebootConst.ON and switch_on_or_off =! RemoteRebootConst.OFF:
raise Exception("-ERROR TEST FAILED \n"
"Function Name: turn_on_or_off_power_supplies \n"
"Parameter 'switch_on_or_off' \n"
"Expected value: %s or %s \n"
"Actual value: %s"
% (RemoteRebootConst.ON, RemoteRebootConst.OFF, switch_on_or_off))
Output omitted...
Why do I do this? Because in this way, if exception is received, the developer which debugs, can know immediately in which function the problems happens, what are expected value/s and what is the actual value. This error messages makes debugging this kind of problems much more easier.
As said earlier, If there have been more parameters,I will do the above code for EACH parameter.
This makes my function body to me much bigger in terms of number of lines of code.
Is there a more pythonic way to print all of the above details in case there is an exception due to invalid parameter value received (function name, parameter name, expected values, actual values?
I can write a function which receives 4 parameters (function name, parameter name, expected value/s, actual value), and then use it each time I would like to raise this kind of exception (this will cause each exception of this sort to be just one line of code instead of several ones)
I will appreciate any help here.
Thanks in advance.
Note that checking the types of your arguments is against duck-typing, which is part of the python philosophy. If you want another developer to be able to debug your code more easily, you should use an assertion:
def turn_on_or_off_power_supplies (engine, power_supply, switch_on_or_off=RemoteRebootConst.OFF):
assert switch_on_or_off in {RemoteRebootConst.ON, RemoteRebootConst.OFF}, 'wrong argument switch_on_or_off'
for more about assertions look here.
Note that assertions will be remove if you optimive your code with the -O flag.
I'm processing data from a serial port in python. The first byte indicates the start of a message and then the second byte indicates what type of message it is. Depending on that second byte we read in the message differently (to account for different types of messages, some are only data others are string and so on).
I now had the following structure. I have a general Message class that contains basic functions for every type of message and then derived classes that represent the different types of Messages (for example DataMessage or StringMessage). These have there own specific read and print function.
In my read_value_from_serial I read in all the byte. Right now I use the following code (which is bad) to determine if a message will be a DataMessage or a StringMessage (there are around 6 different type of messages but I simplify a bit).
msg_type = serial_port.read(size=1).encode("hex").upper()
msg_string = StringMessage()
msg_data = StringData()
processread = {"01" : msg_string.read, "02" : msg_data.read}
result = processread[msg_type]()
Now I want to simplify/improve this type of code. I've read about killing the switch but I don't like it that I have to create objects that I won't use in the end. Any suggestions for improving this specific problem?
Thanks
This is very close to what you have and I see nothing wrong with it.
class Message(object):
def print(self):
pass
class StringMessage(Message):
def __init__(self, port):
self.message = 'get a string from port'
def MessageFactory(port):
readers = {'01': StringMessage, … }
msg_type = serial_port.read(size=1).encode("hex").upper()
return readers[msg_type](port)
You say "I don't like it that I have to create objects that I won't use in the end". How is it that you aren't using the objects? If I have a StringMessage msg, then
msg.print()
is using an object exactly how it is supposed to be used. Did it bother you that your one instance of msg_string only existed to call msg_string.read()? My example code makes a new Message instance for every message read; that's what objects are for. That's actually how Object Oriented Programming works.
This one's a structure design problem, I guess. Back for some advice.
To start: I'm writing a module. Hence the effort of making it as usable to potential developers as possible.
Inside an object (let's call it Swoosh) I have a method which, when called, may result in either success (a new object is returned -- for insight: it's an httplib.HTTPResponse) or failure (surprising, isn't it?).
I'm having trouble deciding how to handle failures. There are two main cases here:
user supplied data that was incorrect
data was okay, but user interaction will be needed () - I need to pass back to the user a string that he or she will need to use in some way.
In (1) I decided to raise ValueError() with an appropriate description.
In (2), as I need to actually pass a str back to the user.. I'm not sure about whether it would be best to just return a string and leave it to the user to check what the function returned (httplib.HTTPResponse or str) or raise a custom exception? Is passing data through raising exceptions a good idea? I don't think I've seen this done anywhere, but on the other hand - I haven't seen much.
What would you, as a developer, expect from an object/function like this?
Or perhaps you find the whole design ridiculous - let me know, I'll happily learn.
As much as I like the approach of handling both cases with specifically-typed exceptions, I'm going to offer a different approach in case it helps: callbacks.
Callbacks tend to work better if you're already using an asynchronous framework like Twisted, but that's not their only place. So you might have a method that takes a function for each outcome, like this:
def do_request(on_success, on_interaction_needed, on_failure):
"""
Submits the swoosh request, and awaits a response.
If no user interaction is needed, calls on_success with a
httplib.HTTPResponse object.
If user interaction is needed, on_interaction_needed is
called with a single string parameter.
If the request failed, a ValueError is passed to on_failure
"""
response = sumbit_request()
if response.is_fine():
on_success(response)
elif response.is_partial()
on_interaction_needed(response.message)
else:
on_failure(ValueError(response.message))
Being Python, there are a million ways to do this. You might not like passing an exception to a function, so you maybe just take a callback for the user input scenario. Also, you might pass the callbacks in to the Swoosh initialiser instead.
But there are drawbacks to this too, such as:
Carelessness may result in spaghetti code
You're allowing your caller to inject logic into your function (eg. exceptions raised in the callback will propagate out of Swoosh)
My example here is simple, your actual function might not be
As usual, careful consideration and good documentation should avoid these problems. In theory.
I think raising an exception may actually be a pretty good idea in this case. Squashing multiple signals into a single return value of a function isn't ideal in Python, due to duck typing. It's not very Pythonic; every time you need to do something like:
result = some_function(...)
if isinstance(result, TypeA):
do_something(result)
elif isinstance(result, TypeB):
do_something_else(result)
you should be thinking about whether it's really the best design (as you're doing).
In this case, if you implement a custom exception, then the code that calls your function can just treat the returned value as a HTTPResponse. Any path where the function is unable to return something its caller can treat that way is handled by throwing an exception.
Likewise, the code that catches the exception and prompts the user with the message doesn't have to worry about the exact type of the thing its getting. It just knows that it's been explicitly instructed (by the exception) to show something to the user.
If the user interaction case means the calling code has to show a prompt, get some input and them pass control back to your function, it might be ugly trying to handle that with an exception. Eg,
try:
Swoosh.method()
except UserInteraction, ex:
# do some user interaction stuff
# pass it back to Swoosh.method()?
# did Swoosh need to save some state from the last call?
except ValueError:
pass # whatever
If this user interaction is a normal part of the control flow, it might be cleaner to pass a user-interaction function into your method in the first place - then it can return a result to the Swoosh code. For example:
# in Swoosh
def method(self, userinteractor):
if more_info_needed:
more_info = userinteractor.prompt("more info")
...
ui = MyUserInteractor(self) # or other state
Swoosh.method(ui)
You can return a tuple of (httplib.HTTPResponse, str) with the str being optionally None.
Definitely raise an exception for 1).
If you don't like returning a tuple, you can also create a "response object" i.e. an instance of a new class ( lets say SomethingResponse ) that encapsulates the HTTPResponse with optional messages to the end-user( in the simplest case, just a str).