Skip to content

Commit f5403bb

Browse files
Zero effect refactoring replacing flavor="webapps" default hack with nice {{flavour}}
1 parent 86df831 commit f5403bb

File tree

2 files changed

+42
-41
lines changed

2 files changed

+42
-41
lines changed

pythonanywhere/api.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
class AuthenticationError(Exception):
2323
pass
2424

25+
2526
class NoTokenError(Exception):
2627
pass
2728

28-
def get_api_endpoint(flavour="webapps"):
29+
def get_api_endpoint():
2930
domain = os.environ.get('PYTHONANYWHERE_DOMAIN', 'pythonanywhere.com')
30-
return 'https://www.{domain}/api/v0/user/{{username}}/{flavour}/'.format(domain=domain, flavour=flavour)
31+
return 'https://www.{domain}/api/v0/user/{{username}}/{{flavour}}/'.format(domain=domain)
3132

3233

3334
def call_api(url, method, **kwargs):
@@ -84,7 +85,7 @@ def sanity_checks(self, nuke):
8485
if nuke:
8586
return
8687

87-
url = get_api_endpoint().format(username=getpass.getuser()) + self.domain + '/'
88+
url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + self.domain + '/'
8889
response = call_api(url, 'get')
8990
if response.status_code == 200:
9091
raise SanityException(
@@ -98,9 +99,9 @@ def sanity_checks(self, nuke):
9899
def create(self, python_version, virtualenv_path, project_path, nuke):
99100
print(snakesay('Creating web app via API'))
100101
if nuke:
101-
webapp_url = get_api_endpoint().format(username=getpass.getuser()) + self.domain + '/'
102+
webapp_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + self.domain + '/'
102103
call_api(webapp_url, 'delete')
103-
post_url = get_api_endpoint().format(username=getpass.getuser())
104+
post_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps")
104105
patch_url = post_url + self.domain + '/'
105106
response = call_api(post_url, 'post', data={
106107
'domain_name': self.domain, 'python_version': PYTHON_VERSIONS[python_version]},
@@ -130,7 +131,7 @@ def create(self, python_version, virtualenv_path, project_path, nuke):
130131
def add_default_static_files_mappings(self, project_path):
131132
print(snakesay('Adding static files mappings for /static/ and /media/'))
132133

133-
url = get_api_endpoint().format(username=getpass.getuser()) + self.domain + '/static_files/'
134+
url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + self.domain + '/static_files/'
134135
call_api(url, 'post', json=dict(
135136
url='/static/', path=str(Path(project_path) / 'static'),
136137
))
@@ -142,7 +143,7 @@ def add_default_static_files_mappings(self, project_path):
142143

143144
def reload(self):
144145
print(snakesay('Reloading {domain} via API'.format(domain=self.domain)))
145-
url = get_api_endpoint().format(username=getpass.getuser()) + self.domain + '/reload/'
146+
url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + self.domain + '/reload/'
146147
response = call_api(url, 'post')
147148
if not response.ok:
148149
raise Exception(
@@ -155,7 +156,7 @@ def reload(self):
155156

156157
def set_ssl(self, certificate, private_key):
157158
print(snakesay('Setting up SSL for {domain} via API'.format(domain=self.domain)))
158-
url = get_api_endpoint().format(username=getpass.getuser()) + self.domain + '/ssl/'
159+
url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + self.domain + '/ssl/'
159160
response = call_api(
160161
url, 'post',
161162
json={'cert': certificate, 'private_key': private_key}
@@ -170,7 +171,7 @@ def set_ssl(self, certificate, private_key):
170171

171172

172173
def get_ssl_info(self):
173-
url = get_api_endpoint().format(username=getpass.getuser()) + self.domain + '/ssl/'
174+
url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + self.domain + '/ssl/'
174175
response = call_api(url, 'get')
175176
if not response.ok:
176177
raise Exception(
@@ -195,14 +196,14 @@ def delete_log(self, log_type, index=0):
195196
'Deleting current {type} log file for {domain} via API'.format(type=log_type, domain=self.domain)))
196197

197198
if index == 1:
198-
url = get_api_endpoint("files").format(username=getpass.getuser()) + "path/var/log/{domain}.{type}.log.1/".format(
199+
url = get_api_endpoint().format(username=getpass.getuser(), flavour="files") + "path/var/log/{domain}.{type}.log.1/".format(
199200
domain=self.domain, type=log_type)
200201
elif index > 1:
201-
url = get_api_endpoint("files").format(
202-
username=getpass.getuser()) + "path/var/log/{domain}.{type}.log.{index}.gz/".format(
202+
url = get_api_endpoint().format(
203+
username=getpass.getuser(), flavour="files") + "path/var/log/{domain}.{type}.log.{index}.gz/".format(
203204
domain=self.domain, type=log_type, index=index)
204205
else:
205-
url = get_api_endpoint("files").format(username=getpass.getuser()) + "path/var/log/{domain}.{type}.log/".format(
206+
url = get_api_endpoint().format(username=getpass.getuser(), flavour="files") + "path/var/log/{domain}.{type}.log/".format(
206207
domain=self.domain, type=log_type)
207208
response = call_api(url, "delete")
208209
if not response.ok:

tests/test_api.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
class TestGetAPIEndpoint:
2020

2121
def test_gets_domain_from_env_if_set(self, monkeypatch):
22-
assert get_api_endpoint() == 'https://www.pythonanywhere.com/api/v0/user/{username}/webapps/'
22+
assert get_api_endpoint() == 'https://www.pythonanywhere.com/api/v0/user/{username}/{flavour}/'
2323
monkeypatch.setenv('PYTHONANYWHERE_DOMAIN', 'foo.com')
24-
assert get_api_endpoint() == 'https://www.foo.com/api/v0/user/{username}/webapps/'
24+
assert get_api_endpoint() == 'https://www.foo.com/api/v0/user/{username}/{flavour}/'
2525

2626

2727
class TestCallAPI:
@@ -67,7 +67,7 @@ def test_compare_not_equal(self):
6767

6868
class TestWebappSanityChecks:
6969
domain = 'www.domain.com'
70-
expected_url = get_api_endpoint().format(username=getpass.getuser()) + domain + '/'
70+
expected_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + domain + '/'
7171

7272
def test_does_not_complain_if_api_token_exists(self, api_token, api_responses):
7373
webapp = Webapp(self.domain)
@@ -115,8 +115,8 @@ def test_nuke_option_overrides_all_but_token_check(
115115
class TestCreateWebapp:
116116

117117
def test_does_post_to_create_webapp(self, api_responses, api_token):
118-
expected_post_url = get_api_endpoint().format(username=getpass.getuser())
119-
expected_patch_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/'
118+
expected_post_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps")
119+
expected_patch_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/'
120120
api_responses.add(responses.POST, expected_post_url, status=201, body=json.dumps({'status': 'OK'}))
121121
api_responses.add(responses.PATCH, expected_patch_url, status=200)
122122

@@ -132,8 +132,8 @@ def test_does_post_to_create_webapp(self, api_responses, api_token):
132132

133133

134134
def test_does_patch_to_update_virtualenv_path_and_source_directory(self, api_responses, api_token):
135-
expected_post_url = get_api_endpoint().format(username=getpass.getuser())
136-
expected_patch_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/'
135+
expected_post_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps")
136+
expected_patch_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/'
137137
api_responses.add(responses.POST, expected_post_url, status=201, body=json.dumps({'status': 'OK'}))
138138
api_responses.add(responses.PATCH, expected_patch_url, status=200)
139139

@@ -149,7 +149,7 @@ def test_does_patch_to_update_virtualenv_path_and_source_directory(self, api_res
149149

150150

151151
def test_raises_if_post_does_not_20x(self, api_responses, api_token):
152-
expected_post_url = get_api_endpoint().format(username=getpass.getuser())
152+
expected_post_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps")
153153
api_responses.add(responses.POST, expected_post_url, status=500, body='an error')
154154

155155
with pytest.raises(Exception) as e:
@@ -160,7 +160,7 @@ def test_raises_if_post_does_not_20x(self, api_responses, api_token):
160160

161161

162162
def test_raises_if_post_returns_a_200_with_status_error(self, api_responses, api_token):
163-
expected_post_url = get_api_endpoint().format(username=getpass.getuser())
163+
expected_post_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps")
164164
api_responses.add(responses.POST, expected_post_url, status=200, body=json.dumps({
165165
"status": "ERROR", "error_type": "bad", "error_message": "bad things happened"
166166
}))
@@ -173,8 +173,8 @@ def test_raises_if_post_returns_a_200_with_status_error(self, api_responses, api
173173

174174

175175
def test_raises_if_patch_does_not_20x(self, api_responses, api_token):
176-
expected_post_url = get_api_endpoint().format(username=getpass.getuser())
177-
expected_patch_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/'
176+
expected_post_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps")
177+
expected_patch_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/'
178178
api_responses.add(responses.POST, expected_post_url, status=201, body=json.dumps({'status': 'OK'}))
179179
api_responses.add(responses.PATCH, expected_patch_url, status=400, json={'message': 'an error'})
180180

@@ -186,8 +186,8 @@ def test_raises_if_patch_does_not_20x(self, api_responses, api_token):
186186

187187

188188
def test_does_delete_first_for_nuke_call(self, api_responses, api_token):
189-
post_url = get_api_endpoint().format(username=getpass.getuser())
190-
webapp_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/'
189+
post_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps")
190+
webapp_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/'
191191
api_responses.add(responses.DELETE, webapp_url, status=200)
192192
api_responses.add(responses.POST, post_url, status=201, body=json.dumps({'status': 'OK'}))
193193
api_responses.add(responses.PATCH, webapp_url, status=200)
@@ -201,8 +201,8 @@ def test_does_delete_first_for_nuke_call(self, api_responses, api_token):
201201

202202

203203
def test_ignores_404_from_delete_call_when_nuking(self, api_responses, api_token):
204-
post_url = get_api_endpoint().format(username=getpass.getuser())
205-
webapp_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/'
204+
post_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps")
205+
webapp_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/'
206206
api_responses.add(responses.DELETE, webapp_url, status=404)
207207
api_responses.add(responses.POST, post_url, status=201, body=json.dumps({'status': 'OK'}))
208208
api_responses.add(responses.PATCH, webapp_url, status=200)
@@ -214,7 +214,7 @@ def test_ignores_404_from_delete_call_when_nuking(self, api_responses, api_token
214214
class TestAddDefaultStaticFilesMapping:
215215

216216
def test_does_two_posts_to_static_files_endpoint(self, api_token, api_responses):
217-
expected_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/static_files/'
217+
expected_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/static_files/'
218218
api_responses.add(responses.POST, expected_url, status=201)
219219
api_responses.add(responses.POST, expected_url, status=201)
220220

@@ -240,7 +240,7 @@ def test_does_two_posts_to_static_files_endpoint(self, api_token, api_responses)
240240
class TestReloadWebapp:
241241

242242
def test_does_post_to_reload_url(self, api_responses, api_token):
243-
expected_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/reload/'
243+
expected_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/reload/'
244244
api_responses.add(responses.POST, expected_url, status=200)
245245

246246
Webapp('mydomain.com').reload()
@@ -252,7 +252,7 @@ def test_does_post_to_reload_url(self, api_responses, api_token):
252252

253253

254254
def test_raises_if_post_does_not_20x(self, api_responses, api_token):
255-
expected_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/reload/'
255+
expected_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/reload/'
256256
api_responses.add(responses.POST, expected_url, status=404, body='nope')
257257

258258
with pytest.raises(Exception) as e:
@@ -265,7 +265,7 @@ def test_raises_if_post_does_not_20x(self, api_responses, api_token):
265265
class TestSetWebappSSL:
266266

267267
def test_does_post_to_ssl_url(self, api_responses, api_token):
268-
expected_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/ssl/'
268+
expected_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/ssl/'
269269
api_responses.add(responses.POST, expected_url, status=200)
270270
certificate = "certificate data"
271271
private_key = "private key data"
@@ -281,7 +281,7 @@ def test_does_post_to_ssl_url(self, api_responses, api_token):
281281

282282

283283
def test_raises_if_post_does_not_20x(self, api_responses, api_token):
284-
expected_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/ssl/'
284+
expected_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/ssl/'
285285
api_responses.add(responses.POST, expected_url, status=404, body='nope')
286286

287287
with pytest.raises(Exception) as e:
@@ -294,7 +294,7 @@ def test_raises_if_post_does_not_20x(self, api_responses, api_token):
294294
class TestGetWebappSSLInfo:
295295

296296
def test_returns_json_from_server_having_parsed_expiry(self, api_responses, api_token):
297-
expected_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/ssl/'
297+
expected_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/ssl/'
298298
api_responses.add(
299299
responses.GET, expected_url, status=200,
300300
body=json.dumps({
@@ -320,7 +320,7 @@ def test_returns_json_from_server_having_parsed_expiry(self, api_responses, api_
320320

321321

322322
def test_raises_if_get_does_not_return_200(self, api_responses, api_token):
323-
expected_url = get_api_endpoint().format(username=getpass.getuser()) + 'mydomain.com/ssl/'
323+
expected_url = get_api_endpoint().format(username=getpass.getuser(), flavour="webapps") + 'mydomain.com/ssl/'
324324
api_responses.add(responses.GET, expected_url, status=404, body='nope')
325325

326326
with pytest.raises(Exception) as e:
@@ -333,8 +333,8 @@ def test_raises_if_get_does_not_return_200(self, api_responses, api_token):
333333
class TestDeleteWebappLog:
334334

335335
def test_delete_current_access_log(self, api_responses, api_token):
336-
expected_url = get_api_endpoint(flavour="files").format(
337-
username=getpass.getuser()) + "path/var/log/mydomain.com.access.log/"
336+
expected_url = get_api_endpoint().format(
337+
username=getpass.getuser(), flavour="files") + "path/var/log/mydomain.com.access.log/"
338338
api_responses.add(responses.DELETE, expected_url, status=200)
339339

340340
Webapp("mydomain.com").delete_log(log_type="access")
@@ -345,8 +345,8 @@ def test_delete_current_access_log(self, api_responses, api_token):
345345
assert post.request.headers['Authorization'] == 'Token {api_token}'.format(api_token=api_token)
346346

347347
def test_delete_old_access_log(self, api_responses, api_token):
348-
expected_url = get_api_endpoint(flavour="files").format(
349-
username=getpass.getuser()) + "path/var/log/mydomain.com.access.log.1/"
348+
expected_url = get_api_endpoint().format(
349+
username=getpass.getuser(), flavour="files") + "path/var/log/mydomain.com.access.log.1/"
350350
api_responses.add(responses.DELETE, expected_url, status=200)
351351

352352
Webapp("mydomain.com").delete_log(log_type="access", index=1)
@@ -357,8 +357,8 @@ def test_delete_old_access_log(self, api_responses, api_token):
357357
assert post.request.headers['Authorization'] == 'Token {api_token}'.format(api_token=api_token)
358358

359359
def test_raises_if_post_does_not_20x(self, api_responses, api_token):
360-
expected_url = get_api_endpoint(flavour="files").format(
361-
username=getpass.getuser()) + "path/var/log/mydomain.com.access.log/"
360+
expected_url = get_api_endpoint().format(
361+
username=getpass.getuser(), flavour="files") + "path/var/log/mydomain.com.access.log/"
362362
api_responses.add(responses.DELETE, expected_url, status=404, body="nope")
363363

364364
with pytest.raises(Exception) as e:

0 commit comments

Comments
 (0)