Requests/urllib3 error: unorderable types: Retry() < int() - session

I understand the error, yet do no understand it in the context of my code. This is in Python 3.4. The relevant bits of code (simplified somewhat for clarity):
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager
class SessionAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLSv1,
cert_reqs = 'CERT_REQUIRED',
ca_certs = certifi.where(),
)
try:
app_session = requests.Session()
app_session.mount('https://', SessionAdapter())
app_response = app_session.post(
url = 'https://<FQD URL>'
, auth = (user, password)
, verify = True
)
# Code errors on the previous line and never executes the logger line
logger.debug('Status code: {}'.format(app_response.status_code))
if app_response.status_code == 401:
return 401
else:
return app_session
except:
logger.debug('Exception')
From sys.exc_info() I see:
", verify = True"): unorderable types: Retry() < int()
If the error were something like SessionAdapter() < int() it might make more sense. But I don't know where the Retry() check is being made.
Does the import of PoolManager need to be done differently for Python 3? I'm using version 1.7.1 of python-urllib3 on Ubuntu.

Related

call DjangoRestFramework DetailAPIView() from another view

solution from #brian-destura below
The DRF test client does not work, but the django.test.client does. Odd (?) because it's a DRF APIView being called.
from django.test import Client
client = Client()
result = client.get('/api/place/6873947')
print(result.json)
I have a DRF DetailAPIView() that returns a complex serializer json response to external API queries, so in the browser, and via curl etc. http://localhost:8000/api/place/6873947/ returns a big JSON object. All good. The url entry in the 'api' app looks like this
path('place/<int:pk>/', views.PlaceDetailAPIView.as_view(), name='place-detail'),
I need to use that in another, function-based view, so first I tried using both django.test.Client and rest_framework.test.APIClient, e.g.
from rest_framework.test import APIClient
from django.urls import reverse
client = APIClient()
url = '/api/place/6873947/'
res = client.get(url)
That gets an empty result. With django Client:
from django.test import Client
c=Client()
Then
res = c.get('/api/place?pk=6873947')
and
res = c.get('/api/place/', {'pk': 6873947})
Both return "as_view() takes 1 positional argument but 2 were given"
I've tried other approaches in my IDE, picked up in StackOverflow, starting with
from api.views import PlaceDetailAPIView
pid = 6873947
from django.test import Client
from django.http import HttpRequest
from places.models import Place
request = HttpRequest()
request.method='GET'
request.GET = {"pk": pid}
Then
res = PlaceDetailAPIView.as_view({"pk": pid})
"as_view() takes 1 positional argument but 2 were given"
res = PlaceDetailAPIView.as_view()(request=request)
"Expected view PlaceDetailAPIView to be called with a URL keyword argument named "pk". Fix your URL conf, or set the .lookup_field attribute on the view correctly"
res = PlaceDetailAPIView.as_view()(request=request._request)
"HttpRequest' object has no attribute '_request"
I must be missing something basic, but hours of thrashing has gotten me nowhere - ideas?

Jmeter throws error on Encryption - using Public Key

I am currently working in a application where RSA Encryption is being used for Encrypting sensitive data. I have tried incorporating the standard encryption method but it is throwing errors. I have selected the language Groovy. Can someone throw light on whether i am doing it right?
import javax.crypto.Cipher
import java.security.KeyFactory
import java.security.spec.X509EncodedKeySpec
def publicKey = '5dy47yt7ty5ad283c0c4955f53csa24wse244wfrfafa34239rsgd89gfsg8342r93r98efae89fdf9983r9gjsdgnsgjkwt23r923r2r0943tf9sdg9d8gfsgf90sgsf89grw098tg09s90ig90g90s903r5244r517823rea8f8werf9842tf24tf42e0132saf9fg6f65afa43f12r103tf4040ryrw0e9rtqtwe0r9t04ty8842t03e9asfads0fgadg675'
def x509PublicKey = new X509EncodedKeySpec(publicKey.decodeBase64())
def keyFactory = KeyFactory.getInstance('RSA')
def key = keyFactory.generatePublic(x509Publickey)
def string2Encrypt = '("testinga#gmail.com|testingb#gmail.com").'
def encryptCipher = Cipher.getInstance('RSA')
encryptCipher.init(Cipher.ENCRYPT_MODE,key)
def secretMessage = string2Encrypt.getBytes('UTF-8')
def encryptedMessage = encryptCipher.doFinal(secretMessage)
def encodedMessage = encryptedMessage.encodedBase64().toString()
vars.put('encodedMessage',encodedMessage)
The Output Error i am getting
Response Code: 500
Response Message:javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: x509Publickey for class: Script4
SampleResult fields:
ContentType:
DataEncoding: null
You have:
def x509PublicKey
^ mind the capital K
and
def key = keyFactory.generatePublic(x509Publickey)
^ mind the lower-case k
in Groovy they're absolutely different beasts and case sensitivity matters a lot, choose one option and stick to it and "your" script will start working as expected (or at least this error will go away)
More information:
Apache Groovy - Syntax
Apache Groovy - Why and How You Should Use It

Pyarrow basic auth: How to prevent `Stream is closed`?

I am new to Arrow Flight and pyarrow (v=6.0.1), and am trying to implement basic auth but I am always getting an error:
OSError: Stream is closed
I have created a minimal reproducing sample, by running the following two files sequentially (representing server and client respectively):
from typing import Dict, Union
from pyarrow.lib import tobytes
from pyarrow.flight import BasicAuth, FlightUnauthenticatedError, ServerAuthHandler, FlightServerBase
from pyarrow._flight import ServerAuthSender, ServerAuthReader
class ServerBasicAuthHandler(ServerAuthHandler):
def __init__(self, creds: Dict[str, str]):
self.creds = {user.encode(): pw.encode() for user, pw in creds.items()}
def authenticate(self, outgoing: ServerAuthSender, incoming: ServerAuthReader):
buf = incoming.read() # this line raises "OSError: Stream is closed"
auth = BasicAuth.deserialize(buf)
if auth.username not in self.creds:
raise FlightUnauthenticatedError("unknown user")
if self.creds[auth.username] != auth.password:
raise FlightUnauthenticatedError("wrong password")
outgoing.write(tobytes(auth.username))
def is_valid(self, token: bytes) -> Union[bytes, str]:
if not token:
raise FlightUnauthenticatedError("no basic auth provided")
if token not in self.creds:
raise FlightUnauthenticatedError("unknown user")
return token
service = FlightServerBase(
location=f"grpc://[::]:50051",
auth_handler=ServerBasicAuthHandler({"user": "pw"}),
)
service.serve()
from pyarrow.flight import FlightClient
client = FlightClient(location=f"grpc://localhost:50051")
client.authenticate_basic_token("user", "pw")
I basically copied the ServerAuthHandler implementation from their tests, so it is proven to work. However, I can't get it to work.
The error message Stream is closed hard to debug. I don't know where it comes from and I can't trace it to anywhere within the pyarrow implementation (neither Pythonside nor C++ side). I can't see where it comes from.
Any help or hints on how to prevent this error would be appreciated.
The example in the OP is mixing up two authentication implementations (which is indeed confusing). The "BasicAuth" object isn't actual HTTP basic authentication that the authenticate_basic_token method implements; this is because contributors have implemented a variety of authentication methods over the years. The actual test is as follows:
header_auth_server_middleware_factory = HeaderAuthServerMiddlewareFactory()
no_op_auth_handler = NoopAuthHandler()
def test_authenticate_basic_token():
"""Test authenticate_basic_token with bearer token and auth headers."""
with HeaderAuthFlightServer(auth_handler=no_op_auth_handler, middleware={
"auth": HeaderAuthServerMiddlewareFactory()
}) as server:
client = FlightClient(('localhost', server.port))
token_pair = client.authenticate_basic_token(b'test', b'password')
assert token_pair[0] == b'authorization'
assert token_pair[1] == b'Bearer token1234'
i.e. we're not using authenticate but rather a "middleware" to do the implementation. A full example looks as follows:
import base64
import pyarrow.flight as flight
class BasicAuthServerMiddlewareFactory(flight.ServerMiddlewareFactory):
def __init__(self, creds):
self.creds = creds
def start_call(self, info, headers):
token = None
for header in headers:
if header.lower() == "authorization":
token = headers[header]
break
if not token:
raise flight.FlightUnauthenticatedError("No credentials supplied")
values = token[0].split(' ', 1)
if values[0] == 'Basic':
decoded = base64.b64decode(values[1])
pair = decoded.decode("utf-8").split(':')
if pair[0] not in self.creds:
raise flight.FlightUnauthenticatedError("No credentials supplied")
if pair[1] != self.creds[pair[0]]:
raise flight.FlightUnauthenticatedError("No credentials supplied")
return BasicAuthServerMiddleware("BearerTokenValue")
raise flight.FlightUnauthenticatedError("No credentials supplied")
class BasicAuthServerMiddleware(flight.ServerMiddleware):
def __init__(self, token):
self.token = token
def sending_headers(self):
return {'authorization': f'Bearer {self.token}'}
class NoOpAuthHandler(flight.ServerAuthHandler):
def authenticate(self, outgoing, incoming):
pass
def is_valid(self, token):
return ""
with flight.FlightServerBase(auth_handler=NoOpAuthHandler(), middleware={
"basic": BasicAuthServerMiddlewareFactory({"test": "password"})
}) as server:
client = flight.connect(('localhost', server.port))
token_pair = client.authenticate_basic_token(b'test', b'password')
print(token_pair)
assert token_pair[0] == b'authorization'
assert token_pair[1] == b'Bearer BearerTokenValue'
I think it's simply due to this not being supported on Windows.
On closer inspection, the test that "proves it work" is being skipped in Windows. The comment refers to this issue. That issue has been fixed though (ostensibly); not anything as to why it wouldn't work with Stream is closed.

