Skip to content

Instantly share code, notes, and snippets.

@lowlevl
Last active June 26, 2020 16:08
Show Gist options
  • Save lowlevl/793a25aa946b7211ce9026b85f31b233 to your computer and use it in GitHub Desktop.
Save lowlevl/793a25aa946b7211ce9026b85f31b233 to your computer and use it in GitHub Desktop.
Transactionnal decorator for Python & GCP Datastore
from google.cloud import datastore
from .transactionnal import transactionnal
client = datastore.Client('<project-id>', '<namespace>')
key = <get a key somehow>
##
# > @transactionnal(client)
# > def _():
# is equivalent to
# > with client.transaction():
# but it cannot fail
@transactionnal(client)
def _():
player = client.get(key)
player['total_points'] += 10
client.put(player)
from tenacity import retry, retry_if_exception_type, wait_random, stop_after_attempt
from google.api_core import exceptions
##
# Simple decorator to be able to reproduce the behaviour of the `with`
# keyword for transactions
def transactionnal(client, *args, **kwargs):
if callable(client):
raise TypeError('transactionnal() missing 1 required positional argument: \'client\'')
@retry(
retry=retry_if_exception_type(exceptions.Aborted),
wait=wait_random(.1, .3),
stop=stop_after_attempt(7))
def _(f):
with client.transaction():
f(*args, **kwargs)
return _
@lowlevl
Copy link
Author

lowlevl commented Jun 26, 2020

Reserved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment