Skip to content

Commit

Permalink
Merge pull request #19 from PEM-Humboldt/adjustmentCodeCollection
Browse files Browse the repository at this point in the history
readme and methods adjustment
  • Loading branch information
denarch22 authored Oct 21, 2024
2 parents 60bae64 + 61b8a81 commit 4958cc3
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 50 deletions.
111 changes: 94 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Antes de usar la herramienta segurese de realizar lo siguiente:

## Uso

### Crear colección
### Preparacion

<details>
<summary>Preparación de los insumos</summary>
Expand All @@ -60,24 +60,101 @@ Para crear una colección siga los siguientes pasos:

1. Cargar la carpeta de la colección en el directorio `input`, esta carpeta debe contar con los archivos correpondientes a las capas (.tif) y el archivo mencionado previamente en la sección `Preparación de los insumos` que describe la colección en formato JSON y siempre debe ser nombrado `collection.json`.

1. Ejecutar el script de carga de la siguiente forma:
```
python src/main.py -f folder_name -c collection_name
```
Tenga en cuenta los siguientes parámetros:
- -f, --folder # Directorio dentro de input que contiene el archivo collection.json y los archivos correspondientes a las capas
- -c, --collection (opcional) # Nombre de la colección, si no se establece se toma como nombre el id definido en el archivo collection.json
- -v, --validate-only (opcional) # Si es verdadero únicamente se valida la colección pero no se carga
- -o, --overwrite (opcional) # Sobrescribe una colección ya existente
---

### Eliminar coleccion
# Instrucciones de Uso

1. Ejecutar el script de eliminacion de la coleccion
```
python src/main.py --remove-collection LossPersistance
```
Tenga en cuenta los siguientes parámetros
- --remove-collection # Comando para remover la coleccion del azure
## Cargar una Colección

Para cargar una colección de capas, ejecuta el siguiente comando:

```
python src/main.py create -f folder_name [-c collection_name] [-o]
```

### Parámetros:
- `-f, --folder` (obligatorio): Directorio con el archivo collection.json y las capas.
- `-c, --collection` (opcional): Nombre de la colección. Si no se proporciona, se tomará el id del archivo collection.json.

### Ejemplo:

* Especificando un nombre de colección
```
python src/main.py create -f my_folder -c MyCollection
o
python src/main.py create --folder my_folder --collection MyCollection
```

Este comando creará la colección `MyCollection` a partir de los archivos en el directorio `input/my_folder`

* Usando el id del archivo collection.json:

```
python src/main.py create -f my_folder
o
python src/main.py create --folder my_folder
```
---

## Validar una Colección

Si solo deseas validar una colección sin cargarla, puedes ejecutar:

```
python src/main.py validate -f folder_name [-c collection_name]
```

### Parámetros:
- `-f, --folder` (obligatorio): Directorio que contiene los archivos de la colección.
- `-c, --collection` (opcional): Nombre de la colección para validar. Si no se proporciona, se tomará el id del archivo collection.json.

### Ejemplo:

```
python src/main.py validate -f my_folder
o
python src/main.py validate --folder my_folder
```

Este comando validará los archivos de la colección en el directorio `input/my_folder` sin cargarlos.

---

## Eliminar una Colección

Para eliminar una colección de STAC y de Azure, ejecuta el siguiente comando:

```
python src/main.py remove --collection collection_name
```

### Parámetros:

- `-c, --collection` (obligatorio): Nombre de la colección a eliminar.

### Ejemplo:

```
python src/main.py remove -c my_collection
o
python src/main.py remove --collection my_collection
```

Este comando eliminará la colección `my_collection` del sistema.

---

## Revisión y formato de estilos para el código

Expand Down
22 changes: 11 additions & 11 deletions spec/collection.example.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"id": "colombia_pp",
"id": "LossPersistence",
"title": "Time series of the binary presence of forests in Colombia",
"description": "Time series of the binary presence of forests in Colombia. Bosque/Non Bosque. With 1 indicating the presence of forests.",
"metadata": {
Expand All @@ -11,32 +11,32 @@
},
"items": [
{
"id": "Colombia_pp_2000-2005",
"id": "2000-2005",
"year": "2005",
"assets": {
"input_file": "Colombia_pp_2000-2005.tif"
"input_file": "2000-2005.tif"
}
},
{
"id": "Colombia_pp_2006-2010",
"id": "2006-2010",
"year": "2010",
"assets": {
"input_file": "Colombia_pp_2006-2010.tif"
"input_file": "2006-2010.tif"
}
},
{
"id": "Colombia_pp_2011-2015",
"id": "2011-2015",
"year": "2015",
"assets": {
"input_file": "Colombia_pp_2011-2015.tif"
"input_file": "2011-2015.tif"
}
},
{
"id": "Colombia_pp_2016-2021",
"year": "2010",
"id": "2016-2021",
"year": "2021",
"assets": {
"input_file": "Colombia_pp_2016-2021.tif"
"input_file": "2016-2021.tif"
}
}
]
}
}
26 changes: 20 additions & 6 deletions src/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ def create_collection(self, collection_name, collection_data):
extent=pystac.Extent(
spatial=spatial_extent, temporal=temporal_extent
),
extra_fields={
"metadata": collection_data["metadata"]
},
)

