Skip to content

Commit 09a06d4

Browse files
servetguneykoalalorenzo
authored andcommitted
Adding Digital Ocean's Project Support (#300)
* Project Support: Project Class has been added Manager: Project Support has been added * Project Support: Project Class has been added. Manager: Project Support has been added. README: The documentation has been added. * Project Support: - Function : Get Project Resources has been added. Manager: Project Support has been added. * Project Support: - Function : Assign Resources to a project * Project Support: - Documentation: Update for the project functions * Project Support: - Travis Build Fail Update * Project Support: - Starting the test implementation of project creation * Project Support: - Starting the test implementation of project creation * Project Support: - Starting the test implementation of project creation * Project Support: - Starting the test implementation of project creation * Project Support: - Starting the test implementation of project creation * Project Support: - Starting the test implementation of project creation * Project Support: - Starting the test implementation of project creation * Project Support: - Starting the test implementation of project creation - Inital 2 Test has been completed * Project Support: - Starting the test implementation of project creation - 2 Test has been completed - test_project - 1 Test has been completed - test_manager * Project Support: - Starting the test implementation of project creation - 2 Test has been completed - test_project - 1 Test has been completed - test_manager - ReadMe Updates - 1 * Project Support: - Starting the test implementation of project creation - 4 Test has been completed - test_project - 1 Test has been completed - test_manager - ReadMe Updates - 1 * Project Support: - Starting the test implementation of project creation - 7 Test has been completed - test_project - 2 Test has been completed - test_manager - ReadMe Updates - 1 * Project Support: - Starting the test implementation of project creation - 9 Test has been completed - test_project - 2 Test has been completed - test_manager - ReadMe Updates - 1 * Project Support: - Starting the test implementation of project creation - 9 Test has been completed - test_project - 2 Test has been completed - test_manager - ReadMe Updates - 1 - Mistake of domain create.json file fix. * Project Support: - Starting the test implementation of project creation - 9 Test has been completed - test_project - 2 Test has been completed - test_manager - ReadMe Updates - 1 - Mistake of domain create.json file fix. - Cleaning some print statements
1 parent 2a27d25 commit 09a06d4

17 files changed

Lines changed: 622 additions & 2 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ MANIFEST
4141
.cache
4242

4343
.venv
44+

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ or via sources:
2222
## Features
2323
python-digitalocean support all the features provided via digitalocean.com APIs, such as:
2424

25+
* Get user's Projects
26+
* Assign a resource to a user project
27+
* List the resources of user's project
2528
* Get user's Droplets
2629
* Get user's Images (Snapshot and Backups)
2730
* Get public Images
@@ -37,6 +40,36 @@ python-digitalocean support all the features provided via digitalocean.com APIs,
3740

3841

3942
## Examples
43+
44+
### Listing the Projects
45+
46+
This example shows how to list all the projects:
47+
48+
```python
49+
import digitalocean
50+
manager = digitalocean.Manager(token="secretspecialuniquesnowflake")
51+
my_projects = manager.get_all_projects()
52+
print(my_projects)
53+
```
54+
55+
### Assign a resource for specific project
56+
57+
```python
58+
import digitalocean
59+
manager = digitalocean.Manager(token="secretspecialuniquesnowflake")
60+
my_projects = manager.get_all_projects()
61+
my_projects[0].assign_resource(["do:droplet:<Droplet Number>"])
62+
```
63+
64+
### List all the resources of a project
65+
```python
66+
import digitalocean
67+
manager = digitalocean.Manager(token="secretspecialuniquesnowflake")
68+
my_projects = manager.get_all_projects()
69+
resources = my_projects[0].get_all_resources()
70+
print(resources)
71+
```
72+
4073
### Listing the droplets
4174

4275
This example shows how to list all the active droplets:

digitalocean/Manager.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from .Snapshot import Snapshot
2121
from .Tag import Tag
2222
from .Volume import Volume
23-
23+
from .Project import Project
2424

