-
Notifications
You must be signed in to change notification settings - Fork 106
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
Create kcsb #54
Conversation
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] |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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__
?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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]) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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("=") |
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
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()] |
There was a problem hiding this comment.
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?)
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 ;) )
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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") |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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
No description provided.