Nim Slack bot Signature Verification Issues

I'm fairly new to Nim, and I suspect I'm just doing something wrong here. I'm using Jester (for routing, etc) and Nimcrytpo (for hmac) but something isn't adding up. Here's how I'm attempting to verify a signature:
import jester
import dotenv
import os, strutils, times
import nimcrypto
const timestampHeader = "X-Slack-Request-Timestamp"
const slackSignatureHeader = "X-Slack-Signature"
const signatureVersion = "v0"
const signingSecret = os.getEnv("SLACK_SIGNING_SECRET")
proc isTimestampRecent(timestamp: int): bool =
abs(getTime().toUnix - timestamp) <= (60 * 5)
proc verifySignature*(request: Request): bool =
if (not request.headers.hasKey timestampHeader) or
(not request.headers.hasKey slackSignatureHeader):
return false
let timestamp = request.headers[timestampHeader].parseInt
if not timestamp.isTimestampRecent():
return false
let baseString = signatureVersion & ':' & $timestamp & ':' & $request.body
let mySignature = sha256.hmac(signingSecret, baseString)
let slackSignature = MDigest[256].fromHex(request.headers[slackSignatureHeader])
mySignature == slackSignature
A few things I'm running into:
The signature doesn't match, and I'm not really sure how to debug that. I'm definitely getting a valid request from Slack and following the instructions for verification here: https://api.slack.com/authentication/verifying-requests-from-slack#about, but it's incorrect.
I know I'm missing the v0= in the comparison, but I'm not quite sure how to do that with the time independent comparison (whether I should be skipping that part or not in the comparison, etc)
My best guess at this point is that somehow the Jester/Httpbeast request body isn't "raw" enough (though it's just plain json...?) or is somehow processed.
Any help or suggestions on how to debug would be greatly appreciated. Thank you in advance!
After fussing with this for a while, I found I was doing a number of things incorrectly! Hopefully this helps others:
The signingSecret is pulled from the env, so it shouldn't be a constant--I moved that into the proc itself defined with let instead.
The slack signature in the headers is prefixed with v0=, which makes it the wrong length for MDigest[256].fromHex(), so that was ending up as the null value (0000...) instead of what should've been.
Here's a working version, now in case anyone else should need one. Please let me know if you see anything that could be improved as well.
import jester
import dotenv
import os, strutils, times
import nimcrypto
const timestampHeader = "X-Slack-Request-Timestamp"
const slackSignatureHeader = "X-Slack-Signature"
const signatureVersion = "v0"
proc isTimestampRecent(timestamp: int): bool =
abs(getTime().toUnix - timestamp) <= (60 * 5)
proc verifySignature*(request: Request): bool =
let signingSecret = os.getEnv("SLACK_SIGNING_SECRET")
if (not request.headers.hasKey timestampHeader) or
(not request.headers.hasKey slackSignatureHeader):
return false
let timestamp = request.headers[timestampHeader].parseInt
if not timestamp.isTimestampRecent():
return false
let baseString = signatureVersion & ':' & $timestamp & ':' & $request.body
let mySignature = sha256.hmac(signingSecret, baseString)
var rawSlackSignature: string = $request.headers[slackSignatureHeader]
rawSlackSignature.removePrefix(signatureVersion & '=')
let slackSignature = MDigest[256].fromHex(rawSlackSignature)
mySignature == slackSignature

