Python Wrapper for DigitalOcean's v2 API
This project is not actively maintained in sync with v2 API changes; if something changes (and therefore breaks the library), open an issue and I will fix it as soon as possible.
pip install skiff import skiff
s = skiff.rig("my_token")
droplets = s.Droplet.all()
#>>> [<cond.in (#267357) nyc1 - Ubuntu 12.10 x64 - 512mb>,
#>>> <hey.github (#2012972) nyc1 - Ubuntu 13.10 x32 - 512mb>,
#>>> <hello.world (#2012974) nyc1 - Ubuntu 13.10 x32 - 512mb>]Creation calls can be made with keyword args or a single dictionary argument.
Calls to s.<resource>.all() can also be passed query parameters. The v2 API currently responds to per_page. For example, s.Image.all(per_page=200) will return all of the images up to the 200th (200 is max). By default, s.<resource>.all() will page through all responses. Pass page=False to stop skiff from automatically retriving all of the possible values.
Each object has a property _json, which contains the json response as a dictionary. If you make local changes to the skiff objects (via update() or similar), be sure to refresh the local json with my_object = my_object.reload().
my_droplet = s.Droplet.create(name='hello.world',
region='nyc1',
size='512mb',
image=5141286)
#>>> <hello.world (#2012974) nyc1 - Ubuntu 14.04 x64 - 512mb>
# wait until droplet is created
my_droplet.wait_till_done()
# refresh network information
my_droplet = my_droplet.refresh()Alternatively, you can pass a dictionary containing those values.
# Get droplet by ID
my_droplet = s.Droplet.get(id)
# Get droplet by Name (not intelligent)
my_droplet = s.Droplet.get('hello.world') my_droplet.destroy() my_droplet.rename('new.name') my_droplet.reboot()
my_droplet.restart() my_droplet.shutdown() my_droplet.power_off() my_droplet.power_on() my_droplet.power_cycle() # Get size via search
some_size = s.Size.get('512')
#>>> <512mb>
my_droplet.resize(some_size)Alternatively, simply pass in the string '512mb'.
ubuntu_image = s.Image.get('Ubuntu 13.10')
my_droplet.rebuild(ubuntu_image) # Default to current Image
my_droplet.restore()
# Specify Image
ubuntu_image = s.Image.get('Ubuntu 13.10')
my_droplet.restore(ubuntu_image) my_droplet.password_reset()
my_droplet.reset_password() new_kernel = my_droplet.kernels()[10]
my_droplet.change_kernel(new_kernel)Alternatively, simply pass the kernel's ID.
my_droplet.enable_ipv6()Note: Droplet must be powered off before you perform this.
my_droplet.snapshot() my_droplet.disable_backups() my_droplet.enable_private_networking() my_droplet.snapshots() my_droplet.backups() my_droplet.actions() my_droplet.kernels()When the droplet's status changes remotely, call this function to manually update your local representation.
This is particularly useful after creating a new droplet because the network info is blank at request time.
my_droplet = my_droplet.refresh()
my_droplet = my_droplet.reload()Returns a boolean regarding whether or not the droplet is processing an action.
my_droplet.has_action_in_progress()
#>>> FalseBlocks until the droplet has no more pending actions.
# waits until the droplet is ready to use, polling every 5 seconds
my_droplet.wait_till_done(5)Returns all actions for a token.
s.Action.all() action_id = 28012139
s.Action.get(action_id)
#>>> <destroy (#28012139) completed> s.Domain.all()
#>>> [<blog.cond.in>,
#>>> <matt.cond.in>,
#>>> <example.com>,
#>>> <example2.com>] # easy, defaulting to fist ipv4 network's public ip
my_domain = my_droplet.create_domain('example.com')
# or more manually
my_domain = s.Domain.create(name='example.com', ip_address=my_droplet.v4[0].ip_address) my_domain = s.Domain.get('example.com')
my_domain = s.Domain.get(domain_id)These are aliases for the same method.
my_domain.delete()
my_domain.destroy() my_domain.records()
#>>>[<example.com - A (#348736) @ -> 123.456.789.123>,
#>>> <example.com - CNAME (#348740) www -> @>,
#>>> <example.com - NS (#348737) -> NS1.DIGITALOCEAN.COM.>,
#>>> <example.com - NS (#348738) -> NS2.DIGITALOCEAN.COM.>,
#>>> <example.com - NS (#348739) -> NS3.DIGITALOCEAN.COM.>] my_domain.create_record(type='CNAME', name='www', data='@')See the DigitalOcean v2 API Docs for more options.
my_record_id = 1234
my_record = my_domain.get_record(my_record_id) my_record = my_record.update('new_name')See the DigitalOcean v2 API Docs for information on what new_name should be.
These are aliases for the same method.
my_record.delete()
my_record.destroy() s.Image.all(per_page=100)
#>>> [<CentOS 5.8 x64 (#1601) CentOS>,
#>>> <CentOS 5.8 x32 (#1602) CentOS>,
#>>> ...........
#>>> <Ghost 0.5 on Ubuntu 14.04 (#5610254) Ubuntu>,
#>>> <Redmine on Ubuntu 14.04 (#4869208) Ubuntu>,
#>>> <WordPress on Ubuntu 14.04 (#4991187) Ubuntu>] # Get by ID
my_image_id = 3101580
my_image = s.Image.get(my_image_id)
# Or by slug
ubuntu_slug = 'ubuntu1404'
ubuntu_image = s.Image.get(ubuntu_slug)
# Or by search (not very intelligent; useful for REPL use)
ubuntu_image = s.Image.get('Ubuntu 13.10')These are aliases for the same method.
my_image.delete()
my_image.destroy() name = 'my_new_image'
my_image = my_image.update(name) new_region = s.Region.get('nyc1')
my_image.transfer(new_region)Alternatively, simply pass the string 'nyc1'.
my_image.actions() action_id = 1234
my_image.get_action(action_id) s.Key.all() # ID
my_key = s.Key.get(1234)
# Name
my_key = s.Key.get('my public key')
# Fingerprint
my_key = s.Key.get('my:fi:ng:er:pr:in:t!') with open('~/.ssh/id_rsa.pub', 'r') as f:
pub_key = f.read()
my_key = s.Key.create(name='my public key', public_key=pub_key) my_key = my_key.update('new public key name')These are aliases for the same method.
my_key.delete()
my_key.destroy() s.Region.all()
#>>> [<New York 1 (nyc1)>,
#>>> <San Francisco 1 (sfo1)>,
#>>> <New York 2 (nyc2)>,
#>>> <Amsterdam 2 (ams2)>,
#>>> <Singapore 1 (sgp1)>]There's probably not much benefit in getting a SkiffRegion instance rather than just passing the region slug string as a parameter.
nyc1_region = s.Region.get('nyc1') s.Size.all()
#>>> [<512mb>, <1gb>, <2gb>, <4gb>, <8gb>, <16gb>, <32gb>, <48gb>, <64gb>] # search, not intelligent
small_size = s.Size.get('512')Suggestions accepted via Issues and Pull-Requests :)
run py.test
Note: Takes a while.
py.test
MIT
