Skip to content

Commit

Permalink
fix: make hive https py2 compat (#389)
Browse files Browse the repository at this point in the history
* fix: make hive https py2 compat

* fix lint
  • Loading branch information
dpgaspar authored Apr 27, 2021
1 parent 3644a97 commit b21c507
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
5 changes: 5 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ First install this package to register it with SQLAlchemy (see ``setup.py``).
logs = Table('my_awesome_data', MetaData(bind=engine), autoload=True)
print select([func.count('*')], from_obj=logs).scalar()
# Hive + HTTPS + LDAP or basic Auth
engine = create_engine('hive+https://username:password@localhost:10000/')
logs = Table('my_awesome_data', MetaData(bind=engine), autoload=True)
print select([func.count('*')], from_obj=logs).scalar()
Note: query generation functionality is not exhaustive or fully tested, but there should be no
problem with raw SQL.

Expand Down
29 changes: 23 additions & 6 deletions pyhive/hive.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,17 @@ def __init__(
/impala/_thrift_api.py#L152-L160
"""
if scheme in ("https", "http") and thrift_transport is None:
port = port or 1000
ssl_context = None
if scheme == "https":
ssl_context = create_default_context()
ssl_context.check_hostname = check_hostname == "true"
ssl_cert = ssl_cert or "none"
ssl_context.verify_mode = ssl_cert_parameter_map.get(ssl_cert, CERT_NONE)
thrift_transport = thrift.transport.THttpClient.THttpClient(
uri_or_host=f"{scheme}://{host}:{port}/cliservice/",
uri_or_host="{scheme}://{host}:{port}/cliservice/".format(
scheme=scheme, host=host, port=port
),
ssl_context=ssl_context,
)

Expand Down Expand Up @@ -259,26 +262,40 @@ def sasl_factory():
def _set_authorization_header(transport, username=None, password=None):
username = username or "user"
password = password or "pass"
auth_credentials = f"{username}:{password}".encode("UTF-8")
auth_credentials = "{username}:{password}".format(
username=username, password=password
).encode("UTF-8")
auth_credentials_base64 = base64.standard_b64encode(auth_credentials).decode(
"UTF-8"
)
transport.setCustomHeaders(
{"Authorization": f"Basic {auth_credentials_base64}"}
{
"Authorization": "Basic {auth_credentials_base64}".format(
auth_credentials_base64=auth_credentials_base64
)
}
)

@staticmethod
def _set_kerberos_header(transport, kerberos_service_name, host) -> None:
def _set_kerberos_header(transport, kerberos_service_name, host):
import kerberos

__, krb_context = kerberos.authGSSClientInit(
service=f"{kerberos_service_name}@{host}"
service="{kerberos_service_name}@{host}".format(
kerberos_service_name=kerberos_service_name, host=host
)
)
kerberos.authGSSClientClean(krb_context, "")
kerberos.authGSSClientStep(krb_context, "")
auth_header = kerberos.authGSSClientResponse(krb_context)

transport.setCustomHeaders({"Authorization": f"Negotiate {auth_header}"})
transport.setCustomHeaders(
{
"Authorization": "Negotiate {auth_header}".format(
auth_header=auth_header
)
}
)

def __enter__(self):
"""Transport should already be opened by __init__"""
Expand Down

0 comments on commit b21c507

Please sign in to comment.