Ejemplos de uso de API

En esta sección, demostraremos cómo se puede utilizar/integrar la API de GeoNode con otras aplicaciones que utilizan Python.

Listado de recursos y detalles

Como se mencionó en capítulos anteriores, los recursos de GeoNode se clasifican en diferentes tipos, por ejemplo, conjuntos de datos, mapas, documentos, etc. Todos los recursos disponibles se pueden enumerar con la API GET /api/v2/resources.

Para obtener un único recurso, se proporciona una clave principal en la URL. Por ejemplo, GET /api/v2/resources/{resource.pk}.

Ejemplos de solicitudes:

  1. Listado

import requests

url = "https://master.demo.geonode.org/api/v2/resources"
response = requests.request("GET", url)
  1. Detalle

import requests

url = "https://master.demo.geonode.org/api/v2/resources/1797"
response = requests.request("GET", url)

Nota

Las solicitudes anteriores funcionan para recursos visibles públicamente. Si un recurso es privado, se debe incluir el token de autenticación básica o de portador dentro de los encabezados.

  1. Listado con autorización básica:

import requests

url = "https://master.demo.geonode.org/api/v2/resources"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("GET", url, headers=headers)

Se puede usar un token en lugar de la autenticación básica configurando 'Authorization': 'Bearer <token>'.

Descarga de recursos

La URL de descarga de un recurso se puede obtener desde resource.download_url. Esta URL ejecuta la descarga sincrónica de un recurso en su formato de descarga predeterminado (ESRI Shapefile para vectores, Geotiff para rásteres y el formato original para documentos). Hay formatos de exportación adicionales para conjuntos de datos disponibles a través de la interfaz de usuario. Por el momento, la API no los expone.

Búsqueda y filtrado de recursos

Los recursos de GeoNode se pueden filtrar con los siguientes parámetros de consulta:

Parámetros

URL

title and abstract (paginated free text search)

/api/v2/resources?page=1&search=text-to-search&search_fields=title&search_fields=abstract

resource_type (dataset, map, document, service, geostory, dashboard)

/api/v2/resources?filter{resource_type}=map

subtype (raster,vector, vector_time, remote)

/api/v2/resources?filter{resource_type}=vector

favorite (Boolean True)

/api/v2/resources?favorite=true

featured (Boolean True or False)

/api/v2/resources?filter{featured}=true

published (Boolean True or False)

/api/v2/resources?filter{is_published}=true

aprroved (Boolean True or False)

/api/v2/resources?filter{is_approved}=true

category

api/v2/resources?filter{category.identifier}=example

keywords

/api/v2/resources?filter{keywords.name}=example

regions

/api/v2/resources?filter{regions.name}=global

owner

/api/v2/resources?filter{owner.username}=test_user

extent (Four comer separated coordinates)

/api/v2/resources?extent=-180,-90,180,90

Ejemplos:

  1. Filtrar con un único valor

import requests

