Skip to content

Commit 8afbd06

Browse files
committed
API changes to better support project creation + async upload
- create_project() only creates empty remote project, no uploads - create_project_and_push() creates a project and does non-async upload - username() new convenience method to get user name - SyncError exception removed - we already have ClientError
1 parent b0a165c commit 8afbd06

File tree

4 files changed

+29
-27
lines changed

4 files changed

+29
-27
lines changed

mergin/client.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from pip._vendor import distro
1414

15-
from .common import ClientError, SyncError
15+
from .common import ClientError
1616
from .merginproject import MerginProject
1717
from .client_pull import download_project_async, download_project_wait, download_project_finalize
1818
from .client_pull import pull_project_async, pull_project_wait, pull_project_finalize
@@ -218,30 +218,31 @@ def login(self, login, password):
218218
}
219219
return session
220220

221-
def create_project(self, project_name, directory=None, is_public=False):
221+
def username(self):
222+
""" Returns user name used in this session or None if not authenticated """
223+
if not self._user_info:
224+
return None # not authenticated
225+
return self._user_info["username"]
226+
227+
def create_project(self, project_name, is_public=False):
222228
"""
223229
Create new project repository in user namespace on Mergin server.
224230
Optionally initialized from given local directory.
225231
226232
:param project_name: Project name
227233
:type project_name: String
228234
229-
:param directory: Local project directory, defaults to None
230-
:type directory: String
231-
232235
:param is_public: Flag for public/private project, defaults to False
233236
:type directory: Boolean
234237
"""
235238
if not self._user_info:
236239
raise Exception("Authentication required")
237-
if directory and not os.path.exists(directory):
238-
raise Exception("Project directory does not exists")
239240

240241
params = {
241242
"name": project_name,
242243
"public": is_public
243244
}
244-
namespace = self._user_info["username"]
245+
namespace = self.username()
245246
try:
246247
self.post("/v1/project/%s" % namespace, params, {"Content-Type": "application/json"})
247248
data = {
@@ -251,10 +252,17 @@ def create_project(self, project_name, directory=None, is_public=False):
251252
}
252253
except Exception as e:
253254
detail = f"Namespace: {namespace}, project name: {project_name}"
254-
raise SyncError(str(e), detail)
255+
raise ClientError(str(e), detail)
256+
257+
def create_project_and_push(self, project_name, directory, is_public=False):
258+
"""
259+
Convenience method to create project and push the initial version right after that.
260+
"""
261+
self.create_project(project_name, is_public)
255262
if directory:
256263
mp = MerginProject(directory)
257-
mp.metadata = data
264+
full_project_name = "{}/{}".format(self.username(), project_name)
265+
mp.metadata = {"name": full_project_name, "version": "v0", "files": []}
258266
if mp.inspect_files():
259267
self.push_project(directory)
260268

@@ -330,7 +338,7 @@ def download_project(self, project_path, directory):
330338
download_project_finalize(job)
331339

332340
def enough_storage_available(self, data):
333-
user_name = self._user_info["username"]
341+
user_name = self.username()
334342
resp = self.get('/v1/user/' + user_name)
335343
info = json.load(resp)
336344
free_space = int(info["storage_limit"]) - int(info["disk_usage"])

mergin/client_push.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import pprint
1515
import concurrent.futures
1616

17-
from .common import UPLOAD_CHUNK_SIZE, ClientError, SyncError
17+
from .common import UPLOAD_CHUNK_SIZE, ClientError
1818
from .merginproject import MerginProject
1919
from .utils import generate_checksum, do_sqlite_checkpoint
2020

@@ -99,7 +99,7 @@ def push_project_async(mc, directory):
9999
if not enough_free_space:
100100
freespace = int(freespace/(1024*1024))
101101
mp.log.error(f"--- push {project_path} - not enough space")
102-
raise SyncError("Storage limit has been reached. Only " + str(freespace) + "MB left")
102+
raise ClientError("Storage limit has been reached. Only " + str(freespace) + "MB left")
103103

104104
if not sum(len(v) for v in changes.values()):
105105
mp.log.info(f"--- push {project_path} - nothing to do")

mergin/common.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@ class ClientError(Exception):
1515
pass
1616

1717

18-
class SyncError(Exception):
19-
def __init__(self, msg, detail=""):
20-
super().__init__(msg)
21-
self.detail = detail
22-
23-
2418
try:
2519
import dateutil.parser
2620
from dateutil.tz import tzlocal

mergin/test/test_client.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import pytest
66
import pytz
77

8-
from ..client import MerginClient, ClientError, MerginProject, SyncError, LoginError
8+
from ..client import MerginClient, ClientError, MerginProject, LoginError
99
from ..utils import generate_checksum
1010

1111
SERVER_URL = os.environ.get('TEST_MERGIN_URL')
@@ -56,7 +56,7 @@ def test_create_delete_project(mc):
5656
assert any(p for p in projects if p['name'] == test_project and p['namespace'] == API_USER)
5757

5858
# try again
59-
with pytest.raises(SyncError, match=f'Project {test_project} already exists'):
59+
with pytest.raises(ClientError, match=f'Project {test_project} already exists'):
6060
mc.create_project(test_project)
6161

6262
# remove project
@@ -80,7 +80,7 @@ def test_create_remote_project_from_local(mc):
8080
shutil.copytree(TEST_DATA_DIR, project_dir)
8181

8282
# create remote project
83-
mc.create_project(test_project, directory=project_dir)
83+
mc.create_project_and_push(test_project, directory=project_dir)
8484

8585
# check basic metadata about created project
8686
project_info = mc.project_info(project)
@@ -119,7 +119,7 @@ def test_push_pull_changes(mc):
119119
cleanup(mc, project, [project_dir, project_dir_2])
120120
# create remote project
121121
shutil.copytree(TEST_DATA_DIR, project_dir)
122-
mc.create_project(test_project, project_dir)
122+
mc.create_project_and_push(test_project, project_dir)
123123

124124
# make sure we have v1 also in concurrent project dir
125125
mc.download_project(project, project_dir_2)
@@ -196,7 +196,7 @@ def test_ignore_files(mc):
196196
# create remote project
197197
shutil.copytree(TEST_DATA_DIR, project_dir)
198198
shutil.copy(os.path.join(project_dir, 'test.qgs'), os.path.join(project_dir, 'test.qgs~'))
199-
mc.create_project(test_project, project_dir)
199+
mc.create_project_and_push(test_project, project_dir)
200200
project_info = mc.project_info(project)
201201
assert not next((f for f in project_info['files'] if f['path'] == 'test.qgs~'), None)
202202

@@ -228,7 +228,7 @@ def test_sync_diff(mc, push_geodiff_enabled, pull_geodiff_enabled):
228228
# create remote project
229229
toggle_geodiff(push_geodiff_enabled)
230230
shutil.copytree(TEST_DATA_DIR, project_dir)
231-
mc.create_project(test_project, project_dir)
231+
mc.create_project_and_push(test_project, project_dir)
232232

233233
# make sure we have v1 also in concurrent project dirs
234234
toggle_geodiff(pull_geodiff_enabled)
@@ -318,7 +318,7 @@ def test_list_of_push_changes(mc):
318318
cleanup(mc, project, [project_dir])
319319
shutil.copytree(TEST_DATA_DIR, project_dir)
320320
toggle_geodiff(True)
321-
mc.create_project(test_project, project_dir)
321+
mc.create_project_and_push(test_project, project_dir)
322322

323323
f_updated = 'base.gpkg'
324324
mp = MerginProject(project_dir)
@@ -342,7 +342,7 @@ def test_force_gpkg_update(mc):
342342
cleanup(mc, project, [project_dir])
343343
# create remote project
344344
shutil.copytree(TEST_DATA_DIR, project_dir)
345-
mc.create_project(test_project, project_dir)
345+
mc.create_project_and_push(test_project, project_dir)
346346

347347
# test push changes with force gpkg file upload:
348348
mp = MerginProject(project_dir)

0 commit comments

Comments
 (0)