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

added support for schedules #30

Closed
wants to merge 2 commits into from
Closed

Conversation

shinchris
Copy link
Contributor

No description provided.

self.assertEqual("Weekly", all_schedules[1].frequency)
self.assertEqual("2016-09-18T06:00:00Z", all_schedules[1].next_run_at)

def test_get_empty(self):
Copy link
Collaborator

@t8y8 t8y8 Sep 13, 2016

Choose a reason for hiding this comment

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

Do we test this for every content type? I'm not sure it's a super valuable test but it's harmless.

Is it just testing that the Schedule.from_response doesn't choke on an empty input?

If that's the case the mocked request might be unnecessary.

This is minor though, I bet this follows the other test's and that's cool.

@t8y8
Copy link
Collaborator

t8y8 commented Sep 13, 2016

🚀

1 similar comment
@graysonarts
Copy link
Contributor

🚀

self._next_run_at = None
self._priority = None
self._state = None
self._type = None
Copy link
Contributor

Choose a reason for hiding this comment

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

What is type. This doesn't feel like it should be just an arbitrary string

Copy link
Collaborator

Choose a reason for hiding this comment

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

"Extract" or "Subscription" -- maybe more in the future

@shinchris shinchris changed the title added ability to query and delete schedules added support for schedules Sep 16, 2016
@t8y8
Copy link
Collaborator

t8y8 commented Sep 16, 2016

Whoa, this got even bigger :)

It'll take me some time to take a look at it, but I've got a long flight tomorrow...

parser.add_argument('--username', '-u', required=True, help='username to sign into server')
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
help='desired logging level (set to error by default)')
args = parser.parse_args()
Copy link
Collaborator

Choose a reason for hiding this comment

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

The other samples probably need this as well -- but this should be in an if __name__ == '__main__' block so it only runs as a script, and so that we can check for no arguments and print the help.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Addressing the other samples can be a different Issue#

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fixed this in all samples

from .. import NAMESPACE


class IntervalItem(object):
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't have an alternate suggestion, so feel free to ignore, but is IntervalItem the best name we've got?

The nested classes are fine for the enum-y purpose you're using it for (man, in py3 we could use real enums) -- but we might be hitting a point where we just needs a constants or common module that holds all these so the actual class with logic doesn't get muddled down.

I think this is also the case for RequestOptions?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ignored for now


cls._validate_time(start_time)
cls._validate_time(end_time)
interval = [(interval_occurrence.lower(), str(interval_value))]
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this doesn't need to be mutable can just return a tuple here

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure why this is a list, but it's consistent so I left it

self.start_time = start_time

@staticmethod
def _validate_time(t):
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might be useful just as a function at the module level, and returns true or false, then the classes that use it can decide what exception to throw, or to handle some other way (like using a default time)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I looked at it for a while and made a small refactor, but pulling it out can happen in another PR and after more conversation.

(_, name, _, _, updated_at, _, frequency, next_run_at, end_schedule_at, execution_order,
priority, interval_item) = self._parse_element(schedule_xml)

self._set_values(None, name, None, None, updated_at, None, frequency, next_run_at, end_schedule_at,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you use keyword arguments for all of these -- else we're doomed to be lost at sea :)

(Side note, can any of these be moved out of the function, it seems crazy big)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fixed


@classmethod
def from_response(cls, resp):
all_schedule_items = list()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: We seem to use the literal in most places []

Copy link
Collaborator

Choose a reason for hiding this comment

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

fixed

end_schedule_at, execution_order, priority, interval_item) = cls._parse_element(schedule_xml)

schedule_item = cls(name, priority, schedule_type, execution_order, interval_item)
schedule_item._set_values(id, None, state, created_at, updated_at, None, frequency, next_run_at,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same comment about keyword arguments

Copy link
Collaborator

Choose a reason for hiding this comment

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

fixed


priority = schedule_xml.get('priority', None)
if priority:
priority = int(priority)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This will fail if priority is a non empty string that isn't an integer. Do we know that's always safe to do this conversion?

def delete(self, schedule_id):
if not schedule_id:
error = "Schedule ID undefined"
raise ValueError(error)
Copy link
Collaborator

Choose a reason for hiding this comment

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

The exception should get logged as an error -- or do we not do that on other endpoints?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Confirmed the XSD schema only allows nonNegInts


return self

def _set_values(self, id, name, state, created_at, updated_at, schedule_type, frequency,
Copy link
Collaborator

@t8y8 t8y8 Oct 2, 2016

Choose a reason for hiding this comment

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

@RussTheAerialist I took a local copy of this PR to try and address my own feedback and put it up for review, and this method made me wonder if there was a better way.

I'm thinking of instead of having a giant setter that does nothing but check that attributes are not false -- what if something like this:

  1. The ScheduleItem constructor has everything initialized to None (or has default args)
  2. _parse_element returns only non-null/None attributes it gets back as a dict
  3. We can loop over the dict to apply the attributes in _set_values (and remove the giant function signature) or I think we can do away with the method entirely, but the idea was on the tip of my tongue and it left me.

I can dig in farther, but for now I've at least done this:

            schedule_item._set_values(id=id,
                                      name=None,
                                      state=state,
                                      created_at=created_at,
                                      updated_at=updated_at,
                                      schedule_type=None,
                                      frequency=frequency,
                                      next_run_at=next_run_at,
                                      end_schedule_at=end_schedule_at,
                                      execution_order=None,
                                      priority=None,
                                      interval_item=None)

EDIT: I looked at the other *_item files and this is the pattern we use everywhere, I still think it's worth converting everything to keyword arguments though!

t8y8 added a commit to t8y8/server-client-python that referenced this pull request Oct 3, 2016
@graysonarts
Copy link
Contributor

#48 supersedes this change

@graysonarts graysonarts closed this Oct 4, 2016
t8y8 added a commit that referenced this pull request Oct 7, 2016
Original PR by @shinchris #30 

* added ability to query and delete schedules
* added ability to create and update schedules
* intervals for schedules are expressed as (Unit)Interval classes
* hourly intervals can take .25 and .5 to represent 15 and 30 minute schedules
@graysonarts graysonarts deleted the feature-schedule branch October 28, 2016 22: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.

None yet

4 participants