DJANGO-STORAGES, PARAMIKO: connection failure for global connection

I have a strange problem using the SFTP-API from django-storages(https://github.com/jschneier/django-storages). I am trying to use it in order to fetch media-files, which are stored on a different server and thus needed to create a Proxy for SFTP Downloads, since plain Django just sends GET-requests to the MEDIA_ROOT. I figured that Middleware provides a good hook:
import mimetypes
from storages.backends.sftpstorage import SFTPStorage
from django.http import HttpResponse
from storages.backends.sftpstorage import SFTPStorage
class SFTPMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = self.get_response(request)
try:
path = request.get_full_path()
SFTP = SFTPStorage() # <- this is where the magic happens
if SFTP.exists(path):
file = SFTP._read(path)
type, encoding = mimetypes.guess_type(path)
response = HttpResponse(file, content_type=type)
response['Content-Disposition'] = u'attachment; filename="{filename}"'.format(filename=path)
except PermissionError:
pass
return response
which works fine, but obviously it opens a new connection every time a website call is issued which I don't want (it also crashes after 3 reloads or something, I think it has to many parallel connections by then). So I tried just opening one connection to the Server via SFTP by moving the SFTP = SFTPStorage()-initialization into the __init__()-method which is just called once:
import mimetypes
from storages.backends.sftpstorage import SFTPStorage
from django.http import HttpResponse
from storages.backends.sftpstorage import SFTPStorage
class SFTPMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.SFTP = SFTPStorage() # <- this is where the magic happens
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = self.get_response(request)
try:
path = request.get_full_path()
if self.SFTP.exists(path):
file = self.SFTP._read(path)
type, encoding = mimetypes.guess_type(path)
response = HttpResponse(file, content_type=type)
response['Content-Disposition'] = u'attachment; filename="{filename}"'.format(filename=path)
except PermissionError:
pass
return response
But this implementation doesn't seem to work, the program is stuck either before the SFTP.exists() or after the SFTP._read() methods.
Can anybody tell me how to fix this problem? Or does anybody even have a better idea as to how to tackle this problem?
Thanks in advance,
Kingrimursel

Resources