p2f-client-py 0.0.11__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.
- p2f_client_py-0.0.11/PKG-INFO +30 -0
- p2f_client_py-0.0.11/README.md +15 -0
- p2f_client_py-0.0.11/p2f_client/__init__.py +0 -0
- p2f_client_py-0.0.11/p2f_client/conn.py +32 -0
- p2f_client_py-0.0.11/p2f_client/datasets.py +66 -0
- p2f_client_py-0.0.11/p2f_client/doi.py +38 -0
- p2f_client_py-0.0.11/p2f_client/harm_data_record.py +65 -0
- p2f_client_py-0.0.11/p2f_client/harm_data_types.py +58 -0
- p2f_client_py-0.0.11/p2f_client/harm_location.py +77 -0
- p2f_client_py-0.0.11/p2f_client/harm_numerical.py +84 -0
- p2f_client_py-0.0.11/p2f_client/harm_reference.py +68 -0
- p2f_client_py-0.0.11/p2f_client/harm_species.py +76 -0
- p2f_client_py-0.0.11/p2f_client/harm_timeslice.py +75 -0
- p2f_client_py-0.0.11/p2f_client/p2f_client.py +84 -0
- p2f_client_py-0.0.11/p2f_client_py.egg-info/PKG-INFO +30 -0
- p2f_client_py-0.0.11/p2f_client_py.egg-info/SOURCES.txt +19 -0
- p2f_client_py-0.0.11/p2f_client_py.egg-info/dependency_links.txt +1 -0
- p2f_client_py-0.0.11/p2f_client_py.egg-info/requires.txt +6 -0
- p2f_client_py-0.0.11/p2f_client_py.egg-info/top_level.txt +2 -0
- p2f_client_py-0.0.11/pyproject.toml +23 -0
- p2f_client_py-0.0.11/setup.cfg +4 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: p2f-client-py
|
|
3
|
+
Version: 0.0.11
|
|
4
|
+
Summary: API Client library for the Past to Future project.
|
|
5
|
+
Author-email: Garrett Speed <g.t.speed@uu.nl>
|
|
6
|
+
Project-URL: Homepage, https://github.com/Past-to-Future-EU-Horizon/p2f-client-py
|
|
7
|
+
Requires-Python: >=3.13
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: furl>=2.1.4
|
|
10
|
+
Requires-Dist: p2f-pydantic
|
|
11
|
+
Requires-Dist: pandas>=2.3.3
|
|
12
|
+
Requires-Dist: pyjwt>=2.10.1
|
|
13
|
+
Requires-Dist: python-dotenv>=1.1.0
|
|
14
|
+
Requires-Dist: requests>=2.32.3
|
|
15
|
+
|
|
16
|
+
# p2f-client-py
|
|
17
|
+
Python client library for the Past to Future projects Portal. Past to Future is an EU Horizon funded project.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
pip install git+https://github.com/Past-to-Future-EU-Horizon/p2f-client-py
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
Create a client
|
|
27
|
+
|
|
28
|
+
from p2f_client import P2F_Client
|
|
29
|
+
|
|
30
|
+
client = P2F_Client("p2f-api.uu.nl", 8000)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# p2f-client-py
|
|
2
|
+
Python client library for the Past to Future projects Portal. Past to Future is an EU Horizon funded project.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
|
|
6
|
+
pip install git+https://github.com/Past-to-Future-EU-Horizon/p2f-client-py
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
Create a client
|
|
12
|
+
|
|
13
|
+
from p2f_client import P2F_Client
|
|
14
|
+
|
|
15
|
+
client = P2F_Client("p2f-api.uu.nl", 8000)
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from furl import furl
|
|
3
|
+
|
|
4
|
+
### We're having an issue with the API needing a connection
|
|
5
|
+
### open to actually get data into the portal. Here we're
|
|
6
|
+
### making a decorator function to probe the health-check
|
|
7
|
+
### endpoint first, opening the connection to the API.
|
|
8
|
+
|
|
9
|
+
def health_probe(base_url):
|
|
10
|
+
def health_probe_func_level(func):
|
|
11
|
+
base_url = furl(base_url)
|
|
12
|
+
prefix = "health-check"
|
|
13
|
+
healthcheckurl = base_url / f"{prefix}/"
|
|
14
|
+
r = requests.get(healthcheckurl)
|
|
15
|
+
if r.ok:
|
|
16
|
+
# Run the decorated function
|
|
17
|
+
def innerfunc(*args, **kwargs):
|
|
18
|
+
return func(*args, **kwargs)
|
|
19
|
+
return innerfunc
|
|
20
|
+
else:
|
|
21
|
+
# Due to above commented issue, if we can't get a GET, then raise an error
|
|
22
|
+
raise requests.exceptions.HTTPError("The client could not connect to the API server.")
|
|
23
|
+
return health_probe_func_level
|
|
24
|
+
|
|
25
|
+
def health_check(base_url: furl):
|
|
26
|
+
prefix = "health-check"
|
|
27
|
+
healthcheck_url = base_url / f"{prefix}/"
|
|
28
|
+
r = requests.get(healthcheck_url)
|
|
29
|
+
if r.ok:
|
|
30
|
+
return True
|
|
31
|
+
else:
|
|
32
|
+
return False
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from p2f_pydantic.datasets import Datasets
|
|
3
|
+
from .conn import health_check
|
|
4
|
+
# Third Party Libraries
|
|
5
|
+
import requests
|
|
6
|
+
from furl import furl
|
|
7
|
+
# Batteries included libraries
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
from typing import Optional, List
|
|
10
|
+
|
|
11
|
+
class datasets:
|
|
12
|
+
def __init__(self, p2fclient):
|
|
13
|
+
self.p2fclient = p2fclient
|
|
14
|
+
self.base_url = p2fclient.base_url
|
|
15
|
+
self.prefix = "datasets/"
|
|
16
|
+
self.dataset_url = self.base_url / self.prefix
|
|
17
|
+
self.upload_queue = []
|
|
18
|
+
def add_dataset(self, dataset: Datasets):
|
|
19
|
+
self.upload_queue.append(dataset)
|
|
20
|
+
def upload_datasets(self):
|
|
21
|
+
uploaded_datasets = []
|
|
22
|
+
if health_check(self.base_url):
|
|
23
|
+
for dataset in self.upload_queue:
|
|
24
|
+
r = requests.post(self.dataset_url,
|
|
25
|
+
data=self.p2fclient.json_serialize_with_auth("dataset", dataset.model_dump_json(exclude_unset=True)),
|
|
26
|
+
headers={"Content-Type": "application/json"})
|
|
27
|
+
uploaded_datasets.append(Datasets(**r.json()))
|
|
28
|
+
# self.uploaded_datasets = uploaded_datasets
|
|
29
|
+
return uploaded_datasets
|
|
30
|
+
def upload_dataset(self, dataset: Datasets):
|
|
31
|
+
if health_check(self.base_url):
|
|
32
|
+
r = requests.post(self.dataset_url,
|
|
33
|
+
data=self.p2fclient.json_serialize_with_auth("dataset", dataset.model_dump_json(exclude_unset=True)),
|
|
34
|
+
headers={"Content-Type": "application/json"})
|
|
35
|
+
return Datasets(**r.json())
|
|
36
|
+
def list_remote_datasets(self,
|
|
37
|
+
is_new_p2f: Optional[bool]=None,
|
|
38
|
+
is_sub_dataset: Optional[bool]=None,
|
|
39
|
+
doi: Optional[str]=None) -> List[Datasets]:
|
|
40
|
+
list_url = self.dataset_url
|
|
41
|
+
# data = {}
|
|
42
|
+
if is_new_p2f is not None:
|
|
43
|
+
list_url.args["is_new_p2f"] = is_new_p2f
|
|
44
|
+
# data["is_new_p2f"] = is_new_p2f
|
|
45
|
+
if is_sub_dataset is not None:
|
|
46
|
+
list_url.args["is_sub_dataset"] = is_sub_dataset
|
|
47
|
+
# data["is_sub_dataset"] = is_sub_dataset
|
|
48
|
+
if doi is not None:
|
|
49
|
+
list_url.args["doi"] = doi
|
|
50
|
+
# data["doi"] = doi
|
|
51
|
+
if health_check(self.base_url):
|
|
52
|
+
r = requests.get(list_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
53
|
+
headers={"Content-Type": "application/json"})
|
|
54
|
+
# self.datasets = [Datasets(**x) for x in r.json()]
|
|
55
|
+
return [Datasets(**x) for x in r.json()]
|
|
56
|
+
def get_remote_dataset(self, dataset_id):
|
|
57
|
+
get_url = self.dataset_url / str(dataset_id)
|
|
58
|
+
if health_check(self.base_url):
|
|
59
|
+
r = requests.get(get_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
60
|
+
headers={"Content-Type": "application/json"})
|
|
61
|
+
return Datasets(**r.json())
|
|
62
|
+
def delete_remote_dataset(self, dataset_id):
|
|
63
|
+
delete_url = self.dataset_url / str(dataset_id)
|
|
64
|
+
if health_check(self.base_url):
|
|
65
|
+
r = requests.delete(delete_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
66
|
+
headers={"Content-Type": "application/json"})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import furl
|
|
2
|
+
|
|
3
|
+
class doi:
|
|
4
|
+
def __init__(self, doi_input: str):
|
|
5
|
+
if doi_input.startswith("10"):
|
|
6
|
+
doi_split = doi_input.split("/")
|
|
7
|
+
print(doi_split)
|
|
8
|
+
if len(doi_split) == 2:
|
|
9
|
+
self.prefix, self.suffix = doi_split
|
|
10
|
+
else:
|
|
11
|
+
raise ValueError("The provided doi object does not conform to the prefix and suffix format.")
|
|
12
|
+
elif doi_input.startswith("http"):
|
|
13
|
+
url = furl.furl(doi_input)
|
|
14
|
+
match url.host:
|
|
15
|
+
case "doi.org":
|
|
16
|
+
print(url.path.segments)
|
|
17
|
+
self.prefix = [x for x in url.path.segments if x.startswith("10")][0]
|
|
18
|
+
self.suffix = url.path.segments[url.path.segments.index(self.prefix) + 1]
|
|
19
|
+
case "doi.pangaea.de":
|
|
20
|
+
print(url.path.segments)
|
|
21
|
+
self.prefix = [x for x in url.path.segments if x.startswith("10")][0]
|
|
22
|
+
self.suffix = url.path.segments[url.path.segments.index(self.prefix) + 1]
|
|
23
|
+
elif doi_input.startswith("doi:"):
|
|
24
|
+
doi_input = doi_input[4:]
|
|
25
|
+
doi_split = doi_input.split("/")
|
|
26
|
+
print(doi_split)
|
|
27
|
+
if len(doi_split) == 2:
|
|
28
|
+
self.prefix, self.suffix = doi_split
|
|
29
|
+
else:
|
|
30
|
+
raise ValueError("The provided doi object does not conform to the prefix and suffix format.")
|
|
31
|
+
else:
|
|
32
|
+
raise ValueError("Unable to recognize the format of this doi")
|
|
33
|
+
self.url = furl.furl(f"https://doi.org/{self.prefix}/{self.suffix}")
|
|
34
|
+
self.string = f"{self.prefix}/{self.suffix}"
|
|
35
|
+
def __str__(self):
|
|
36
|
+
return self.string
|
|
37
|
+
def __repr__(self):
|
|
38
|
+
return f"<doi object prefix={self.prefix} suffix={self.suffix}>"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from p2f_pydantic.harm_data_record import HARM_Data_Record
|
|
3
|
+
from .conn import health_check
|
|
4
|
+
# Third Party Libraries
|
|
5
|
+
import requests
|
|
6
|
+
from furl import furl
|
|
7
|
+
# Batteries included libraries
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
from typing import Optional, List
|
|
10
|
+
import hashlib
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
from zoneinfo import ZoneInfo
|
|
13
|
+
|
|
14
|
+
class harm_data_records:
|
|
15
|
+
def __init__(self, p2fclient):
|
|
16
|
+
self.p2fclient = p2fclient
|
|
17
|
+
self.base_url = p2fclient.base_url
|
|
18
|
+
self.prefix = "harm-data-records/"
|
|
19
|
+
self.hdr_url = self.base_url / self.prefix
|
|
20
|
+
self.harm_data_records_queue = []
|
|
21
|
+
def add_data_record(self, data_record: HARM_Data_Record):
|
|
22
|
+
self.harm_data_records_queue.append(data_record)
|
|
23
|
+
def upload_data_records(self):
|
|
24
|
+
uploaded_records = []
|
|
25
|
+
if health_check(self.base_url):
|
|
26
|
+
for record in self.harm_data_records_queue:
|
|
27
|
+
r = requests.post(self.hdr_url,
|
|
28
|
+
data=self.p2fclient.json_serialize_with_auth("new_data_record", record.model_dump_json(exclude_unset=True)),
|
|
29
|
+
headers={"Content-Type": "application/json"})
|
|
30
|
+
record.append(HARM_Data_Record(**r.json()))
|
|
31
|
+
self.uploaded_records = uploaded_records
|
|
32
|
+
return uploaded_records
|
|
33
|
+
def upload_data_record(self, data_record: HARM_Data_Record):
|
|
34
|
+
if health_check(self.base_url):
|
|
35
|
+
r = requests.post(self.hdr_url,
|
|
36
|
+
data=self.p2fclient.json_serialize_with_auth("new_data_record", data_record.model_dump_json(exclude_unset=True)),
|
|
37
|
+
headers={"Content-Type": "application/json"})
|
|
38
|
+
return HARM_Data_Record(**r.json())
|
|
39
|
+
def list_remote_records(self,
|
|
40
|
+
dataset: Optional[str]=None,
|
|
41
|
+
data_type: Optional[str]=None):
|
|
42
|
+
params = {"dataset": dataset,
|
|
43
|
+
"data_type": data_type}
|
|
44
|
+
params = {x:y for x, y in params.items() if y != None}
|
|
45
|
+
if health_check(self.base_url):
|
|
46
|
+
r = requests.get(self.hdr_url,
|
|
47
|
+
params=params, data=self.p2fclient.json_serialize_with_auth(),
|
|
48
|
+
headers={"Content-Type": "application/json"})
|
|
49
|
+
return [HARM_Data_Record(**x) for x in r.json()]
|
|
50
|
+
def get_remote_record(self, record_hash: str):
|
|
51
|
+
if health_check(self.base_url):
|
|
52
|
+
r = requests.get(self.hdr_url / record_hash, data=self.p2fclient.json_serialize_with_auth(),
|
|
53
|
+
headers={"Content-Type": "application/json"})
|
|
54
|
+
return HARM_Data_Record(**r.json())
|
|
55
|
+
def delete_remote_dataset(self, record_hash: str):
|
|
56
|
+
if health_check(self.base_url):
|
|
57
|
+
r = requests.delete(self.hdr_url / record_hash, data=self.p2fclient.json_serialize_with_auth(),
|
|
58
|
+
headers={"Content-Type": "application/json"})
|
|
59
|
+
def calculate_hash(self, dataset_id, row_number, debugging=False):
|
|
60
|
+
hasher = hashlib.md5()
|
|
61
|
+
hasher.update(str(dataset_id).encode("utf8"))
|
|
62
|
+
hasher.update(str(row_number).encode("utf8"))
|
|
63
|
+
if debugging == True:
|
|
64
|
+
hasher.update(str(datetime.now(tz=ZoneInfo("UTC")).isoformat(sep="T")).encode("utf8"))
|
|
65
|
+
return str(hasher.hexdigest())
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from p2f_pydantic.harm_data_types import HARM_Data_Type
|
|
3
|
+
from .conn import health_check
|
|
4
|
+
# Third Party Libraries
|
|
5
|
+
import requests
|
|
6
|
+
from furl import furl
|
|
7
|
+
# Batteries included libraries
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
from typing import Optional, List
|
|
10
|
+
|
|
11
|
+
class harm_data_type:
|
|
12
|
+
def __init__(self, p2fclient):
|
|
13
|
+
self.p2fclient = p2fclient
|
|
14
|
+
self.base_url = p2fclient.base_url
|
|
15
|
+
self.prefix = "harm-data-types/"
|
|
16
|
+
self.hdt_url = self.base_url / self.prefix
|
|
17
|
+
self.harm_data_types_queue = []
|
|
18
|
+
def add_harm_data_type(self, new_data_type: HARM_Data_Type):
|
|
19
|
+
self.harm_data_types_queue.append(new_data_type)
|
|
20
|
+
def upload_data_types(self):
|
|
21
|
+
if health_check(self.base_url):
|
|
22
|
+
for datatype in self.harm_data_types_queue:
|
|
23
|
+
r = requests.post(self.hdt_url,
|
|
24
|
+
data=self.p2fclient.json_serialize_with_auth("new_harm_data_type", datatype.model_dump_json(exclude_unset=True)),
|
|
25
|
+
headers={"Content-Type": "application/json"})
|
|
26
|
+
def upload_data_type(self, new_data_type: HARM_Data_Type):
|
|
27
|
+
if health_check(self.base_url):
|
|
28
|
+
r = requests.post(self.hdt_url,
|
|
29
|
+
data=self.p2fclient.json_serialize_with_auth("new_harm_data_type", new_data_type.model_dump_json(exclude_unset=True)),
|
|
30
|
+
headers={"Content-Type": "application/json"})
|
|
31
|
+
return HARM_Data_Type(**r.json())
|
|
32
|
+
def list_data_types(self,
|
|
33
|
+
measure: Optional[str]=None,
|
|
34
|
+
unit_of_measure: Optional[str]=None,
|
|
35
|
+
method: Optional[str]=None,
|
|
36
|
+
dataset_id: Optional[UUID]=None):
|
|
37
|
+
params = {"measure": measure,
|
|
38
|
+
"unit_of_measure": unit_of_measure,
|
|
39
|
+
"method": method,
|
|
40
|
+
"dataset_id": dataset_id}
|
|
41
|
+
params = {x:y for x, y in params.items() if y != None}
|
|
42
|
+
if health_check(self.base_url):
|
|
43
|
+
r = requests.get(self.hdt_url,
|
|
44
|
+
params=params,
|
|
45
|
+
data=self.p2fclient.json_serialize_with_auth(),
|
|
46
|
+
headers={"Content-Type": "application/json"})
|
|
47
|
+
return [HARM_Data_Type(**x) for x in r.json()]
|
|
48
|
+
def get_data_type(self, datatype_id: UUID):
|
|
49
|
+
if health_check(self.base_url):
|
|
50
|
+
r = requests.get(self.hdt_url / datatype_id,
|
|
51
|
+
data=self.p2fclient.json_serialize_with_auth(),
|
|
52
|
+
headers={"Content-Type": "application/json"})
|
|
53
|
+
return HARM_Data_Type(**r.json())
|
|
54
|
+
def delete_data_type(self, datatype_id: UUID):
|
|
55
|
+
if health_check(self.base_url):
|
|
56
|
+
r = requests.delete(self.hdt_url / datatype_id,
|
|
57
|
+
data=self.p2fclient.json_serialize_with_auth(),
|
|
58
|
+
headers={"Content-Type": "application/json"})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from p2f_pydantic.harm_data_metadata import HARM_Bounding_Box, HARM_Location
|
|
3
|
+
from .conn import health_check
|
|
4
|
+
# Third Party Libraries
|
|
5
|
+
import requests
|
|
6
|
+
from furl import furl
|
|
7
|
+
# Batteries included libraries
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
from typing import Optional, List, Union
|
|
10
|
+
|
|
11
|
+
class harm_location:
|
|
12
|
+
def __init__(self, p2fclient):
|
|
13
|
+
self.p2fclient = p2fclient
|
|
14
|
+
self.base_url = p2fclient.base_url
|
|
15
|
+
self.prefix = "harm-data-locations/"
|
|
16
|
+
self.hdl_url = self.base_url / self.prefix
|
|
17
|
+
self.harmonized_location_queue = []
|
|
18
|
+
def add_harm_location(self, new_location: HARM_Location):
|
|
19
|
+
self.harmonized_location_queue.append(new_location)
|
|
20
|
+
def upload_harm_locations(self):
|
|
21
|
+
inserted_locations = []
|
|
22
|
+
if health_check(self.base_url):
|
|
23
|
+
for location in self.harmonized_location_queue:
|
|
24
|
+
r = requests.post(self.hdl_url,
|
|
25
|
+
data=self.p2fclient.json_serialize_with_auth("new_location", location.model_dump_json(exclude_unset=True)),
|
|
26
|
+
headers={"Content-Type": "application/json"})
|
|
27
|
+
inserted_locations.append(HARM_Location(**r.json()))
|
|
28
|
+
return inserted_locations
|
|
29
|
+
def upload_harm_location(self, new_location: HARM_Location):
|
|
30
|
+
if health_check(self.base_url):
|
|
31
|
+
r = requests.post(self.hdl_url,
|
|
32
|
+
data=self.p2fclient.json_serialize_with_auth("new_location", new_location.model_dump_json(exclude_unset=True)),
|
|
33
|
+
headers={"Content-Type": "application/json"})
|
|
34
|
+
return HARM_Location(**r.json())
|
|
35
|
+
def list_harm_locations(self,
|
|
36
|
+
bounding_box: Optional[HARM_Bounding_Box]=None,
|
|
37
|
+
location_name: Optional[str]=None,
|
|
38
|
+
location_code: Optional[str]=None,
|
|
39
|
+
minimum_elevation: Optional[float]=None,
|
|
40
|
+
maximum_elevation: Optional[float]=None,
|
|
41
|
+
min_location_age: Optional[float]=None,
|
|
42
|
+
max_location_age: Optional[float]=None,
|
|
43
|
+
dataset_id: Optional[UUID]=None):
|
|
44
|
+
params = {
|
|
45
|
+
"bounding_box": bounding_box,
|
|
46
|
+
"location_name": location_name,
|
|
47
|
+
"location_code": location_code,
|
|
48
|
+
"minimum_elevation": minimum_elevation,
|
|
49
|
+
"maximum_elevation": maximum_elevation,
|
|
50
|
+
"min_location_age": min_location_age,
|
|
51
|
+
"max_location_age": max_location_age,
|
|
52
|
+
"dataset_id": dataset_id
|
|
53
|
+
}
|
|
54
|
+
params = {x: y for x, y in params.items() if y != None}
|
|
55
|
+
if health_check(self.base_url):
|
|
56
|
+
r = requests.get(self.hdl_url,
|
|
57
|
+
params=params, data=self.p2fclient.json_serialize_with_auth(),
|
|
58
|
+
headers={"Content-Type": "application/json"})
|
|
59
|
+
return [HARM_Location(**x) for x in r.json()]
|
|
60
|
+
def get_harm_location(self, location_identifier: UUID):
|
|
61
|
+
if health_check(self.base_url):
|
|
62
|
+
r = requests.get(self.hdl_url/str(location_identifier), data=self.p2fclient.json_serialize_with_auth(),
|
|
63
|
+
headers={"Content-Type": "application/json"})
|
|
64
|
+
return HARM_Location(**r.json())
|
|
65
|
+
def delete_harm_location(self, location_identifier: UUID):
|
|
66
|
+
if health_check(self.base_url):
|
|
67
|
+
r = requests.delete(self.hdl_url/str(location_identifier), data=self.p2fclient.json_serialize_with_auth(),
|
|
68
|
+
headers={"Content-Type": "application/json"})
|
|
69
|
+
def assign_location_to_record(self, location_identifier: UUID, record_hash: str):
|
|
70
|
+
# params = {"location_identifier": str(location_identifier),
|
|
71
|
+
# "record_hash": record_hash}
|
|
72
|
+
assign_url = self.hdl_url / "assign"
|
|
73
|
+
assign_url.args["location_identifier"] = str(location_identifier)
|
|
74
|
+
assign_url.args["record_hash"] = record_hash
|
|
75
|
+
if health_check(self.base_url):
|
|
76
|
+
r = requests.post(assign_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
77
|
+
headers={"Content-Type": "application/json"})
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from p2f_pydantic.harm_data_numerical import HARM_Float, HARM_Float_Confidence
|
|
3
|
+
from p2f_pydantic.harm_data_numerical import HARM_Int, HARM_Int_Confidence
|
|
4
|
+
from p2f_pydantic.harm_data_numerical import Insert_HARM_Numerical, Return_HARM_Numerical
|
|
5
|
+
from .conn import health_check
|
|
6
|
+
# Third Party Libraries
|
|
7
|
+
import requests
|
|
8
|
+
from furl import furl
|
|
9
|
+
# Batteries included libraries
|
|
10
|
+
from uuid import UUID
|
|
11
|
+
from typing import Optional, List, Union, Literal
|
|
12
|
+
|
|
13
|
+
Harm_numerical_union = Union[HARM_Int, HARM_Int_Confidence, HARM_Float, HARM_Float_Confidence]
|
|
14
|
+
|
|
15
|
+
class harm_numerical:
|
|
16
|
+
def __init__(self, p2fclient):
|
|
17
|
+
self.p2fclient = p2fclient
|
|
18
|
+
self.base_url = p2fclient.base_url
|
|
19
|
+
self.prefix = "harm-numerical/"
|
|
20
|
+
self.hdn_url = self.base_url / self.prefix
|
|
21
|
+
self.harmonized_numerical_records_queue = []
|
|
22
|
+
def add_harm_numerical(self, new_numerical_record: Insert_HARM_Numerical):
|
|
23
|
+
self.harmonized_numerical_records_queue.append(new_numerical_record)
|
|
24
|
+
def upload_harm_numericals(self):
|
|
25
|
+
inserted_numericals = []
|
|
26
|
+
if health_check(self.base_url):
|
|
27
|
+
for nummer in self.harmonized_numerical_records_queue:
|
|
28
|
+
r = requests.post(self.hdn_url,
|
|
29
|
+
data=self.p2fclient.json_serialize_with_auth("new_numeric", nummer.model_dump_json(exclude_unset=True)),
|
|
30
|
+
headers={"Content-Type": "application/json"})
|
|
31
|
+
inserted_numericals.append(self.identify_numeric_object(r.json(), nummer.model_dump_json(exclude_unset=True)))
|
|
32
|
+
return inserted_numericals
|
|
33
|
+
def upload_harm_numerical(self, new_record: Insert_HARM_Numerical):
|
|
34
|
+
if health_check(self.base_url):
|
|
35
|
+
r = requests.post(self.hdn_url, data=self.p2fclient.json_serialize_with_auth("new_numeric", new_record.model_dump_json(exclude_unset=True)),
|
|
36
|
+
headers={"Content-Type": "application/json"})
|
|
37
|
+
return self.identify_numeric_object(r.json(), new_record.model_dump(exclude_unset=True))
|
|
38
|
+
def list_harm_numericals(self,
|
|
39
|
+
record_hash: Optional[str]=None,
|
|
40
|
+
numeric_type: Optional[Literal["float_confidence",
|
|
41
|
+
"float",
|
|
42
|
+
"int_confidence",
|
|
43
|
+
"int"]]=None,
|
|
44
|
+
data_type: Optional[UUID]=None,
|
|
45
|
+
dataset_id: Optional[UUID]=None):
|
|
46
|
+
params = {
|
|
47
|
+
"record_hash": record_hash,
|
|
48
|
+
"numeric_type": numeric_type,
|
|
49
|
+
"data_type": data_type,
|
|
50
|
+
"dataset_id": dataset_id
|
|
51
|
+
}
|
|
52
|
+
params = {x:y for x, y in params.items() if y != None}
|
|
53
|
+
if health_check(self.base_url):
|
|
54
|
+
r = requests.get(self.hdn_url,
|
|
55
|
+
params=params, data=self.p2fclient.json_serialize_with_auth(),
|
|
56
|
+
headers={"Content-Type": "application/json"})
|
|
57
|
+
return Return_HARM_Numerical(**r.json())
|
|
58
|
+
def identify_numeric_object(self,
|
|
59
|
+
incoming_json,
|
|
60
|
+
original: Optional[Insert_HARM_Numerical]=None) -> Harm_numerical_union:
|
|
61
|
+
if original:
|
|
62
|
+
number_type = original["numerical_type"]
|
|
63
|
+
else:
|
|
64
|
+
incoming_value = incoming_json["value"]
|
|
65
|
+
if "." in str(incoming_value):
|
|
66
|
+
number_type = "FLOAT"
|
|
67
|
+
else:
|
|
68
|
+
number_type = "INT"
|
|
69
|
+
if "upper_conf_value" in incoming_json.keys():
|
|
70
|
+
number_type += "_CONFIDENCE"
|
|
71
|
+
match number_type:
|
|
72
|
+
case "INT":
|
|
73
|
+
rv = HARM_Int(**incoming_json)
|
|
74
|
+
case "INT_CONFIDENCE":
|
|
75
|
+
rv = HARM_Int_Confidence(**incoming_json)
|
|
76
|
+
case "FLOAT":
|
|
77
|
+
rv = HARM_Float(**incoming_json)
|
|
78
|
+
case "FLOAT_CONFIDENCE":
|
|
79
|
+
rv = HARM_Float_Confidence(**incoming_json)
|
|
80
|
+
return rv
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from p2f_pydantic.harm_reference import HARM_Reference
|
|
3
|
+
from .conn import health_check
|
|
4
|
+
# Third Party Libraries
|
|
5
|
+
import requests
|
|
6
|
+
# Batteries included libraries
|
|
7
|
+
from typing import Optional, List
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
|
|
10
|
+
class harm_reference:
|
|
11
|
+
def __init__(self, p2fclient):
|
|
12
|
+
self.p2fclient = p2fclient
|
|
13
|
+
self.base_url = p2fclient.base_url
|
|
14
|
+
self.prefix = "harm-reference/"
|
|
15
|
+
self.hr_url = self.base_url / self.prefix
|
|
16
|
+
self.harmonized_reference_queue = []
|
|
17
|
+
def add_harm_reference(self, new_reference: HARM_Reference):
|
|
18
|
+
self.harmonized_reference_queue.append(new_reference)
|
|
19
|
+
def upload_harm_reference_queue(self) -> List[HARM_Reference]:
|
|
20
|
+
inserted_harm_references = []
|
|
21
|
+
if health_check(self.base_url):
|
|
22
|
+
for ref in self.harmonized_reference_queue:
|
|
23
|
+
r = requests.post(self.hr_url, data=self.p2fclient.json_serialize_with_auth("new_reference", ref.model_dump_json(exclude_unset=True)),
|
|
24
|
+
headers={"Content-Type": "application/json"})
|
|
25
|
+
inserted_harm_references.append(HARM_Reference(**r.json()))
|
|
26
|
+
return inserted_harm_references
|
|
27
|
+
def upload_harm_reference(self, new_reference: HARM_Reference) -> HARM_Reference:
|
|
28
|
+
if health_check(self.base_url):
|
|
29
|
+
r = requests.post(self.hr_url, data=self.p2fclient.json_serialize_with_auth("new_reference", new_reference.model_dump_json(exclude_unset=True)),
|
|
30
|
+
headers={"Content-Type": "application/json"})
|
|
31
|
+
if r.ok:
|
|
32
|
+
return (HARM_Reference(**r.json()))
|
|
33
|
+
def list_harm_references(self) -> List[HARM_Reference]:
|
|
34
|
+
if health_check(self.base_url):
|
|
35
|
+
r = requests.get(self.hr_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
36
|
+
headers={"Content-Type": "application/json"})
|
|
37
|
+
if r.ok:
|
|
38
|
+
return [HARM_Reference(**x) for x in r.json()]
|
|
39
|
+
else:
|
|
40
|
+
return []
|
|
41
|
+
def get_harm_reference(self, reference_id: UUID) -> HARM_Reference:
|
|
42
|
+
if health_check(self.base_url):
|
|
43
|
+
r = requests.get(self.hr_url / reference_id, data=self.p2fclient.json_serialize_with_auth(),
|
|
44
|
+
headers={"Content-Type": "application/json"})
|
|
45
|
+
if r.ok:
|
|
46
|
+
return HARM_Reference(**r.json())
|
|
47
|
+
def delete_harm_reference(self, reference_id: UUID):
|
|
48
|
+
if health_check(self.base_url):
|
|
49
|
+
r = requests.delete(self, reference_id, data=self.p2fclient.json_serialize_with_auth(),
|
|
50
|
+
headers={"Content-Type": "application/json"})
|
|
51
|
+
def assign_harm_reference(self,
|
|
52
|
+
reference_id: UUID,
|
|
53
|
+
record_hash: str):
|
|
54
|
+
assign_url = self.hr_url
|
|
55
|
+
assign_url.args["reference_id"] = reference_id
|
|
56
|
+
assign_url.args["record_hash"] = record_hash
|
|
57
|
+
if health_check(self.base_url):
|
|
58
|
+
r = requests.post(assign_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
59
|
+
headers={"Content-Type": "application/json"})
|
|
60
|
+
def remove_harm_reference(self,
|
|
61
|
+
reference_id: UUID,
|
|
62
|
+
record_hash: str):
|
|
63
|
+
assign_url = self.hr_url
|
|
64
|
+
assign_url.args["reference_id"] = reference_id
|
|
65
|
+
assign_url.args["record_hash"] = record_hash
|
|
66
|
+
if health_check(self.base_url):
|
|
67
|
+
r = requests.delete(assign_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
68
|
+
headers={"Content-Type": "application/json"})
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from p2f_pydantic.harm_data_metadata import HARM_Data_Species
|
|
3
|
+
from .conn import health_check
|
|
4
|
+
# Third Party Libraries
|
|
5
|
+
import requests
|
|
6
|
+
# Batteries included libraries
|
|
7
|
+
from typing import Optional, List
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
|
|
10
|
+
class harm_species:
|
|
11
|
+
def __init__(self, p2fclient):
|
|
12
|
+
self.p2fclient = p2fclient
|
|
13
|
+
self.base_url = p2fclient.base_url
|
|
14
|
+
self.prefix = "harm-data-species/"
|
|
15
|
+
self.hds_url = self.base_url / self.prefix
|
|
16
|
+
self.harmonized_species_queue = []
|
|
17
|
+
def add_harm_species(self, new_species: HARM_Data_Species):
|
|
18
|
+
self.harmonized_species_queue.append(new_species)
|
|
19
|
+
def upload_harm_species_queue(self) -> List[HARM_Data_Species]:
|
|
20
|
+
inserted_species = []
|
|
21
|
+
if health_check(self.base_url):
|
|
22
|
+
for record in self.harmonized_species_queue:
|
|
23
|
+
r = requests.post(self.hds_url,
|
|
24
|
+
data=self.p2fclient.json_serialize_with_auth("new_species", record.model_dump_json(exclude_unset=True)),
|
|
25
|
+
headers={"Content-Type": "application/json"})
|
|
26
|
+
inserted_species.append(HARM_Data_Species(**r.json()))
|
|
27
|
+
return inserted_species
|
|
28
|
+
def upload_harm_species(self, new_species: HARM_Data_Species):
|
|
29
|
+
if health_check(self.base_url):
|
|
30
|
+
r = requests.post(self.hds_url,
|
|
31
|
+
data=self.p2fclient.json_serialize_with_auth("new_species", new_species.model_dump_json(exclude_unset=True)),
|
|
32
|
+
headers={"Content-Type": "application/json"})
|
|
33
|
+
return HARM_Data_Species(**r.json())
|
|
34
|
+
def list_harm_species(self,
|
|
35
|
+
tax_domain: Optional[str]=None,
|
|
36
|
+
tax_kingdom: Optional[str]=None,
|
|
37
|
+
tax_subkingdom: Optional[str]=None,
|
|
38
|
+
tax_infrakingdom: Optional[str]=None,
|
|
39
|
+
tax_phylum: Optional[str]=None,
|
|
40
|
+
tax_class: Optional[str]=None,
|
|
41
|
+
tax_subclass: Optional[str]=None,
|
|
42
|
+
tax_order: Optional[str]=None,
|
|
43
|
+
tax_suborder: Optional[str]=None,
|
|
44
|
+
tax_superfamily: Optional[str]=None,
|
|
45
|
+
tax_family: Optional[str]=None,
|
|
46
|
+
tax_subfamily: Optional[str]=None,
|
|
47
|
+
tax_genus: Optional[str]=None,
|
|
48
|
+
tax_species: Optional[str]=None,
|
|
49
|
+
tax_subspecies: Optional[str]=None,
|
|
50
|
+
common_name: Optional[str]=None,
|
|
51
|
+
display_species: Optional[str]=None,) -> HARM_Data_Species:
|
|
52
|
+
params = {x: y for x, y in locals().items() if x.startswith("tax_")}
|
|
53
|
+
params["common_name"] = common_name
|
|
54
|
+
params["display_species"] = display_species
|
|
55
|
+
params = {x: y for x, y in params.items() if y != None}
|
|
56
|
+
if health_check(self.base_url):
|
|
57
|
+
r = requests.get(self.hds_url,
|
|
58
|
+
params=params, data=self.p2fclient.json_serialize_with_auth(),
|
|
59
|
+
headers={"Content-Type": "application/json"})
|
|
60
|
+
return [HARM_Data_Species(**x) for x in r.json()]
|
|
61
|
+
def get_harm_species(self, species_identifier: UUID):
|
|
62
|
+
if health_check(self.base_url):
|
|
63
|
+
r = requests.get(self.hds_url/species_identifier, data=self.p2fclient.json_serialize_with_auth(),
|
|
64
|
+
headers={"Content-Type": "application/json"})
|
|
65
|
+
return HARM_Data_Species(**r.json())
|
|
66
|
+
def delete_harm_species(self, species_identifier: UUID):
|
|
67
|
+
if health_check(self.base_url):
|
|
68
|
+
r = requests.delete(self.hds_url/species_identifier, data=self.p2fclient.json_serialize_with_auth(),
|
|
69
|
+
headers={"Content-Type": "application/json"})
|
|
70
|
+
def assign_species_to_record(self, species_identifier: UUID, record_hash: str):
|
|
71
|
+
assign_url = self.hds_url / "assign"
|
|
72
|
+
assign_url.args["species_id"] = species_identifier
|
|
73
|
+
assign_url.args["record_hash"] = record_hash
|
|
74
|
+
if health_check(self.base_url):
|
|
75
|
+
r = requests.post(assign_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
76
|
+
headers={"Content-Type": "application/json"})
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from p2f_pydantic.harm_timeslices import HARM_Timeslice
|
|
3
|
+
from .conn import health_check
|
|
4
|
+
# Third Party Libraries
|
|
5
|
+
import requests
|
|
6
|
+
# Batteries included libraries
|
|
7
|
+
from uuid import UUID
|
|
8
|
+
from typing import Optional, List
|
|
9
|
+
|
|
10
|
+
class harm_timeslice:
|
|
11
|
+
def __init__(self, p2fclient):
|
|
12
|
+
self.p2fclient = p2fclient
|
|
13
|
+
self.base_url = p2fclient.base_url
|
|
14
|
+
self.prefix = "harm-timeslice/"
|
|
15
|
+
self.ht_url = self.base_url / self.prefix
|
|
16
|
+
self.harmonized_timeslice_queue = []
|
|
17
|
+
def add_timeslice(self, new_timeslice: HARM_Timeslice):
|
|
18
|
+
self.harmonized_timeslice_queue.append(new_timeslice)
|
|
19
|
+
def upload_timeslice_queue(self):
|
|
20
|
+
inserted_timeslice_list = []
|
|
21
|
+
if health_check(self.base_url):
|
|
22
|
+
for timeslice in self.harmonized_timeslice_queue:
|
|
23
|
+
r = requests.post(self.ht_url,
|
|
24
|
+
data=self.p2fclient.json_serialize_with_auth("new_harm_timeslice", timeslice.model_dump_json(exclude_unset=True)),
|
|
25
|
+
headers={"Content-Type": "application/json"})
|
|
26
|
+
inserted_timeslice_list.append(HARM_Timeslice(**r.json()))
|
|
27
|
+
return inserted_timeslice_list
|
|
28
|
+
def upload_timeslice(self, new_timeslice: HARM_Timeslice) -> HARM_Timeslice:
|
|
29
|
+
if health_check(self.base_url):
|
|
30
|
+
r = requests.post(self.ht_url,
|
|
31
|
+
data=self.p2fclient.json_serialize_with_auth("new_harm_timeslice", new_timeslice.model_dump_json(exclude_unset=True)),
|
|
32
|
+
headers={"Content-Type": "application/json"})
|
|
33
|
+
return HARM_Timeslice(**r.json())
|
|
34
|
+
def list_timeslices(self,
|
|
35
|
+
named_time_period: Optional[str]=None,
|
|
36
|
+
older_search_age: Optional[int]=None,
|
|
37
|
+
recent_search_age: Optional[int]=None,) -> List[HARM_Timeslice]:
|
|
38
|
+
params = {"named_time_period": named_time_period,
|
|
39
|
+
"older_search_age": older_search_age,
|
|
40
|
+
"recent_search_age": recent_search_age}
|
|
41
|
+
params = {x: y for x, y in params.items() if y != None}
|
|
42
|
+
if health_check(self.base_url):
|
|
43
|
+
r = requests.get(self.ht_url,
|
|
44
|
+
params=params, data=self.p2fclient.json_serialize_with_auth(),
|
|
45
|
+
headers={"Content-Type": "application/json"})
|
|
46
|
+
return [HARM_Timeslice(**x) for x in r.json()]
|
|
47
|
+
def get_timeslice(self,
|
|
48
|
+
timeslice_id: UUID) -> HARM_Timeslice:
|
|
49
|
+
if health_check(self.base_url):
|
|
50
|
+
r = requests.get(self.ht_url / timeslice_id, data=self.p2fclient.json_serialize_with_auth(),
|
|
51
|
+
headers={"Content-Type": "application/json"})
|
|
52
|
+
return HARM_Timeslice(**r.json())
|
|
53
|
+
def delete_timeslice(self,
|
|
54
|
+
timeslice_id: UUID) -> HARM_Timeslice:
|
|
55
|
+
if health_check(self.base_url):
|
|
56
|
+
r = requests.delete(self.ht_url / timeslice_id, data=self.p2fclient.json_serialize_with_auth(),
|
|
57
|
+
headers={"Content-Type": "application/json"})
|
|
58
|
+
def assign_timeslice(self,
|
|
59
|
+
timeslice_id: UUID,
|
|
60
|
+
record_hash: str):
|
|
61
|
+
assign_url = self.ht_url / "assign"
|
|
62
|
+
assign_url.args["timeslice_id"] = timeslice_id
|
|
63
|
+
assign_url.args["record_hash"] = record_hash
|
|
64
|
+
if health_check(self.base_url):
|
|
65
|
+
r = requests.post(assign_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
66
|
+
headers={"Content-Type": "application/json"})
|
|
67
|
+
def remove_timeslice(self,
|
|
68
|
+
timeslice_id: UUID,
|
|
69
|
+
record_hash: str):
|
|
70
|
+
remove_url = self.ht_url / "remove"
|
|
71
|
+
remove_url.args["timeslice_id"] = timeslice_id
|
|
72
|
+
remove_url.args["record_hash"] = record_hash
|
|
73
|
+
if health_check(self.base_url):
|
|
74
|
+
r = requests.delete(remove_url, data=self.p2fclient.json_serialize_with_auth(),
|
|
75
|
+
headers={"Content-Type": "application/json"})
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Local libraries
|
|
2
|
+
from .datasets import datasets
|
|
3
|
+
from .harm_data_record import harm_data_records
|
|
4
|
+
from .harm_data_types import harm_data_type
|
|
5
|
+
from .harm_numerical import harm_numerical
|
|
6
|
+
from .harm_location import harm_location
|
|
7
|
+
from .harm_species import harm_species
|
|
8
|
+
from .harm_timeslice import harm_timeslice
|
|
9
|
+
from .harm_reference import harm_reference
|
|
10
|
+
from .conn import health_check
|
|
11
|
+
from p2f_pydantic.temp_accounts import Temp_Account
|
|
12
|
+
# Third Party Libraries
|
|
13
|
+
import requests
|
|
14
|
+
import furl
|
|
15
|
+
# Batteries included libraries
|
|
16
|
+
from datetime import datetime, timedelta
|
|
17
|
+
from zoneinfo import ZoneInfo
|
|
18
|
+
from typing import Optional
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class P2F_Client:
|
|
22
|
+
def __init__(self,
|
|
23
|
+
hostname: str,
|
|
24
|
+
port: int=443,
|
|
25
|
+
https: bool=True,
|
|
26
|
+
email: Optional[str]=None,
|
|
27
|
+
token: Optional[str] = None,
|
|
28
|
+
token_expiration: Optional[datetime]=None):
|
|
29
|
+
self.version = (0, 0, 10) # turn this into a real named tuple one day
|
|
30
|
+
self.hostname = hostname
|
|
31
|
+
self.port = port
|
|
32
|
+
if https:
|
|
33
|
+
self.protocol = "https"
|
|
34
|
+
else:
|
|
35
|
+
self.protocol = "http"
|
|
36
|
+
self.host_url = f"{self.protocol}://{self.hostname}:{self.port}"
|
|
37
|
+
self.base_url = furl.furl(self.host_url)
|
|
38
|
+
self.email= email
|
|
39
|
+
self.token = token
|
|
40
|
+
if self.token is not None:
|
|
41
|
+
if token_expiration is None:
|
|
42
|
+
# It's not true, but it does inform us that the token could possibly last till tomorrow
|
|
43
|
+
self.TOKEN_EXPIRATION = datetime.now(tz=ZoneInfo("UTC")) + timedelta(hours=24)
|
|
44
|
+
raise UserWarning("A generic token expiration time was used, the token could expire sooner than the currently set token expiration time")
|
|
45
|
+
else:
|
|
46
|
+
self.TOKEN_EXPIRATION = token_expiration
|
|
47
|
+
if self.email is not None:
|
|
48
|
+
self.temp_account = Temp_Account(email=self.email, token=self.token)
|
|
49
|
+
self.child_class_loading()
|
|
50
|
+
def child_class_loading(self):
|
|
51
|
+
# Separated this out so we can reload it later.
|
|
52
|
+
self.datasets = datasets(self)
|
|
53
|
+
self.harm_data_records = harm_data_records(self)
|
|
54
|
+
self.harm_data_type = harm_data_type(self)
|
|
55
|
+
self.harm_numerical = harm_numerical(self)
|
|
56
|
+
self.harm_location = harm_location(self)
|
|
57
|
+
self.harm_species = harm_species(self)
|
|
58
|
+
self.harm_timeslice = harm_timeslice(self)
|
|
59
|
+
self.harm_reference = harm_reference(self)
|
|
60
|
+
def request_token(self):
|
|
61
|
+
# self.email = email
|
|
62
|
+
self.token_url = self.base_url / "token"
|
|
63
|
+
self.token_request_url = self.token_url / "request"
|
|
64
|
+
token_request_model = Temp_Account(email=self.email)
|
|
65
|
+
# calculate the datetime of the token before making the request
|
|
66
|
+
# so that our expiration time is just before actual expiration.
|
|
67
|
+
self.TOKEN_EXPIRATION = datetime.now(tz=ZoneInfo("UTC")) + timedelta(hours=24)
|
|
68
|
+
if health_check(self.base_url):
|
|
69
|
+
r = requests.post(self.token_request_url,
|
|
70
|
+
data=token_request_model.model_dump_json(exclude_unset=True),
|
|
71
|
+
headers={"Content-Type": "application/json"})
|
|
72
|
+
print(r.json())
|
|
73
|
+
def set_token(self, token: str):
|
|
74
|
+
self.token = token
|
|
75
|
+
self.temp_account = Temp_Account(email=self.email, token=self.token)
|
|
76
|
+
# reload the child classes so they will have the token
|
|
77
|
+
self.child_class_loading()
|
|
78
|
+
def json_serialize_with_auth(self,
|
|
79
|
+
label: Optional[str]=None,
|
|
80
|
+
JSON_str: Optional[str]=None):
|
|
81
|
+
if label is not None:
|
|
82
|
+
return f"""{{"auth":{self.temp_account.model_dump_json(exclude_unset=True)},"{label}":{JSON_str}}}"""
|
|
83
|
+
if label is None:
|
|
84
|
+
return self.temp_account.model_dump_json(exclude_unset=True)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: p2f-client-py
|
|
3
|
+
Version: 0.0.11
|
|
4
|
+
Summary: API Client library for the Past to Future project.
|
|
5
|
+
Author-email: Garrett Speed <g.t.speed@uu.nl>
|
|
6
|
+
Project-URL: Homepage, https://github.com/Past-to-Future-EU-Horizon/p2f-client-py
|
|
7
|
+
Requires-Python: >=3.13
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: furl>=2.1.4
|
|
10
|
+
Requires-Dist: p2f-pydantic
|
|
11
|
+
Requires-Dist: pandas>=2.3.3
|
|
12
|
+
Requires-Dist: pyjwt>=2.10.1
|
|
13
|
+
Requires-Dist: python-dotenv>=1.1.0
|
|
14
|
+
Requires-Dist: requests>=2.32.3
|
|
15
|
+
|
|
16
|
+
# p2f-client-py
|
|
17
|
+
Python client library for the Past to Future projects Portal. Past to Future is an EU Horizon funded project.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
pip install git+https://github.com/Past-to-Future-EU-Horizon/p2f-client-py
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
Create a client
|
|
27
|
+
|
|
28
|
+
from p2f_client import P2F_Client
|
|
29
|
+
|
|
30
|
+
client = P2F_Client("p2f-api.uu.nl", 8000)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
p2f_client/__init__.py
|
|
4
|
+
p2f_client/conn.py
|
|
5
|
+
p2f_client/datasets.py
|
|
6
|
+
p2f_client/doi.py
|
|
7
|
+
p2f_client/harm_data_record.py
|
|
8
|
+
p2f_client/harm_data_types.py
|
|
9
|
+
p2f_client/harm_location.py
|
|
10
|
+
p2f_client/harm_numerical.py
|
|
11
|
+
p2f_client/harm_reference.py
|
|
12
|
+
p2f_client/harm_species.py
|
|
13
|
+
p2f_client/harm_timeslice.py
|
|
14
|
+
p2f_client/p2f_client.py
|
|
15
|
+
p2f_client_py.egg-info/PKG-INFO
|
|
16
|
+
p2f_client_py.egg-info/SOURCES.txt
|
|
17
|
+
p2f_client_py.egg-info/dependency_links.txt
|
|
18
|
+
p2f_client_py.egg-info/requires.txt
|
|
19
|
+
p2f_client_py.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "p2f-client-py"
|
|
3
|
+
version = "0.0.11"
|
|
4
|
+
description = "API Client library for the Past to Future project."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"furl>=2.1.4",
|
|
9
|
+
"p2f-pydantic",
|
|
10
|
+
"pandas>=2.3.3",
|
|
11
|
+
"pyjwt>=2.10.1",
|
|
12
|
+
"python-dotenv>=1.1.0",
|
|
13
|
+
"requests>=2.32.3",
|
|
14
|
+
]
|
|
15
|
+
authors = [
|
|
16
|
+
{ name="Garrett Speed", email="g.t.speed@uu.nl"}
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://github.com/Past-to-Future-EU-Horizon/p2f-client-py"
|
|
21
|
+
|
|
22
|
+
[tool.setuptools.packages.find]
|
|
23
|
+
exclude = ["Pliocene_SSTs"]
|