-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
f14c878
commit 2f02a51
Showing
15 changed files
with
495 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
server/admin_management/api/app/integration/forest_client_integration.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import logging | ||
from http import HTTPStatus | ||
from typing import List | ||
|
||
import requests | ||
from api.config import config | ||
from api.app.schemas import ForestClientIntegrationFindResponse | ||
|
||
LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
class ForestClientIntegrationService(): | ||
""" | ||
The class is used for making requests to get information from Forest Client API. | ||
Api is located at BC API Service Portal: https://api.gov.bc.ca/devportal/api-directory/3179. | ||
API-key needs to be requested from the portal. | ||
Spec of API: | ||
test: https://nr-forest-client-api-test.api.gov.bc.ca/ | ||
prod: https://nr-forest-client-api-prod.api.gov.bc.ca/ | ||
""" | ||
# https://requests.readthedocs.io/en/latest/user/quickstart/#timeouts | ||
# https://docs.python-requests.org/en/latest/user/advanced/#timeouts | ||
TIMEOUT = (5, 10) # Timeout (connect, read) in seconds. | ||
|
||
def __init__(self): | ||
self.api_base_url = config.get_forest_client_api_baseurl() | ||
self.api_clients_url = f"{self.api_base_url}/api/clients" | ||
self.API_TOKEN = config.get_forest_client_api_token() | ||
self.headers = {"Accept": "application/json", "X-API-KEY": self.API_TOKEN} | ||
|
||
# See Python: https://requests.readthedocs.io/en/latest/user/advanced/ | ||
self.session = requests.Session() | ||
self.session.headers.update(self.headers) | ||
|
||
def find_by_client_number(self, p_client_number: str) -> List[ForestClientIntegrationFindResponse]: | ||
""" | ||
Find Forest Client(s) information based on p_client_number search query field. | ||
:param p_client_number: Forest Client Number string (8 digits). | ||
Note! Current Forest Client API can only do exact match. | ||
'/api/clients/findByClientNumber/{clientNumber}' | ||
:return: Search result as List for a Forest Client information object. | ||
Current Forest Client API returns exact one result or http status | ||
other than 200 with message content. The intent for FAM search is for | ||
wild card search and Forest Client API could be capable of doing that | ||
in next version. | ||
""" | ||
url = f"{self.api_clients_url}/findByClientNumber/{p_client_number}" | ||
LOGGER.debug(f"ForestClientIntegrationService find_by_client_number() - url: {url}") | ||
|
||
try: | ||
r = self.session.get(url, timeout=self.TIMEOUT) | ||
r.raise_for_status() | ||
# !! Don't map and return schema.FamForestClient or object from "scheam.py" as that | ||
# will create circular dependency issue. let crud to map the result. | ||
api_result = r.json() | ||
LOGGER.debug(f"API result: {api_result}") | ||
return [api_result] | ||
|
||
# Below except catches only HTTPError not general errors like network connection/timeout. | ||
except requests.exceptions.HTTPError as he: | ||
status_code = r.status_code | ||
LOGGER.debug(f"API status code: {status_code}") | ||
LOGGER.debug(f"API result: {r.content or r.reason}") | ||
|
||
# For some reason Forest Client API uses (a bit confusing): | ||
# - '404' as general "client 'Not Found'", not as conventional http Not Found. | ||
# | ||
# Forest Client API returns '400' as "Invalid Client Number"; e.g. /findByClientNumber/abcde0001 | ||
# Howerver FAM 'search' (as string type param) is intended for either 'number' or 'name' search), | ||
# so if 400, will return empty. | ||
if ((status_code == HTTPStatus.NOT_FOUND) or (status_code == HTTPStatus.BAD_REQUEST)): | ||
return [] # return empty for FAM forest client search | ||
|
||
# Else raise error, including 500 | ||
# There is a general error handler, see: requests_http_error_handler | ||
raise he |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
server/admin_management/api/app/services/validator/forest_client_validator.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import logging | ||
from typing import List, Union | ||
|
||
from api.app.constants import FOREST_CLIENT_STATUS | ||
from api.app.schemas import ForestClientIntegrationFindResponse | ||
|
||
|
||
LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
def forest_client_number_exists( | ||
forest_client_find_result: List[ForestClientIntegrationFindResponse], | ||
) -> bool: | ||
# Exact client number search - should only contain 1 result. | ||
return len(forest_client_find_result) == 1 | ||
|
||
|
||
def forest_client_active( | ||
forest_client_find_result: List[ForestClientIntegrationFindResponse], | ||
) -> bool: | ||
return ( | ||
( | ||
forest_client_find_result[0][FOREST_CLIENT_STATUS["KEY"]] | ||
== FOREST_CLIENT_STATUS["CODE_ACTIVE"] | ||
) | ||
if forest_client_number_exists(forest_client_find_result) | ||
else False | ||
) | ||
|
||
|
||
def get_forest_client_status( | ||
forest_client_find_result: List[ForestClientIntegrationFindResponse], | ||
) -> Union[str, None]: | ||
return ( | ||
forest_client_find_result[0][FOREST_CLIENT_STATUS["KEY"]] | ||
if forest_client_number_exists(forest_client_find_result) | ||
else None | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.