Skip to content

Commit

Permalink
Merge pull request #24 from georchestra/backend_search_distant_gn
Browse files Browse the repository at this point in the history
implement and test search function
  • Loading branch information
mki-c2c authored Feb 5, 2025
2 parents 9106ca0 + 4943e29 commit 1ff30b3
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 14 deletions.
9 changes: 9 additions & 0 deletions backend/maelstro/common/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from typing import Any, Optional
from pydantic import BaseModel, Field


class SearchQuery(BaseModel):
query: Optional[dict[str, Any]] = {"query_string": {"query": "*"}}
source_: Optional[list[str]] = Field([], alias="_source")
from_: Optional[int] = Field(0, alias="from")
size: Optional[int] = 20
22 changes: 21 additions & 1 deletion backend/maelstro/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@

from io import BytesIO
from typing import Annotated, Any
from fastapi import FastAPI, HTTPException, status, Request, Response, Header
from fastapi import (
FastAPI,
HTTPException,
status,
Request,
Response,
Header,
Body,
)
from fastapi.responses import PlainTextResponse
from geonetwork import GnApi
from maelstro.config import ConfigError, app_config as config
from maelstro.metadata import Meta
from maelstro.core import CloneDataset
from maelstro.common.models import SearchQuery


app = FastAPI(root_path="/maelstro-backend")
Expand Down Expand Up @@ -101,6 +110,17 @@ def get_destinations() -> list[dict[str, str]]:
return config.get_destinations()


@app.post("/search/{src_name}")
def post_search(
src_name: str, search_query: Annotated[SearchQuery, Body()]
) -> dict[str, Any]:
src_info = config.get_access_info(
is_src=True, is_geonetwork=True, instance_id=src_name
)
gn = GnApi(src_info["url"], src_info["auth"])
return gn.search(search_query.model_dump(by_alias=True, exclude_unset=True))


@app.get("/sources/{src_name}/data/{uuid}/layers")
def get_layers(src_name: str, uuid: str) -> list[dict[str, str]]:
try:
Expand Down
2 changes: 1 addition & 1 deletion backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies = [
"lxml (>=5.3.0,<6.0.0)",
"types-pyyaml (>=6.0.12.20241230,<7.0.0.0)",
"lxml-stubs (>=0.5.1,<0.6.0)",
"geonetwork @ git+https://github.com/camptocamp/python-geonetwork",
"geonetwork @ git+https://github.com/camptocamp/python-geonetwork@93aafcb9700914114d94dc111a3c5e4b7b58b606",
"geoservercloud @ git+https://github.com/camptocamp/python-geoservercloud",
]

Expand Down
39 changes: 39 additions & 0 deletions backend/tests/test_API.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
from fastapi.testclient import TestClient

from maelstro.main import app
Expand All @@ -10,3 +11,41 @@ def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {'Hello': 'World'}


@pytest.mark.skip("Search on demo server currently down")
def test_search():
response = client.post("/search/GeonetworkDemo", json={})
assert response.json()['hits']['total'] == {'value': 8316, 'relation': 'eq'}


@pytest.mark.skip("Search on demo server currently down")
def test_search2():
response = client.post("/search/GeonetworkDemo", json={"query": {"wildcard": {"resourceTitleObject.default": {"value": "plan_*"}}}, "size": 1})
assert len(response.json()['hits']['hits']) == 1
assert response.json()['hits']['total'] == 2


def test_search3():
response = client.post("/search/GeonetworkRennes", json={"query": {"multi_match": {"fields": ["resourceTitleObject.*"], "query": "plan", "type": "bool_prefix"}}})
assert len(response.json()['hits']['hits']) == 10
assert response.json()['hits']['total']['value'] == 22


def test_search4():
response = client.post("/search/GeonetworkRennes", json={
"query": {"query_string": {"fields": ["resourceTitleObject.*"], "query": "plan", "type": "bool_prefix"}},
"size": 15,
})
assert len(response.json()['hits']['hits']) == 15
assert response.json()['hits']['total']['value'] == 22


def test_search5():
response = client.post("/search/GeonetworkRennes", json={
"source": [],
"from_": 0,
"size": 5
})
assert len(response.json()['hits']['hits']) == 5
assert response.json()['hits']['total']['value'] == 388
21 changes: 14 additions & 7 deletions backend/tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import pytest
from maelstro.config import Config, ConfigError
from maelstro.common.types import Credentials


