{"action":"created","issue":{"url":"https://api.github.com/repos/treasure-data/td-client-python/issues/12","labels_url":"https://api.github.com/repos/treasure-data/td-client-python/issues/12/labels{/name}","comments_url":"https://api.github.com/repos/treasure-data/td-client-python/issues/12/comments","events_url":"https://api.github.com/repos/treasure-data/td-client-python/issues/12/events","html_url":"https://github.com/treasure-data/td-client-python/pull/12","id":112004256,"number":12,"title":"avoid an exception raised when \"start\" is nil","user":{"login":"k24d","id":924388,"avatar_url":"https://avatars.githubusercontent.com/u/924388?v=3","gravatar_id":"","url":"https://api.github.com/users/k24d","html_url":"https://github.com/k24d","followers_url":"https://api.github.com/users/k24d/followers","following_url":"https://api.github.com/users/k24d/following{/other_user}","gists_url":"https://api.github.com/users/k24d/gists{/gist_id}","starred_url":"https://api.github.com/users/k24d/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/k24d/subscriptions","organizations_url":"https://api.github.com/users/k24d/orgs","repos_url":"https://api.github.com/users/k24d/repos","events_url":"https://api.github.com/users/k24d/events{/privacy}","received_events_url":"https://api.github.com/users/k24d/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-10-18T06:36:27Z","updated_at":"2015-10-18T09:39:24Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/treasure-data/td-client-python/pulls/12","html_url":"https://github.com/treasure-data/td-client-python/pull/12","diff_url":"https://github.com/treasure-data/td-client-python/pull/12.diff","patch_url":"https://github.com/treasure-data/td-client-python/pull/12.patch"},"body":"I got an exception when I created a schedule with 'cron' = ''.  This is a valid schedule meaning that the query is not scheduled to run.\r\n\r\n```python\r\nIn [1]: import tdclient\r\n\r\nIn [2]: c = tdclient.Client()\r\n\r\nIn [3]: c.create_schedule('test1', {'database': 'db1', 'cron': '', 'query': 'select 1'})\r\n---------------------------------------------------------------------------\r\nAttributeError                            Traceback (most recent call last)\r\n<ipython-input-28-82b4b391c57e> in <module>()\r\n----> 1 c.create_schedule('test1', {'database': 'db1', 'cron': '', 'query': 'select 1'})\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/tdclient/client.py in create_schedule(self, name, params)\r\n    511             raise ValueError(\"'query' option is required\")\r\n    512         params = {} if params is None else params\r\n--> 513         return self.api.create_schedule(name, params)\r\n    514\r\n    515     def delete_schedule(self, name):\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/tdclient/schedule_api.py in create_schedule(self, name, params)\r\n     26                 self.raise_error(\"Create schedule failed\", res, body)\r\n     27             js = self.checked_json(body, [\"start\"])\r\n---> 28             return self._parsedate(js[\"start\"], \"%Y-%m-%d %H:%M:%S %Z\")\r\n     29\r\n     30     def delete_schedule(self, name):\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/tdclient/api.py in _parsedate(self, s, fmt)\r\n    337         # TODO: parse datetime with using format string\r\n    338         # for now, this ignores given format string since API may return date in ambiguous format :(\r\n--> 339         return dateutil.parser.parse(s)\r\n    340\r\n    341     def get_or_else(self, hashmap, key, default_value=None):\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/dateutil/parser.py in parse(timestr, parserinfo, **kwargs)\r\n   1006         return parser(parserinfo).parse(timestr, **kwargs)\r\n   1007     else:\r\n-> 1008         return DEFAULTPARSER.parse(timestr, **kwargs)\r\n   1009\r\n   1010\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/dateutil/parser.py in parse(self, timestr, default, ignoretz, tzinfos, **kwargs)\r\n    390             res, skipped_tokens = self._parse(timestr, **kwargs)\r\n    391         else:\r\n--> 392             res = self._parse(timestr, **kwargs)\r\n    393\r\n    394         if res is None:\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/dateutil/parser.py in _parse(self, timestr, dayfirst, yearfirst, fuzzy, fuzzy_with_tokens)\r\n    490\r\n    491         res = self._result()\r\n--> 492         l = _timelex.split(timestr)         # Splits the timestr into tokens\r\n    493\r\n    494         # keep up with the last token skipped so we can recombine\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/dateutil/parser.py in split(cls, s)\r\n    172\r\n    173     def split(cls, s):\r\n--> 174         return list(cls(s))\r\n    175     split = classmethod(split)\r\n    176\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/dateutil/parser.py in __next__(self)\r\n    162\r\n    163     def __next__(self):\r\n--> 164         token = self.get_token()\r\n    165         if token is None:\r\n    166             raise StopIteration\r\n\r\n/Users/knishida/miniconda/envs/pandas3/lib/python3.4/site-packages/dateutil/parser.py in get_token(self)\r\n     80                 nextchar = self.charstack.pop(0)\r\n     81             else:\r\n---> 82                 nextchar = self.instream.read(1)\r\n     83                 while nextchar == '\\x00':\r\n     84                     nextchar = self.instream.read(1)\r\n\r\nAttributeError: 'NoneType' object has no attribute 'read'\r\n```\r\n\r\nWith this patch, create_schedule returns '' (empty string) when cron is ''.  There might be a better value than ''.  The API probably should return a Python object or JSON object instead of start time, but it breaks compatibility.\r\n\r\n```python\r\nIn [1]: import tdclient\r\n\r\nIn [2]: c = tdclient.Client()\r\n\r\nIn [3]: c.create_schedule('test3', {'database': 'db1', 'cron': '', 'query': 'select 1'})\r\nOut[3]: ''\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/treasure-data/td-client-python/issues/comments/148995366","html_url":"https://github.com/treasure-data/td-client-python/pull/12#issuecomment-148995366","issue_url":"https://api.github.com/repos/treasure-data/td-client-python/issues/12","id":148995366,"user":{"login":"k24d","id":924388,"avatar_url":"https://avatars.githubusercontent.com/u/924388?v=3","gravatar_id":"","url":"https://api.github.com/users/k24d","html_url":"https://github.com/k24d","followers_url":"https://api.github.com/users/k24d/followers","following_url":"https://api.github.com/users/k24d/following{/other_user}","gists_url":"https://api.github.com/users/k24d/gists{/gist_id}","starred_url":"https://api.github.com/users/k24d/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/k24d/subscriptions","organizations_url":"https://api.github.com/users/k24d/orgs","repos_url":"https://api.github.com/users/k24d/repos","events_url":"https://api.github.com/users/k24d/events{/privacy}","received_events_url":"https://api.github.com/users/k24d/received_events","type":"User","site_admin":false},"created_at":"2015-10-18T09:39:23Z","updated_at":"2015-10-18T09:39:23Z","body":"Oh, update_schedule has the same bug.  Fixing.."}}