boto/botocore — pull request #286 by jamesls (2014-05-21 22:23:24+00:00)
Title: Add support for creds file

The high level purpose of this PR is to add support for `~/.aws/credentials`.
This was also taken as an opportunity to cleanup and refactor some of the creds/config code to allow it to be more extensible. In terms of extensibility, there were a few high level goals:

* Make it possible to inject a new credential provider at runtime anywhere into the credential provider chain. This makes it possible to add support for credential providers that may not make sense in botocore. For example, OS keychain support or custom credential agents are now supported. This is now possible via:

```
custom_creds = KeychainProvider()
session.get_component(‘credential-resolver’).insert_before(‘env’, custom_creds)
```

* Make it possible to hook into the config var resolution process. The session previously had a fixed lookup process (instance-var, env var, config file, default value). A new “VariableResolver” is added which is similar to the credential provider chain which allows you to extend this process to look up variables by creating a class that implements `resolve(self, name)`. The SessionVariables are still there, but I would think the eventual goal is to move everything into the `VariableResolver`.

* Move logic out of the `Session` class. Over time the session has been growing additional capabilities. This isn’t necessarily a bad thing, but there are definitely “clumps” of functionality that can be their own class. The session can delegate out to these objects, but from both a management and extensibility standpoint, it makes sense to move these out into a separate object. This has been started via the credentials/config/loader/event classes.

* Provide a consistent interface to access/replace these extracted classes. This is done via the ComponentLocator object (a very simple and stripped down service locator). For example, if you want to get a reference to the credential-provider, you can use:

```
cred_chain = session.get_component(‘credential-provider’)
```

If you wanted to completely replace the credential provider chain, you could say:

```
alternate_cred_chain = MyCredentialChain()
session.register_component(‘credential-provider’, alternate_cred_chain)
```

As more objects are moved over to the ComponentLocator, they are all accessible via this consistent interface. For example, if we move the `Service` class over to this we have potential to address #152.

This will also require a corresponding change in the CLI.

cc @danielgtaylor