Skip to content

Commit 38df086

Browse files
authored
26087 - Auth API: support affiliations search parameters (#3361)
1 parent 3c35962 commit 38df086

File tree

3 files changed

+51
-14
lines changed

3 files changed

+51
-14
lines changed

auth-api/src/auth_api/models/dataclass.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"""This module holds data classes."""
1515

1616
from dataclasses import dataclass, field
17-
from typing import List, Optional
17+
from typing import List, Optional, Self
18+
19+
from requests import Request
1820

1921
from auth_api.utils.enums import KeycloakGroupActions
2022

@@ -47,6 +49,29 @@ class AffiliationInvitationSearch: # pylint: disable=too-many-instance-attribut
4749
is_deleted: bool = False
4850

4951

52+
@dataclass
53+
class AffiliationSearchDetails: # pylint: disable=too-many-instance-attributes
54+
"""Used for filtering Affiliations based on filters passed."""
55+
56+
identifier: Optional[str]
57+
status: Optional[str]
58+
name: Optional[str]
59+
type: Optional[str]
60+
page: int
61+
limit: int
62+
63+
@classmethod
64+
def from_request_args(cls, req: Request) -> Self:
65+
return cls(
66+
identifier=req.args.get("identifier"),
67+
status=req.args.getlist("status") or [],
68+
name=req.args.get("name"),
69+
type=req.args.getlist("type") or [],
70+
page=int(req.args.get("page", 1)),
71+
limit=int(req.args.get("limit", 100000)),
72+
)
73+
74+
5075
@dataclass
5176
class AffiliationInvitationData: # pylint: disable=too-many-instance-attributes
5277
"""Used for as affiliation invitation DTO."""

auth-api/src/auth_api/resources/v1/org.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from auth_api.models import Affiliation as AffiliationModel
2525
from auth_api.models import Org as OrgModel
2626
from auth_api.models.dataclass import Affiliation as AffiliationData
27-
from auth_api.models.dataclass import DeleteAffiliationRequest, SimpleOrgSearch
27+
from auth_api.models.dataclass import AffiliationSearchDetails, DeleteAffiliationRequest, SimpleOrgSearch
2828
from auth_api.models.org import OrgSearch # noqa: I005; Not sure why isort doesn't like this
2929
from auth_api.schemas import InvitationSchema, MembershipSchema
3030
from auth_api.schemas import utils as schema_utils
@@ -382,11 +382,16 @@ def new_affiliation_search(org_id):
382382
"""Get all affiliated entities for the given org by calling into Names and LEAR."""
383383
# get affiliation identifiers and the urls for the source data
384384
affiliations = AffiliationModel.find_affiliations_by_org_id(org_id)
385-
affiliations_details_list = asyncio.run(AffiliationService.get_affiliation_details(affiliations, org_id))
385+
search_details = AffiliationSearchDetails.from_request_args(request)
386+
affiliations_details_list = asyncio.run(
387+
AffiliationService.get_affiliation_details(affiliations, search_details, org_id)
388+
)
386389
# Use orjson serializer here, it's quite a bit faster.
387390
response, status = (
388391
current_app.response_class(
389-
response=orjson.dumps({"entities": affiliations_details_list}), # pylint: disable=maybe-no-member
392+
response=orjson.dumps(
393+
{"entities": affiliations_details_list, "totalResults": len(affiliations_details_list)}
394+
), # pylint: disable=maybe-no-member
390395
status=200,
391396
mimetype="application/json",
392397
),

auth-api/src/auth_api/services/affiliation.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"""Service for managing Affiliation data."""
1515
import datetime
1616
import re
17-
from typing import Dict, List
17+
from dataclasses import asdict
18+
from typing import Dict, List, Optional
1819

1920
from flask import current_app
2021
from requests.exceptions import HTTPError
@@ -29,7 +30,7 @@
2930
from auth_api.models.contact_link import ContactLink
3031
from auth_api.models.dataclass import Activity
3132
from auth_api.models.dataclass import Affiliation as AffiliationData
32-
from auth_api.models.dataclass import DeleteAffiliationRequest
33+
from auth_api.models.dataclass import AffiliationSearchDetails, DeleteAffiliationRequest
3334
from auth_api.models.entity import Entity
3435
from auth_api.models.membership import Membership as MembershipModel
3536
from auth_api.schemas import AffiliationSchema
@@ -453,17 +454,24 @@ def _affiliation_details_url(affiliation: AffiliationModel) -> str:
453454
return current_app.config.get("LEAR_AFFILIATION_DETAILS_URL")
454455

455456
@staticmethod
456-
async def get_affiliation_details(affiliations: List[AffiliationModel], org_id) -> List:
457+
async def get_affiliation_details(
458+
affiliations: List[AffiliationModel], search_details: AffiliationSearchDetails, org_id
459+
) -> List:
457460
"""Return affiliation details by calling the source api."""
458461
url_identifiers = {} # i.e. turns into { url: [identifiers...] }
462+
search_dict = asdict(search_details)
459463
for affiliation in affiliations:
460464
url = Affiliation._affiliation_details_url(affiliation)
461-
url_identifiers.setdefault(url, [affiliation.entity.business_identifier]).append(
462-
affiliation.entity.business_identifier
463-
)
464-
465+
url_identifiers.setdefault(url, []).append(affiliation.entity.business_identifier)
465466
call_info = [
466-
{"url": url, "payload": {"identifiers": identifiers}} for url, identifiers in url_identifiers.items()
467+
{
468+
"url": url,
469+
"payload": {
470+
"identifiers": identifiers,
471+
**search_dict,
472+
},
473+
}
474+
for url, identifiers in url_identifiers.items()
467475
]
468476

469477
token = RestService.get_service_account_token(
@@ -488,7 +496,7 @@ def sort_key(item):
488496
return combined
489497
except ServiceUnavailableException as err:
490498
logger.debug(err)
491-
logger.debug("Failed to get affiliations details: %s", affiliations)
499+
logger.debug("Failed to get affiliations details: %s", affiliations)
492500
raise ServiceUnavailableException("Failed to get affiliation details") from err
493501

494502
@staticmethod
@@ -560,7 +568,6 @@ def _get_nr_details(nr_number: str):
560568
except (HTTPError, ServiceUnavailableException) as e:
561569
logger.info(e)
562570
raise BusinessException(Error.DATA_NOT_FOUND, None) from e
563-
564571
return get_nr_response.json()
565572

566573
@staticmethod

0 commit comments

Comments
 (0)