url = "https://master.demo.geonode.org/api/v2/resources/?filter{resource_type}=map"
response = requests.request("GET", url, headers=headers, data=payload
  1. Filtrar con múltiples valores

import requests

url = "https://master.demo.geonode.org/api/v2/resources/?filter{resource_type.in}=map&filter{resource_type.in}=dataset"
response = requests.request("GET", url, headers=headers, data=payload)

Nota

Con las API de filtro de formato /api/v2/resources?filter{filter_key}=value, se pueden usar métodos adicionales (in e icontains) para proporcionar resultados filtrados de forma exhaustiva. Por ejemplo, /api/v2/resources?filter{regions.name.icontains}=global /api/v2/resources?filter{regions.name.in}=global.

Es importante tener en cuenta que otros métodos distinguen entre mayúsculas y minúsculas, excepto los icontains.

Recursos específicos del conjunto de datos

Obtenga los metadatos de los conjuntos de datos cargados con:
  • API: GET /api/v2/datasets/{id}

  • Código de estado: 200

Nota

Esto es muy similar a GET /api/v2/resources pero proporciona metadatos adicionales específicamente para conjuntos de datos como featureinfo_custom_template o attribute_set

Ejemplo:

import requests

DATASET_ID = "the dataset id"
url = f"https://master.demo.geonode.org/api/v2/datasets/{DATASET_ID}"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("GET", url, headers=headers)

Carga de recursos

La API admite la carga de conjuntos de datos y documentos.

Conjuntos de datos

El formulario de carga de conjuntos de datos acepta formatos de archivo ESRI Shapefile, GeoTIFF, Comma Separated Value (CSV), Zip Archive, XML Metadata File y Styled Layer Descriptor (SLD). Para una carga exitosa, el formulario requiere base_file, dbf_file, shx_file y prj_file. xml_file y Sld_file son opcionales.

  • API: POST /api/v2/uploads/upload

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/uploads/upload"
files= [
('sld_file',('BoulderCityLimits.sld',open('/home/myuser/BoulderCityLimits.sld','rb'),'application/octet-stream')),   ('base_file',('BoulderCityLimits.shp',open('/home/BoulderCityLimits.shp','rb'),'application/octet-stream')),  ('dbf_file',('BoulderCityLimits.dbf',open('/home/BoulderCityLimits.dbf','rb'),'application/octet-stream')),  ('shx_file',('BoulderCityLimits.shx',open('/home/BoulderCityLimits.shx','rb'),'application/octet-stream')),
('prj_file',('BoulderCityLimits.prj',open('/home/myuser/BoulderCityLimits.prj','rb'),'application/octet-stream))
]
headers = {
'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("POST", url, headers=headers, files=files)

Documentos

Los documentos se pueden cargar como datos de formulario.

  • API: POST /api/v2/documents

  • Código de estado: 200

Ejemplo:

import requests

url = "http://localhost:8000/api/v2/documents"
payload={
    'title': 'An example image'
}
files=[
    ('doc_file',('image.jpg',open('/home/myuser/image.jpg','rb'),'image/jpeg'))
]
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)

También se pueden crear documentos para hacer referencia a recursos remotos. En este caso, se debe utilizar el parámetro doc_url para establecer la URL del documento remoto.

  • API: POST /api/v2/documents

  • Código de estado: 200

Ejemplo:

import requests

url = "http://localhost:8000/api/v2/documents"
payload={
    'title': 'An example image',
    'doc_url' : 'http://examples.com/image.jpg'
}
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)

Tenga en cuenta que si la URL no termina con una extensión de documento válida, se debe utilizar el parámetro extension (por ejemplo, extension: 'jpeg').

Seguimiento del progreso de carga del conjunto de datos

Cuando se ejecuta una solicitud de carga, GeoNode crea una «Solicitud de ejecución» y continúa actualizando sus atributos de estado y progreso (es un atributo de propiedad, calculado al obtener la respuesta) a medida que el recurso se crea y configura en Geoserver. Una ejecución puede estar en uno de los siguientes estados:

  • ready

  • running

  • failed

  • finished

Cuando el conjunto de datos se carga correctamente, el estado final de la carga se establece como «finished».

Para ver el estado de la ejecución, el método API GET /api/v2/executionrequest/{execution_id} donde {execution_id} es el valor devuelto por la llamada inicial a la API de carga.

El objeto devuelto contiene, además de toda la información relacionada con la ejecución, los datos de entrada que se pasaron a la solicitud de ejecución y los parámetros de salida específicos del tipo de ejecución. En el caso de una carga de conjunto de datos, los parámetros de salida contienen la URL de la página del catálogo para el nuevo conjunto de datos.

"output_params": {
    "detail_url": [
        "/catalogue/#/dataset/9881"
    ]
},

También puedes filtrar las ejecuciones por estado. Por ejemplo, GET /api/v2/executionrequest?filter{action}=import&filter{source}=upload&filter{status}=finished

Ejemplo:

import requests

url = "https://stable.demo.geonode.org/api/v2/executionrequest/5f640b6b-8c51-4514-a054-995133fee107"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("GET", url, headers=headers)

Sobrescribir un conjunto de datos

Al cargar un recurso se creará de forma predeterminada un nuevo conjunto de datos. Este comportamiento se puede cambiar configurando el parámetro overwrite_existing_layer en True. En este caso, el procedimiento de carga sobrescribirá un recurso cuyo nombre coincida con el nuevo.

Omitir el conjunto de datos existente

Si el parámetro skip_existing_layers se establece en verdadero True el procedimiento uplad ignorará los archivos cuyo nombre coincida con recursos ya existentes.

Carga de un archivo de metadatos

Se puede cargar un archivo de metadatos completo que cumpla con la norma ISO-19115 para un conjunto de datos.

  • API: PUT /api/v2/datasets/{dataset_id}/metadata

  • Código de estado: 200

Ejemplo:

import requests

url = "http://localhost:8000/api/v2/datasets/1/metadata"
files=[
        ('metadata_file',('metadata.xml',open('/home/user/metadata.xml','rb'),'text/xml'))
    ]
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("PUT", url, headers=headers, data={}, files=files)

Eliminar recurso

  • API: DELETE /api/v2/resources/{pk}/delete

  • Código de estado: 204

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/resources/1778"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("DELETE", url, headers=headers)

Descarga de recursos

GeoNode ofrece una opción de descarga para los recursos de tipo de recurso dataset y documento. Para los conjuntos de datos, la opción de descarga solo está disponible para aquellos que tienen archivos cargados.

Conjuntos de datos

  • API: GET /datasets/{resource.alternate}/dataset_download

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/datasets/geonode:BoulderCityLimits3/dataset_download"
response = requests.request("GET", url)

Documentos

  • API: GET /documents/{resource.pk}/download

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/documents/1781/download"
response = requests.request("GET", url)

Actualización de Metadatos del Conjunto de Datos

  • API: PATCH /api/v2/datasets/{id}

  • Código de estado: 200

El siguiente ejemplo cambia el título y la licencia de un conjunto de datos.

import requests

url = ROOT + "api/v2/datasets/" + DATASET_ID
auth = (LOGIN_NAME, LOGIN_PASSWORD)

data = {
    "title": "a new title",
    "license": 4,
}
response = requests.patch(url, auth=auth, json=data)

Nota

bbox_polygon y ll_bbox_polygon son valores derivados que no se pueden cambiar.

Usuarios, grupos y permisos

Usuarios

Listado

  • API: POST /api/v2/users

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/users"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("GET", url, headers=headers)

Detalle del usuario

  • API: POST /api/v2/users/{pk}

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/users/1000"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("GET", url, headers=headers)

Crear un nuevo usuario

  • API: POST /api/v2/users

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/users"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
payload={"username": "username",
        "password": "password",
        "email": "email@email.com",
        "first_name":"first_name",
        "last_name":"last_name",
        "avatar": "https://www.gravatar.com/avatar/7a68c67c8d409ff07e42aa5d5ab7b765/?s=240"}
response = requests.request("POST", url, headers=headers, data=payload)

Editar un usuario

  • API: PATCH /api/v2/users/{pk}

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/users/1000"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
payload={"password": "new_password"}
response = requests.request("PATCH", url, headers=headers, data=payload)

Eliminar un usuario

  • API: DELETE /api/v2/users/{pk}

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/users/1000"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
payload={"password": "new_password"}
response = requests.request("DELETE", url, headers=headers, data=payload)

En este caso, se comprueba la lista de reglas de validación configuradas en USER_DELETION_RULES antes de ejecutar la eliminación.

Lista de grupos de usuarios

  • API: POST /api/v2/users/{pk}/groups

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/users/1000/groups"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("GET", url, headers=headers)

Transferir recursos de propiedad de un usuario a otro

  • API: POST /api/v2/users/{pk}/transfer_resources

  • Código de estado: 200

Ejemplo:

import requests
payload={"owner": 1001}
url = "https://master.demo.geonode.org/api/v2/users/1000/transfer_resources"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("POST", url, headers=headers, data=payload)

En este caso los recursos serán transferidos al usuario con id 1001, en lugar de utilizar el payload={«owner»: «DEFAULT»} los recursos serán transferidos al usuario principal

Eliminar usuario como administrador de grupo

  • API: POST /api/v2/users/{pk}/remove_from_group_manager

  • Código de estado: 200

Ejemplo:

import requests
payload={"groups": [1,2,3]}
url = "https://master.demo.geonode.org/api/v2/users/1000/remove_from_group_manager"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("POST", url, headers=headers, data=payload)

En este caso, el usuario será eliminado como administrador de grupo de los siguientes ID de grupo; si la carga útil fuera payload={«groups»: «ALL»}, el usuario será eliminado como administrador de grupo de todos los grupos de los que forma parte

Grupos

En GeoNode, al listar grupos, la API devuelve grupos que tienen perfiles de grupo. Por lo tanto, para Django, los grupos que no están relacionados con un perfil de grupo no se incluyen en la respuesta. Sin embargo, se puede acceder a ellos en el panel de administración de Django.

  • API: POST /api/v2/groups

  • Código de estado: 200

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/groups"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("GET", url, headers=headers)

Permisos

Los permisos en GeoNode se configuran por recurso y por usuario o grupo. Los siguientes son permisos generales que se pueden asignar:

  • Ver: permite ver el recurso. [view_resourcebase]

  • Descargar: permite descargar recursos, específicamente conjuntos de datos y documentos. [ view_resourcebase, download_resourcebase]

  • Editar: permite cambiar atributos, propiedades de las características, estilos y metadatos de los conjuntos de datos para el recurso especificado. [view_resourcebase, download_resourcebase, change_resourcebase, change_dataset_style, change_dataset_data, change_resourcebase_metadata]

  • Administrar: permite actualizar, eliminar, cambiar permisos, publicar y anular la publicación del recurso. [view_resourcebase, download_resourcebase, change_resourcebase, change_dataset_style, change_dataset_data, publish_resourcebase, delete_resourcebase, change_resourcebase_metadata, change_resourcebase_permissions]

Obtención de permisos sobre un recurso

Al enumerar los recursos o en la API de detalles de recursos, GeoNode incluye el atributo perms para cada recurso con una lista de permisos que tiene el usuario que realiza la solicitud sobre el recurso respectivo.

GeoNode también proporciona una API para obtener una descripción general de los permisos establecidos en un recurso. La respuesta contiene usuarios y grupos con permisos establecidos en ellos. Sin embargo, esta API devuelve «200» si un usuario solicitante tiene permisos de «administración» en el recurso; de lo contrario, devolverá «403 (Prohibido)».

  • API: GET /api/v2/resources/1791/permissions

Ejemplo:

import requests

url = "https://master.demo.geonode.org/api/v2/resources/1791/permissions"
headers = {
    'Authorization': 'Basic dXNlcjpwYXNzd29yZA=='
}
response = requests.request("GET", url, headers=headers)

Cambiar los permisos de un recurso

Los permisos se configuran con una denominada «especificación de permisos», que es una estructura JSON donde se pueden especificar permisos para usuarios individuales y grupos.

El siguiente ejemplo muestra una especificación de permiso para las siguientes reglas:

  • el user1 puede editar

  • el user2 puede administrar

  • el group1 puede editar

  • los usuarios anónimos (públicos) pueden ver

  • los miembros registrados pueden descargar

NOTA: El id de los grupos “anónimos” y “miembros registrados” se puede obtener de los permisos del recurso. No se listan dentro de la API de grupos, ya que se trata de grupos internos especiales

{
    "users": [
        {
            "id": <id_of_user1>,
            "permissions": "edit"
        },
        {
            "id": <id_of_user2>,
            "permissions": "manage"
        }
    ],
    "organizations": [
        {
            "id": <id_of_group1>,
            "permissions": "edit"
        },
    ],
    "groups": [
        {
            "id": <id_of_anonymous_group>,
            "permissions": "view"
        },
        {
            "id": <id_of_regisdtered-members_group>,
            "permissions": "download"
        }
    ]
}

La especificación permanente se envía como JSON, con el tipo de contenido application/json, dentro de una solicitud PUT.

import requests
import json

url = "https://master.demo.geonode.org/api/v2/resources/1791/permissions"
payload = json.dumps({
"users": [
    {
    "id": 1001,
    "permissions": "edit"
    },
    {
    "id": 1002,
    "permissions": "manage"
    }
],
"organizations": [
    {
    "id": 1,
    "permissions": "edit"
    }
],
"groups": [
    {
    "id": 2,
    "permissions": "view"
    },
    {
    "id": 3,
    "permissions": "download"
    }
]
})
headers = {
'Authorization': 'Basic dXNlcjpwYXNzd29yZA==',
'Content-Type': 'application/json',
}

response = requests.request("PUT", url, headers=headers, data=payload)

Esta es una operación asincrónica que devuelve una respuesta similar a la siguiente:

{
    "status": "ready",
    "execution_id": "7ed578c2-7db8-47fe-a3f5-6ed3ca545b67",
    "status_url": "https://master.demo.geonode.org/api/v2/resource-service/execution-status/7ed578c2-7db8-47fe-a3f5-6ed3ca545b67"
}

La propiedad status_url devuelve la URL para realizar un seguimiento del progreso de la solicitud. Al consultar la URL, se obtendrá un resultado similar al siguiente:

{
    "user": "admin",
    "status": "running",
    "func_name": "set_permissions",
    "created": "2022-07-08T11:16:32.240453Z",
    "finished": null,
    "last_updated": "2022-07-08T11:16:32.240485Z",
    "input_params": {
    ...
    }
}

La operación se completará una vez que la propiedad status se actualice con el valor finished.

Listado y detalles de recursos vinculados

Todos los recursos vinculados disponibles se pueden listar con la API mediante GET /api/v2/resources/{pk}/linked_resources. donde pk es el ID base del recurso

Ejemplos de solicitudes:

  1. Listar todos los enlaces de recursos

import requests

url = "https://master.demo.geonode.org/api/v2/resources/{pk}/linked_resources"
response = requests.request("GET", url)