Untitled

mail@pastecode.io avatar
unknown
plain_text
10 days ago
6.1 kB
3
Indexable
Never
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional, List
import requests
import strawberry
from strawberry.fastapi import GraphQLRouter

app = FastAPI()

## Hard-coded configuration values
AUTH_URL = ""
TENANT_URL = ""
USERNAME = ""
PASSWORD = ""
AUTHORIZATION_CODE = ""  

# Define the model representing the fields
class MDMFields(BaseModel):
    displayName: Optional[str] = None
    therapeuticArea: Optional[str] = None
    groupStatus: Optional[str] = None
    pGJNFLAG: Optional[str] = None
    uri: Optional[str] = None
    displayName_product: Optional[str] = None
    groupType: Optional[str] = None

    class Config:
        orm_mode = True
        exclude_none = True  # Exclude fields with None values from the output

# Function to get the access token
def get_access_token():
    try:
        response = requests.post(
            AUTH_URL,
            data={
                'grant_type': 'password',
                'username': USERNAME,
                'password': PASSWORD
            },
            headers={
                'Content-Type': 'application/x-www-form-urlencoded',
                'Authorization': AUTHORIZATION_CODE
            },
            verify=False  # Disable SSL verification for testing
        )
        response.raise_for_status()  # Check if the request was successful
        return response.json().get('access_token')
    except requests.RequestException as e:
        raise HTTPException(status_code=500, detail=f"Authentication error: {e}")

# Function to extract the first string from an array of dictionaries
def extract_string_from_dict(arr):
    if arr and isinstance(arr, list) and len(arr) > 0:
        item = arr[0]
        if isinstance(item, dict):
            return item.get('value')  # Adjust based on the actual key in the dictionary
    return None

# Function to map JSON response to MDMFields model
def map_json(response_data) -> List[MDMFields]:
    mapped_fields = []
    
    if response_data and 'objects' in response_data:
        for obj in response_data['objects']:
            attributes = obj.get('attributes', {})

            # Create MDMFields instance and map values
            mdm_field = MDMFields(
                displayName=extract_string_from_dict(attributes.get('DisplayName', [])),
                displayName_product=extract_string_from_dict(attributes.get('DisplayName', [])),
                therapeuticArea=extract_string_from_dict(attributes.get('TherapeuticArea', [])),
                groupStatus=extract_string_from_dict(attributes.get('GroupStatus', [])),
                pGJNFLAG=extract_string_from_dict(attributes.get('pGJNFLAG', [])),
                groupType=extract_string_from_dict(attributes.get('GroupType', [])),
                uri=obj.get('uri', None)
            )

            # If `uri` exists, trim the first 9 characters
            if mdm_field.uri:
                mdm_field.uri = mdm_field.uri[9:]

            # Only append if there are non-null values
            if any(value is not None for value in [
                mdm_field.displayName,
                mdm_field.therapeuticArea,
                mdm_field.groupStatus,
                mdm_field.pGJNFLAG,
                mdm_field.uri,
                mdm_field.displayName_product,
                mdm_field.groupType
            ]):
                mapped_fields.append(mdm_field)

    return mapped_fields

# Function to make the API call
def api_call(product_name: str = None, reltio_id: str = None):
    request_param = "equals(type,'configuration/entityTypes/ProductGroup') and equals(attributes.GroupType,'Brand')"

    if reltio_id:
        request_param += f" and contains (uri,'*{reltio_id}*')"

    if product_name:
        request_param += f" and contains(attributes.Name,'*{product_name}*')"

    try:
        access_token = get_access_token()
        
        response = requests.post(
            TENANT_URL,
            json=None,  # Adjust this based on your API's requirements
            headers={
                'Authorization': f'Bearer {access_token}',
                'Content-Type': 'application/json'
            },
            params={'filter': request_param},
            verify=False  # Disable SSL verification for testing
        )
        response.raise_for_status()  # Check if the request was successful
        return response.json()

    except requests.RequestException as e:
        raise HTTPException(status_code=500, detail=str(e))

# Define GraphQL types and schema
@strawberry.type
class MDMFieldType:
    displayName: Optional[str]
    therapeuticArea: Optional[str]
    groupStatus: Optional[str]
    pGJNFLAG: Optional[str]
    uri: Optional[str]
    displayName_product: Optional[str]
    groupType: Optional[str]

@strawberry.type
class Query:
    @strawberry.field
    def search_products(self, product_name: Optional[str] = None, reltio_id: Optional[str] = None) -> List[MDMFieldType]:
        try:
            response_data = api_call(product_name, reltio_id)
            mapped_fields = map_json(response_data)

            # Return a list of MDMFieldType while excluding null values
            return [
                MDMFieldType(
                    displayName=field.displayName,
                    therapeuticArea=field.therapeuticArea,
                    groupStatus=field.groupStatus,
                    pGJNFLAG=field.pGJNFLAG,
                    uri=field.uri,
                    displayName_product=field.displayName_product,
                    groupType=field.groupType
                ) for field in mapped_fields
            ]
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))

schema = strawberry.Schema(query=Query)

# Create a GraphQL router
graphql_app = GraphQLRouter(schema)

# Include the GraphQL router in the FastAPI app
app.include_router(graphql_app, prefix="/graphql")
Leave a Comment