2525
class Manager(BaseAPI):
2626
def __init__(self, *args, **kwargs):
@@ -349,5 +349,35 @@ def get_volume(self, volume_id):
349349
"""
350350
return Volume.get_object(api_token=self.token, volume_id=volume_id)
351351

352+
def get_all_projects(self):
353+
"""
354+
All the projects of the account
355+
"""
356+
data = self.get_data("projects")
357+
projects = list()
358+
for jsoned in data['projects']:
359+
project = Project(**jsoned)
360+
project.token = self.token
361+
projects.append(project)
362+
return projects
363+
364+
def get_project(self, project_id):
365+
"""
366+
Return a Project by its ID.
367+
"""
368+
return Project.get_object(
369+
api_token=self.token,
370+
project_id=project_id,
371+
)
372+
373+
def get_default_project(self):
374+
"""
375+
Return default project of the account
376+
"""
377+
return Project.get_object(
378+
api_token=self.token,
379+
project_id="default",
380+
)
381+
352382
def __str__(self):
353383
return "<Manager>"

digitalocean/Project.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
from .baseapi import BaseAPI, GET, POST, DELETE, PUT
2+
3+
4+
class Project(BaseAPI):
5+
def __init__(self,*args, **kwargs):
6+
self.name = None
7+
self.description = None
8+
self.purpose = None
9+
self.environment = None
10+
self.id = None
11+
self.is_default = None
12+
self.owner_uuid = None
13+
self.owner_id = None
14+
self.created_at = None
15+
self.updated_at = None
16+
self.resources = None
17+
super(Project,self).__init__(*args, **kwargs)
18+
19+
@classmethod
20+
def get_object(cls, api_token, project_id):
21+
"""Class method that will return a Project object by ID.
22+
Args:
23+
api_token (str): token
24+
kwargs (str): project id or project name
25+
"""
26+
27+
project = cls(token=api_token, id=project_id)
28+
project.load()
29+
return project
30+
31+
def load(self):
32+
# URL https://api.digitalocean.com/v2/projects
33+
project = self.get_data("projects/%s" % self.id)
34+
project = project['project']
35+
for attr in project.keys():
36+
setattr(self, attr, project[attr])
37+
38+
def set_as_default_project(self):
39+
40+
data = {
41+
"name": self.name,
42+
"description": self.description,
43+
"purpose": self.purpose,
44+
"environment": self.environment,
45+
"is_default": True
46+
}
47+
48+
project = self.get_data("projects/%s" % self.id, type=PUT, params=data)
49+
return project
50+
51+
def create_project(self):
52+
53+
"""Creating Project with the following arguments
54+
Args:
55+
api_token (str): token
56+
"name": Name of the Project - Required
57+
"description": Description of the Project - Optional
58+
"purpose": Purpose of the project - Required
59+
"environment": Related Environment of Project - Optional
60+
- Development
61+
- Stating
62+
- Production
63+
"""
64+
65+
data = {
66+
"name": self.name,
67+
"purpose": self.purpose
68+
}
69+
if self.description:
70+
data['description'] = self.description
71+
if self.environment:
72+
data['environment'] = self.environment
73+
74+
data = self.get_data("projects", type=POST, params=data)
75+
76+
if data:
77+
self.id = data['project']['id']
78+
self.owner_uuid = data['project']['owner_uuid']
79+
self.owner_id = data['project']['owner_id']
80+
self.name = data['project']['name']
81+
self.description = data['project']['description']
82+
self.purpose = data['project']['purpose']
83+
self.environment = data['project']['environment']
84+
self.is_default = data['project']['is_default']
85+
self.created_at = data['project']['created_at']
86+
self.updated_at = data['project']['updated_at']
87+
88+
def delete_project(self):
89+
data = dict()
90+
return self.get_data("projects/%s" % self.id, type=DELETE, params=data)
91+
92+
def update_project(self, **kwargs):
93+
data = dict()
94+
data['name'] = kwargs.get("name", self.name)
95+
data['description'] = kwargs.get("description", self.description)
96+
data['purpose'] = kwargs.get("purpose", self.purpose)
97+
"""
98+
Options for Purpose by Digital Ocean
99+
- Just Trying out DigitalOcean
100+
- Class Project / Educational Purposes
101+
- Website or blog
102+
- Web Application
103+
- Service or API
104+
- Mobile Application
105+
- Machine Learning / AI / Data Processing
106+
- IoT
107+
- Operational / Developer tooling
108+
- Other
109+
"""
110+
data['environment'] = kwargs.get("environment", self.environment)
111+
"""
112+
Options for Environment by Digital Ocean
113+
- Development
114+
- Stating
115+
- Production
116+
"""
117+
data['is_default'] = kwargs.get("is_default", self.is_default)
118+
update_response = self.get_data("projects/%s" % self.id, type=PUT, params=data)
119+
for attr in update_response['project'].keys():
120+
setattr(self, attr, update_response['project'][attr])
121+
122+
def get_all_resources(self):
123+
project_resources_response = self.get_data("projects/%s/resources" % self.id)
124+
project_resources = project_resources_response['resources']
125+
self.resources = []
126+
for i in project_resources:
127+
self.resources.append(i['urn'])
128+
return self.resources
129+
130+
def load_resources(self):
131+
project_resources_response = self.get_data("projects/%s/resources" % self.id)
132+
project_resources = project_resources_response['resources']
133+
self.resources = []
134+
for i in project_resources:
135+
self.resources.append(i['urn'])
136+
137+
def assign_resource(self, resources):
138+
data = {
139+
'resources': resources
140+
}
141+
return self.get_data("projects/%s/resources" % self.id, type=POST, params=data)
142+
143+
def __str__(self):
144+
return "<Project: " + self.name + "> " + self.id

digitalocean/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@
2626
from .LoadBalancer import StickySesions, ForwardingRule, HealthCheck
2727
from .Certificate import Certificate
2828
from .Snapshot import Snapshot
29+
from .Project import Project

digitalocean/baseapi.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def get_data(self, url, type=GET, params=None):
162162

163163
try:
164164
data = req.json()
165+
165166
except ValueError as e:
166167
raise JSONReadError(
167168
'Read failed from DigitalOcean: %s' % str(e)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"projects": [
3+
{
4+
"id": "4e1bfbc3-dc3e-41f2-a18f-1b4d7ba71679",
5+
"owner_uuid": "99525febec065ca37b2ffe4f852fd2b2581895e7",
6+
"owner_id": 2,
7+
"name": "my-web-api",
8+
"description": "My website API",
9+
"purpose": "Service or API",
10+
"environment": "Production",
11+
"is_default": false,
12+
"created_at": "2018-09-27T20:10:35Z",
13+
"updated_at": "2018-09-27T20:10:35Z"
14+
}
15+
],
16+
"links": {
17+
"pages": {
18+
"first": "https://api.digitalocean.com/v2/projects?page=1",
19+
"last": "https://api.digitalocean.com/v2/projects?page=1"
20+
}
21+
},
22+
"meta": {
23+
"total": 1
24+
}
25+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"resources": [
3+
{
4+
"urn": "do:droplet:1",
5+
"assigned_at": "2018-09-28T19:26:37Z",
6+
"links": {
7+
"self": "https://api.digitalocean.com/v2/droplets/1"
8+
},
9+
"status": "assigned"
10+
},
11+
{
12+
"urn": "do:floatingip:192.168.99.100",
13+
"assigned_at": "2018-09-28T19:26:37Z",
14+
"links": {
15+
"self": "https://api.digitalocean.com/v2/floating_ips/192.168.99.100"
16+
},
17+
"status": "assigned"
18+
}
19+
],
20+
"links": {
21+
"pages": {
22+
"first": "https://api.digitalocean.com/v2/projects/4e1bfbc3-dc3e-41f2-a18f-1b4d7ba71679/resources?page=1",
23+
"last": "https://api.digitalocean.com/v2/projects/4e1bfbc3-dc3e-41f2-a18f-1b4d7ba71679/resources?page=1"
24+
}
25+
},
26+
"meta": {
27+
"total": 2
28+
}
29+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"project": {
3+
"id": "4e1bfbc3-dc3e-41f2-a18f-1b4d7ba71679",
4+
"owner_uuid": "99525febec065ca37b2ffe4f852fd2b2581895e7",
5+
"owner_id": 2,
6+
"name": "my-web-api",
7+
"description": "My website API",
8+
"purpose": "Service or API",
9+
"environment": "Production",
10+
"is_default": false,
11+
"created_at": "2018-09-27T15:52:48Z",
12+
"updated_at": "2018-09-27T15:52:48Z"
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"project": {
3+
"id": "4e1bfbc3-dc3e-41f2-a18f-1b4d7ba71679",
4+
"owner_uuid": "99525febec065ca37b2ffe4f852fd2b2581895e7",
5+
"owner_id": 2,
6+
"name": "my-web-api",
7+
"description": "My website API",
8+
"purpose": "Service or API",
9+
"environment": "Production",
10+
"is_default": true,
11+
"created_at": "2018-09-27T20:10:35Z",
12+
"updated_at": "2018-09-27T20:10:35Z"
13+
}
14+
}

0 commit comments

Comments
 (0)