Skip to content

Commit c0c6907

Browse files
Merge pull request #44 from ninsbl/job_terminate
Add support for terminate job endpoint and unify request_and_check function
2 parents cfa2753 + d9dd43d commit c0c6907

11 files changed

Lines changed: 152 additions & 143 deletions

File tree

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ jobs:
1414
steps:
1515
- uses: actions/checkout@v4
1616
- name: Start containers
17-
run: docker-compose -f "docker/docker-compose-test.yml" up -d --build
17+
run: docker compose -f "docker/docker-compose-test.yml" up -d --build
1818
- name: List running docker
1919
run: docker ps
2020
- name: Running tests
2121
run: make test
2222
- name: Stop containers
23-
run: docker-compose -f "docker/docker-compose-test.yml" down
23+
run: docker compose -f "docker/docker-compose-test.yml" down

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "actinia-python-client"
7-
version = "0.3.1"
7+
version = "0.4.5"
88
authors = [
99
{ name="Anika Weinmann", email="weinmann@mundialis.de" },
1010
]

src/actinia/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
__maintainer__ = "Anika Weinmann"
2929

3030
from pkg_resources import get_distribution, DistributionNotFound
31-
from actinia.actinia import Actinia
31+
from actinia.actinia import Actinia as Actinia
3232

3333
try:
3434
# Change here if project is renamed and does not equal the package name

src/actinia/actinia.py

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@
2727
__copyright__ = "Copyright 2022, mundialis GmbH & Co. KG"
2828
__maintainer__ = "Anika Weinmann"
2929

30-
import json
3130
import re
32-
import requests
3331

3432
from actinia.location import Location
3533
from actinia.resources.templating import tplEnv
3634
from actinia.resources.logger import log
35+
from actinia.utils import request_and_check
3736

3837

3938
class Actinia:
@@ -43,13 +42,16 @@ def __init__(
4342
api_version="latest",
4443
user=None,
4544
pw=None,
45+
connect_timeout=None,
46+
read_timeout=None,
4647
):
4748
self.api_prefix = api_version
4849
self.base_url = url
4950
self.headers = {"content-type": "application/json; charset=utf-8"}
5051
self.user = None
5152
self.__password = None
5253
self.__auth = None
54+
self.timeout = (connect_timeout, read_timeout)
5355
if user and pw:
5456
self.set_authentication(user, pw)
5557
self.locations = dict()
@@ -67,11 +69,9 @@ def __set_url(self):
6769

6870
def __check_version(self):
6971
version_url = f"{self.url}/version"
70-
resp = requests.get(version_url)
71-
if resp.status_code != 200:
72-
raise Exception("Connection to actinia server failed!")
73-
74-
data = json.loads(resp.text)
72+
data = request_and_check(
73+
"GET", version_url, **{"timeout": self.timeout}
74+
)
7575

7676
if len(data) > 2:
7777
log.debug(f"{self.url} is working and will be used.")
@@ -102,23 +102,16 @@ def get_version(self):
102102
"""
103103

104104
version_url = f"{self.url}/version"
105-
resp = requests.get(version_url)
106-
if resp.status_code != 200:
107-
raise Exception("Connection to actinia server failed!")
108-
data = json.loads(resp.text)
109-
return data
105+
return request_and_check(
106+
"GET", version_url, **{"timeout": self.timeout}
107+
)
110108

111109
def __check_auth(self):
112110
url = f"{self.url}/locations"
113-
resp = requests.get(url, auth=(self.__auth))
114-
if resp.status_code == 401:
115-
raise Exception(
116-
"Wrong user or password. Please check your inputs."
117-
)
118-
elif resp.status_code != 200:
119-
raise Exception(f"Error {resp.status_code}: {resp.text}")
120-
else:
121-
log.debug(f"{self.user} is logged in.")
111+
request_and_check(
112+
"GET", url, **{"timeout": self.timeout, "auth": (self.__auth)}
113+
)
114+
log.debug(f"{self.user} is logged in.")
122115

123116
def set_authentication(self, user, pw):
124117
"""
@@ -155,11 +148,9 @@ def __request_locations(self):
155148
raise Exception("Authentication is not set.")
156149

157150
url = f"{self.url}/locations"
158-
resp = requests.get(url, auth=(self.__auth))
159-
if resp.status_code != 200:
160-
raise Exception(f"Error {resp.status_code}: {resp.text}")
161-
162-
loc_names = json.loads(resp.text)["locations"]
151+
loc_names = request_and_check(
152+
"GET", url, **{"timeout": self.timeout, "auth": (self.__auth)}
153+
)["locations"]
163154
loc = {
164155
lname: Location(lname, self, self.__auth) for lname in loc_names
165156
}
@@ -178,18 +169,16 @@ def create_location(self, name, epsgcode):
178169
postbody = tpl.render(epsgcode=epsgcode)
179170

180171
url = f"{self.url}/locations/{name}"
181-
resp = requests.post(
172+
request_and_check(
173+
"POST",
182174
url,
183-
auth=(self.__auth),
184-
headers=self.headers,
185-
data=postbody,
175+
**{
176+
"timeout": self.timeout,
177+
"auth": (self.__auth),
178+
"headers": self.headers,
179+
"data": postbody,
180+
},
186181
)
187-
if resp.status_code != 200:
188-
try:
189-
msg = json.loads(resp.text)["message"]
190-
except Exception:
191-
msg = resp.text
192-
raise Exception(f"Error {resp.status_code}: {msg}")
193182

194183
location = Location(name, self, self.__auth)
195184
if len(self.locations) == 0:

src/actinia/job.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@
2727
__copyright__ = "Copyright 2022, mundialis GmbH & Co. KG"
2828
__maintainer__ = "Anika Weinmann"
2929

30-
import json
31-
import requests
3230
from time import sleep
3331

3432
from actinia.resources.logger import log
33+
from actinia.utils import request_and_check
3534

3635

3736
class Job:
@@ -62,15 +61,13 @@ def poll(self, quiet=False):
6261
if self.status not in ["accepted", "running"]:
6362
log.warning("The job is not running and can not be updated.")
6463

65-
kwargs = dict()
66-
kwargs["headers"] = self.__actinia.headers
67-
kwargs["auth"] = self.__auth
64+
kwargs = {
65+
"headers": self.__actinia.headers,
66+
"auth": self.__auth,
67+
"timeout": self.__actinia.timeout,
68+
}
6869
url = self.urls["status"]
69-
try:
70-
actiniaResp = requests.get(url, **kwargs)
71-
except requests.exceptions.ConnectionError as e:
72-
raise e
73-
resp = json.loads(actiniaResp.text)
70+
resp = request_and_check("GET", url, status_code=(200, 400), **kwargs)
7471

7572
if "process_results" not in resp:
7673
resp["process_results"] = {}
@@ -114,9 +111,12 @@ def poll_until_finished(self, waiting_time=5, quiet=False):
114111
)
115112
log.info(msg)
116113

117-
# def terminate(self):
118-
# """
119-
# Terminate job.
120-
# """
121-
#
122-
# TODO
114+
def terminate(self):
115+
"""Terminate the current job"""
116+
kwargs = {"auth": self._Job__auth, "timeout": self.__actinia.timeout}
117+
url = (
118+
f"{self._Job__actinia.url}/resources/"
119+
f"{self.user_id}/{self.resource_id}"
120+
)
121+
request_and_check("DELETE", url, **kwargs)
122+
log.info("Termination request for job {self.resource_id} committed.")

src/actinia/location.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from actinia.region import Region
3737
from actinia.mapset import Mapset
3838
from actinia.job import Job
39-
from actinia.utils import set_job_names
39+
from actinia.utils import set_job_names, request_and_check
4040

4141

4242
class Location:
@@ -56,11 +56,11 @@ def __request_info(self):
5656
raise Exception("Authentication is not set.")
5757

5858
url = f"{self.__actinia.url}/locations/{self.name}/info"
59-
resp = requests.get(url, auth=(self.__auth))
60-
if resp.status_code != 200:
61-
raise Exception(f"Error {resp.status_code}: {resp.text}")
62-
63-
proc_res = json.loads(resp.text)["process_results"]
59+
proc_res = request_and_check(
60+
"GET",
61+
url,
62+
**{"auth": (self.__auth), "timeout": self.__actinia.timeout},
63+
)["process_results"]
6464
self.projection = proc_res["projection"]
6565
self.region = Region(**proc_res["region"])
6666

@@ -86,9 +86,11 @@ def __request_mapsets(self):
8686
def delete(self):
8787
"""Delete a location via delete request."""
8888
url = f"{self.__actinia.url}/locations/{self.name}"
89-
resp = requests.delete(url, auth=self.__auth)
90-
if resp.status_code != 200:
91-
raise Exception(f"Error {resp.status_code}: {resp.text}")
89+
request_and_check(
90+
"DELETE",
91+
url,
92+
**{"auth": self.__auth, "timeout": self.__actinia.timeout},
93+
)
9294
del self.__actinia.locations[self.name]
9395

9496
def get_mapsets(self):
@@ -123,7 +125,7 @@ def delete_mapset(self, name):
123125
Mapset.delete_mapset_request(
124126
name, self.name, self.__actinia, self.__auth
125127
)
126-
if name is name in self.mapsets:
128+
if name and name in self.mapsets:
127129
del self.mapsets[name]
128130
return self.mapsets
129131

@@ -140,6 +142,7 @@ def __validate_process_chain(self, pc, type):
140142
auth=self.__auth,
141143
headers=self.__actinia.headers,
142144
data=json.dumps(pc),
145+
timeout=self.__actinia.timeout,
143146
)
144147
return resp
145148

@@ -183,9 +186,11 @@ def create_processing_export_job(self, pc, name=None):
183186
"processing_async_export"
184187
)
185188
# make POST request
186-
postkwargs = dict()
187-
postkwargs["headers"] = self.__actinia.headers
188-
postkwargs["auth"] = self.__auth
189+
postkwargs = {
190+
"headers": self.__actinia.headers,
191+
"auth": self.__auth,
192+
"timeout": self.__actinia.timeout,
193+
}
189194
if isinstance(pc, str):
190195
if os.path.isfile(pc):
191196
with open(pc, "r") as pc_file:
@@ -197,12 +202,8 @@ def create_processing_export_job(self, pc, name=None):
197202
else:
198203
raise Exception("Given process chain has no valid type.")
199204

200-
try:
201-
actiniaResp = requests.post(url, **postkwargs)
202-
except requests.exceptions.ConnectionError as e:
203-
raise e
205+
resp = request_and_check("POST", url, **postkwargs)
204206
# create a job
205-
resp = json.loads(actiniaResp.text)
206207
job = Job(orig_name, self.__actinia, self.__auth, resp)
207208
self.__actinia.jobs[name] = job
208209
return job

0 commit comments

Comments
 (0)