Skip to content

Add profile_name option to sessions - #69

Closed
danielgtaylor wants to merge 1 commit into
developfrom
session-profile
Closed

danielgtaylor wants to merge 1 commit into
developfrom
session-profile

Conversation

@danielgtaylor

Copy link
Copy Markdown
Contributor

This change makes it possible to create a session using a profile name, which
was previously only possible via an environment variable. It allows you to
create clients and resources from any number of sessions using any number of
profiles.

Given that we have the following ~/.aws/credentials:

[default]
aws_access_key_id = DEFAULT
aws_secret_access_key = SECRET1

[dev]
aws_access_key_id = DEV
aws_secret_access_key = SECRET2

[prod]
aws_access_key_id = PROD
aws_secret_access_key = SECRET3

You can do the following:

import boto3.session

dev = boto3.session.Session(profile_name='dev')
prod = boto3.session.Session(profile_name='prod')

for session in [dev, prod]:
    print('Profile: ' + session.profile)
    s3 = session.resource('s3')
    for bucket in s3.buckets.all():
        print(bucket.name)
    print('')

It is also possible to setup the default session with a profile:

import boto3

boto3.setup_default_session(profile_name='dev')

s3 = boto3.resource('s3')

And of course you can still use the environment variable:

$ BOTO_DEFAULT_PROFILE=dev ipython
>>> import boto3
>>> s3dev = boto3.resource('s3')

Once a session is created, the profile is immutable. The profile_name
property is provided for convenience and just surfaces the underlying
Botocore session's profile property.

Why not provide a profile name to the client and resource methods?
Currently there is no easy way to clone a session, and the behavior of
creating a new blank session (from one which may have customizations)
leads to possibly unintended side-effects like clients without the
proper event handlers registered. This would be an additive change
should we want to revisit in the future. At this point, the change
in this commit provides a way for Boto 3 users to use multiple profiles
without resorting to creating their own Botocore sessions.

I'm definitely open to suggestions and counter-arguments.

cc @jamesls @kyleknap

This change makes it possible to create a session using a profile name, which
was previously only possible via an environment variable. It allows you to
create clients and resources from any number of sessions using any number of
profiles.

Given that we have the following `~/.aws/credentials`:

```ini
[default]
aws_access_key_id = DEFAULT
aws_secret_access_key = SECRET1

[dev]
aws_access_key_id = DEV
aws_secret_access_key = SECRET2

[prod]
aws_access_key_id = PROD
aws_secret_access_key = SECRET3
```

You can do the following:

```python
import boto3.session

dev = boto3.session.Session(profile_name='dev')
prod = boto3.session.Session(profile_name='prod')

s3dev = dev.resource('s3')
s3prod = prod.resource('s3')

for resource in [s3dev, s3prod]:
    print('Profile: ' + resource.profile)
    for bucket in resource.buckets.all():
        print(bucket.name)
    print('')
```

It is also possible to setup the default session with a profile:

```python
import boto3

boto3.setup_default_session(profile_name='dev')

s3 = boto3.resource('s3')
```

And of course you can still use the environment variable:

```bash
$ BOTO_DEFAULT_PROFILE=dev ipython
>>> import boto3
>>> s3dev = boto3.resource('s3')
```

Once a session is created, the profile is immutable. The `profile_name`
property is provided for convenience and just surfaces the underlying
Botocore session's profile property.

Why not provide a profile name to the `client` and `resource` methods?
Currently there is no easy way to clone a session, and the behavior of
creating a new blank session (from one which may have customizations)
leads to possibly unintended side-effects like clients without the
proper event handlers registered. This would be an additive change
should we want to revisit in the future. At this point, the change
in this commit provides a way for Boto 3 users to use multiple profiles
without resorting to creating their own Botocore sessions.

I'm definitely open to suggestions and counter-arguments.
Comment thread boto3/session.py

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would strongly prefer that this always return a string, but it could be either 'default' or a blank string. It makes code like this simpler:

if session.profile.startswith('prod'):
    # Do something here!
    pass

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is probably ok at this layer. I believe the reason it's like that in botocore is because parts of the code need to distinguish between "was explicitly set to default by the user" and "try the default profile if one hasn't been set". The former case is an error, the latter case just means move on to the next credential provider.

@danielgtaylor danielgtaylor added the enhancement This issue requests an improvement to a current feature. label Feb 27, 2015
@danielgtaylor danielgtaylor self-assigned this Feb 27, 2015
@danielgtaylor

Copy link
Copy Markdown
Contributor Author

This is one possible implementation of #21.

@jamesls

jamesls commented Feb 27, 2015

Copy link
Copy Markdown
Member

I think this seems reasonable. Looks good to me, :shipit:

@kyleknap

Copy link
Copy Markdown
Contributor

Looks good 🚒

@danielgtaylor

Copy link
Copy Markdown
Contributor Author

Merged in 8da893b

@danielgtaylor
danielgtaylor deleted the session-profile branch February 27, 2015 21:36
@coveralls

Copy link
Copy Markdown

Coverage Status

Changes Unknown when pulling 2a10ea6 on session-profile into * on develop*.

@ream88

ream88 commented Feb 3, 2016

Copy link
Copy Markdown

For everybody coming from Google: it is now called AWS_PROFILE.

$ AWS_PROFILE=dev ipython
>>> import boto3
>>> s3dev = boto3.resource('s3')

@quiver

quiver commented Mar 4, 2016

Copy link
Copy Markdown
Contributor

kudos go to @Haihappen

@GBR-613

GBR-613 commented Feb 2, 2020

Copy link
Copy Markdown

It does not work for me now (Boto3 v1.11.9, Python v3.8.1), at least with S3

The profile I specify is listed in boto3.Session().available_profiles
AWS CLI does work with the profile.
Who could verify this functionality is not simply broken in the last versions?
Thanks in advance!

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

Labels

enhancement This issue requests an improvement to a current feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants