feat: add Perenual API service with error fallback

This commit is contained in:
Stephan Kerkman 2026-05-28 09:49:32 +02:00
parent b3f0a1cd40
commit a6c3c683d4
3 changed files with 60 additions and 0 deletions

View file

View file

@ -0,0 +1,20 @@
import requests
from django.conf import settings
_BASE = 'https://perenual.com/api'
def search_species(query):
"""Query Perenual species-list endpoint. Returns list of result dicts or [] on any error."""
if not settings.PERENUAL_API_KEY:
return []
try:
resp = requests.get(
f'{_BASE}/species-list',
params={'q': query, 'key': settings.PERENUAL_API_KEY},
timeout=5,
)
resp.raise_for_status()
return resp.json().get('data', [])
except Exception:
return []

View file

@ -0,0 +1,40 @@
import pytest
from unittest.mock import patch, MagicMock
from plants.services.perenual import search_species
def test_search_returns_empty_without_api_key(settings):
settings.PERENUAL_API_KEY = ''
results = search_species('rose')
assert results == []
def test_search_returns_data(settings):
settings.PERENUAL_API_KEY = 'test-key'
mock_resp = MagicMock()
mock_resp.json.return_value = {
'data': [{'id': 1, 'common_name': 'Rose', 'scientific_name': ['Rosa multiflora']}]
}
mock_resp.raise_for_status = MagicMock()
with patch('plants.services.perenual.requests.get', return_value=mock_resp):
results = search_species('rose')
assert len(results) == 1
assert results[0]['common_name'] == 'Rose'
def test_search_returns_empty_on_timeout(settings):
settings.PERENUAL_API_KEY = 'test-key'
with patch('plants.services.perenual.requests.get', side_effect=Exception('timeout')):
results = search_species('rose')
assert results == []
def test_search_returns_empty_on_bad_status(settings):
settings.PERENUAL_API_KEY = 'test-key'
mock_resp = MagicMock()
mock_resp.raise_for_status.side_effect = Exception('404')
with patch('plants.services.perenual.requests.get', return_value=mock_resp):
results = search_species('rose')
assert results == []