drown 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drown
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: CLI tool for managing apps on Drown Platform - a self-hosted PaaS
5
5
  Home-page: https://github.com/drownplatform/drown-cli
6
6
  Author: Drown Platform
@@ -1,3 +1,3 @@
1
1
  """Drown Platform CLI - Manage your self-hosted PaaS from the command line."""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.2.2"
@@ -0,0 +1,187 @@
1
+ """API wrapper functions for Drown Platform."""
2
+
3
+ import requests
4
+ from drown.config import get_api_base
5
+
6
+
7
+ def _make_request(method, endpoint, token=None, data=None):
8
+ """
9
+ Make an HTTP request to the API.
10
+
11
+ Returns: (success: bool, result: dict)
12
+ """
13
+ api_base = get_api_base()
14
+ url = f"{api_base}{endpoint}"
15
+
16
+ headers = {}
17
+ if token:
18
+ headers["Authorization"] = f"Bearer {token}"
19
+
20
+ try:
21
+ if method == "GET":
22
+ response = requests.get(url, headers=headers, timeout=10)
23
+ elif method == "POST":
24
+ headers["Content-Type"] = "application/json"
25
+ response = requests.post(url, headers=headers, json=data, timeout=10)
26
+ else:
27
+ return False, {"error": f"Unsupported HTTP method: {method}"}
28
+
29
+ if response.status_code == 200:
30
+ try:
31
+ return True, response.json()
32
+ except ValueError:
33
+ return True, {"message": response.text}
34
+
35
+ elif response.status_code == 201:
36
+ try:
37
+ return True, response.json()
38
+ except ValueError:
39
+ return True, {"message": "Created successfully"}
40
+
41
+ elif response.status_code == 400:
42
+ try:
43
+ error_data = response.json()
44
+ error_msg = error_data.get("error", "Bad request")
45
+ except ValueError:
46
+ error_msg = "Bad request"
47
+ return False, {"error": error_msg}
48
+
49
+ elif response.status_code == 401:
50
+ return False, {
51
+ "error": "Invalid credentials. Please run 'drown login' again."
52
+ }
53
+
54
+ elif response.status_code == 403:
55
+ return False, {
56
+ "error": "Forbidden: You don't have access to this resource."
57
+ }
58
+
59
+ elif response.status_code == 404:
60
+ return False, {
61
+ "error": "Not found. The app or resource doesn't exist."
62
+ }
63
+
64
+ elif response.status_code >= 500:
65
+ return False, {
66
+ "error": "Server error. Please try again later."
67
+ }
68
+
69
+ else:
70
+ return False, {
71
+ "error": f"Unexpected response: {response.status_code}"
72
+ }
73
+
74
+ except requests.exceptions.ConnectionError:
75
+ return False, {
76
+ "error": f"Unable to connect to {api_base}. Please check your internet connection."
77
+ }
78
+
79
+ except requests.exceptions.Timeout:
80
+ return False, {
81
+ "error": "Request timed out. Please try again."
82
+ }
83
+
84
+ except requests.exceptions.RequestException as e:
85
+ return False, {
86
+ "error": f"Network error: {str(e)}"
87
+ }
88
+
89
+
90
+ def login(username, password):
91
+ """
92
+ Authenticate with the platform.
93
+ """
94
+ return _make_request(
95
+ "POST",
96
+ "/api/auth/login",
97
+ data={
98
+ "username": username,
99
+ "password": password
100
+ }
101
+ )
102
+
103
+
104
+ def get_apps(token):
105
+ """
106
+ Get list of all apps.
107
+ """
108
+ return _make_request(
109
+ "GET",
110
+ "/api/apps",
111
+ token=token
112
+ )
113
+
114
+
115
+ def create_app(token, app_name):
116
+ """
117
+ Create a new app.
118
+ """
119
+ return _make_request(
120
+ "POST",
121
+ "/api/apps/create",
122
+ token=token,
123
+ data={
124
+ "name": app_name
125
+ }
126
+ )
127
+
128
+
129
+ def scale_app(token, app_name, replicas):
130
+ """
131
+ Scale an app.
132
+ """
133
+ return _make_request(
134
+ "POST",
135
+ f"/api/apps/{app_name}/scale",
136
+ token=token,
137
+ data={
138
+ "replicas": replicas
139
+ }
140
+ )
141
+
142
+
143
+ def get_logs(token, app_name):
144
+ """
145
+ Get logs for an app.
146
+ """
147
+ return _make_request(
148
+ "GET",
149
+ f"/api/apps/{app_name}/logs",
150
+ token=token
151
+ )
152
+
153
+
154
+ def link_app(token, app_name):
155
+ """
156
+ Link to an existing app.
157
+ """
158
+ return _make_request(
159
+ "POST",
160
+ f"/api/apps/{app_name}/link",
161
+ token=token
162
+ )
163
+
164
+
165
+ def get_metrics(token, app_name):
166
+ """
167
+ Get metrics for an app.
168
+ """
169
+ return _make_request(
170
+ "GET",
171
+ f"/api/apps/{app_name}/metrics",
172
+ token=token
173
+ )
174
+
175
+
176
+ def register_ssh_key(token, public_key):
177
+ """
178
+ Register an SSH public key with the platform.
179
+ """
180
+ return _make_request(
181
+ "POST",
182
+ "/api/keys/register",
183
+ token=token,
184
+ data={
185
+ "public_key": public_key
186
+ }
187
+ )
@@ -6,11 +6,11 @@ import subprocess
6
6
  import sys
