{"id":20905053,"url":"https://github.com/kaste/waterf","last_synced_at":"2025-09-18T08:57:54.814Z","repository":{"id":6848885,"uuid":"8097531","full_name":"kaste/waterf","owner":"kaste","description":"Chain tasks on Google Appengine's taskqueue","archived":false,"fork":false,"pushed_at":"2013-06-03T10:22:18.000Z","size":156,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-20T08:44:57.809Z","etag":null,"topics":["app-engine","google-appengine"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaste.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-08T17:11:46.000Z","updated_at":"2022-06-14T19:53:36.000Z","dependencies_parsed_at":"2022-09-10T08:20:42.458Z","dependency_job_id":null,"html_url":"https://github.com/kaste/waterf","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaste%2Fwaterf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaste%2Fwaterf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaste%2Fwaterf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaste%2Fwaterf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaste","download_url":"https://codeload.github.com/kaste/waterf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243296235,"owners_count":20268551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["app-engine","google-appengine"],"created_at":"2024-11-18T13:21:29.598Z","updated_at":"2025-09-18T08:57:49.785Z","avatar_url":"https://github.com/kaste.png","language":"Python","readme":"A convenience module on top of the deferred library that comes with the Google AppEngine (GAE).\n\nIn a nutshell::\n\n    from waterf import queue, task\n\n    queue.inorder(\n        task(check_condition),\n        queue.parallel(\n            task(remove, id=101),\n            task(remove, id=102),\n            task(remove, id=103)\n        ),\n        task(email, to='foo@bar.com')\n    ).enqueue()\n\nShould be pretty self-explanatory: it first runs the function ``check_condition``, then it runs the function ``remove`` three times in parallel, after that it runs ``email``.\n\nTo abort execution of a series you either raise ``queue.PermanentTaskFailure`` or as a convenience return ``queue.ABORT``. If you return another task, you further defer so to speak: the original task will get resolved (or aborted) as soon as the new (returned) task gets resolved (or aborted).\n\nYou use ``task()`` exactly the same as you used ``deferred.defer()``::\n\n    task(check, id=102, _countdown=20)\n    task(email, to='foo@bar.com', _queue='mailer')\n\nAfter constructing a task you ``enqueue()`` it; the relation to the deferred.defer is roughly speaking::\n\n    task(foo, 'bar').enqueue()  \u003c==\u003e deferred.defer(foo, 'bar')\n    task(foo, 'bar').run()      \u003c==\u003e foo('bar')\n\nEnqueue'ing takes (again) the same options defer took, overruling the ones you used in the constructor, e.g.::\n\n    task(foo).enqueue(queue='mailer', countdown=60)\n\nwaterf adds two options::\n\n    use_id  True | False | str\n            Use if you don't come up with a good name to prevent double-scheduling\n            The value True means autogenerate a good id, otherwise takes your str\n            Defaults to True if a name is not set, otherwise to False\n\n    release_after \u003cseconds\u003e\n            Determines when the id will be released after your task has finished\n            Defaults to 0, immediately\n\nTasks implement a jquery-like callback interface::\n\n    task(foo).then(email_user, email_admin).always(...)\n\nThe callbacks must accept as their first argument the message the task sent. But this message passing will likely be dropped in a future version, because it's unused by the library.\n\nOn top of the waterf.queue there is some experimental jet set in the waterf.snake module, which implements a ndb.tasklet like api::\n\n    from waterf import snake\n\n    def A():\n        raise snake.Return('A')\n\n    def B(): ...\n\n    def work():\n        anA = yield snake.task(A)\n        yield snake.task(B), snake.task(C) ...  # parallel yield\n\n    snake.task(work).enqueue()\n\n\n\n\nNote that you have to enable the deferred library in your app.yaml\n\n::\n\n    builtins:\n    - deferred: on\n\nThank you.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaste%2Fwaterf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaste%2Fwaterf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaste%2Fwaterf/lists"}