os.environ["CONFIG_PATH"] = os.path.join(os.path.dirname(__file__), "test_config.yaml")
Expand All @@ -14,6 +15,10 @@ def test_init():
{
"name": "GeonetworkMaster",
"api_url": "https://demo.georchestra.org/geonetwork/srv/api",
},
{
"name": "GeonetworkRennes",
"api_url": "https://public.sig.rennesmetropole.fr/geonetwork/srv/api",
}
],
"geoserver_instances": [
Expand All @@ -35,7 +40,9 @@ def test_init():
"destinations": {
"CompoLocale": {
"geonetwork": {
"api_url": "http://geonetwork:8080/geonetwork/srv/api",
"api_url": "https://georchestra-127-0-0-1.nip.io/geonetwork/srv/api",
"login": "testadmin",
"password": "testadmin",
},
"geoserver": {
"url": "https://georchestra-127-0-0-1.nip.io/geoserver"
Expand Down Expand Up @@ -72,7 +79,7 @@ def test_init():


def test_subst_env():
os.environ["DEMO_LOGIN"] = "demo"
os.environ["DEMO_CRD"] = "demo"
os.environ["LOCAL_LOGIN"] = "test"
conf = Config("CONFIG_PATH")
conf.config["sources"]["geonetwork_instances"][0]["login"] == "demo"
Expand All @@ -82,19 +89,19 @@ def test_subst_env():


def test_get_info():
os.environ.pop("DEMO_LOGIN")
os.environ["DEMO_LOGIN"] = "demo"
os.environ.pop("DEMO_CRD")
os.environ["DEMO_CRD"] = "demo"
conf = Config("CONFIG_PATH")
assert conf.get_access_info(True, True, "GeonetworkMaster") == {
"auth": ("demo", "demo"),
"auth": Credentials("demo", "demo"),
"url": "https://demo.georchestra.org/geonetwork/srv/api",
}
assert conf.get_access_info(True, False, "https://mastergs.rennesmetropole.fr/geoserver-geofence/") == {
"auth": ("toto6", "Str0ng_passW0rd"),
"auth": Credentials("toto6", "Str0ng_passW0rd"),
"url": "https://mastergs.rennesmetropole.fr/geoserver-geofence/",
}
assert conf.get_access_info(False, True, "PlateformeProfessionnelle") == {
"auth": ("toto", "passW0rd"),
"auth": Credentials("toto", "passW0rd"),
"url": "https://portail.sig.rennesmetropole.fr/geonetwork/srv/api",
}
assert conf.get_access_info(False, False, "CompoLocale") == {
Expand Down
10 changes: 6 additions & 4 deletions backend/tests/test_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ sources:
- name: "GeonetworkMaster"
# api_url: https://mastergn.rennesmetropole.fr/geonetwork/srv/api
api_url: https://demo.georchestra.org/geonetwork/srv/api
login_env_var: DEMO_LOGIN
password_env_var: DEMO_LOGIN
login_env_var: DEMO_CRD
password_env_var: DEMO_CRD
- name: "GeonetworkRennes"
api_url: https://public.sig.rennesmetropole.fr/geonetwork/srv/api
geoserver_instances:
- url: "https://mastergs.rennesmetropole.fr/geoserver/"
login: test
Expand All @@ -24,9 +26,9 @@ destinations:
# nom de l'instance geOrchestra destination, telle qu'il apparaitra dans la UI
"CompoLocale":
geonetwork:
api_url: http://geonetwork:8080/geonetwork/srv/api
api_url: https://georchestra-127-0-0-1.nip.io/geonetwork/srv/api
login_env_var: LOCAL_LOGIN
password_env_var: LOCAL_LOGIN
password_env_var: LOCAL_PASSWORD
geoserver:
url: https://georchestra-127-0-0-1.nip.io/geoserver
"PlateformeProfessionnelle":
Expand Down
7 changes: 6 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ services:
- georchestra_datadir:/etc/georchestra
environment:
MAELSTRO_CONFIG: /app/tests/test_config.yaml
LOCAL_LOGIN: admin
LOCAL_LOGIN: testadmin
LOCAL_PASSWORD: testadmin
healthcheck:
test: "health_check"
interval: 10s
Expand All @@ -49,5 +50,9 @@ services:
build:
context: ./backend
target: check
environment:
MAELSTRO_CONFIG: /app/tests/test_config.yaml
LOCAL_LOGIN: testadmin
LOCAL_PASSWORD: testadmin
volumes:
- ./backend:/app

0 comments on commit 1ff30b3

Please sign in to comment.