7
7
  from pathlib import Path
8
8
 
9
- from drown import api, config
9
+ from drown import api, config, __version__
10
10
 
11
11
 
12
12
  @click.group()
13
- @click.version_option(version="0.1.0", prog_name="drown")
13
+ @click.version_option(version=__version__, prog_name="drown")
14
14
  def cli():
15
15
  """Drown Platform CLI - Manage your self-hosted PaaS."""
16
16
  pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drown
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: CLI tool for managing apps on Drown Platform - a self-hosted PaaS
5
5
  Home-page: https://github.com/drownplatform/drown-cli
6
6
  Author: Drown Platform
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="drown",
8
- version="0.2.0",
8
+ version="0.2.2",
9
9
  author="Drown Platform",
10
10
  author_email="platform@dr0wn.duckdns.org",
11
11
  description="CLI tool for managing apps on Drown Platform - a self-hosted PaaS",
drown-0.2.0/drown/api.py DELETED
@@ -1,156 +0,0 @@
1
- """API wrapper functions for Drown Platform."""
2
-
3
- import requests
4
- from drown.config import get_api_base
5
-
6
-
7
- def _make_request(method, endpoint, token=None, data=None):
8
- """
9
- Make an HTTP request to the API.
10
-
11
- Returns: (success: bool, result: dict)
12
- """
13
- api_base = get_api_base()
14
- url = f"{api_base}{endpoint}"
15
-
16
- headers = {}
17
- if token:
18
- headers["Authorization"] = f"Bearer {token}"
19
-
20
- try:
21
- if method == "GET":
22
- response = requests.get(url, headers=headers, timeout=10)
23
- elif method == "POST":
24
- headers["Content-Type"] = "application/json"
25
- response = requests.post(url, headers=headers, json=data, timeout=10)
26
- else:
27
- return False, {"error": f"Unsupported HTTP method: {method}"}
28
-
29
- # Handle different status codes
30
- if response.status_code == 200:
31
- try:
32
- return True, response.json()
33
- except ValueError:
34
- return True, {"message": response.text}
35
- elif response.status_code == 201:
36
- try:
37
- return True, response.json()
38
- except ValueError:
39
- return True, {"message": "Created successfully"}
40
- elif response.status_code == 401:
41
- return False, {"error": "Invalid credentials. Please run 'drown login' again."}
42
- elif response.status_code == 403:
43
- return False, {"error": "Forbidden: You don't have access to this resource."}
44
- elif response.status_code == 404:
45
- return False, {"error": "Not found. The app or resource doesn't exist."}
46
- elif response.status_code == 400:
47
- try:
48
- error_data = response.json()
49
- error_msg = error_data.get("error", "Bad request")
50
- except ValueError:
51
- error_msg = "Bad request"
52
- return False, {"error": error_msg}
53
- elif response.status_code >= 500:
54
- return False, {"error": "Server error. Please try again later."}
55
- else:
56
- return False, {"error": f"Unexpected response: {response.status_code}"}
57
-
58
- except requests.exceptions.ConnectionError:
59
- return False, {"error": f"Unable to connect to {api_base}. Please check your internet connection."}
60
- except requests.exceptions.Timeout:
61
- return False, {"error": "Request timed out. Please try again."}
62
- except requests.exceptions.RequestException as e:
63
- return False, {"error": f"Network error: {str(e)}"}
64
-
65
-
66
- def login(username, password):
67
- """
68
- Authenticate with the platform.
69
-
70
- Returns: (success: bool, result: dict)
71
- result contains: {"token": "...", "username": "..."} or {"error": "..."}
72
- """
73
- return _make_request("POST", "/api/auth/login", data={
74
- "username": username,
75
- "password": password
76
- })
77
-
78
-
79
- def get_apps(token):
80
- """
81
- Get list of all apps.
82
-
83
- Returns: (success: bool, result: dict)
84
- result contains: {"apps": [...]} or {"error": "..."}
85
- """
86
- return _make_request("GET", "/api/apps", token=token)
87
-
88
-
89
- def create_app(token, app_name):
90
- """
91
- Create a new app.
92
-
93
- Returns: (success: bool, result: dict)
94
- result contains: {"app": {...}, "domain": "...", "git_remote": "...", "push_instructions": "..."} or {"error": "..."}
95
- """
96
- return _make_request("POST", "/api/apps/create", token=token, data={
97
- "name": app_name
98
- })
99
-
100
-
101
- def scale_app(token, app_name, replicas):
102
- """
103
- Scale an app to specified replica count.
104
-
105
- Returns: (success: bool, result: dict)
106
- result contains: {"app": {...}, "replicas": ...} or {"error": "..."}
107
- """
108
- return _make_request("POST", f"/api/apps/{app_name}/scale", token=token, data={
109
- "replicas": replicas
110
- })
111
-
112
-
113
- def get_logs(token, app_name):
114
- """
115
- Get logs for an app.
116
-
117
- Returns: (success: bool, result: dict)
118
- result contains: {"app": "...", "logs": "..."} or {"error": "..."}
119
- """
120
- return _make_request("GET", f"/api/apps/{app_name}/logs", token=token)
121
-
122
-
123
- def link_app(token, app_name):
124
- """
125
- Link to an existing app (get git remote info).
126
-
127
- Returns: (success: bool, result: dict)
128
- result contains: {"app": {...}, "domain": "...", "git_remote": "...", "push_instructions": "..."} or {"error": "..."}
129
- """
130
- return _make_request("POST", f"/api/apps/{app_name}/link", token=token)
131
- """
132
- Get metrics for an app.
133
-
134
- Returns: (success: bool, result: dict)
135
- result contains: {"app": "...", "replicas": [...]} or {"error": "..."}
136
- """
137
- return _make_request("GET", f"/api/apps/{app_name}/metrics", token=token)
138
-
139
-
140
- def get_metrics(token, app_name):
141
- """
142
- Get metrics for an app.
143
-
144
- Returns: (success: bool, result: dict)
145
- result contains: {"app": "...", "replicas": [...]} or {"error": "..."}
146
- """
147
- return _make_request("GET", f"/api/apps/{app_name}/metrics", token=token)
148
- """
149
- Register an SSH public key with the platform.
150
-
151
- Returns: (success: bool, result: dict)
152
- result contains: {"message": "..."} or {"error": "..."}
153
- """
154
- return _make_request("POST", "/api/keys/register", token=token, data={
155
- "public_key": public_key
156
- })
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes