Skip to content

Commit

Permalink
Merge pull request #16 from gopythongo/pr14
Browse files Browse the repository at this point in the history
#14 Allow non-root locations in aptly API URLs
  • Loading branch information
jdelic authored Apr 14, 2018
2 parents ac328fb + 2b2a730 commit 868e9ed
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 32 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ build
.env
__pycache__
.coverage
.mypy_cache
.tox
.toxenv
3 changes: 0 additions & 3 deletions aptly_api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ def __init__(self, base_url: str, ssl_verify: Union[str, bool, None]=None,
self.http_auth = http_auth
self.exc_class = AptlyAPIException

while self.base_url.endswith("/"):
self.base_url = self.base_url[:-1]

def _error_from_response(self, resp: requests.Response) -> str:
if resp.status_code == 200:
return "no error (status 200)"
Expand Down
8 changes: 4 additions & 4 deletions aptly_api/parts/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
class FilesAPISection(BaseAPIClient):
def list(self, directory: str=None) -> Sequence[str]:
if directory is None:
resp = self.do_get("/api/files")
resp = self.do_get("api/files")
else:
resp = self.do_get("/api/files/%s" % directory)
resp = self.do_get("api/files/%s" % directory)

return resp.json()

Expand All @@ -27,7 +27,7 @@ def upload(self, destination: str, *files: str) -> Sequence[str]:
to_upload.append((f, fh),)

try:
resp = self.do_post("/api/files/%s" % destination,
resp = self.do_post("api/files/%s" % destination,
files=to_upload)
except AptlyAPIException:
raise
Expand All @@ -39,4 +39,4 @@ def upload(self, destination: str, *files: str) -> Sequence[str]:
return resp.json()

def delete(self, path: str=None) -> None:
self.do_delete("/api/files/%s" % path)
self.do_delete("api/files/%s" % path)
2 changes: 1 addition & 1 deletion aptly_api/parts/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def graph(self, ext: str, layout: str="horizontal") -> None:
raise NotImplementedError("The Graph API is not yet supported")

def version(self) -> str:
resp = self.do_get("/api/version")
resp = self.do_get("api/version")
if "Version" in resp.json():
return resp.json()["Version"]
else:
Expand Down
2 changes: 1 addition & 1 deletion aptly_api/parts/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ def package_from_response(api_response: Union[str, Dict[str, str]]) -> Package:
)

def show(self, key: str) -> Package:
resp = self.do_get("/api/packages/%s" % quote(key))
resp = self.do_get("api/packages/%s" % quote(key))
return self.package_from_response(resp.json())
10 changes: 5 additions & 5 deletions aptly_api/parts/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def escape_prefix(prefix: str) -> str:
return prefix

def list(self) -> Sequence[PublishEndpoint]:
resp = self.do_get("/api/publish")
resp = self.do_get("api/publish")
ret = []
for rpe in resp.json():
ret.append(self.endpoint_from_response(rpe))
Expand Down Expand Up @@ -84,9 +84,9 @@ def publish(self, *, source_kind: str="local",
if "name" not in source and "Name" not in source:
raise AptlyAPIException("Each source in publish() must contain the 'name' attribute")

url = "/api/publish"
url = "api/publish"
if prefix is not None and prefix != "":
url = "/api/publish/%s" % quote(self.escape_prefix(prefix))
url = "api/publish/%s" % quote(self.escape_prefix(prefix))

body = {
"SourceKind": source_kind,
Expand Down Expand Up @@ -171,13 +171,13 @@ def update(self, *, prefix: str, distribution: str,
sign_dict["PassphraseFile"] = sign_passphrase_file
body["Signing"] = sign_dict

resp = self.do_put("/api/publish/%s/%s" %
resp = self.do_put("api/publish/%s/%s" %
(quote(self.escape_prefix(prefix)), quote(distribution),), json=body)
return self.endpoint_from_response(resp.json())

def drop(self, *, prefix: str, distribution: str, force_delete: bool=False) -> None:
params = {}
if force_delete:
params["force"] = "1"
self.do_delete("/api/publish/%s/%s" %
self.do_delete("api/publish/%s/%s" %
(quote(self.escape_prefix(prefix)), quote(distribution),), params=params)
20 changes: 10 additions & 10 deletions aptly_api/parts/repos.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ def create(self, reponame: str, comment: str=None, default_distribution: str=Non
if default_component:
data["DefaultComponent"] = default_component

resp = self.do_post("/api/repos", json=data)
resp = self.do_post("api/repos", json=data)

return self.repo_from_response(resp.json())

def show(self, reponame: str) -> Repo:
resp = self.do_get("/api/repos/%s" % quote(reponame))
resp = self.do_get("api/repos/%s" % quote(reponame))
return self.repo_from_response(resp.json())

def search_packages(self, reponame: str, query: str=None, with_deps: bool=False,
Expand All @@ -75,7 +75,7 @@ def search_packages(self, reponame: str, query: str=None, with_deps: bool=False,
if detailed:
params["format"] = "details"

resp = self.do_get("/api/repos/%s/packages" % quote(reponame), params=params)
resp = self.do_get("api/repos/%s/packages" % quote(reponame), params=params)
ret = []
for rpkg in resp.json():
ret.append(PackageAPISection.package_from_response(rpkg))
Expand All @@ -95,11 +95,11 @@ def edit(self, reponame: str, comment: str=None, default_distribution: str=None,
if default_component is not None:
body["DefaultComponent"] = default_component

resp = self.do_put("/api/repos/%s" % quote(reponame), json=body)
resp = self.do_put("api/repos/%s" % quote(reponame), json=body)
return self.repo_from_response(resp.json())

def list(self) -> Sequence[Repo]:
resp = self.do_get("/api/repos")
resp = self.do_get("api/repos")

repos = []
for rdesc in resp.json():
Expand All @@ -109,7 +109,7 @@ def list(self) -> Sequence[Repo]:
return repos

def delete(self, reponame: str, force: bool=False) -> None:
self.do_delete("/api/repos/%s" % quote(reponame), params={"force": "1" if force else "0"})
self.do_delete("api/repos/%s" % quote(reponame), params={"force": "1" if force else "0"})

def add_uploaded_file(self, reponame: str, dir: str, filename: str=None, remove_processed_files: bool=True,
force_replace: bool=False) -> FileReport:
Expand All @@ -120,21 +120,21 @@ def add_uploaded_file(self, reponame: str, dir: str, filename: str=None, remove_
params["forceReplace"] = "1"

if filename is None:
resp = self.do_post("/api/repos/%s/file/%s" % (quote(reponame), quote(dir),), params=params)
resp = self.do_post("api/repos/%s/file/%s" % (quote(reponame), quote(dir),), params=params)
else:
resp = self.do_post("/api/repos/%s/file/%s/%s" % (quote(reponame), quote(dir), quote(filename),),
resp = self.do_post("api/repos/%s/file/%s/%s" % (quote(reponame), quote(dir), quote(filename),),
params=params)

return self.filereport_from_response(resp.json())

def add_packages_by_key(self, reponame: str, *package_keys: str) -> Repo:
resp = self.do_post("/api/repos/%s/packages" % quote(reponame), json={
resp = self.do_post("api/repos/%s/packages" % quote(reponame), json={
"PackageRefs": package_keys,
})
return self.repo_from_response(resp.json())

def delete_packages_by_key(self, reponame: str, *package_keys: str) -> Repo:
resp = self.do_delete("/api/repos/%s/packages" % quote(reponame), json={
resp = self.do_delete("api/repos/%s/packages" % quote(reponame), json={
"PackageRefs": package_keys,
})
return self.repo_from_response(resp.json())
16 changes: 8 additions & 8 deletions aptly_api/parts/snapshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def list(self, sort: str='name') -> Sequence[Snapshot]:
if sort not in ['name', 'time']:
raise AptlyAPIException("Snapshot LIST only supports two sort modes: 'name' and 'time'. %s is not "
"supported." % sort)
resp = self.do_get("/api/snapshots")
resp = self.do_get("api/snapshots")
ret = []
for rsnap in resp.json():
ret.append(self.snapshot_from_response(rsnap))
Expand All @@ -44,7 +44,7 @@ def create_from_repo(self, reponame: str, snapshotname: str, description: str=No
if description is not None:
body["Description"] = description

resp = self.do_post("/api/repos/%s/snapshots" % quote(reponame), json=body)
resp = self.do_post("api/repos/%s/snapshots" % quote(reponame), json=body)
return self.snapshot_from_response(resp.json())

def create_from_packages(self, snapshotname: str, description: str=None,
Expand All @@ -62,7 +62,7 @@ def create_from_packages(self, snapshotname: str, description: str=None,
if package_refs is not None:
body["PackageRefs"] = package_refs

resp = self.do_post("/api/snapshots", json=body)
resp = self.do_post("api/snapshots", json=body)
return self.snapshot_from_response(resp.json())

def update(self, snapshotname: str, newname: str=None, newdescription: str=None) -> Snapshot:
Expand All @@ -76,11 +76,11 @@ def update(self, snapshotname: str, newname: str=None, newdescription: str=None)
if newdescription is not None:
body["Description"] = newdescription

resp = self.do_put("/api/snapshots/%s" % quote(snapshotname), json=body)
resp = self.do_put("api/snapshots/%s" % quote(snapshotname), json=body)
return self.snapshot_from_response(resp.json())

def show(self, snapshotname: str) -> Snapshot:
resp = self.do_get("/api/snapshots/%s" % quote(snapshotname))
resp = self.do_get("api/snapshots/%s" % quote(snapshotname))
return self.snapshot_from_response(resp.json())

def list_packages(self, snapshotname: str, query: str=None, with_deps: bool=False,
Expand All @@ -93,7 +93,7 @@ def list_packages(self, snapshotname: str, query: str=None, with_deps: bool=Fals
if detailed:
params["format"] = "details"

resp = self.do_get("/api/snapshots/%s/packages" % quote(snapshotname), params=params)
resp = self.do_get("api/snapshots/%s/packages" % quote(snapshotname), params=params)
ret = []
for rpkg in resp.json():
ret.append(PackageAPISection.package_from_response(rpkg))
Expand All @@ -106,8 +106,8 @@ def delete(self, snapshotname: str, force: bool=False) -> None:
"force": "1",
}

self.do_delete("/api/snapshots/%s" % quote(snapshotname), params=params)
self.do_delete("api/snapshots/%s" % quote(snapshotname), params=params)

def diff(self, snapshot1: str, snapshot2: str) -> Sequence[Dict[str, str]]:
resp = self.do_get("/api/snapshots/%s/diff/%s" % (quote(snapshot1), quote(snapshot2),))
resp = self.do_get("api/snapshots/%s/diff/%s" % (quote(snapshot1), quote(snapshot2),))
return resp.json()
14 changes: 14 additions & 0 deletions aptly_api/tests/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ def test_instantiate(self) -> None:
"Client (Aptly API Client) <http://test/>"
)

@requests_mock.Mocker(kw='rmock')
def test_api_subdir_get(self, *, rmock: requests_mock.Mocker) -> None:
# register mock:// scheme with urllib.parse
import urllib.parse
urllib.parse.uses_netloc += ['mock']
urllib.parse.uses_relative += ['mock']
urllib.parse.uses_fragment += ['mock']
urllib.parse.uses_params += ['mock']

cl = AptlyClient("mock://test/basedir/")
rmock.get("mock://test/basedir/api/test", status_code=200, text='')
cl.files.do_get("api/test")
self.assertTrue(rmock.called)

def test_error_no_error(self) -> None:
class MockResponse:
def __init__(self, status_code: int=200) -> None:
Expand Down

0 comments on commit 868e9ed

Please sign in to comment.