Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create kcsb #54

Merged
merged 15 commits into from
Aug 16, 2018
Merged

Create kcsb #54

merged 15 commits into from
Aug 16, 2018

Conversation

toshetah
Copy link
Contributor

No description provided.

@toshetah toshetah self-assigned this Aug 14, 2018
result.append(
"Please provide the following data ot Kusto: CRID='{0}' Description:'{1}'".format(
q[self._crid_column], q[self._status_column]
row[self._crid_column], row[self._status_column]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could do this:

"Please provide the following data ot Kusto: CRID='{0._crid_column}' Description:'{0._status_column}'".format(self)

:param str user_id: AAD user ID.
:param str password: Corresponding password of the AAD user.
"""
_ensure_value_is_valid(connection_string)
Copy link
Contributor

@danield137 danield137 Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

naming conventions for checks that raise is usually - assert_value_is_valid. assert_non_empty probably better describes the function

:param str user_id: AAD user ID.
:param str password: Corresponding password of the AAD user.
"""
_ensure_value_is_valid(connection_string)
Copy link
Contributor

@danield137 danield137 Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably assert connection_string in init as this method is more specific for username + password

return self._internal_dict[self.ValidKeywords.authority_id]
return None

@authority_id.setter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this covered by __setitem__ ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__setitem__ is for x[y] = 1 -- the setter implements x.y = 1 (which is __setattr__).

The body of this setter actually relies on __setitem__ :)


def _ensure_value_is_valid(value):
if not value or not value.strip():
raise ValueError
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ValueError('Should not be empty')

"""Acquire tokens from AAD."""
token = self._adal_context.acquire_token(
self._kusto_cluster, self._username, self._client_id
)
if token is not None:
expiration_date = dateutil.parser.parse(token[TokenResponseFields.EXPIRES_ON])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it in the same timezone?

Copy link
Contributor Author

@toshetah toshetah Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if connection_string is not None and "=" not in connection_string.partition(";")[0]:
connection_string = "Data Source=" + connection_string
for kvp_string in connection_string.split(";"):
kvp = kvp_string.split("=")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

key, _, value = kvp_string.partition("=") is likely better here, as it will better handle strings like "Password=My=Password=Has=Equals=In=It"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

>>> kusto_client = KustoClient(kusto_cluster, username='your_username', password='your_password')
def __setitem__(self, key, value):
try:
keyword = key if isinstance(key, self.ValidKeywords) else self._Keywords[key.strip()]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a neat trick, you can also put all the ValidKeywords values in _Keywords and then just unconditionally look it up (depending on how critical the .strip() is - is leading/trailing whitespace something you expect to see? But not case-insensitive?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the strip is important, and thanks for showing me the case insensitivity, as it is required as well.
What would you recommend in such a case? How to implement a one to many enum, when the keys are case insensitive and should be stripped?

Copy link
Member

@zooba zooba Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you really expect an enum, but will also map a str to a member of that enum. So in that case what you have is fine, but I'd flip the logic around and convert str to the enum first:

if isinstance(key, str):
    # all the keys in _Keywords should be lowercase
    keyword = self._Keywords.get(key.strip().lower())
if not isinstance(key, self.ValidKeywords):
    raise ValueError(...)
# rest of function

KustoClient works with both 2.x and 3.x flavors of Python. All primitive types are supported.
KustoClient takes care of ADAL authentication, parsing response and giving you typed result set.
@unique
class ValidKeywords(Enum):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason for this to be nested within this class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only a logic reason. Those are the valid keywords to build a Kusto connection string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing to test is that you can put these values into a dict and round-trip it using pickle. Sometimes it can't handle certain nesting, though I think this one will be fine.

"""
if self.ValidKeywords.data_source in self._internal_dict:
return self._internal_dict[self.ValidKeywords.data_source]
return None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern is the same as return self._internal_dict.get(self.ValidKeywords.data_source) (except the shorter one doesn't have a race condition ;) )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

return self._internal_dict[self.ValidKeywords.authority_id]
return None

@authority_id.setter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__setitem__ is for x[y] = 1 -- the setter implements x.y = 1 (which is __setattr__).

The body of this setter actually relies on __setitem__ :)

data_frame = (
client.execute_query("PythonTest", "Deft")
.primary_results[0]
.to_dataframe(errors="ignore")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'd indent these two lines again to make it clearer that they're part of the same expression (dots, not commas).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd agree with you, but black doesn't :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Looks like it's being tracked on Black at psf/black#147

@toshetah toshetah merged commit 493322b into master Aug 16, 2018
@toshetah toshetah deleted the create_kcsb branch August 16, 2018 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants