{ "info": { "author": "Asher Pembroke", "author_email": "apembroke@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6" ], "description": "\n\n```python\n%load_ext autoreload\n\n%autoreload 2\n```\n\n# Hourly\nA simple hour tracker for git projects. ```hourly``` parses your commit messages for \"clock in/out\" keywords and uses their unix timestamps to precisely calculate work hours.\n\n\n## Getting Started\n\n## Install\n\n pip install hourly\n\n\n### Requirements\n\n\tpandas\n gitpython\n\n### Usage\n\nHourly will look for key words for clocking in/out.\n\nTo clock in:\n\n git commit -m \"clock in - starting work on new feature\"\n\ndo stuff as usual, then clock out\n\n git commit -m \"clock out - finished feature\"\n\n\n# Tutorial\n\nWe can illustrate how to use hourly on the hourly repo itself.\n\n git clone https://github.com/asherp/hourly.git\n cd hourly\n\n\n```python\nfrom hourly.hourly import get_work_commits, get_labor, get_earnings\n```\n\n```get_work_commits``` gathers all commits into a pandas array\n\n\n```python\nwork = get_work_commits('.')\nwork\n```\n\n c:\\programdata\\miniconda2\\lib\\site-packages\\pandas\\core\\sorting.py:257: FutureWarning: Converting timezone-aware DatetimeArray to timezone-naive ndarray with 'datetime64[ns]' dtype. In the future, this will return an ndarray with 'object' dtype where each element is a 'pandas.Timestamp' with the correct 'tz'.\n \tTo accept the future behavior, pass 'dtype=object'.\n \tTo keep the old behavior, pass 'dtype=\"datetime64[ns]\"'.\n items = np.asanyarray(items)\n\n\n\n\n\n
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
messagehash
time
2018-10-19 23:40:41-04:00Initial commitef5690543bfb354b9325d1fbd1f9abbafbb4d9a4
2018-10-19 23:57:48-04:00clock in5c8f05b57b739ec525291c248ea9200651b49997
2018-10-20 00:21:40-04:00preparing setup.py254ecdacb52fc70bc358f8d55be58df3b70c7609
2018-10-20 00:39:11-04:00clock out - work done for the day0e33fa3d74f663f954b05dd9f30e0128ca7af162
2018-10-20 01:06:08-04:00clock in - start adding requirements and examp...dc065b17337b14c2f8e0458de61e6880a338d6ae
2018-10-20 01:47:01-04:00clock out644ad6ebf4c9015fd512ed47b858602d784d6204
2018-10-20 01:47:45-04:00clock in - pro bonoe6b5f78daa68e3731f82effccb66fd4bd14996bf
2018-10-20 01:51:36-04:00clock out - pro bono1aff88af5e9688645966ccd15da8e1530205cfea
2018-10-20 02:03:56-04:00clock in - finishing tutorial53bd7316e579d8582c46af09277b40fbba3a390e
2018-10-20 02:11:54-04:00clock out - converted notebook for READMEd55b5718a3178ab6161f7e3a148c6561a305cd79
2018-10-20 02:14:21-04:00had to clock out so notebook examples don't breakd9ec537b36475b565df6b28d0cab6edc3a89f2da
2018-10-20 02:18:27-04:00fixed for renderinge2f8a2ca212fa9e7568618934da18a0ec7164fa3
2018-10-20 02:22:56-04:00fixing requiremens that raised a security alerte0e71a05c6c5af1fc5515040ec75f33b71bd3b15
2018-10-20 02:51:13-04:00fixed requirements, tutorial updatesd8d87767005022c9a8e83015d40f6fb736f2b73b
2018-10-20 02:57:22-04:00mergingf5585c89612a5fac2d948ee61536fffe276f8949
2018-10-20 03:24:58-04:00Remove autoreloadb2c1d8677ea57aeb959350d663475ba3077f2c96
2018-10-20 11:53:00-04:00clock in - handling errant messagesfa615994ba6b771594d711dea6087cc7ba0348b5
2018-10-20 13:16:13-04:00clock out - converting to pd.Timestamped7aab29e43e7120428816481216198a255de8f4
2018-10-20 13:47:56-04:00clock in - adding work log5b398037bf24cd503a7fc88c3b078913fa184f7e
2018-10-20 14:33:35-04:00clock out - see WorkLog.md93c2aa04aeba7cfe1573205abec053c7da9e9864
2018-10-20 14:35:58-04:00merged6a7f4ac45de70d94fb943d0676265cafd5bf1e41
2018-10-20 17:34:38-04:00pushing version2b633644d6ba24b9c1bbff6881a99df6ab935a8d
2018-10-28 13:44:48-04:00clock inc4e95f59dc0c8ce296a40300760ab68800f7e139
2018-10-28 13:56:35-04:00clock outf5200e718c062e828d436506286fd05e56b606c5
2018-11-23 13:51:05-05:00changed formatting of wages earned9630e123f8748bb8260da27498e3600a3271e4c2
2018-11-23 14:14:38-05:00changed license to Apache 2.0'b7791826f2df0212ce49b51b621dd7e7cc0d6f14
2019-02-25 10:19:10-05:00clock in T-1hrd7add63b4d2e3e1ca1423296aaed25d9c28944da
2019-02-25 12:49:51-05:00clock out T-5macfb8596317786e38177345aa2531098043a5c49
\n
\n\n\n\n```get_labor``` calculates hours worked by differencing commit timestamps and raises an error if clock in and clock out are of different lengths.\n\n### Getting time card\n\n\n```python\nimport pandas as pd\npd.set_option('display.width', 400)\n```\n\n\n```python\nget_labor(work, end_date='2018-10-20 02:11:54-04:00')\n```\n\n pay period: 2018-10-19 23:57:48-04:00 -> 2018-10-20 02:11:54-04:00\n\n\n\n\n\n
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
TimeInlog inTimeOutlog outTimeDelta
02018-10-19 23:57:48-04:00clock in2018-10-20 00:39:11-04:00clock out - work done for the day00:41:23
12018-10-20 01:06:08-04:00clock in - start adding requirements and examp...2018-10-20 01:47:01-04:00clock out00:40:53
22018-10-20 01:47:45-04:00clock in - pro bono2018-10-20 01:51:36-04:00clock out - pro bono00:03:51
32018-10-20 02:03:56-04:00clock in - finishing tutorial2018-10-20 02:11:54-04:00clock out - converted notebook for README00:07:58
\n
\n\n\n\n### Handling errant clock in/out messages\nIf you mistakenly put \"clock out\" in a message, hourly will interpret the message as a legitimate end time. This will likely raise an error when computing the labor. For example, there is a problematic commit in the this repo's history:\n\n\n```python\nproblematic_commit = work[work.hash == 'd9ec537b36475b565df6b28d0cab6edc3a89f2da']\nproblematic_commit\n```\n\n\n\n\n
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
messagehash
time
2018-10-20 02:14:21-04:00had to clock out so notebook examples don't breakd9ec537b36475b565df6b28d0cab6edc3a89f2da
\n
\n\n\n\nWhen we include this in our labor calculation, we get the following error:\n\n\n```python\ntry:\n get_labor(work, end_date = '2018-10-20 13:16:13-04:00')\nexcept ValueError as e:\n print(e)\n```\n\n pay period: 2018-10-19 23:57:48-04:00 -> 2018-10-20 13:16:13-04:00\n In/Out logs do not match\n\n\nWe can skip this errant commit by setting ```errant_clocks```\n\n\n```python\nget_labor(work, end_date = '2018-10-20 13:16:13-04:00', \n errant_clocks = ['d9ec537b36475b565df6b28d0cab6edc3a89f2da'])\n```\n\n pay period: 2018-10-19 23:57:48-04:00 -> 2018-10-20 13:16:13-04:00\n\n\n\n\n\n
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
TimeInlog inTimeOutlog outTimeDelta
02018-10-19 23:57:48-04:00clock in2018-10-20 00:39:11-04:00clock out - work done for the day00:41:23
12018-10-20 01:06:08-04:00clock in - start adding requirements and examp...2018-10-20 01:47:01-04:00clock out00:40:53
22018-10-20 01:47:45-04:00clock in - pro bono2018-10-20 01:51:36-04:00clock out - pro bono00:03:51
32018-10-20 02:03:56-04:00clock in - finishing tutorial2018-10-20 02:11:54-04:00clock out - converted notebook for README00:07:58
42018-10-20 11:53:00-04:00clock in - handling errant messages2018-10-20 13:16:13-04:00clock out - converting to pd.Timestamp01:23:13
\n
\n\n\n\n### Filtering work session keywords\n\nUse the \"ignore\" key word to skip any work you don't want to include in your invoices.\n\n\n```python\nlabor = get_labor(work, \n ignore = 'pro bono', \n end_date = '2018-10-20 13:16:13-04:00',\n errant_clocks = ['d9ec537b36475b565df6b28d0cab6edc3a89f2da'])\nlabor\n```\n\n pay period: 2018-10-19 23:57:48-04:00 -> 2018-10-20 13:16:13-04:00\n ignoring pro bono\n\n\n\n\n\n
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
TimeInlog inTimeOutlog outTimeDelta
02018-10-19 23:57:48-04:00clock in2018-10-20 00:39:11-04:00clock out - work done for the day00:41:23
12018-10-20 01:06:08-04:00clock in - start adding requirements and examp...2018-10-20 01:47:01-04:00clock out00:40:53
32018-10-20 02:03:56-04:00clock in - finishing tutorial2018-10-20 02:11:54-04:00clock out - converted notebook for README00:07:58
42018-10-20 11:53:00-04:00clock in - handling errant messages2018-10-20 13:16:13-04:00clock out - converting to pd.Timestamp01:23:13
\n
\n\n\n\n## Get total earnings\n\nTotal earnings can be found using this function. Currency is just a string for printing, but in the future we can add unit conversion.\n\n\n```python\nget_earnings(labor, wage = 30, currency = 'USD')\n```\n\n 0 days 02:53:27, 2.89 hours worked\n 86.72 USD\n\n\n\n\n\n 86.72\n\n\n\n# Time adjustment\n\nIf you forget to clock in or clock out, you can correct your time sheet by adjusting your clock time. By default, Hourly adjusts time stamps automatically when a commit message contains the keyword \"T-\". Set ```correct_times``` to false to override this behavior.\n\n\n```python\nwork = get_work_commits('.', correct_times=False) # reports the actual time of the commit\nwork = work[work.message.str.contains('T-')] #filter by T-\nwork\n```\n\n\n\n\n
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
messagehash
time
2019-02-25 11:19:10-05:00clock in T-1hrd7add63b4d2e3e1ca1423296aaed25d9c28944da
2019-02-25 12:54:51-05:00clock out T-5macfb8596317786e38177345aa2531098043a5c49
\n
\n\n\n\n\n```python\nwork = get_work_commits('.') # reports actual work time, according to commit message\nwork = work[work.message.str.contains('T-')] #filter by T-\nwork\n```\n\n\n\n\n
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
messagehash
time
2019-02-25 10:19:10-05:00clock in T-1hrd7add63b4d2e3e1ca1423296aaed25d9c28944da
2019-02-25 12:49:51-05:00clock out T-5macfb8596317786e38177345aa2531098043a5c49
\n
\n\n\n\nNote: Only time subtractions are supported for now.\n\n### Time delta formats\n\nHourly uses pandas' Timedelta format to modify times. This allows for a lot of flexibility.\n\n\n```python\npd.Timedelta('1hr45m')\n```\n\n\n\n\n Timedelta('0 days 01:45:00')\n\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://asherp.github.io/hourly/", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "hourly", "package_url": "https://pypi.org/project/hourly/", "platform": "", "project_url": "https://pypi.org/project/hourly/", "project_urls": { "Homepage": "https://asherp.github.io/hourly/" }, "release_url": "https://pypi.org/project/hourly/0.1.1/", "requires_dist": [ "Click", "pandas", "gitpython", "dash (==1.1.1)" ], "requires_python": "", "summary": "A simple hour tracker for git", "version": "0.1.1" }, "last_serial": 5859898, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "7559c29f84a88a05dd0f7c9791a3f42f", "sha256": "a7a0a5e15c0d050eddc8013bdcd3336344864e9cff46635232e21da23cc281cb" }, "downloads": -1, "filename": "hourly-0.0.1-py2.7.egg", "has_sig": false, "md5_digest": "7559c29f84a88a05dd0f7c9791a3f42f", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 5514, "upload_time": "2018-10-20T07:10:36", "url": "https://files.pythonhosted.org/packages/b5/66/ec050a0f6ac8673aea5de3a8ef3e801b510b96f6cfee73dada194d6df64a/hourly-0.0.1-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "9adde773d1c7eea76deff4bba97233f3", "sha256": "50fdd6fa22a5624d654bc4722f573b06365b728e9bd5e70a941cd9b2512ecc82" }, "downloads": -1, "filename": "hourly-0.0.1-py3.7.egg", "has_sig": false, "md5_digest": "9adde773d1c7eea76deff4bba97233f3", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": null, "size": 5645, "upload_time": "2018-10-20T07:04:27", "url": "https://files.pythonhosted.org/packages/51/49/b220d67a9e0892e1f2f7b81a6cafcf14a9a693635f78e6acacc991387d9c/hourly-0.0.1-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "c021978d53ed1a1b10d42892cc4fd8fb", "sha256": "ddbb01f21e381e3d7f8ac8b4655512a430f7ec13052dca2c3c784a37315089e3" }, "downloads": -1, "filename": "hourly-0.0.1.tar.gz", "has_sig": false, "md5_digest": "c021978d53ed1a1b10d42892cc4fd8fb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3793, "upload_time": "2018-10-20T07:10:37", "url": "https://files.pythonhosted.org/packages/87/03/3c4df65423dd9c8502e15fb2328e6fde644949d6d076444fd8a0d0751dd0/hourly-0.0.1.tar.gz" } ], "0.0.1.dev0": [ { "comment_text": "", "digests": { "md5": "619dfed837361b6124e5792699f505ea", "sha256": "59189486fb473207c922be9bda42df5ce7d94ba35c9ce5f8f1813432e6474f3a" }, "downloads": -1, "filename": "hourly-0.0.1.dev0-py2.7.egg", "has_sig": false, "md5_digest": "619dfed837361b6124e5792699f505ea", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 4313, "upload_time": "2018-10-20T04:35:37", "url": "https://files.pythonhosted.org/packages/c5/c9/b466bb7e49ebcc3300565231881f793bcedf84a16dddab31d98234219608/hourly-0.0.1.dev0-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "2856a7bd9c62c6fd4dfee486e1b4a371", "sha256": "bde81b27af2c8f5ed8872c69ab81c09f56707449290ff94476c57a072e439ba1" }, "downloads": -1, "filename": "hourly-0.0.1.dev0.tar.gz", "has_sig": false, "md5_digest": "2856a7bd9c62c6fd4dfee486e1b4a371", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2190, "upload_time": "2018-10-20T04:35:38", "url": "https://files.pythonhosted.org/packages/f4/52/7aa4d4d5b2671f0e2b3165c3aa0019b0f06139f3f2221525114c338621fd/hourly-0.0.1.dev0.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "a76318544e0ee577b5914d7cf1de9816", "sha256": "3f0e65859490507ae585f40d982dbaaf9441c623bf87d58cf211f7cce1dac804" }, "downloads": -1, "filename": "hourly-0.0.2-py3.7.egg", "has_sig": false, "md5_digest": "a76318544e0ee577b5914d7cf1de9816", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": null, "size": 6943, "upload_time": "2018-10-20T21:36:41", "url": "https://files.pythonhosted.org/packages/a3/b2/4fd4374c5ae3742aa3f2c1a0db791ae1ed95b4323265189b0bb369249109/hourly-0.0.2-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "d7ed6ec97bfa161e16c711f3f37c300b", "sha256": "70804db0fc2ece46bab8876192c435aa255ab8d551d6fae7fd2d4fb00970f175" }, "downloads": -1, "filename": "hourly-0.0.2.tar.gz", "has_sig": false, "md5_digest": "d7ed6ec97bfa161e16c711f3f37c300b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6156, "upload_time": "2018-10-20T21:36:42", "url": "https://files.pythonhosted.org/packages/9c/5b/4250819edd5d2533f8d641a74f1489aee4beb251006e6f867e888db4591b/hourly-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "543d8a4e64677a6c9ecc74928909ef6d", "sha256": "d900d81a27aae00d86c457b18ff632bf8d0e2403b1260cdd459dcec1342fff7b" }, "downloads": -1, "filename": "hourly-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "543d8a4e64677a6c9ecc74928909ef6d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 10555, "upload_time": "2019-02-25T18:24:47", "url": "https://files.pythonhosted.org/packages/fd/74/6a7441a5f4f378a0992596b5d4c5ce902c4b8219a41f67b6b3aa0344dcc7/hourly-0.0.3-py3-none-any.whl" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "cdd474a95bd4f0e8120b68f271e5ad23", "sha256": "c65c982e7fbc1e8cb192ab48a716eaec2690f57d8e59867c6528d0a975960db8" }, "downloads": -1, "filename": "hourly-0.0.4-py2-none-any.whl", "has_sig": false, "md5_digest": "cdd474a95bd4f0e8120b68f271e5ad23", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 7300, "upload_time": "2019-03-12T22:24:42", "url": "https://files.pythonhosted.org/packages/6a/77/92817761ba2c414fa23a59d65ead14e48fd2685feb4cd6a1ccdf66e38eb0/hourly-0.0.4-py2-none-any.whl" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "61ee9e0aaabfdae7626c46039c0ef595", "sha256": "181b9397232dbd0b341c89026ac1821c64b4c71bcd1baba181dcfe97bb9f4438" }, "downloads": -1, "filename": "hourly-0.0.5-py2-none-any.whl", "has_sig": false, "md5_digest": "61ee9e0aaabfdae7626c46039c0ef595", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 7327, "upload_time": "2019-03-12T22:40:11", "url": "https://files.pythonhosted.org/packages/97/a3/7b2040bea4079e8ce200be7e5346a180c48315d83cc9c6030f227f712b6b/hourly-0.0.5-py2-none-any.whl" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "a738a684043ed43388c93bfe4eacf01a", "sha256": "ad3197301fcddc17466a23082926973301e3e56090bfe3bfc02e46a1da1c418a" }, "downloads": -1, "filename": "hourly-0.0.6-py2-none-any.whl", "has_sig": false, "md5_digest": "a738a684043ed43388c93bfe4eacf01a", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 7470, "upload_time": "2019-03-16T23:10:59", "url": "https://files.pythonhosted.org/packages/d6/f3/ac47ad2103ccbbef74578578cad8ef78607eba90f08873333f1e18e50c03/hourly-0.0.6-py2-none-any.whl" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "356d50013b879cc084db84359123889a", "sha256": "22bf24b9b3d5d88bae31e3fd44c18bc65bbad52b58ca1b206794b58ebd22239c" }, "downloads": -1, "filename": "hourly-0.0.7-py2-none-any.whl", "has_sig": false, "md5_digest": "356d50013b879cc084db84359123889a", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 7557, "upload_time": "2019-03-21T01:28:35", "url": "https://files.pythonhosted.org/packages/6a/6b/dccb808a7615a4d690c27f2ece34d9b7910333ab40ae2b08d74e5b456df7/hourly-0.0.7-py2-none-any.whl" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "59cb27bb6a636ea77ba34aeca66396ae", "sha256": "0659d7f7e77e8e30bb3fc847acabfd3b3df7e4516c1bb070738497e66f12f336" }, "downloads": -1, "filename": "hourly-0.0.8-py3-none-any.whl", "has_sig": false, "md5_digest": "59cb27bb6a636ea77ba34aeca66396ae", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11660, "upload_time": "2019-04-08T06:21:30", "url": "https://files.pythonhosted.org/packages/61/fa/e40373c463ce95b43108d9a31d7279dc16cd4a24f8afff3a918537ac6ebc/hourly-0.0.8-py3-none-any.whl" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "c816e45dfefe9cec8439cfafdaddf250", "sha256": "cd6ddcdc560b73ce73b470ba8fdec36912f03f1b55724d4cf0510339882550b3" }, "downloads": -1, "filename": "hourly-0.0.9-py3-none-any.whl", "has_sig": false, "md5_digest": "c816e45dfefe9cec8439cfafdaddf250", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12212, "upload_time": "2019-04-11T07:27:40", "url": "https://files.pythonhosted.org/packages/9d/a6/0eafceb7522fa47a2262aa0fe28ef0f79847b1014a103c13d9ec7dbff40a/hourly-0.0.9-py3-none-any.whl" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "1bc8e2f1dd9151bf12d10b7a0fb57ff0", "sha256": "cc558e7c96d37e8ea266f45f7d6b10d0d4a87442faa99a3bd30eee6e67ada902" }, "downloads": -1, "filename": "hourly-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "1bc8e2f1dd9151bf12d10b7a0fb57ff0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 13171, "upload_time": "2019-09-20T02:52:35", "url": "https://files.pythonhosted.org/packages/cc/a7/563c9d851572631fc27e842c3253f926a21d0f10ca5b491a071023e09e50/hourly-0.1.1-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "1bc8e2f1dd9151bf12d10b7a0fb57ff0", "sha256": "cc558e7c96d37e8ea266f45f7d6b10d0d4a87442faa99a3bd30eee6e67ada902" }, "downloads": -1, "filename": "hourly-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "1bc8e2f1dd9151bf12d10b7a0fb57ff0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 13171, "upload_time": "2019-09-20T02:52:35", "url": "https://files.pythonhosted.org/packages/cc/a7/563c9d851572631fc27e842c3253f926a21d0f10ca5b491a071023e09e50/hourly-0.1.1-py3-none-any.whl" } ] }