Rafa Viotti
Rafa Viotti

Reputation: 10522

How to extend a Boto3 resource?

On boto3, how can I extend ResourceModel? What I wan't to do is subclass boto3.resources.factory.ec2.Instance and add a run method to it. That method would be used to remotely run commands on the EC2 instance represented by the Python object, via SSH. I wish to do this in a clean way, i.e., without resorting to monkey patches or other obscure techniques.

Update

Based on Daniel's answer, I came up with the following code. Requires a recent version of Boto 3, and Spur for the SSH connection (pip install spur boto3).

from boto3 import session
from shlex import split
from spur import SshShell

# Customize here.
REGION = 'AWS-REGION'
INSTID = 'AWS-INSTANCE-ID'
USERID = 'SSH-USER'

def hook_ssh(class_attributes, **kwargs):
    def run(self, command):
        '''Run a command on the EC2 instance via SSH.'''

        # Create the SSH client.
        if not hasattr(self, '_ssh_client'):
            self._ssh_client = SshShell(self.public_ip_address, USERID)

        print(self._ssh_client.run(split(command)).output.decode())

    class_attributes['run'] = run

if __name__ == '__main__':
    b3s = session.Session()
    ec2 = b3s.resource('ec2', region_name=REGION)

    # Hook the "run" method to the "ec2.Instance" resource class.
    b3s.events.register('creating-resource-class.ec2.Instance', hook_ssh)

    # Run some commands.
    ec2.Instance(INSTID).run('uname -a')
    ec2.Instance(INSTID).run('uptime')

Upvotes: 6

Views: 2594

Answers (1)

Daniel
Daniel

Reputation: 8772

The short answer is that this isn't yet possible but it is planned to allow customizations of this sort. You can already see them in action with the new upload_file and download_file customization available on the S3 client. The plan is to use that same sort of mechanism for Boto 3 resources.

  1. Resources will fire some kind of event when creating a class that includes the attribute dict of all methods/attributes
  2. You hook your own method into the attribute dict
  3. The class gets created with your custom method - no monkey-patching required.

Take a look here:

https://github.com/boto/boto3/blob/develop/boto3/session.py#L314-L318 https://github.com/boto/boto3/tree/develop/boto3/s3

Boto 3 extensibility is definitely on our radar.

Upvotes: 2

Related Questions