self.stac_collection.validate()
Expand Down Expand Up @@ -156,12 +159,11 @@ def remove_collection(self, collection_name=None):
items_collection = stac_rest.get(f"{collection_url}/items").json()
for item in items_collection["features"]:
for asset_key, asset_value in item["assets"].items():
parsed_url = parse.urlparse(asset_value["href"])
blob_url = parsed_url.path.split("/")[-1]
url = asset_value["href"]
logger.info(
f"Deleting file: {blob_url} from Azure Blob Storage"
f"Deleting file: {url} from Azure Blob Storage"
)
self.storage.remove_file(blob_url)
self.storage.remove_file(url)

stac_rest.delete(collection_url)
logger.info(f"Collection {collection_id} removed successfully")
Expand All @@ -175,20 +177,32 @@ def upload_collection(self):
Upload the collection and items to the STAC server.
"""
try:
logger.info(
f"Uploading collection: {self.stac_collection.to_dict()}"
)

stac_rest.post_or_put(
parse.urljoin(self.stac_url, "/collections"),
self.stac_collection.to_dict(),
)
logger.info(
f"Collection {self.stac_collection.id} uploaded successfully"
)

for item in self.stac_items:
stac_rest.post_or_put(
item_dict = item.to_dict()
item_response = stac_rest.post_or_put(
parse.urljoin(
self.stac_url,
f"/collections/{self.stac_collection.id}/items",
),
item.to_dict(),
item_dict,
)
logger.info(
f"Item upload response: {item_response.status_code}"
)
except Exception as e:
logger.error(f"Error uploading collection: {e}")
raise RuntimeError(f"Error uploading collection: {e}")

def convert_layers(self, input_dir, output_dir):
Expand Down
22 changes: 12 additions & 10 deletions src/utils/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@ def validate_format(data):
"""
with open("spec/collection.json", "r") as f:
schema = load(f)

try:
validate(instance=data, schema=schema)
metadata_properties_lengths = [
len(data["metadata"]["properties"][key])
for key in data["metadata"]["properties"]
]
if not len(set(metadata_properties_lengths)) == 1:
raise FormatError(
"Los elementos de la propiedad metadata properties no tienen "
"la misma longitud."
)

if "metadata" in data and "properties" in data["metadata"]:
metadata_properties_lengths = [
len(data["metadata"]["properties"][key])
for key in data["metadata"]["properties"]
]
if len(set(metadata_properties_lengths)) != 1:
raise FormatError(
"Error en las propiedades de la colección: "
"Los elementos dentro de 'metadata.properties' no tienen la misma longitud."
)

except Exception as e:
raise FormatError(
f"El archivo no cumple con el formato JSON. Detalles: {e}"
Expand Down
17 changes: 11 additions & 6 deletions src/utils/stac_rest.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import requests

from utils.logging_config import logger


def post_or_put(url: str, data: dict):
"""
Post or put data to url
"""
try:
response = requests.post(url, json=data)

if response.status_code == 409:
response = requests.put(url, json=data)

response = requests.post(url, json=data)
if response.status_code == 409:
response = requests.put(url, json=data)
if not response.status_code == 404:
response.raise_for_status()
else:
response.raise_for_status()
return response
except requests.exceptions.RequestException as e:
logger.error(f"Error during post or put: {e}")
raise e


def get(url: str):
Expand Down
22 changes: 22 additions & 0 deletions src/utils/storage.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from urllib import parse

from azure.storage.blob import BlobServiceClient

from config import get_settings

from utils.logging_config import logger


class Storage:

Expand Down Expand Up @@ -28,6 +33,23 @@ def remove_file(self, file_path):
"""
Remove a blob from Azure Blob Storage
"""
if file_path.startswith("https://"):
parsed_url = parse.urlparse(file_path)
file_path = parsed_url.path.lstrip("/")

container_name = self.container_client.container_name

if file_path.startswith(f"{container_name}/"):
file_path = file_path[len(f"{container_name}/") :]

blob_client = self.container_client.get_blob_client(file_path)

if blob_client.exists():
blob_client.delete_blob()
logger.info(
f"Successfully deleted {file_path} from Azure Blob Storage."
)
else:
logger.warning(
f"Blob {file_path} does not exist in Azure Blob Storage."
)

0 comments on commit 4958cc3

Please sign in to comment.