Nathan
Nathan

Reputation: 7699

Setting boto3 dynamodb endpoint_url globaly

I want to use dynamodb local for local (unit) testing of my python/boto3 based application.

Now I can do something like this

if test_mode:
    client = boto3.client("dynamodb", endpoint_url="localhost:8000")
    resource = boto3.resource("dynamodb", endpoint_url="localhost:8000")
else:
    client = boto3.client("dynamodb")
    resource = boto3.resource("dynamodb")

But I would like to avoid the test_mode check.

Can I somehow "prepare" boto3 so the dynamodb endpoint URL is set globally?

Update

To further explain what I want. I want some sort of function, where I can say:

boto3.setGlobalDynamodbEndpoint("http://localhost:8000")

such that when, after calling this function, I do:

client = boto3.client("dynamodb")
resource = boto3.resource("dynamodb")

The endpoint will automatically be set to "http://localhost:8000"

Upvotes: 3

Views: 2400

Answers (2)

Rachel
Rachel

Reputation: 2894

I've just submitted a PR to the boto3 project to use an env var to override the endpoint_url, which might be useful for this.

https://github.com/boto/boto3/pull/2746

https://github.com/rwillmer/boto3

Upvotes: 2

bjmc
bjmc

Reputation: 3272

As far as I know, there's no built-in function in the boto3 library that will do this for you, but you could achieve a similar result using the functools.partial utility in the Python standard library. This tool takes a Python callable and one or more arguments, and returns a new callable that does the same thing, but with those arguments "pre-set". In functional programming jargon, this is called "partially applying" a function (hence the name partial).

For example,

import functools
import boto3

URL = "http://localhost:8000"
boto3.client = functools.partial(botot3.client, endpoint_url=URL)
boto3.resource = functools.partial(boto3.resource, endpoint_url=URL)

By redefining boto3.client and boto3.resource to be our new partial, instead of the original versions from the library, we're monkey-patching boto3.

Later on in your code, when you call:

client = boto3.client("dynamodb")
resource = boto3.resource("dynamodb")

You won't need to explicitly pass endpoint_url because the client and resource objects will be automatically instantiated with the previously-set URL value in the partial object.

Upvotes: 4

Related Questions