diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 9adbce0..de6dde4 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -15,13 +15,12 @@ concurrency:
cancel-in-progress: true
jobs:
+ # Tests for GRASS 8.4
tests:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- # with:
- # path: "."
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Tests of actinia-module-plugin
@@ -34,3 +33,25 @@ jobs:
file: docker/actinia-module-plugin-test/Dockerfile
no-cache: true
# pull: true
+
+ # Tests for GRASS 8.3
+ tests-G83:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - name: Replace run integration test command
+ run: |
+ sed -i "s+mundialis/actinia:latest+mundialis/actinia:2.9.2_G83+g" docker/actinia-module-plugin-test/Dockerfile
+ - name: Tests of actinia-module-plugin
+ id: docker_build
+ uses: docker/build-push-action@v6
+ with:
+ push: false
+ tags: actinia-module-plugin-test:alpine
+ context: .
+ file: docker/actinia-module-plugin-test/Dockerfile
+ no-cache: true
+ # pull: true
diff --git a/.gitignore b/.gitignore
index eb65e97..00723a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,3 +53,7 @@ resp.json
# docker
!docker/actinia-module-plugin-test/actinia-module-plugin-test.cfg
+
+# linting with shared config file
+ruff-github-workflows.toml
+ruff-merged.toml
diff --git a/actinia-module.md b/actinia-module.md
index 8518384..ef47a3c 100644
--- a/actinia-module.md
+++ b/actinia-module.md
@@ -499,8 +499,8 @@ List / Describe combined
Execute module
-* POST /locations/{location_name}/processing_export
-* POST /locations/{location_name}/mapsets/{mapset_name}/processing (TODO)
+* POST /projects/{project_name}/processing_export
+* POST /projects/{project_name}/mapsets/{mapset_name}/processing (TODO)
Full API docs
diff --git a/src/actinia_module_plugin/api/processing.py b/src/actinia_module_plugin/api/processing.py
index 793cc87..521583e 100644
--- a/src/actinia_module_plugin/api/processing.py
+++ b/src/actinia_module_plugin/api/processing.py
@@ -208,15 +208,15 @@ def __init__(self):
ResourceBase.__init__(self)
@swagger.doc(deepcopy(SCHEMA_DOC_EPHEMERAL_PROCESSING_WITH_EXPORT))
- def post(self, location_name):
+ def post(self, project_name):
"""
- Execute a user defined process chain in an ephemeral location/mapset
+ Execute a user defined process chain in an ephemeral project/mapset
and store the processing results for download.
"""
preprocess_kwargs = {}
preprocess_kwargs["has_json"] = True
- preprocess_kwargs["location_name"] = location_name
+ preprocess_kwargs["project_name"] = project_name
start_job = start_job_ephemeral_processing_with_export
@@ -236,7 +236,7 @@ def __init__(self):
ResourceBase.__init__(self)
@swagger.doc(deepcopy(SCHEMA_DOC_PERSISTENT_PROCESSING))
- def post(self, location_name, mapset_name):
+ def post(self, project_name, mapset_name):
"""
Execute a user defined process chain that creates a new mapset or
runs in an existing one.
@@ -244,7 +244,7 @@ def post(self, location_name, mapset_name):
preprocess_kwargs = {}
preprocess_kwargs["has_json"] = True
- preprocess_kwargs["location_name"] = location_name
+ preprocess_kwargs["project_name"] = project_name
preprocess_kwargs["mapset_name"] = mapset_name
start_job = start_job_persistent_processing
diff --git a/src/actinia_module_plugin/core/modules/processor.py b/src/actinia_module_plugin/core/modules/processor.py
index 8dd47e2..aaccfd3 100644
--- a/src/actinia_module_plugin/core/modules/processor.py
+++ b/src/actinia_module_plugin/core/modules/processor.py
@@ -66,41 +66,41 @@
def initGrass(self):
"""
* not using enqueue_job to get always a response
- * the function creates a new location cause not all users can access
- a location
+ * the function creates a new project cause not all users can access
+ a project
"""
- # check if location exists
- location_name = "location_for_listing_modules_" + str(uuid.uuid4())
- # '/actinia_core/grassdb/location_for_listing_modules'
- location = os.path.join(global_config.GRASS_DATABASE, location_name)
- # Check the location path
- if os.path.isdir(location):
+ # check if project exists
+ project_name = "project_for_listing_modules_" + str(uuid.uuid4())
+ # '/actinia_core/grassdb/project_for_listing_modules'
+ project = os.path.join(global_config.GRASS_DATABASE, project_name)
+ # Check the project path
+ if os.path.isdir(project):
msg = (
- "Unable to create location. "
- "Location <%s> exists in global database." % location_name
+ "Unable to create project. "
+ "Project <%s> exists in global database." % project_name
)
return self.get_error_response(message=msg)
# Check also for the user database
- # '/actinia_core/userdata/superadmin/location_for_listing_modules'
- location = os.path.join(
- self.grass_user_data_base, self.user_group, location_name
+ # '/actinia_core/userdata/superadmin/project_for_listing_modules'
+ project = os.path.join(
+ self.grass_user_data_base, self.user_group, project_name
)
- # Check the location path
- if os.path.isdir(location):
+ # Check the project path
+ if os.path.isdir(project):
msg = (
- "Unable to create location. "
- "Location <%s> exists in user database." % location_name
+ "Unable to create project. "
+ "Project <%s> exists in user database." % project_name
)
return self.get_error_response(message=msg)
- # create new location cause not each user can access a location
+ # create new project cause not each user can access a project
if not os.path.isdir(
os.path.join(self.grass_user_data_base, self.user_group)
):
os.mkdir(os.path.join(self.grass_user_data_base, self.user_group))
- os.mkdir(location)
- mapset = os.path.join(location, "PERMANENT")
+ os.mkdir(project)
+ mapset = os.path.join(project, "PERMANENT")
os.mkdir(mapset)
with open(os.path.join(mapset, "DEFAULT_WIND"), "w") as out:
wind = (
@@ -134,30 +134,30 @@ def initGrass(self):
)
out.write(wind)
- return location_name
+ return project_name
-def deinitGrass(self, location_name):
+def deinitGrass(self, project_name):
"""
- * the function deletes above location
+ * the function deletes above project
"""
- # remove location
- location = os.path.join(global_config.GRASS_DATABASE, location_name)
- if os.path.isdir(location):
- shutil.rmtree(location)
- location = os.path.join(
- self.grass_user_data_base, self.user_group, location_name
+ # remove project
+ project = os.path.join(global_config.GRASS_DATABASE, project_name)
+ if os.path.isdir(project):
+ shutil.rmtree(project)
+ project = os.path.join(
+ self.grass_user_data_base, self.user_group, project_name
)
- if os.path.isdir(location):
- shutil.rmtree(location)
+ if os.path.isdir(project):
+ shutil.rmtree(project)
# del
- # self.user_credentials["permissions"]['accessible_datasets'][location_name]
+ # self.user_credentials["permissions"]['accessible_datasets'][project_name]
class EphemeralModuleLister(EphemeralProcessing):
"""
Overwrites EphemeralProcessing from actinia_core to bypass permission
- check for modules and temporary location, needed for self-description
+ check for modules and temporary project, needed for self-description
"""
def __init__(self, *args, pc):
@@ -188,20 +188,20 @@ def run_process_chain(self, process_chain):
"""
Used to list all GRASS modules, to describe a certain GRASS module
and to generate actinia module description out of containing GRASS modules.
- ATTENTION! This call skips permission checks, so temporary location can be
+ ATTENTION! This call skips permission checks, so temporary project can be
used. If user is not allowed to use GRASS modules used here, this will be
allowed in these cases.
"""
- location_name = initGrass(self)
+ project_name = initGrass(self)
- # self.user_credentials["permissions"]['accessible_datasets'][location_name]
+ # self.user_credentials["permissions"]['accessible_datasets'][project_name]
# = ['PERMANENT']
rdc = self.preprocess(
has_json=False,
has_xml=False,
- location_name=location_name,
+ project_name=project_name,
mapset_name="PERMANENT",
)
@@ -215,6 +215,6 @@ def list_modules(*args, process_chain=process_chain):
else:
http_code, response_model = pickle.loads(self.response_data)
- deinitGrass(self, location_name)
+ deinitGrass(self, project_name)
return response_model
diff --git a/src/actinia_module_plugin/endpoints.py b/src/actinia_module_plugin/endpoints.py
index 660bf33..c31595a 100644
--- a/src/actinia_module_plugin/endpoints.py
+++ b/src/actinia_module_plugin/endpoints.py
@@ -19,8 +19,8 @@
Add endpoints to flask app with endpoint definitions and routes
"""
-__author__ = "Carmen Tawalika"
-__copyright__ = "2018-2021 mundialis GmbH & Co. KG"
+__author__ = "Carmen Tawalika, Anika Weinmann"
+__copyright__ = "2018-2024 mundialis GmbH & Co. KG"
__license__ = "Apache-2.0"
@@ -45,6 +45,36 @@
from actinia_module_plugin.api.actinia_templates import ActiniaTemplate
from actinia_module_plugin.api.actinia_templates import ActiniaTemplateId
+from actinia_core.endpoints import get_endpoint_class_name
+
+
+def create_project_endpoints(apidoc, projects_url_part="projects"):
+ """
+ Function to add resources with "projects" inside the endpoint url.
+
+ Args:
+ apidoc (flask_restful_swagger_2.Api): Flask api
+ projects_url_part (str): The name of the projects inside the endpoint
+ URL; to add deprecated location endpoints set
+ it to "locations"
+ """
+
+ apidoc.add_resource(
+ GdiAsyncEphemeralExportResource,
+ f"/{projects_url_part}/Operations
Query the Google Landsat archives using time interval, lat/lon coordinates, scene id, spacecraft id and cloud cover.
Operations
Operations
Mapset Management
@@ -179,28 +179,28 @@ Operations
Processing
@@ -208,46 +208,46 @@ Operations
Raster Management
@@ -255,16 +255,16 @@ Operations
Raster Statistics
@@ -272,28 +272,28 @@ Operations
STRDS Management
@@ -301,16 +301,16 @@ Operations
STRDS Sampling
@@ -318,16 +318,16 @@ Operations
STRDS Statistics
@@ -335,25 +335,25 @@ Operations
Vector Management
@@ -444,7 +444,7 @@ Operations
Schema Definitions
- LocationListResponseModel
+ ProjectListResponseModel
SimpleResponseModel
MapsetInfoResponseModel
ProcessLogModel
@@ -550,16 +550,16 @@ Examples:
List all locations that are available in the actinia persistent database:
curl -X GET "https://actinia.mundialis.de/api/v3/locations" -H "authorization: Basic ..."
+ List all projects that are available in the actinia persistent database:
curl -X GET "https://actinia.mundialis.de/api/v3/projects" -H "authorization: Basic ..."
List all mapsets in the location latlong_wgs84:
curl -X GET "https://actinia.mundialis.de/api/v3/locations/latlong_wgs84/mapsets" -H "authorization: Basic ..."
+ List all mapsets in the project latlong_wgs84:
curl -X GET "https://actinia.mundialis.de/api/v3/projects/latlong_wgs84/mapsets" -H "authorization: Basic ..."
List all space-time raster datasets (STRDS) in location latlong_wgs84 and mapset Sentinel_timeseries:
curl -X GET "https://actinia.mundialis.de/api/v3/locations/latlong_wgs84/mapsets/Sentinel_timeseries/strds" -H "authorization: Basic ..."
+ List all space-time raster datasets (STRDS) in project latlong_wgs84 and mapset Sentinel_timeseries:
curl -X GET "https://actinia.mundialis.de/api/v3/projects/latlong_wgs84/mapsets/Sentinel_timeseries/strds" -H "authorization: Basic ..."
List all raster map layers of the STRDS:
curl -X GET "https://actinia.mundialis.de/api/v3/locations/latlong_wgs84/mapsets/Sentinel_timeseries/strds/S2A_B04/raster_layers" -H "authorization: Basic ..."
+ List all raster map layers of the STRDS:
curl -X GET "https://actinia.mundialis.de/api/v3/projects/latlong_wgs84/mapsets/Sentinel_timeseries/strds/S2A_B04/raster_layers" -H "authorization: Basic ..."
@@ -2867,8 +2867,8 @@
Download and import Landsat scenes into a new mapset and create a space-time raster dataset for each imported band. The resulting data will be located in a persistent user database. The location name is part of the path and must exist. The mapset will be created while importing and should not already exist in the location. The names of theLandsat scenes that should be downloaded must be specified in the HTTP body as application/json content. In addition, the basename of the STRDS that should manage the Landsat scenes must be provided in the application/json content. For each band a separate strds will be cerated and the STRDS base name will be extended with the band number.This call is performed asynchronously. The provided resource URL must be pulled to receive the status of the import. The data is available in the provided location/mapset, after the download and import finished. Minimum required user role: user.
+Download and import Landsat scenes into a new mapset and create a space-time raster dataset for each imported band. The resulting data will be located in a persistent user database. The project name is part of the path and must exist. The mapset will be created while importing and should not already exist in the project. The names of theLandsat scenes that should be downloaded must be specified in the HTTP body as application/json content. In addition, the basename of the STRDS that should manage the Landsat scenes must be provided in the application/json content. For each band a separate strds will be cerated and the STRDS base name will be extended with the band number.This call is performed asynchronously. The provided resource URL must be pulled to receive the status of the import. The data is available in the provided project/mapset, after the download and import finished. Minimum required user role: user.
The location name to import the Landsat scenes in
+The project name to import the Landsat scenes in
Download and import Sentinel2A scenes into a new mapset and create a space-time raster dataset for each imported band. The resulting data will be located in a persistent user database. The location name is part of the path and must exist. The mapset will be created while importing and should not already exist in the location. The names of theSentinel-2 scenes and the band names that should be downloaded must be specified in the HTTP body as application/json content. In addition, the names of the STRDS that should manage the sentinel scenes must be provided in the application/json content. For each band a separate STRDS name must be provided.This call is performed asynchronously. The provided resource URL must be pulled to receive the status of the import. The data is available in the provided location/mapset, after the download and import finished. Minimum required user role: user.
+Download and import Sentinel2A scenes into a new mapset and create a space-time raster dataset for each imported band. The resulting data will be located in a persistent user database. The project name is part of the path and must exist. The mapset will be created while importing and should not already exist in the project. The names of theSentinel-2 scenes and the band names that should be downloaded must be specified in the HTTP body as application/json content. In addition, the names of the STRDS that should manage the sentinel scenes must be provided in the application/json content. For each band a separate STRDS name must be provided.This call is performed asynchronously. The provided resource URL must be pulled to receive the status of the import. The data is available in the provided project/mapset, after the download and import finished. Minimum required user role: user.
The location name to import the Sentinel2A scenes in
+The project name to import the Sentinel2A scenes in
Get a list of all available locations that are located in the GRASS database and the user has access to. Minimum required user role: user.
+Get a list of all available projects that are located in the GRASS database and the user has access to. Minimum required user role: user.
This response returns a list of location names
+This response returns a list of project names
{
- "locations": [
+ "projects": [
"nc_spm_08",
"latlong_wgs84",
"ECAD"
@@ -6640,30 +6640,30 @@ Response Example
Delete an existing location and everything inside from the user database. Minimum required user role: admin.
+Delete an existing project and everything inside from the user database. Minimum required user role: admin.
The name of the location to be deleted
+The name of the project to be deleted
Success message for location deletion
+Success message for project deletion
Create a new location based on EPSG code in the user database. Minimum required user role: admin.
+Create a new project based on EPSG code in the user database. Minimum required user role: admin.
The name of the location to be created
+The name of the project to be created
Create a new location based on EPSG code
+Create a new project based on EPSG code
Get the location projection and current computational region of the PERMANENT mapset. Minimum required user role: user.
+Get the project projection and current computational region of the PERMANENT mapset. Minimum required user role: user.
The name of the location
+The name of the project
The location projection and current computational region of the PERMANENT mapset
+The project projection and current computational region of the PERMANENT mapset
The name of the location
+The name of the project