algorithm giving an unexpected argument in requests_http_signature library - python

In the below code I'm attempting to use the, 'RSA_V1_5_SHA256', algorithm to create a signature for connecting to an API. However, despite the documentation having it written this way, it doesn't seem to recognize algorithm as a valid argument.
Here's the documentation linked as well,
https://pyauth.github.io/requests-http-signature/#asymmetric-key-algorithms
auth = HTTPSignatureAuth(
algorithm=algorithms.RSA_V1_5_SHA256, key=preshared_secret, key_id=signature_key_id
)
This is the specific error that's being returned,
TypeError: __init__() got an unexpected keyword argument 'algorithm'.
I assume perhaps the documentation may be outdated, as I need to pass a passphrase that was used when I created the public and private keys, to properly authenticate my requests to said API... and passphrase/password isn't an acceptable argument in the other available algorithms based on what I've seen in the source code for this library.
Any help is appreciated!

You're totally right and the docs aren't updated, by checking the source code we can see that the __init__ method for the HTTPSignatureAuth class has no algorithm argument. Instead we find a signature_algorithm parameter (also we can see that this is the parameter that we need - source) so I would go with that:
auth = HTTPSignatureAuth(
signature_algorithm=algorithms.RSA_V1_5_SHA256, key=preshared_secret, key_id=signature_key_id
)
The changes were made in version v0.3.0 so if you use a previous version you will be able to use algorithm as the argument. But I would go with the first approach. (Note that version v0.3.0 was released 23 days ago so it's pretty recent and they may update the docs soon!

Related

email.utils.parseaddr() is now legacy API. Can I continue to use it?

I've spent some time reading the documentation of the email library module. We have got a new API. The old API is now marked legacy.
I have only one small email application and I expected it won't be difficult to rewrite it to use the new and better API only. However I am unable to find a simple replacement for the simple email.utils.parseaddr() function. They say:
There is no need to directly use these with the new API, since the
parsing and formatting they provide is done automatically by the
header parsing machinery of the new API.
It may be true regarding the email module alone, but I need to pass RFC821-style addresses to smtplib module functions expecting from_addr and to_addrs. Those SMTP Envelope addresses are basically stripped message header addresses and parseaddr can create them easily:
smtp_addr = email.utils.parseaddr(email_addr)[1]
Is there a comparably simple alternative in the new API (I must have overseen it)? If not, should I expect that a "legacy" API will stay in the library or it will be rather deprecated in the future?
Note: I know smtplib can extract the addresses from the message headers. I still like to pass addresses explicitly.
Short answer: Yes, you can keep using it, as of now.
Long answer:
PEP 4 specifies that before supported APIs are removed, they must be deprecated; specifies a process for deprecation; and lists all deprecated modules, current and historical.
None of the "Legacy API" submodules currently documented under email are marked "deprecated" in PEP 4 or in their Python 3.6.5 documentation. There is an open proposal to deprecate support for the isdst option in email.utils.localtime, but that is the only proposed deprecation to the email module I was able to turn up in searching.
Documentation elsewhere in the email package indicates, to me anyway, that this is an API that receives a fair amount of attention and care, and is not neglected. I see no obvious reason to fear that currently documented APIs there will be deprecated any time soon, even the ones in the "Legacy API" section.
For example, this remark in email.mime:
This module is part of the legacy (Compat32) email API. Its functionality is partially replaced by the contentmanager in the new API, but in certain applications these classes may still be useful, even in non-legacy code.
tells me that the designation of "legacy" implies only that it is no longer considered the best, most preferred module to use for the most common purposes; there is no actual deprecation warning that the API will soon disappear.
Of course, seeing no proposal for deprecation today is no guarantee that it will not suddenly be deprecated tomorrow; and I suppose one might expect a "Legacy API" to be a more likely target for deprecation. But until deprecation is formally proposed, if not approved, there is in theory no reason to fear using an API; and considering the amazing length of the Python 2 to 3 transition period (what is it, 11 years now?), I think you have little to worry about with this API.

Forcing ArrayFire to switch backends in Python

I have been attempting to force ArrayFire to use its CPU backend, rather than the default CUDA backend. According to this documentation page, you only need to call arrayfire.set_backend('cpu'). However, when I attempt to do this, an error is thrown with the message global name 'backend' is not defined. If you take a look at the source code, you will see that a global variable backend is defined within the module directly before the set_backend function is implemented. The following functions set and get various attributes of this backend object. My question is: is an internal implementation error on their part causing this error, or is there something I'm doing wrong (or that can be done on my part to fix this)? I haven't worked much with Python modules before, and would greatly appreciate any help!

Passing string rather than function in django url pattern

In the Django docs it says about url patterns:
It is possible to pass a string containing the path to a view rather
than the actual Python function object. This alternative is supported
for the time being, though is not recommended and will be removed in a
future version of Django.
Does anyone have any insight as to why this the case? I find this alternative to be quite handy and can't find anything explaining why this is a bad (or, at least, less than ideal) idea.
I think the 1.8 Release Notes in the repo explains it quite well. Here's a summary of the main points:
In the modern era, we have updated the tutorial to instead recommend importing
your views module and referencing your view functions (or classes) directly.
This has a number of advantages, all deriving from the fact that we are using
normal Python in place of "Django String Magic": the errors when you mistype a
view name are less obscure, IDEs can help with autocompletion of view names,
etc.
Thus patterns() serves little purpose and is a burden when teaching new users
(answering the newbie's question "why do I need this empty string as the first
argument to patterns()?"). For these reasons, we are deprecating it.
Updating your code is as simple as ensuring that urlpatterns is a list of
:func:django.conf.urls.url instances.

How to pass UniqueRequestToken to AWS mechanical turk using Boto

I'm trying to use the UniqueRequestToken parameter of create_hit as documented here. It doesn't show up as a parameter in boto.mturk.connection.MTurkConnection.create_hit. I tried to use it, guessing that it would be called unique_request_token, and got the following:
TypeError: create_hit() got an unexpected keyword argument 'unique_request_token'
Does boto simply not support that parameter? Is there any way to get around this, short of patching the boto client?
It is not implemented by Boto. You need to patch Boto to add this if you want to continue using Boto.
Alternatively, you can use my Python mTurk API. You'd make this request like:
from mturkcore import MechanicalTurk
m = MechanicalTurk()
m.create_request("CreateHIT", {..."UniqueRequestToken":"..."})
I personally believe mine is a better option because it uses the exact names in the documentation and supports the entire API. If a new name is added, it will (hopefully) be supported by mine even if I do not update :)
Best of luck!

learning python 3, the docs seem bad

How do you figure out what methods are available within a class?
Example :
I am trying to learn about urllib.request. I found urlopen() in the docs :
http://docs.python.org/3.0/library/urllib.request.html
So I have :
response = urllib.request.urlopen(url)
What does this return? I know it will probably be an object, but what are this objects methods? Eventually I get to the examples (stuck at the bottom of the page far from where the idea was introduced) and discover read(), but I had to look outside the docs to find .decode(), which finally lets you do what the whole purpose of this library is.
Im having this type of problem with much of the docs.python.org pages. Is there a better documentation somewhere else, or am I going about learning this all the wrong way?
The real problem here is that you're using a very old version of the documentation. I have no idea how you found it, but it should be pretty clear from the URL http://docs.python.org/3.0/library/urllib.request.html, and the header on the top of that page ("Python v3.0.1 documentation"), and so on that you're not looking at the documentation for your version.*
If you were looking at the 3.3 documentation, you would have seen this:
For http and https urls, this function returns a http.client.HTTPResponse object which has the following HTTPResponse Objects methods.
The first link takes you to the reference for the exact class, the second to the reference for the abstract type. Which gives you exactly what you were looking for—the read method, and everything else.
In older versions of Python, the term "file-like object" was thrown around loosely. This was always a vague term (sometimes it means "an iterable of lines", "has a read() and/or write() as appropriate", "has a fileno()", …), and became much more so in Python 3 (because you have to distinguish a binary file from a text file). So, over the years, they've phased this out in favor of more specific documentation. But if you're looking at the very earliest Python 3 documentation, you're not getting the benefit.
* Note that if you visit any recent-ish version of the docs, like the 3.3 linked above, there's a pulldown menu in the header that lets you switch to a different version if you've found the wrong one. And, the default will always be 2.7 or the latest stable 3.x, and those are also the most common search results, and the easiest things to link to, so you will usually be on one of those unless you're really trying to make things hard for yourself. If you do find yourself on ancient docs like 3.0 or 2.4 or something, you can often just edit the URL to 3.3 or 2.7, or just 3 or 2; if not, a quick search should work.
The key phrase in the documentation of urlopen is:
This function returns a file-like object with two additional methods from the urllib.response module
The fact that this is a file-like object indicates that all the normal file operation functions (read, close) apply to the returned object also.
The document you linked to says this:
This function returns a file-like object with two additional methods
from the urllib.response module
geturl() — return the URL of the resource retrieved, commonly used to determine if a redirect was followed
info() — return the meta-information of the page, such as headers, in the form of an http.client.HTTPMessage instance (see Quick Reference to HTTP Headers)
Emphasis mine. A "file-like object" is defined as follows:
file object
An object exposing a file-oriented API (with methods such as read() or write()) to an underlying resource. Depending on the way it was created, a file object can mediate access to a real on-disk file or to another type of storage or communication device (for example standard input/output, in-memory buffers, sockets, pipes, etc.). File objects are also called file-like objects or streams.
As #abarnert points out, you're probably just better off using the new docs, which explicitly link to the methods of the returned object.
If you aren't using Ipython already you should be. Then you can just type urllib. and press tab to see all the available options and do the same for whatever it returns. If you type a question mark after the function it will bring up the documentation, two question marks often brings up the source.
For what its worth though I have always found the online documentation to be very helpful. It does say that urllib.request.urlopen is going to return a file like object early in the explanation

Categories