-
Notifications
You must be signed in to change notification settings - Fork 2
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
Feature/logger and redis and api improvements #16
base: master
Are you sure you want to change the base?
Feature/logger and redis and api improvements #16
Conversation
oleksii-symon-corva-ai
commented
Jan 15, 2021
•
edited
Loading
edited
- improved cache type hinting
- improved cache tests
- improved api type hinting
- deleted logger
- deleted obsolete fixtures
…nto feature/minor-logger-and-redis-improvements
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.
Before making improvements I'd like to try out existing implementation. I think we are ready to work with bare requests
and bare Redis
adapter to build an application
@property | ||
def get(self): | ||
return self._request('GET') |
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.
why are all methods are properties?
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.
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 does not sound like a good idea to use language features to force IDE to behave in the way you want it to.
Since get
is a method of the Api
class - it's ok to have it as the first parameter in parameters
def _request(self, method: str): | ||
def _request_helper( | ||
path: str, | ||
*, | ||
data: Optional[dict] = None, # request body | ||
params: Optional[dict] = None, # url query string params | ||
headers: Optional[dict] = None, # additional headers to include in request | ||
max_retries: Optional[int] = None, # custom value for max number of retries | ||
timeout: Optional[int] = None, # request timeout in seconds | ||
) -> Response: | ||
if method not in self.ALLOWED_METHODS: |
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.
Overcomplicated. We can make do without a nested function
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 didn't find another way to get proper parameter information like displayed above
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.
make user-facing function accept these as parameters?
corva/state/redis_adapter.py
Outdated
name = name or self.default_name | ||
|
||
n_set = super().hset(name=name, key=key, value=value, mapping=mapping) | ||
n_set = super().hset(name=self.name, key=key, value=value, mapping=mapping) | ||
|
||
if expiry is None and self.pttl(name=name) > 0: | ||
self.persist(name=name) | ||
if expiry is None and self.pttl() > 0: | ||
self.persist(name=self.name) | ||
|
||
if expiry is not None: | ||
self.expire(name=name, time=expiry) | ||
self.expire(name=self.name, time=expiry) |
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.
need documentation on why do we re-define hset
default behavior
def delete(self) -> int: | ||
return super().delete(self.name) |
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 there any way we can use a non-modified Redis adapter?
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.
yes, we can. logic from overridden functions in RedisAdapter can be moved to corresponding functions in RedisState (e.g move logic from RedisAdapter.hset to RedisState.store). we will get rid of RedisAdapter class and logic will become more straightforward.
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 have some general questions here, as well as inline feedback on the PR:
- What task does this correspond to?
- Why are we refactoring the API interface?
- Why are we removing the logger?
There are a lot of different changes all wrapped up into a single PR here. It would be nice to limit this to only API, only Redis, or only logger changes, if those are necessary. Can we justify this PR?
@@ -52,15 +47,13 @@ def _run(self, event: Event) -> None: | |||
try: | |||
context = self.get_context(event=event) | |||
except Exception: |
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.
These try/except blocks seem pointless now that we are just reraising.
@@ -54,20 +54,25 @@ def _init_session(api_key: str, app_name: str, max_retries: int, allowed_methods | |||
|
|||
return session | |||
|
|||
def get(self, path: str, **kwargs): | |||
return self._request('GET', path, **kwargs) | |||
@property |
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 should leave these as functions and call or pass parameters through directly instead of using a layer of indirection with properties and wrapped functions. See the requests library itself for an example, or just revert back to how it was.
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.
The properties were added with the purpose of getting proper parameter information in IDE. Do you think it'd be better to use functions like before, but without hints?
We can get rid of Api class and instead pass user a Session instance with binded Authorization headers. In this case users will have to write all timeouts and retries themselves. I think it will simplify the code and make the library more intuitive, what do you think? |
It doesnt directly correspond to any task but DC-741. These are small changes, that I've spent like an hour on, but thought would be useful enough to compensate for that time.
Api and Redis interfaces were refactored to add parameter information displayed here
Users should define their own loggers and the library doesnt use it also
Should probably split the PR then and create corresponding tasks in JIRA |
Possibly. But not for certain. We will know for sure when we implement the first app with this library. For now, we can just expose class Api:
def get(self, url, **kwargs):
headers = kwargs.pop('headers', None)
if headers:
headers['Token'] = f'Bearer {AUTH_TOKEN}'
return requests.get(url, headers=headers, **kwargs) The one and only important question is: how a user will interact with this library? |
Can we leave this PR on hold for now? I don't want to make significant interface changes on this, and I'd prefer that we focus just on the stream/scheduled app implementation until that's released. |
Yes, lets hold |