koalalorenzo / python-digitalocean Goto Github PK
View Code? Open in Web Editor NEW🐍🐳 Python module to manage Digital Ocean droplets
License: GNU Lesser General Public License v3.0
🐍🐳 Python module to manage Digital Ocean droplets
License: GNU Lesser General Public License v3.0
Hello,
Here is a code snippet I am trying to use to create a droplet:
droplet = digitalocean.Droplet(token=secret,
name=domain,
region='sgp1', # Singapore 1
ssh_keys=[default_key],
image='centos-6-5-x64', # Centos 6.5 x64
size_slug='512mb', # 512MB
backups=False,
private_networking=True)
My droplets are created successfully except private networking is always disabled.
I receive no error during droplet creation.
Thanks
This one is my fault. I used regular expressions in Droplet.__get_ssh_keys_id_or_fingerprint, but forgot to import re. Just add
import re
to the top of Droplet.py
Note [https://github.com//pull/81] also fixes this issue. But you can add this as a separate commit.
I'm really sorry, this was such a stupid mistake.
In Droplet.create()
, the private_networking
argument is ignored. There is a line which checks self.private_networking
but not local var private_networking
.
In Domain.py" on line 58 in get_records. Removing params=data seems to fix the issue:
data = self.get_data(
"domains/%s/records/" % self.name,
type="GET"
)
Having an issue with record.destroy, here is my code:
manager = digitalocean.Manager(token=args.token)
my_domains = manager.get_all_domains()
for domain in my_domains:
dns = domain.get_records()
for dr in dns:
logging.debug("dr domain is %s", dr.domain)
if args.id:
logging.debug("looking for %d in %d:%s", args.id, dr.id, dr.name)
if dr.id == args.id:
logging.info("deleting the dns record %d, %s", dr.id, dr.name)
dr.domain = domain.name
dr.destroy()
I looked at the source, the destroy() method needs the self.domain and self.id to prime the digitalocean api. The id is there, but, self.domain is "". In the init method is it set to blank, I didn't look any further because I don't know what is going on there. I could force it to work using the line before the destroy call 'dr.domain = domain.name'.
I suppose it's too late to suggest a license change? I would think this library would be much better suited for a Apache, BSD, or LGPL license over the GPL.
I noticed there are several contributers, so a change in license might be tricky, but thought I'd throw it as an idea in case others feel the same.
in digitalocean/Manager.py(19)__call_api()
22 if data['status'] != "OK":
23 raise Exception(data[u'error_message'])
*** KeyError: u'error_message'
instropecting the data variable:
(Pdb) data
{u'status': u'ERROR', u'message': u'Access Denied'}
so probably need to show message instead of error_message.
Hello. Thanks for your work.
Could you explain why I get 20 times "completed" state:
>>> actions = droplet.get_actions()
>>> for action in actions:
... action.load()
... # Once it shows complete, droplet is up and running
... print action.status
...
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
completed
What does these mean?
Thanks!
When attempting to create an instance with ssh-keys, it doesn't seem to work, the instance doesn't get provisioned with the key. v1.0.3
As of this morning, api v2 is no longer beta. Does this mean we are ready for python-digitalocean v1.5 to get pushed to PyPi?
It happened to me that API request hanged because I didn't receive any response from DigitalOcean. That was probably a glitch on their side, but such situation should be handled.
It should be simple to set a timeout for each request.
Also, in that case Action.wait()
should tolerate some number of timeouts.
Tested this in two regions that offer private networking. The code below reproduces the problem. SSH_KEY_ID is a valid ssh key fingerprint. Droplets are successfully created, but private networking is not enabled.
new_droplet = Droplet(
name='newserver',
size_slug='1gb',
image='ubuntu-14-04-x64',
region='nyc2',
private_networking=True,
ssh_keys=[SSH_KEY_ID],
backups_enabled=False,
token=TOKEN)
new_droplet.create()
I just came across this library and find it very well put together. There is one feature I would like to see. I would like to create a droplet referencing the ssh key by name. I have several keys stored at DO and add one or several of them to each droplet I create. Using the key name to reference the key just makes sense to me. I will look into what it would take to do this.
It would appear pypi has v1.0.3 as the latest release, which doesn't support the user_data
feature on droplet creation. Could you update pypi to use latest 1.0.5b?
[crazybill@centos-xx home]# python2.6 new-code.py
Gonna check status in about 10 seconds
Number of events returned by call to droplet.get_events()
1
73
I modified the code to sleep for 10 seconds before calling:
events = droplet.get_events()
I then print the # of events returned on the get_events() call
and print the percentage.
Gonna look deeper to make sure this is not a weird dependency on python build.
Cheers mate.
does not work to create a droplet with ssh_key id, the error in the wrong ID.
when working with cURL - successfully
Can you add a license.txt file?
After installing, and running the following test code:
manager = digitalocean.Manager(token="MYDOTOKEN")
my_droplets = manager.get_all_droplets()
I get an "access denied" message. I can reproduce this error 100% and I cannot get the token to authenticate. Will I need to do something in the DO control panel to allow this app?
Thanks
oh... the call trace may help....
Traceback (most recent call last):
File "C:\Workspace\mypy\src\TestProgram.py", line 22, in
my_droplets = manager.get_all_droplets()
File "C:\Python34\lib\site-packages\digitalocean\Manager.py", line 46, in get_all_droplets
data = self.__call_api("/droplets/")
File "C:\Python34\lib\site-packages\digitalocean\Manager.py", line 24, in __call_api
raise Exception(msg)
Exception: Access Denied
Hi!
Im playing with creating a Qt gui using your lib. Great work!
But I would like to have functions to retrieve a single action and droplet instead of having to loop through all of them each time. Or, am I missing something?
after running manager.get_all_droplets()
, I get the following error:
/Library/Python/2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
InsecurePlatformWarning
"droplet" should be "domains" here.
29: setattr(self,attr,droplet[attr])
python2.7 in a virtualenv
python-digitalocean$ python digitalocean/tests/test_droplet.py
Traceback (most recent call last):
File "digitalocean/tests/test_droplet.py", line 7, in <module>
from .BaseTest import BaseTest
ValueError: Attempted relative import in non-package
Also it would be nice if there was a single test file to run instead of 3 separate ones.
It would be desirable if there was a way to wait untill droplet creation and destroying are completed.
A good way would be to return an Action in the said functions.
Thus it would be possible to say
droplet.create().wait(5)
or
droplet.destroy.wait(5)
Those are the functions that I have interacted with, there could be more that want the same treatment.
When creating a droplet you should be able to give a key fingerprint to Droplet.create(). The current code tries to interpret any string as an actual public key.
Adding an additional check to see if it's a fingerprint, instead of a full public key, after finding a string in Droplet.__get_ssh_keys_id and then directly adding the fingerprint to the id list allows it to work.
error parsing properties at an amount of 50 droplets
Currently droplet.destroy looks like this
def destroy(self):
"""
Destroy the droplet
Optional Args:
return_dict - bool : Return a dict when True (default),
otherwise return an Action.
Returns dict or Action
"""
return self.get_data("droplets/%s" % self.id, type=DELETE)
Either the comments should be corrected to reflect the actual situation (no args accepted), or the function should be changed to accept the optional arg return_dict
and return a dict
or an Action
. Currently it returns a boolean
?
After creating a droplet using the piece of code from the README:
import digitalocean
droplet = digitalocean.Droplet(token="secretspecialuniquesnowflake",
name='Example',
region='nyc2', # New York 2
image='ubuntu-14-04-x64', # Ubuntu 14.04 x64
size_slug='512mb', # 512MB
backups=True)
droplet.create()
the response from the API provides data about the just created instance like the id. The id is setted as attribute of the droplet object, as seen here:
https://github.com/koalalorenzo/python-digitalocean/blob/master/digitalocean/Droplet.py#L495
however other attributes are not setted. I find interesting to be able to access to droplet.ip_address at least. Does it make sense that I submit a patch for this? Other attributes could be set too, like memory or ip_v6_address.
More information about returned data at https://developers.digitalocean.com/documentation/v2/#create-a-new-droplet (see Response Body)
Hey,
PyPi has an 0.7 release, but there doesn't seem to be a corresponding tag in git. Could you please tag the appropriate commit (or git push the tag if you just forgot)?
It helps users to know the difference between the latest release on PyPi and git master. That way you can decide whether to install from source or use pip.
Thanks!
droplet.take_snapshot(
"test-snapshot",
return_dict=False,
power_off=True ).wait(update_every_seconds=10)
is causing this:
File "digitalocean/baseapi.py", line 113, in get_data
raise DataReadError(msg)
digitalocean.baseapi.DataReadError: Droplet is currently on. Please power it off to run this event.
This only just started happening a few days ago, and I can't find any changes that may have caused this.
Since python 3 is supported, it should be noted that long and unicode are not defined in python 3 (u'string literal' still works). This is a problem for __get_ssh_key_id_or_fingerprint in Droplet. A possible solution would be
try:
inttype = [int, long]
strtype = [str, unicode]
except NameError:
inttype = [int]
strtype = [str]
By the way, many of the unit tests fail on python 3.
In API v2 doc: To create a new record to a domain, send a POST request to /v2/domains/$DOMAIN_NAME/records.
So in Record.py line 31 should be:
"domains/%s/records/" % self.domain,
Btw, do you in general prefer issue reports or pull requests for such issues?
I had that error while calling "Droplet.rebuild". I checked the Droplet class source and BaseAPI too and they really don't have the mentioned attribute.
The manager already has the client_id and the api_key, why doesn't the manager also handle Droplet creation?
manager = digitalocean.Manager(client_id="...", api_key="...")
manager.create_droplet(name='Example',
region_id=1, # New York
image_id=2676, # Ubuntu 12.04 x64 Server
size_id=66, # 512MB
backup_active=False)
looks cleaner to me
something, I'm guessing the requests
library, is turning the Authorization header from Bearer
to Basic
, which causes authentication to fail.
droplet.py.txt
droplet.log.txt
I got "Exception: The resource you were accessing could not be found." when deleting an image.
The problem is in the v1 type url in Image.py on line 31. In the v2 API docs: To delete an image, send a DELETE request to /v2/images/$IMAGE_ID.
Made local changes and this worked nicely:
def destroy(self):
"""
Destroy the image
"""
return self.get_data(
"images/%s/" % self.id,
type="DELETE",
)
The current version 0.7 uploaded on pypi does not include the save() method on the Record object (introduced in 909752c).
The following snippet says it all:
import requests
import zlibheaders = {"Content-Type": "application/json",
... "Authorization": "Bearer "+DIGITALOCEAN_TOKEN}r = requests.get("https://api.digitalocean.com/v2/account/keys", headers=headers)
print (r.text) # Binary gibberish
u'\x1f\ufffd\x08\x00\x00\x00\x00\x00\x00\x03mR\u066e\ufffd@\x14\ufffd\ufffd\ufffd~\ufffd\x19\ufffd\x06\ufffdNn2(^\x14\ufffd\ufffd\x05\ufffd\ufffdd\ufffdt\ufffd\n\ufffd\u0266h\ufffd\ufffda\ufffdy\ufffd\ufffdIUN\ufffd\ufffd\ufffd\x0bT\ufffd\ufffd\ufffd\ufffdu\x15@?_ \ufffd\x00)P\ufffd<\x1c\ufffdS\ufffd\ufffdYY\ufffdQV\x03\x04h\ufffd\ufffd\ufffd DPA#\x01\x11\x19i<\x12\t\ufffd\x1aR%D)\x12\x05D\x05\ufffd\ufffd(<!\ufffd\ufffd!(\ufffd0\ufffd\ufffd_\ufffd^\u07a7|++\ufffd\ufffd\ufffd3\ufffd\ufffd\x13O\ufffd\ufffd\ufffd\ufffd\x7ft~\ufffd7\u0545\ufffd\ufffd^\x07\ufffd\ufffd(\u04f9f\ufffd\ufffd(\ufffd\x06\u0409oYP\ufffd\ufffd\ufffd\ufffd\ufffd\x10\ufffdR\ufffdu#\ufffd.EM.}>\ufffd\ufffd$\ufffd\ufffd\x0e\ufffd\ufffd:\ufffd5\ufffdz!\ufffd\ufffdd\ufffd\x19\ufffd{\ufffd1ek\ufffd\ufffd\x05\ufffd3w\u04d1_\ufffd{\ufffdc\ufffd\x11f>]\ufffd\ufffdym\ufffd\ufffd\ufffd\u0792\ufffd\ufffd\ufffd\ufffd\x15\ufffd\x14\ufffd\ufffd\u06d6O\ufffd\ufffd/rT\ufffd\ufffd\x13\ufffd\ufffdQ7\ufffd\ufffd|\ufffd|\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u051et%\x0e\ufffd\ufffd\x02{\ufffd\ufffd\ufffd\ufffd\ufffd\x06\ufffdk\ufffd\x10\ufffd_\ufffd\ufffd\ufffdf\ufffd\x15\ufffd\ufffd\ufffdY\ufffdT\ufffd:[c\ufffd\ufffd\x0bC\ufffd\u02fd2\ufffd\x13\xe8!\ufffd6\u0725\ufffd\x1232\ufffd\ufffd\u02a0\ufffd\u019e\ufffd1~\u06a9\ufffd5\ufffd\ufffdN\ufffd\ufffdAg~\u05b9\ufffdVI\ufffd\x04\ufffd\u2b0e\u0311\ufffd\ufffd5\ufffd}u\ufffd\v\ufffdWp\x0f\ufffd?,\x0f\ufffd\ufffd4\x0e\u072ea\ufffd\ufffd\ufffd=\u0359S\ufffdj\ufffd\ufffd;\ufffdx\ufffd\ufffd\ufffd y\u05b2G\ufffd\ufffd\x1f\ufffd\x14G\ufffdw\ufffd\ufffd}?\x19NY\ufffd\ufffd\ufffd\ufffd\ufffd_C\ufffdD\u0675\x7f\ufffd\ufffd{\x08RV\ufffd\x1e\ufffd:\ufffdq\x02\ufffd\ufffd~\ufffd\x01T\ufffd#\ufffd7\x02\x00\x00'
r.content # Binary gibberish
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03mR\xd9\xae\xa2@\x14\xfc\x95\x9b~\xd5\x19\x96\x06\x81Nn2(^\x14\x95\xc5\x05\xc5\xc9d\xd2t\xb7\n\xb2\xc9\xa6h\xfc\xf7a\xe6y\xce\xc3IUN\xaa\xea\xa1\xce\x0bT\xd5\xe5\xf7\x95u\x15@?_ \xa2\x00)P\x82<\x1c\x82S\x94\x9dYY\x94QV\x03\x04h\x88\xa0\x8c DPA#\x01\x11\x19i<\x12\t\xc2\x1aR%D)\x12\x05D\x05\xa4\xa9(<!\x85\x81!(\x9a0\x89\xc8_\xef^\xde\xa7|++\xfc\xa1\xf73\x86\xf6\x13O\x84\x8e\x88\xd3\x7ft~\xef\xb77\xd5\x85\x8b\x95^\x07\x83\xbd(\xd3\xb9f\xc0\xe7(\xd0\x06\xd0\x89oYP\xe4\xb9\xc2\xf9\xfb\xfc\x10\xedR\xe8u#\xb8.EM.}>\xc6\xce$\x9c\x8d\x0e\xc1\xed:\xad5\xee\xacz!\x9d\xc8d\x99\x19\xb9{\xbc1ek\x8a\xc6\x05\xe3\xb83w\xd3\x91_\xeb{\xb1c\xa4\x11f>]\x96\xf1ym\xca\xde\xf3\xde\x92\xb0\xb1\xa5\xa7\x15\xef\x14\x87\x97\xdb\x96O\x9d\x9d/rT\xa2\xf1\xa2\x13\x85\xbcQ7\xb6\xd9|\xe9\x87|\x99\xa8\xae\xa4\xb1\x95\xd4\x9et%\x0e\xd2\xc3\x02{\xa2\xdb\xf8\xb2\xe9\x06\xe3k\x97\x10\xb9_\x83\x88\x8ef\x92\x15\x84\xba\x91Y\xedT\xf8:[c\xc1\xa5\x0bC\x80\xcb\xbd2\xd8\x13\xc3\xa8!\x966\xdc\xa5\xd8\x1232\xb9\xc5\xca\xa0\xeb\xc6\x9e\x901~\xda\xa9\xee5\xbc\xbcN\xac\xbbAg~\xd6\xb9\xf3\xa2VI\xf2\x9c\x04\x85\xe2\xac\x8e\xcc\x91\xac\xf95\xc8}u\x93\v\xb6Wp\x0f\x9a?,\x0f\x87\xcb4\x0e\xdc\xaea\x99\xfe\xb5=\xcd\x99S\xb5j\xa9\xdc;\xeex\xff\xfc\xfc y\xd6\xb2G\xc5\xea\x1f\xe7\x14G\xc9w\x92\xa7}?\x19NY\xdf\xcc\xff\x8e\xef_C\x90D\xd9\xb5\x7f\x8a\xd7{\x08RV\xe3\x1e\x81:\xafq\x02\x90\xf0~\xff\x01T\xdb#\x867\x02\x00\x00'
print (zlib.decompress(r.content, 16+zlib.MAX_WBITS)) # Decompress and say hello to my public key.
{"ssh_keys":[{"id":734303,"fingerprint":"db:35:33:37:61:c5:90:2c:a9:84:dd:21:d1:98:bf:7e","public_key":"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1hJmk++W25dI9D3z6Y9+3OjqnYpoo7/VWoXiUm3Qy63Rr295rV0jaOCbH6XYqkEt9/g8QbdC5cLnDoPZqe7TG2DhaajyGUE6VtAW2yecu1HVdLrjgRG5QzwvcbuN4zJjU7O05vv0mOUV2/d4djKy21ou8SNGuFAXoLl8P49eM4vfA7jYmXKaQ2PuV5GPYBkylc5srYid6H4JYbADnJvE1FgJB1PdKD13LW7+WcDDt3a4S/hpTcGiG/KMDdRuNCcBazNmAQu05RlJwDdHVnyPIpt8clzCYp7OMZeO4JIkYoV8SlhUNQp/xdoxJQabLmjYPyuenAFTfIeOsv8r7wy/Zw== [email protected]","name":"[email protected]"}],"links":{},"meta":{"total":1}}
Here's what's in r.headers (note content-encoding):
{'cache-control': 'max-age=0, private, must-revalidate',
'cf-ray': '1dba5fd98f7a17b6-SIN',
'connection': 'keep-alive',
'content-encoding': 'gzip',
'content-type': 'application/json; charset=utf-8',
'date': 'Thu, 23 Apr 2015 14:49:20 GMT',
'ratelimit-limit': '5000',
'ratelimit-remaining': '4981',
'ratelimit-reset': '1429801676',
'server': 'cloudflare-nginx',
'set-cookie': '__cfduid=d5df7a2d5f73dd12bdd87d2f9cec562c41429800559; expires=Fri, 22-Apr-16 14:49:19 GMT; path=/; domain=.digitalocean.com; HttpOnly',
'status': '200 OK',
'transfer-encoding': 'chunked',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-request-id': 'e8292c02-5fcc-4105-b7e6-4643dca05ac7',
'x-runtime': '0.027317',
'x-xss-protection': '1; mode=block'}
TypeError Traceback (most recent call last)
in ()
----> 1 manager = digitalocean.Manager(token = "XXXXXX")
/root/python-digitalocean/digitalocean/Manager.py in init(self, _args, *_kwargs)
10 class Manager(BaseAPI):
11 def init(self, _args, *_kwargs):
---> 12 super(Manager, self).init(_args, *_kwargs)
13
14 def get_data(self, _args, *_kwargs):
/root/python-digitalocean/digitalocean/baseapi.py in init(self, _args, *_kwargs)
11
12 def init(self, _args, *_kwargs):
---> 13 super(BaseAPI, self).init(_args, *_kwargs)
14 self.token = ""
15 self.call_response = None
TypeError: object.init() takes no parameters
Python 2.7.5
Any plan to have a cli script ? I'm currently working on a script for my own use:-
import os
import baker
import digitalocean
token = open('/Users/kamal/.python-do.rc').read().strip()
manager = digitalocean.Manager(token=token)
@baker.command
def list_droplets():
my_droplets = manager.get_all_droplets()
for droplet in my_droplets:
print droplet
return my_droplets
def get_droplet(name):
droplets = list_droplets()
for droplet in droplets:
if droplet.name == name:
return droplet
def poweroff_droplet(name):
droplet = get_droplet(name)
confirm = raw_input('Poweroff %s ? [Y/n]' % (name))
if confirm == 'Y':
droplet.power_off()
def poweron_droplet(name):
droplet = get_droplet(name)
confirm = raw_input('Poweroff %s ? [Y/n]' % (name))
if confirm == 'Y':
droplet.power_on()
@baker.command
def resize_droplet(name, size, disk=False):
droplet = get_droplet(name)
confirm = raw_input('Resize %s to %s ? [Y/n]' % (name, size))
if confirm == 'Y':
droplet.resize(size, disk=disk)
baker.run()
I can make it into proper PR if you're interested.
The json parameter wasn't added to requests until version 2.4.2 So python-digitalocean is currently broken on systems with older versions like Ubuntu 14.04:
$ apt-cache policy python-requests
python-requests:
Installed: 2.2.1-1ubuntu0.1
Candidate: 2.2.1-1ubuntu0.1
Version table:
*** 2.2.1-1ubuntu0.1 0
500 http://us.archive.ubuntu.com/ubuntu/ trusty-updates/main amd64 Packages
500 http://security.ubuntu.com/ubuntu/ trusty-security/main amd64 Packages
100 /var/lib/dpkg/status
2.2.1-1 0
500 http://us.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
======================================================================
ERROR: test_take_snapshot_action (digitalocean.tests.test_droplet.TestDroplet)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<string>", line 2, in _wrapper_
File "/usr/lib/python2.7/dist-packages/responses.py", line 167, in wrapped
return func(*args, **kwargs)
File "/home/asb/projects/python-digitalocean/digitalocean/tests/test_droplet.py", line 338, in test_take_snapshot_action
response = self.droplet.take_snapshot("New Snapshot", return_dict=False)
File "/home/asb/projects/python-digitalocean/digitalocean/Droplet.py", line 274, in take_snapshot
return_dict
File "/home/asb/projects/python-digitalocean/digitalocean/Droplet.py", line 159, in _perform_action
params=params
File "/home/asb/projects/python-digitalocean/digitalocean/Droplet.py", line 118, in get_data
data = super(Droplet, self).get_data(*args, **kwargs)
File "/home/asb/projects/python-digitalocean/digitalocean/baseapi.py", line 95, in get_data
req = self.__perform_request(url, type, params)
File "/home/asb/projects/python-digitalocean/digitalocean/baseapi.py", line 80, in __perform_request
r = self.__perform_post(url, headers=headers, params=params)
File "/home/asb/projects/python-digitalocean/digitalocean/baseapi.py", line 48, in __perform_post
return requests.post(url, headers=headers, json=params)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 88, in post
return request('post', url, data=data, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
TypeError: request() got an unexpected keyword argument 'json'
I'm a bit conflicted on this issue as using json instead of query params is definitely the "right" thing to do, but Ubuntu 14.04 is an important target for me personally (https://github.com/andrewsomething/digitalocean-indicator) A more graceful fall back would be best.
Curious if you can add a snapshots property to the Droplet class. I would like to be able to access the snapshots for a specific droplet.
Unless there is a way to do it currently in Manager.get_my_images()
I am really stuck *(
key = "magicToken1234"
import digitalocean
droplet = digitalocean.Droplet(token=key,
name='Example',
region='nyc2', # New York 2
image='ubuntu-14-04-x64', # Ubuntu 14.04 x64
size_slug='512mb', # 512MB
backups=True)
droplet.create()
https://developers.digitalocean.com/changelog/api-v2/change-size-to-size-slug/
Digital Ocean have made a breaking change to their API. Droplets no longer have a size
object, but instead have a size_slug
field that references the size in the data retrieved from the sizes endpoint.
The size
dictionary on a droplet object no longer exists, but could be created using details from the Digital Ocean sizes API.
have you managed to create a droplet with ssh_keys ? like coreos
the examples in the REAME work perfectly for me except when I want to create an image with ssh_keys.
I use Python 3.4 in Windows and I got this error while I was trying to list all of user images. Traceback is here:
Traceback (most recent call last):
File "C:\Users\YusufTuğrul\Desktop\digitalocean.py\digitaloceancli.py", line 216, in <module>
DigitalOcean().cmdloop()
File "C:\Python34\lib\cmd.py", line 138, in cmdloop
stop = self.onecmd(line)
File "C:\Python34\lib\cmd.py", line 217, in onecmd
return func(arg)
File "C:\Users\YusufTuğrul\Desktop\digitalocean.py\digitaloceancli.py", line 204, in do_lsimages
images = self.manager.get_all_images()
File "C:\Python34\lib\site-packages\python_digitalocean-1.1-py3.4.egg\digitalocean\Manager.py", line 113, in get_all_images
data = self.get_data("images/")
File "C:\Python34\lib\site-packages\python_digitalocean-1.1-py3.4.egg\digitalocean\Manager.py", line 26, in get_data
unpaged_data = self.__deal_with_pagination(args[0], data, params)
File "C:\Python34\lib\site-packages\python_digitalocean-1.1-py3.4.egg\digitalocean\Manager.py", line 43, in __deal_with_pagination
more_values = new_data.values()[0]
TypeError: 'dict_values' object does not support indexing
Hi I tried the sample code, but I believe there are some typos:
// I had to change this to be events.load()
event.load()
// I had to change this to be events.percentage
print event.percentage
I also tried to fetch new status updates, and was unable to.
I resorted to accomplishing this task using digitalocean.Manager
instead.
It's possible to create droplet with unique name using this API
SInce the droplet snapshot requires the droplet to be off before it can create a snapshot, why not add that in the take_snapshot function?
This would allow us to create a snapshot without first having to check it's status, power it off, and wait for the action to complete before then calling the take_snapshot function separately.
Am I off the mark on this? What are your thoughts?
All the droplet actions (power_on, shutdown, take_snapshot, etc.) return actions. However the corresponding methods in Droplet return raw dictionaries. It might be a better idea to return Action objects instead.
Adding this feature might break backwards compatibility, since some people might depend on the fact that those methods return dictionaries.
I am willing to implement this myself, if you give the go ahead.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.