diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index e564f56b..40c4103b 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -24,4 +24,4 @@ jobs: pip install ruff - name: Running Ruff Check run: | - ruff check $(git ls-files '*.py') + ruff check diff --git a/data/ccai_service_kit/conf_score_cfx/main.py b/data/ccai_service_kit/conf_score_cfx/main.py index c28f5f96..ebf6d07d 100644 --- a/data/ccai_service_kit/conf_score_cfx/main.py +++ b/data/ccai_service_kit/conf_score_cfx/main.py @@ -16,6 +16,7 @@ import json import logging + from dfcx_scrapi.tools.webhook_util import WebhookUtil # logging config diff --git a/data/get_weather_tool.py b/data/get_weather_tool.py index d95d37b7..60fd841a 100644 --- a/data/get_weather_tool.py +++ b/data/get_weather_tool.py @@ -1,12 +1,12 @@ """Sample Tool for Agent Builder.""" import logging + import requests -from google.auth import default as google_default_auth -from google.auth.transport.requests import Request as GoogleRequest -from flask import Flask, request from firebase_admin import initialize_app from firebase_functions import https_fn - +from flask import Flask, request +from google.auth import default as google_default_auth +from google.auth.transport.requests import Request as GoogleRequest initialize_app() app = Flask(__name__) diff --git a/examples/bot_building_series/bot_building_101.py b/examples/bot_building_series/bot_building_101.py index 24673c95..5acf1b1e 100644 --- a/examples/bot_building_series/bot_building_101.py +++ b/examples/bot_building_series/bot_building_101.py @@ -14,15 +14,17 @@ # limitations under the License. import sys + import pandas as pd from dfcx_scrapi.core.agents import Agents -from dfcx_scrapi.core.intents import Intents from dfcx_scrapi.core.flows import Flows +from dfcx_scrapi.core.intents import Intents from dfcx_scrapi.core.pages import Pages from dfcx_scrapi.tools.dataframe_functions import DataframeFunctions from dfcx_scrapi.tools.maker_util import MakerUtil + def build_agent(creds_path, project_id): """Build a simple agent.""" diff --git a/examples/bot_building_series/bot_building_102_intents_with_annotated_tp.py b/examples/bot_building_series/bot_building_102_intents_with_annotated_tp.py index ef3cf814..79b1d3ef 100644 --- a/examples/bot_building_series/bot_building_102_intents_with_annotated_tp.py +++ b/examples/bot_building_series/bot_building_102_intents_with_annotated_tp.py @@ -17,7 +17,9 @@ # limitations under the License. import sys + import pandas as pd + from dfcx_scrapi.core.agents import Agents from dfcx_scrapi.tools.dataframe_functions import DataframeFunctions @@ -40,18 +42,18 @@ def build_agent(creds_path, project_id, gcp_region, display_name): # Next, we will set some variables for our agent creation or retrieval args # Then we will call the `create_agent` and capture the result in a var call - # `my_agent` + # `my_agent` my_agent = agent_instance.create_agent(project_id, display_name, gcp_region) # Option 2: If agent already exists # The agent ID must be entered as a string # "projects//locations//agents/" # my_agent = a.get_agent( - # "projects//locations//agents/") + # "projects//locations//agents/") # ## Create Your First Intent # For this demo agent, we'll build a basic intent from list of Training - # Phrases (TPs) + # Phrases (TPs) # To simplify the Intent creation, we'll utilize the `DataframeFunctions` # class from the `tools` portion of the SCRAPI library. diff --git a/pyproject.toml b/pyproject.toml index 3a08d453..c5b2769f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,16 @@ build-backend = "setuptools.build_meta" [tool.ruff] line-length = 80 -extend-exclude = ["*.ipynb"] +extend-exclude = ["tests", "*.ipynb"] + +[tool.ruff.lint] +select = [ + "E", # pycodestyle + "F", # Pyflakes + "I", # isort + "W" # warn + ] +ignore = [] [tool.ruff.format] quote-style = "double" diff --git a/setup.py b/setup.py index 3224edce..0ab4c793 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,8 @@ # limitations under the License. import pathlib -from setuptools import setup, find_packages + +from setuptools import find_packages, setup here = pathlib.Path(__file__).parent.resolve() diff --git a/src/agent_assist/agent_assist.py b/src/agent_assist/agent_assist.py index c346e94a..947953d6 100644 --- a/src/agent_assist/agent_assist.py +++ b/src/agent_assist/agent_assist.py @@ -15,14 +15,16 @@ # limitations under the License. import logging - -from dfcx_scrapi.core import scrapi_base from typing import Dict -from google.cloud.dialogflow_v2beta1 import services -from google.cloud.dialogflow_v2beta1 import types -from google.cloud.dialogflow_v2beta1.services.knowledge_bases import KnowledgeBasesClient + +from google.cloud.dialogflow_v2beta1 import services, types +from google.cloud.dialogflow_v2beta1.services.knowledge_bases import ( + KnowledgeBasesClient, +) from google.protobuf import field_mask_pb2 +from dfcx_scrapi.core import scrapi_base + # logging config logging.basicConfig( level=logging.INFO, @@ -169,7 +171,7 @@ def create_conversation_profile( query_config.max_results = max_results feature_config.query_config = query_config - conversation_profile.human_agent_assistant_config.human_agent_suggestion_config.feature_configs = [feature_config] # pylint: disable=C0301 + conversation_profile.human_agent_assistant_config.human_agent_suggestion_config.feature_configs = [feature_config] # noqa: E501 request = types.conversation_profile.CreateConversationProfileRequest( parent= project_path, diff --git a/src/dfcx_scrapi/agent_extract/agents.py b/src/dfcx_scrapi/agent_extract/agents.py index 0bcf8879..e75bf2d8 100644 --- a/src/dfcx_scrapi/agent_extract/agents.py +++ b/src/dfcx_scrapi/agent_extract/agents.py @@ -15,22 +15,22 @@ # limitations under the License. import logging -import time import os import shutil +import time from typing import Dict -from dfcx_scrapi.core import agents -from dfcx_scrapi.core import operations -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.agent_extract import graph -from dfcx_scrapi.agent_extract import flows -from dfcx_scrapi.agent_extract import intents -from dfcx_scrapi.agent_extract import entity_types -from dfcx_scrapi.agent_extract import test_cases -from dfcx_scrapi.agent_extract import webhooks -from dfcx_scrapi.agent_extract import gcs_utils -from dfcx_scrapi.agent_extract import types +from dfcx_scrapi.agent_extract import ( + entity_types, + flows, + gcs_utils, + graph, + intents, + test_cases, + types, + webhooks, +) +from dfcx_scrapi.core import agents, operations, scrapi_base # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/agent_extract/common.py b/src/dfcx_scrapi/agent_extract/common.py index 26b86ff3..0a97b7af 100644 --- a/src/dfcx_scrapi/agent_extract/common.py +++ b/src/dfcx_scrapi/agent_extract/common.py @@ -16,6 +16,7 @@ import logging import re + from dfcx_scrapi.agent_extract import types # logging config diff --git a/src/dfcx_scrapi/agent_extract/entity_types.py b/src/dfcx_scrapi/agent_extract/entity_types.py index 17469b58..43b9edd2 100644 --- a/src/dfcx_scrapi/agent_extract/entity_types.py +++ b/src/dfcx_scrapi/agent_extract/entity_types.py @@ -16,11 +16,10 @@ import json import os - from typing import Dict -from dfcx_scrapi.agent_extract import common -from dfcx_scrapi.agent_extract import types +from dfcx_scrapi.agent_extract import common, types + class EntityTypes: """Entity Type processing methods and functions.""" diff --git a/src/dfcx_scrapi/agent_extract/flows.py b/src/dfcx_scrapi/agent_extract/flows.py index 6d991dac..4a74df41 100644 --- a/src/dfcx_scrapi/agent_extract/flows.py +++ b/src/dfcx_scrapi/agent_extract/flows.py @@ -16,15 +16,16 @@ import json import os - from typing import List -from dfcx_scrapi.agent_extract import graph -from dfcx_scrapi.agent_extract import common -from dfcx_scrapi.agent_extract import types -from dfcx_scrapi.agent_extract import pages -from dfcx_scrapi.agent_extract import routes -from dfcx_scrapi.agent_extract import route_groups +from dfcx_scrapi.agent_extract import ( + common, + graph, + pages, + route_groups, + routes, + types, +) class Flows: diff --git a/src/dfcx_scrapi/agent_extract/gcs_utils.py b/src/dfcx_scrapi/agent_extract/gcs_utils.py index c3daff89..6a351539 100644 --- a/src/dfcx_scrapi/agent_extract/gcs_utils.py +++ b/src/dfcx_scrapi/agent_extract/gcs_utils.py @@ -15,6 +15,7 @@ # limitations under the License. import zipfile + from google.cloud import storage from google.oauth2 import service_account diff --git a/src/dfcx_scrapi/agent_extract/graph.py b/src/dfcx_scrapi/agent_extract/graph.py index b94217ce..828528c6 100644 --- a/src/dfcx_scrapi/agent_extract/graph.py +++ b/src/dfcx_scrapi/agent_extract/graph.py @@ -16,6 +16,7 @@ import collections + class Graph: """Utility class for manaing graph structure.""" diff --git a/src/dfcx_scrapi/agent_extract/intents.py b/src/dfcx_scrapi/agent_extract/intents.py index e8d46dca..7023a26a 100644 --- a/src/dfcx_scrapi/agent_extract/intents.py +++ b/src/dfcx_scrapi/agent_extract/intents.py @@ -17,8 +17,7 @@ import json import os -from dfcx_scrapi.agent_extract import common -from dfcx_scrapi.agent_extract import types +from dfcx_scrapi.agent_extract import common, types class Intents: diff --git a/src/dfcx_scrapi/agent_extract/pages.py b/src/dfcx_scrapi/agent_extract/pages.py index 51a710c6..d0ee6b6d 100644 --- a/src/dfcx_scrapi/agent_extract/pages.py +++ b/src/dfcx_scrapi/agent_extract/pages.py @@ -16,12 +16,9 @@ import json import os +from typing import Any, Dict -from typing import Dict, Any - -from dfcx_scrapi.agent_extract import common -from dfcx_scrapi.agent_extract import types -from dfcx_scrapi.agent_extract import routes +from dfcx_scrapi.agent_extract import common, routes, types class Pages: diff --git a/src/dfcx_scrapi/agent_extract/route_groups.py b/src/dfcx_scrapi/agent_extract/route_groups.py index 3a73e50a..fdefaf90 100644 --- a/src/dfcx_scrapi/agent_extract/route_groups.py +++ b/src/dfcx_scrapi/agent_extract/route_groups.py @@ -14,12 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os import json +import os -from dfcx_scrapi.agent_extract import common -from dfcx_scrapi.agent_extract import types -from dfcx_scrapi.agent_extract import routes +from dfcx_scrapi.agent_extract import common, routes, types class RouteGroups: diff --git a/src/dfcx_scrapi/agent_extract/routes.py b/src/dfcx_scrapi/agent_extract/routes.py index ef37b1a6..15987d25 100644 --- a/src/dfcx_scrapi/agent_extract/routes.py +++ b/src/dfcx_scrapi/agent_extract/routes.py @@ -14,10 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, Any +from typing import Any, Dict -from dfcx_scrapi.agent_extract import common -from dfcx_scrapi.agent_extract import types +from dfcx_scrapi.agent_extract import common, types class Fulfillments: diff --git a/src/dfcx_scrapi/agent_extract/test_cases.py b/src/dfcx_scrapi/agent_extract/test_cases.py index ee5be205..6eda8d35 100644 --- a/src/dfcx_scrapi/agent_extract/test_cases.py +++ b/src/dfcx_scrapi/agent_extract/test_cases.py @@ -16,11 +16,9 @@ import json import os +from typing import Any, Dict, List -from typing import Dict, List, Any - -from dfcx_scrapi.agent_extract import common -from dfcx_scrapi.agent_extract import types +from dfcx_scrapi.agent_extract import common, types class TestCases: diff --git a/src/dfcx_scrapi/agent_extract/types.py b/src/dfcx_scrapi/agent_extract/types.py index ac25c34d..8935ace1 100644 --- a/src/dfcx_scrapi/agent_extract/types.py +++ b/src/dfcx_scrapi/agent_extract/types.py @@ -14,11 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, List, Any, Tuple from dataclasses import dataclass, field +from typing import Any, Dict, List, Tuple from dfcx_scrapi.agent_extract import graph as graph_class + @dataclass class AgentMetadata: """Used to track the current Agent Metadata attrinbutes.""" diff --git a/src/dfcx_scrapi/agent_extract/webhooks.py b/src/dfcx_scrapi/agent_extract/webhooks.py index 38467080..d8ee2996 100644 --- a/src/dfcx_scrapi/agent_extract/webhooks.py +++ b/src/dfcx_scrapi/agent_extract/webhooks.py @@ -17,8 +17,8 @@ import json import os -from dfcx_scrapi.agent_extract import common -from dfcx_scrapi.agent_extract import types +from dfcx_scrapi.agent_extract import common, types + class Webhooks: """Webhook linter methods and functions.""" diff --git a/src/dfcx_scrapi/builders/agents.py b/src/dfcx_scrapi/builders/agents.py index 76a9c274..2a15d980 100644 --- a/src/dfcx_scrapi/builders/agents.py +++ b/src/dfcx_scrapi/builders/agents.py @@ -17,8 +17,8 @@ import logging from typing import List -from google.cloud.dialogflowcx_v3beta1.types import Agent -from google.cloud.dialogflowcx_v3beta1.types import SpeechToTextSettings +from google.cloud.dialogflowcx_v3beta1.types import Agent, SpeechToTextSettings + from dfcx_scrapi.builders.builders_common import BuildersCommon # logging config diff --git a/src/dfcx_scrapi/builders/builders_common.py b/src/dfcx_scrapi/builders/builders_common.py index d14ea69c..307f06ee 100644 --- a/src/dfcx_scrapi/builders/builders_common.py +++ b/src/dfcx_scrapi/builders/builders_common.py @@ -17,8 +17,10 @@ import logging from typing import List, Union -from google.cloud.dialogflowcx_v3beta1.types import TransitionRoute -from google.cloud.dialogflowcx_v3beta1.types import EventHandler +from google.cloud.dialogflowcx_v3beta1.types import ( + EventHandler, + TransitionRoute, +) # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/builders/entity_types.py b/src/dfcx_scrapi/builders/entity_types.py index f28ef6b2..c995aa83 100644 --- a/src/dfcx_scrapi/builders/entity_types.py +++ b/src/dfcx_scrapi/builders/entity_types.py @@ -18,6 +18,7 @@ from typing import List, Union from google.cloud.dialogflowcx_v3beta1.types import EntityType + from dfcx_scrapi.builders.builders_common import BuildersCommon # logging config diff --git a/src/dfcx_scrapi/builders/flows.py b/src/dfcx_scrapi/builders/flows.py index 2f7c702f..2164137d 100644 --- a/src/dfcx_scrapi/builders/flows.py +++ b/src/dfcx_scrapi/builders/flows.py @@ -18,14 +18,19 @@ from dataclasses import dataclass from typing import List, Union -from google.cloud.dialogflowcx_v3beta1.types import Flow -from google.cloud.dialogflowcx_v3beta1.types import NluSettings -from google.cloud.dialogflowcx_v3beta1.types import TransitionRoute -from google.cloud.dialogflowcx_v3beta1.types import EventHandler +from google.cloud.dialogflowcx_v3beta1.types import ( + EventHandler, + Flow, + NluSettings, + TransitionRoute, +) + from dfcx_scrapi.builders.builders_common import BuildersCommon -from dfcx_scrapi.builders.routes import TransitionRouteBuilder -from dfcx_scrapi.builders.routes import EventHandlerBuilder from dfcx_scrapi.builders.fulfillments import FulfillmentBuilder +from dfcx_scrapi.builders.routes import ( + EventHandlerBuilder, + TransitionRouteBuilder, +) # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/builders/fulfillments.py b/src/dfcx_scrapi/builders/fulfillments.py index 6b2194d0..cd6433d0 100644 --- a/src/dfcx_scrapi/builders/fulfillments.py +++ b/src/dfcx_scrapi/builders/fulfillments.py @@ -15,10 +15,10 @@ # limitations under the License. import logging -from typing import List, Dict, Any +from typing import Any, Dict, List + +from google.cloud.dialogflowcx_v3beta1.types import Fulfillment, ResponseMessage -from google.cloud.dialogflowcx_v3beta1.types import Fulfillment -from google.cloud.dialogflowcx_v3beta1.types import ResponseMessage from dfcx_scrapi.builders.builders_common import BuildersCommon from dfcx_scrapi.builders.response_messages import ResponseMessageBuilder diff --git a/src/dfcx_scrapi/builders/generative_settings.py b/src/dfcx_scrapi/builders/generative_settings.py index 6cbcf4bb..4f025a71 100644 --- a/src/dfcx_scrapi/builders/generative_settings.py +++ b/src/dfcx_scrapi/builders/generative_settings.py @@ -17,8 +17,13 @@ import logging from typing import List -from google.cloud.dialogflowcx_v3beta1.types.generative_settings import GenerativeSettings -from google.cloud.dialogflowcx_v3beta1.types.safety_settings import SafetySettings +from google.cloud.dialogflowcx_v3beta1.types.generative_settings import ( + GenerativeSettings, +) +from google.cloud.dialogflowcx_v3beta1.types.safety_settings import ( + SafetySettings, +) + from dfcx_scrapi.builders.builders_common import BuildersCommon # logging config diff --git a/src/dfcx_scrapi/builders/intents.py b/src/dfcx_scrapi/builders/intents.py index 80fd32f9..6be2f1cc 100644 --- a/src/dfcx_scrapi/builders/intents.py +++ b/src/dfcx_scrapi/builders/intents.py @@ -15,14 +15,13 @@ # limitations under the License. import logging -from string import ascii_lowercase -from string import digits from collections import defaultdict -from dataclasses import dataclass -from dataclasses import field -from typing import List, Dict, Union +from dataclasses import dataclass, field +from string import ascii_lowercase, digits +from typing import Dict, List, Union from google.cloud.dialogflowcx_v3beta1.types import Intent + from dfcx_scrapi.builders.builders_common import BuildersCommon # logging config diff --git a/src/dfcx_scrapi/builders/pages.py b/src/dfcx_scrapi/builders/pages.py index c9093683..f2481d2e 100644 --- a/src/dfcx_scrapi/builders/pages.py +++ b/src/dfcx_scrapi/builders/pages.py @@ -18,15 +18,20 @@ from dataclasses import dataclass from typing import List, Union -from google.cloud.dialogflowcx_v3beta1.types import Page -from google.cloud.dialogflowcx_v3beta1.types import Form -from google.cloud.dialogflowcx_v3beta1.types import Fulfillment -from google.cloud.dialogflowcx_v3beta1.types import TransitionRoute -from google.cloud.dialogflowcx_v3beta1.types import EventHandler +from google.cloud.dialogflowcx_v3beta1.types import ( + EventHandler, + Form, + Fulfillment, + Page, + TransitionRoute, +) + from dfcx_scrapi.builders.builders_common import BuildersCommon -from dfcx_scrapi.builders.routes import TransitionRouteBuilder -from dfcx_scrapi.builders.routes import EventHandlerBuilder from dfcx_scrapi.builders.fulfillments import FulfillmentBuilder +from dfcx_scrapi.builders.routes import ( + EventHandlerBuilder, + TransitionRouteBuilder, +) # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/builders/response_messages.py b/src/dfcx_scrapi/builders/response_messages.py index 672b2558..426d9abf 100644 --- a/src/dfcx_scrapi/builders/response_messages.py +++ b/src/dfcx_scrapi/builders/response_messages.py @@ -14,12 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import re import logging -from typing import List, Dict, Union, Any +import re +from typing import Any, Dict, List, Union from google.cloud.dialogflowcx_v3beta1.types import ResponseMessage from google.protobuf import struct_pb2 + from dfcx_scrapi.builders.builders_common import BuildersCommon # logging config diff --git a/src/dfcx_scrapi/builders/routes.py b/src/dfcx_scrapi/builders/routes.py index 735bee26..424b6b8e 100644 --- a/src/dfcx_scrapi/builders/routes.py +++ b/src/dfcx_scrapi/builders/routes.py @@ -16,9 +16,12 @@ import logging -from google.cloud.dialogflowcx_v3beta1.types import Fulfillment -from google.cloud.dialogflowcx_v3beta1.types import TransitionRoute -from google.cloud.dialogflowcx_v3beta1.types import EventHandler +from google.cloud.dialogflowcx_v3beta1.types import ( + EventHandler, + Fulfillment, + TransitionRoute, +) + from dfcx_scrapi.builders.builders_common import BuildersCommon from dfcx_scrapi.builders.fulfillments import FulfillmentBuilder diff --git a/src/dfcx_scrapi/builders/transition_route_groups.py b/src/dfcx_scrapi/builders/transition_route_groups.py index dd3a882a..6945546f 100644 --- a/src/dfcx_scrapi/builders/transition_route_groups.py +++ b/src/dfcx_scrapi/builders/transition_route_groups.py @@ -17,8 +17,11 @@ import logging from typing import List, Union -from google.cloud.dialogflowcx_v3beta1.types import TransitionRoute -from google.cloud.dialogflowcx_v3beta1.types import TransitionRouteGroup +from google.cloud.dialogflowcx_v3beta1.types import ( + TransitionRoute, + TransitionRouteGroup, +) + from dfcx_scrapi.builders.builders_common import BuildersCommon from dfcx_scrapi.builders.routes import TransitionRouteBuilder diff --git a/src/dfcx_scrapi/core/agents.py b/src/dfcx_scrapi/core/agents.py index 63787886..856c93db 100644 --- a/src/dfcx_scrapi/core/agents.py +++ b/src/dfcx_scrapi/core/agents.py @@ -16,13 +16,12 @@ import logging from typing import Dict, List -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types -from google.protobuf import field_mask_pb2 + from google.cloud import bigquery +from google.cloud.dialogflowcx_v3beta1 import services, types +from google.protobuf import field_mask_pb2 -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import environments +from dfcx_scrapi.core import environments, scrapi_base # logging config logging.basicConfig( @@ -95,7 +94,7 @@ def modify_bq_settings_kwargs( return bq_settings def get_bq_dataset_table_map(self, agent_id: str) -> Dict[str, str]: - """Get all dataset/tables accessible from the provided agent_id.""" + """Get all dataset/tables accessible from the provided agent_id.""" parts = self._parse_resource_path("agent", agent_id) project_id = parts.get("project", None) @@ -705,8 +704,8 @@ def get_bq_settings( return { "advanced_settings": { "logging_settings": { - "enable_stackdriver_logging": agent.advanced_settings.logging_settings.enable_stackdriver_logging, - "enable_interaction_logging": agent.advanced_settings.logging_settings.enable_interaction_logging + "enable_stackdriver_logging": agent.advanced_settings.logging_settings.enable_stackdriver_logging, # noqa: E501 + "enable_interaction_logging": agent.advanced_settings.logging_settings.enable_interaction_logging # noqa: E501 } }, "bigquery_export_settings": { @@ -735,7 +734,7 @@ def update_bq_settings( agent. Use `get_bq_settings` to get the proper input format for this option. enable_stackdriver_logging: (Optional) Boolean indicating whether - Stackdriver logging is enabled. + Stackdriver logging is enabled. enable_interaction_logging: (Optional) Boolean indicating whether interaction logging is enabled. biqquery_enabled: (Optional) Boolean indicating whether BigQuery @@ -756,7 +755,7 @@ def update_bq_settings( if not agent_id: agent_id = self.agent_id - + if not bq_settings and not any(BIGQUERY_INPUTS): raise ValueError( "At least one setting must be provided if 'bq_settings' is"\ @@ -780,5 +779,5 @@ def update_bq_settings( advanced_settings = bq_settings["advanced_settings"], bigquery_export_settings = bq_settings["bigquery_export_settings"] ) - + return agent diff --git a/src/dfcx_scrapi/core/changelogs.py b/src/dfcx_scrapi/core/changelogs.py index db7ccf55..72f74922 100644 --- a/src/dfcx_scrapi/core/changelogs.py +++ b/src/dfcx_scrapi/core/changelogs.py @@ -16,13 +16,11 @@ import datetime import logging - from typing import Dict import pandas as pd +from google.cloud.dialogflowcx_v3beta1 import services, types -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types from dfcx_scrapi.core import scrapi_base # logging config diff --git a/src/dfcx_scrapi/core/conversation.py b/src/dfcx_scrapi/core/conversation.py index 6baa25f2..75506305 100644 --- a/src/dfcx_scrapi/core/conversation.py +++ b/src/dfcx_scrapi/core/conversation.py @@ -18,21 +18,15 @@ import time import traceback import uuid - -from typing import Dict, Any from threading import Thread +from typing import Any, Dict import pandas as pd - -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types from google.api_core import exceptions as core_exceptions -from proto.marshal.collections import repeated -from proto.marshal.collections import maps +from google.cloud.dialogflowcx_v3beta1 import services, types +from proto.marshal.collections import maps, repeated -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import flows -from dfcx_scrapi.core import pages +from dfcx_scrapi.core import flows, pages, scrapi_base logging.basicConfig( format="[dfcx] %(levelname)s:%(message)s", level=logging.INFO @@ -652,7 +646,7 @@ def _unpack_match(self, df: pd.DataFrame): .assign( match_type = lambda df: df.match.apply( # pylint: disable=W0212 - lambda match_value: match_value.match_type._name_ + lambda match_value: match_value.match_type._name_ if match_value else "" ), confidence = lambda df: df.match.apply( diff --git a/src/dfcx_scrapi/core/conversation_history.py b/src/dfcx_scrapi/core/conversation_history.py index fe0018fd..80667c5d 100644 --- a/src/dfcx_scrapi/core/conversation_history.py +++ b/src/dfcx_scrapi/core/conversation_history.py @@ -17,13 +17,11 @@ import json import logging import os -from typing import Dict, List, Any +from typing import Any, Dict, List +from google.cloud.dialogflowcx_v3beta1 import services, types from tqdm.contrib.concurrent import thread_map -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types - from dfcx_scrapi.core import scrapi_base # logging config diff --git a/src/dfcx_scrapi/core/data_stores.py b/src/dfcx_scrapi/core/data_stores.py index b1561d8b..75c4660a 100644 --- a/src/dfcx_scrapi/core/data_stores.py +++ b/src/dfcx_scrapi/core/data_stores.py @@ -16,15 +16,16 @@ import logging from typing import Dict, List -from google.longrunning.operations_pb2 import Operation + from google.cloud.discoveryengine import ( + CreateDataStoreRequest, DataStore, DataStoreServiceClient, - ListDataStoresRequest, + DeleteDataStoreRequest, GetDataStoreRequest, - CreateDataStoreRequest, - DeleteDataStoreRequest - ) + ListDataStoresRequest, +) +from google.longrunning.operations_pb2 import Operation from dfcx_scrapi.core import scrapi_base diff --git a/src/dfcx_scrapi/core/engines.py b/src/dfcx_scrapi/core/engines.py index 6439a480..e255eece 100644 --- a/src/dfcx_scrapi/core/engines.py +++ b/src/dfcx_scrapi/core/engines.py @@ -16,15 +16,16 @@ import logging from typing import Dict, List -from google.longrunning.operations_pb2 import Operation + from google.cloud.discoveryengine import ( + CreateEngineRequest, + DeleteEngineRequest, Engine, EngineServiceClient, - ListEnginesRequest, GetEngineRequest, - CreateEngineRequest, - DeleteEngineRequest - ) + ListEnginesRequest, +) +from google.longrunning.operations_pb2 import Operation from dfcx_scrapi.core import scrapi_base @@ -126,14 +127,17 @@ def build_chat_engine_proto( return engine - def build_search_engine_proto(self, display_name: str, data_store_ids: List[str], - search_tier: str = "SEARCH_TIER_STANDARD"): + def build_search_engine_proto( + self, display_name: str, data_store_ids: List[str], + search_tier: str = "SEARCH_TIER_STANDARD"): """Build the Search Engine proto for creating a new Engine. Args: - display_name: the human readable display name of the Search Engine - data_store_ids: a list of Data Store IDs associated with this engine. - search_tier: either SEARCH_TIER_STANDARD (default) or SEARCH_TIER_ENTERPRISE + display_name: the human readable display name of the Search Engine + data_store_ids: a list of Data Store IDs associated with this + engine. + search_tier: either SEARCH_TIER_STANDARD (default) or + SEARCH_TIER_ENTERPRISE Returns: The Engine object configured as a SearchEngine. diff --git a/src/dfcx_scrapi/core/entity_types.py b/src/dfcx_scrapi/core/entity_types.py index 6662ccd5..9bec1a95 100644 --- a/src/dfcx_scrapi/core/entity_types.py +++ b/src/dfcx_scrapi/core/entity_types.py @@ -18,8 +18,7 @@ from typing import Dict, List import pandas as pd -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 from dfcx_scrapi.core import scrapi_base diff --git a/src/dfcx_scrapi/core/environments.py b/src/dfcx_scrapi/core/environments.py index 034e6c68..5aa361f3 100644 --- a/src/dfcx_scrapi/core/environments.py +++ b/src/dfcx_scrapi/core/environments.py @@ -14,15 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import List, Dict, Tuple import logging +from typing import Dict, List, Tuple + +from google.cloud.dialogflowcx_v3beta1 import services, types from google.oauth2 import service_account -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import flows -from dfcx_scrapi.core import versions +from dfcx_scrapi.core import flows, scrapi_base, versions # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/core/examples.py b/src/dfcx_scrapi/core/examples.py index 0671557f..1db07663 100644 --- a/src/dfcx_scrapi/core/examples.py +++ b/src/dfcx_scrapi/core/examples.py @@ -14,15 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import playbooks -from dfcx_scrapi.core import tools -from typing import Dict, List, Any +from typing import Any, Dict, List -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 +from dfcx_scrapi.core import playbooks, scrapi_base, tools + class Examples(scrapi_base.ScrapiBase): """Core Class for CX Examples Resource functions.""" diff --git a/src/dfcx_scrapi/core/experiments.py b/src/dfcx_scrapi/core/experiments.py index eac0c84e..b3122ce2 100644 --- a/src/dfcx_scrapi/core/experiments.py +++ b/src/dfcx_scrapi/core/experiments.py @@ -17,8 +17,9 @@ import json import logging from typing import Dict -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types + +from google.cloud.dialogflowcx_v3beta1 import services, types + from dfcx_scrapi.core import scrapi_base # logging config diff --git a/src/dfcx_scrapi/core/flows.py b/src/dfcx_scrapi/core/flows.py index 58bd266d..7bf206da 100644 --- a/src/dfcx_scrapi/core/flows.py +++ b/src/dfcx_scrapi/core/flows.py @@ -17,11 +17,11 @@ import logging import time from typing import Dict, List -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types + +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import pages + +from dfcx_scrapi.core import pages, scrapi_base # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/core/generators.py b/src/dfcx_scrapi/core/generators.py index 5b8c71c2..6ae2a9dd 100644 --- a/src/dfcx_scrapi/core/generators.py +++ b/src/dfcx_scrapi/core/generators.py @@ -14,12 +14,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import re import logging -from typing import Dict, List, Any +import re +from typing import Any, Dict, List -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 from dfcx_scrapi.core import scrapi_base diff --git a/src/dfcx_scrapi/core/intents.py b/src/dfcx_scrapi/core/intents.py index ef0d4a70..a6dd36cd 100644 --- a/src/dfcx_scrapi/core/intents.py +++ b/src/dfcx_scrapi/core/intents.py @@ -14,13 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from collections import defaultdict import logging +from collections import defaultdict from typing import Dict, List, Tuple -import pandas as pd -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +import pandas as pd +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 from dfcx_scrapi.core import scrapi_base diff --git a/src/dfcx_scrapi/core/operations.py b/src/dfcx_scrapi/core/operations.py index 05f2577f..68b3d3ec 100644 --- a/src/dfcx_scrapi/core/operations.py +++ b/src/dfcx_scrapi/core/operations.py @@ -17,7 +17,7 @@ import logging from typing import Dict -from google.api_core import operations_v1, grpc_helpers +from google.api_core import grpc_helpers, operations_v1 from dfcx_scrapi.core import scrapi_base diff --git a/src/dfcx_scrapi/core/pages.py b/src/dfcx_scrapi/core/pages.py index 1b425dc0..fa0662d0 100644 --- a/src/dfcx_scrapi/core/pages.py +++ b/src/dfcx_scrapi/core/pages.py @@ -16,6 +16,7 @@ import logging from typing import Dict, List + from google.cloud.dialogflowcx_v3beta1.services import pages from google.cloud.dialogflowcx_v3beta1.types import page as gcdc_page from google.protobuf import field_mask_pb2 diff --git a/src/dfcx_scrapi/core/playbooks.py b/src/dfcx_scrapi/core/playbooks.py index 4458097b..0b44051a 100644 --- a/src/dfcx_scrapi/core/playbooks.py +++ b/src/dfcx_scrapi/core/playbooks.py @@ -17,8 +17,7 @@ import logging from typing import Dict, List -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 from dfcx_scrapi.core import scrapi_base diff --git a/src/dfcx_scrapi/core/scrapi_base.py b/src/dfcx_scrapi/core/scrapi_base.py index e67c4717..eeff0d9a 100644 --- a/src/dfcx_scrapi/core/scrapi_base.py +++ b/src/dfcx_scrapi/core/scrapi_base.py @@ -14,36 +14,32 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging +import functools import json +import logging import re -import time -import functools import threading -import vertexai -import requests +import time from collections import defaultdict -from typing import Dict, Any, Iterable, List, Optional +from typing import Any, Dict, Iterable, List, Optional -from google.auth import default +import requests +import vertexai from google.api_core import exceptions +from google.auth import default +from google.auth.transport.requests import Request from google.cloud.dialogflowcx_v3beta1 import types from google.oauth2 import service_account -from google.auth.transport.requests import Request -from google.protobuf import json_format -from google.protobuf import field_mask_pb2, struct_pb2 - +from google.protobuf import field_mask_pb2, json_format, struct_pb2 +from proto.marshal.collections import maps, repeated from vertexai.generative_models import ( GenerativeModel, HarmBlockThreshold, HarmCategory, - SafetySetting - ) + SafetySetting, +) from vertexai.language_models import TextEmbeddingModel, TextGenerationModel -from proto.marshal.collections import repeated -from proto.marshal.collections import maps - _INTERVAL_SENTINEL = object() # The following models are supported for Metrics and Evaluations, either for @@ -286,72 +282,72 @@ def _parse_resource_path( standard_id_match = r"[-0-9a-f]{1,36}" version_id_match = r"[0-9]{1,4}" - matcher_root = f"^projects/(?P.+?)/locations/(?P{location_id_match})" + matcher_root = f"^projects/(?P.+?)/locations/(?P{location_id_match})" # noqa: E501 pattern_map = { "agent": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})$", - "format": "`projects//locations//agents/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})$", # noqa: E501 + "format": "`projects//locations//agents/`", # noqa: E501 }, "data_store": { - "matcher": fr"{matcher_root}/collections/default_collection/dataStores/(?P{data_store_match})$", - "format": "`projects//locations//collections/default_collection/dataStores/`" + "matcher": fr"{matcher_root}/collections/default_collection/dataStores/(?P{data_store_match})$", # noqa: E501 + "format": "`projects//locations//collections/default_collection/dataStores/`" # noqa: E501 }, "engine": { - "matcher": fr"{matcher_root}/collections/default_collection/engines/(?P{engine_match})$", - "format": "`projects//locations//collections/default_collection/engines/`" + "matcher": fr"{matcher_root}/collections/default_collection/engines/(?P{engine_match})$", # noqa: E501 + "format": "`projects//locations//collections/default_collection/engines/`" # noqa: E501 }, "entity_type": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/entityTypes/(?P{entity_id_match})$", - "format": "`projects//locations//agents//entityTypes/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/entityTypes/(?P{entity_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//entityTypes/`", # noqa: E501 }, "environment": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/environments/(?P{standard_id_match})$", - "format": "`projects//locations//agents//environments/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/environments/(?P{standard_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//environments/`", # noqa: E501 }, "flow": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/flows/(?P{standard_id_match})$", - "format": "`projects//locations//agents//flows/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/flows/(?P{standard_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//flows/`", # noqa: E501 }, "intent": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/intents/(?P{standard_id_match})$", - "format": "`projects//locations//agents//intents/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/intents/(?P{standard_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//intents/`", # noqa: E501 }, "page": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/flows/(?P{standard_id_match})/pages/(?P{page_id_match})$", - "format": "`projects//locations//agents//flows//pages/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/flows/(?P{standard_id_match})/pages/(?P{page_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//flows//pages/`", # noqa: E501 }, "project": { "matcher": fr"{matcher_root}$", "format": "`projects//locations//`", }, "security_setting": { - "matcher": fr"{matcher_root}/securitySettings/(?P{standard_id_match})$", - "format": "`projects//locations//securitySettings/`", + "matcher": fr"{matcher_root}/securitySettings/(?P{standard_id_match})$", # noqa: E501 + "format": "`projects//locations//securitySettings/`", # noqa: E501 }, "session": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/sessions/(?P{session_id_match})$", - "format": "`projects//locations//agents//sessions/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/sessions/(?P{session_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//sessions/`", # noqa: E501 }, "session_entity_type": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/sessions/(?P{session_id_match})/entityTypes/(?P{entity_id_match})$", - "format": "`projects//locations//agents//sessions//entityTypes/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/sessions/(?P{session_id_match})/entityTypes/(?P{entity_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//sessions//entityTypes/`", # noqa: E501 }, "test_case": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/testCases/(?P{standard_id_match})$", - "format": "`projects//locations//agents//testCases/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/testCases/(?P{standard_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//testCases/`", # noqa: E501 }, "transition_route_group": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/flows/(?P{standard_id_match})/transitionRouteGroups/(?P{standard_id_match})$", - "format": "`projects//locations//agents//flows//transitionRouteGroups/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/flows/(?P{standard_id_match})/transitionRouteGroups/(?P{standard_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//flows//transitionRouteGroups/`", # noqa: E501 }, "version": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/flows/(?P{standard_id_match})/versions/(?P{version_id_match})$", - "format": "`projects//locations//agents//flows/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/flows/(?P{standard_id_match})/versions/(?P{version_id_match})$", # noqa: E501 + "format": "`projects//locations//agents//flows/`", # noqa: E501 }, "webhook": { - "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/webhooks/(?P{standard_id_match})$", - "format": "`projects//locations//agents/`", + "matcher": fr"{matcher_root}/agents/(?P{standard_id_match})/webhooks/(?P{standard_id_match})$", # noqa: E501 + "format": "`projects//locations//agents/`", # noqa: E501 } } @@ -420,7 +416,7 @@ def is_valid_sys_instruct_model(llm_model: str) -> bool: valid_sys_instruct = False return valid_sys_instruct - + @staticmethod def _update_kwargs(obj, **kwargs) -> field_mask_pb2.FieldMask: """Create a FieldMask for Environment, Experiment, TestCase, Version.""" @@ -488,7 +484,7 @@ def build_safety_settings( """Build a SafetyConfig payload for Gemini SDK calls. If a safety_config dict is not provided, we'll set the defaults to OFF. - + Args: safety_config: (Optional) A key / value pair dictionary containing the category names and thresholds to set for each category. If not @@ -568,7 +564,8 @@ def _handle_requests_response(response: requests.Response): elif response.status_code == 404: return None else: - raise requests.exceptions.RequestException("API request failed", response.status_code, response) + raise requests.exceptions.RequestException( + "API request failed", response.status_code, response) def _set_request_headers(self, client_options: dict): """Different regions have different API endpoints diff --git a/src/dfcx_scrapi/core/search.py b/src/dfcx_scrapi/core/search.py index a1941a8f..53fb8c22 100644 --- a/src/dfcx_scrapi/core/search.py +++ b/src/dfcx_scrapi/core/search.py @@ -15,16 +15,18 @@ # limitations under the License. import re -from typing import Dict, Any, List, Union, Optional +from typing import Any, Dict, List, Optional, Union + from google.cloud.discoveryengine import ( - SearchServiceClient, + Document, DocumentServiceClient, + Interval, + ListDocumentsRequest, SearchRequest, + SearchServiceClient, UserInfo, - Interval, - Document, - ListDocumentsRequest - ) +) + from dfcx_scrapi.core import scrapi_base @@ -84,7 +86,7 @@ def build_interval(interval_dict: Dict[str, Any]) -> Interval: return Interval(exclusive_maximum=v) else: return None - + @staticmethod def search_url(urls: List[str], url: str, regex: bool = False) -> List[str]: """Searches a url in a list of urls.""" @@ -214,7 +216,7 @@ def get_spell_correct_mode_from_map( self, spell_spec_dict: Dict[str, Any] ) -> SearchRequest.SpellCorrectionSpec.Mode: mode_map = { - "SUGGESTION_ONLY": SearchRequest.SpellCorrectionSpec.Mode.SUGGESTION_ONLY, # pylint: disable=C0301 + "SUGGESTION_ONLY": SearchRequest.SpellCorrectionSpec.Mode.SUGGESTION_ONLY, # noqa: E501 "AUTO": SearchRequest.SpellCorrectionSpec.Mode.AUTO, } @@ -240,7 +242,7 @@ def build_model_prompt_spec( "model_prompt_spec", None ) if model_prompt_spec_dict: - return SearchRequest.ContentSearchSpec.SummarySpec.ModelPromptSpec( # pylint: disable=C0301 + return SearchRequest.ContentSearchSpec.SummarySpec.ModelPromptSpec( preamble=model_prompt_spec_dict.get("preamble", None) ) @@ -357,7 +359,7 @@ def build_embedding_spec( else: return None - + def list_documents( self, datastore_id: str, page_size: int = 1000) -> List[Document]: """List all documents in the provided datastore.""" @@ -380,7 +382,7 @@ def list_documents( all_docs.append(doc) return all_docs - + def list_indexed_urls( self, datastore_id: str, docs: Optional[List[Document]] = None ) -> List[str]: @@ -403,7 +405,7 @@ def search_doc_id( elif not docs and datastore_id: docs = self.list_documents(datastore_id) - + doc_found = False for doc in docs: if doc.parent_document_id == document_id: @@ -436,42 +438,41 @@ def check_datastore_index_status(self, datastore_id: str): print(SUCCESS_MESSAGE.replace("{DOCS}", str(len(docs)))) - # pylint: disable=C0301 def search(self, search_config: Dict[str, Any], total_results: int = 10): """Performs a search against an indexed Vertex Data Store. Args: - search_config: A dictionary containing keys that correspond to the - SearchRequest attributes as defined in: - https://cloud.google.com/python/docs/reference/discoveryengine/latest/google.cloud.discoveryengine.SearchRequest + search_config: A dictionary containing keys that correspond to the + SearchRequest attributes as defined in: https://cloud.google.com/python/docs/reference/discoveryengine/latest/google.cloud.discoveryengine.SearchRequest + For complex attributes that require nested fields, you can pass in another Dictionary as the value. - Example: To represent the complex facet_specs config with some - other simple parameters, you would do the following. + Example: To represent the complex facet_specs config with some + other simple parameters, you would do the following. ```py - search_config = { - "facet_specs": [ - { - "facet_key": { - "key": "my_key", - "intervals": [ - { - "minimum": .5 - }, - { - "maximum": .95 - } - ], - "case_insensitive": True - }, - "limit": 10 - } - ], - "page_size": 10, - "offset": 2 - } + search_config = { + "facet_specs": [ + { + "facet_key": { + "key": "my_key", + "intervals": [ + { + "minimum": .5 + }, + { + "maximum": .95 + } + ], + "case_insensitive": True + }, + "limit": 10 + } + ], + "page_size": 10, + "offset": 2 + } total_results: Total number of results to return for the search. If not specified, will default to 10 results. Increasing this to a high number can result in long search times. diff --git a/src/dfcx_scrapi/core/security_settings.py b/src/dfcx_scrapi/core/security_settings.py index 0617478f..8129bba8 100644 --- a/src/dfcx_scrapi/core/security_settings.py +++ b/src/dfcx_scrapi/core/security_settings.py @@ -14,14 +14,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict import json import logging -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from typing import Dict + +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 -from dfcx_scrapi.core import scrapi_base +from dfcx_scrapi.core import scrapi_base # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/core/session_entity_types.py b/src/dfcx_scrapi/core/session_entity_types.py index 62cbf215..01b98652 100644 --- a/src/dfcx_scrapi/core/session_entity_types.py +++ b/src/dfcx_scrapi/core/session_entity_types.py @@ -17,9 +17,8 @@ import logging from typing import Dict, List +from google.cloud.dialogflowcx_v3beta1 import services, types from google.oauth2 import service_account -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types from google.protobuf import field_mask_pb2 from dfcx_scrapi.core import scrapi_base diff --git a/src/dfcx_scrapi/core/sessions.py b/src/dfcx_scrapi/core/sessions.py index 10e76ea5..8f2d1ff2 100644 --- a/src/dfcx_scrapi/core/sessions.py +++ b/src/dfcx_scrapi/core/sessions.py @@ -17,16 +17,13 @@ import logging import uuid from typing import Dict, List -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types + +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf.json_format import MessageToDict +from IPython.display import Markdown, display from proto.marshal.collections import maps -from IPython.display import display, Markdown -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import tools -from dfcx_scrapi.core import playbooks -from dfcx_scrapi.core import flows +from dfcx_scrapi.core import flows, playbooks, scrapi_base, tools # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/core/sites.py b/src/dfcx_scrapi/core/sites.py index bcc60cb4..b8aef50c 100644 --- a/src/dfcx_scrapi/core/sites.py +++ b/src/dfcx_scrapi/core/sites.py @@ -16,18 +16,19 @@ import logging from typing import Dict, List -from google.longrunning.operations_pb2 import Operation + from google.cloud.discoveryengine import ( - TargetSite, - SiteSearchEngineServiceClient, - ListTargetSitesRequest, - GetTargetSiteRequest, CreateTargetSiteRequest, DeleteTargetSiteRequest, - EnableAdvancedSiteSearchRequest, DisableAdvancedSiteSearchRequest, - RecrawlUrisRequest + EnableAdvancedSiteSearchRequest, + GetTargetSiteRequest, + ListTargetSitesRequest, + RecrawlUrisRequest, + SiteSearchEngineServiceClient, + TargetSite, ) +from google.longrunning.operations_pb2 import Operation from dfcx_scrapi.core import scrapi_base diff --git a/src/dfcx_scrapi/core/test_cases.py b/src/dfcx_scrapi/core/test_cases.py index 6305898e..ea673553 100644 --- a/src/dfcx_scrapi/core/test_cases.py +++ b/src/dfcx_scrapi/core/test_cases.py @@ -14,16 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pandas as pd import logging from typing import Dict, List, Union -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +import pandas as pd +from google.cloud.dialogflowcx_v3beta1 import services, types -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import flows -from dfcx_scrapi.core import pages +from dfcx_scrapi.core import flows, pages, scrapi_base # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/core/tools.py b/src/dfcx_scrapi/core/tools.py index af3bcfed..cd394152 100644 --- a/src/dfcx_scrapi/core/tools.py +++ b/src/dfcx_scrapi/core/tools.py @@ -14,13 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -from dfcx_scrapi.core import scrapi_base from typing import Dict -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 +from dfcx_scrapi.core import scrapi_base + class Tools(scrapi_base.ScrapiBase): """Core Class for Tools Resource methods.""" diff --git a/src/dfcx_scrapi/core/transition_route_groups.py b/src/dfcx_scrapi/core/transition_route_groups.py index 29f0bab6..a36b87b0 100644 --- a/src/dfcx_scrapi/core/transition_route_groups.py +++ b/src/dfcx_scrapi/core/transition_route_groups.py @@ -17,17 +17,12 @@ import logging import time from typing import Dict + import pandas as pd -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 -from dfcx_scrapi.core import flows -from dfcx_scrapi.core import intents -from dfcx_scrapi.core import pages -from dfcx_scrapi.core import webhooks -from dfcx_scrapi.core import scrapi_base - +from dfcx_scrapi.core import flows, intents, pages, scrapi_base, webhooks # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/core/versions.py b/src/dfcx_scrapi/core/versions.py index cc94fd19..9c05f9da 100644 --- a/src/dfcx_scrapi/core/versions.py +++ b/src/dfcx_scrapi/core/versions.py @@ -16,9 +16,10 @@ import logging from typing import Dict + +from google.cloud.dialogflowcx_v3beta1 import services, types from google.oauth2 import service_account -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types + from dfcx_scrapi.core import scrapi_base # logging config diff --git a/src/dfcx_scrapi/core/webhooks.py b/src/dfcx_scrapi/core/webhooks.py index f54085b0..03050875 100644 --- a/src/dfcx_scrapi/core/webhooks.py +++ b/src/dfcx_scrapi/core/webhooks.py @@ -17,9 +17,9 @@ import logging from typing import Dict -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 + from dfcx_scrapi.core import scrapi_base # logging config diff --git a/src/dfcx_scrapi/core_async/test_cases.py b/src/dfcx_scrapi/core_async/test_cases.py index c307d3bd..bf561f2c 100644 --- a/src/dfcx_scrapi/core_async/test_cases.py +++ b/src/dfcx_scrapi/core_async/test_cases.py @@ -17,8 +17,7 @@ import logging from typing import Dict, List -from google.cloud.dialogflowcx_v3beta1 import services -from google.cloud.dialogflowcx_v3beta1 import types +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 from dfcx_scrapi.core.scrapi_base import ScrapiBase diff --git a/src/dfcx_scrapi/tools/agent_checker_util.py b/src/dfcx_scrapi/tools/agent_checker_util.py index ff6e331a..b8423b00 100644 --- a/src/dfcx_scrapi/tools/agent_checker_util.py +++ b/src/dfcx_scrapi/tools/agent_checker_util.py @@ -17,10 +17,11 @@ import logging import time from typing import Dict, List + import pandas as pd -from dfcx_scrapi.core import scrapi_base from dfcx_scrapi.agent_extract import agents +from dfcx_scrapi.core import scrapi_base # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/tools/agent_response.py b/src/dfcx_scrapi/tools/agent_response.py index fc141637..b7925c43 100644 --- a/src/dfcx_scrapi/tools/agent_response.py +++ b/src/dfcx_scrapi/tools/agent_response.py @@ -16,10 +16,10 @@ import dataclasses import json - from typing import Any, Union -from google.protobuf.json_format import MessageToDict + from google.cloud.dialogflowcx_v3beta1 import types +from google.protobuf.json_format import MessageToDict DataStoreConnectionSignals = ( types.data_store_connection.DataStoreConnectionSignals @@ -310,7 +310,8 @@ def cited_search_results(self): @property def cited_search_result_links(self): - return [search_result.uri for search_result in self.cited_search_results] + return [ + search_result.uri for search_result in self.cited_search_results] @property def prompt_snippets(self): diff --git a/src/dfcx_scrapi/tools/agent_task_generator.py b/src/dfcx_scrapi/tools/agent_task_generator.py index 38c6ac40..1efd48e3 100644 --- a/src/dfcx_scrapi/tools/agent_task_generator.py +++ b/src/dfcx_scrapi/tools/agent_task_generator.py @@ -14,26 +14,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os import json import logging +import os import random -from typing import Dict, Any, List from pathlib import Path +from typing import Any, Dict, List +from google.cloud.dialogflowcx_v3beta1 import types from google.oauth2 import service_account +from vertexai.generative_models import GenerationConfig, GenerativeModel -from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.core.agents import Agents from dfcx_scrapi.core.flows import Flows from dfcx_scrapi.core.intents import Intents from dfcx_scrapi.core.playbooks import Playbooks +from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.core.tools import Tools from dfcx_scrapi.tools.gcs_utils import GcsUtils -from google.cloud.dialogflowcx_v3beta1 import types -from vertexai.generative_models import GenerativeModel, GenerationConfig - class AgentTaskGenerator(ScrapiBase): @@ -331,7 +330,7 @@ def get_agent_tasks(self) -> Dict[str, Any]: tasks_dict = json.loads(res.text) return tasks_dict - + def get_agent_tasks_from_user_input( self, tasks: Any) -> Dict[str, Any]: """Given an arbitrary user input, clean and format with LLM.""" @@ -364,7 +363,7 @@ class Prompts: """ # System prompt for task generation - task_system: str = """You are a senior virtual agent evaluator. + task_system: str = """You are a senior virtual agent evaluator. Your job is to determine the core tasks that a virtual agent can handle based on its provided details, playbook, and available tools. Focus on the main functionalities that would be useful to an end user rather than individual steps or specific details within the process. Do not include generic functionalities such as "Intent Detection" or "Sentiment Analysis" unless those features provide a tangible outcome for the end user. Explain each functionality clearly and concisely. Return a concise list of the primary capabilities. @@ -406,7 +405,7 @@ class Prompts: ] } ``` -""" +""" # noqa: E501 user_task_main: str = """APP DETAILS PROVIDED BY USER: {USER_DETAILS} @@ -438,4 +437,4 @@ class Schemas: "required": [ "tasks" ] - } \ No newline at end of file + } diff --git a/src/dfcx_scrapi/tools/copy_util.py b/src/dfcx_scrapi/tools/copy_util.py index 7abcf446..a0f96ff2 100644 --- a/src/dfcx_scrapi/tools/copy_util.py +++ b/src/dfcx_scrapi/tools/copy_util.py @@ -17,19 +17,19 @@ import copy import logging import time -from typing import Dict, List from collections import defaultdict +from typing import Dict, List -from google.cloud.dialogflowcx_v3beta1 import types from google.api_core import exceptions as core_exceptions +from google.cloud.dialogflowcx_v3beta1 import types -from dfcx_scrapi.core.scrapi_base import ScrapiBase -from dfcx_scrapi.core.intents import Intents from dfcx_scrapi.core.entity_types import EntityTypes from dfcx_scrapi.core.flows import Flows +from dfcx_scrapi.core.intents import Intents from dfcx_scrapi.core.pages import Pages -from dfcx_scrapi.core.webhooks import Webhooks +from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.core.transition_route_groups import TransitionRouteGroups +from dfcx_scrapi.core.webhooks import Webhooks # logging config logging.basicConfig( @@ -181,8 +181,8 @@ def _convert_form_parameters( # pylint: disable=too-many-arguments if "webhook" in ( param.fill_behavior.initial_prompt_fulfillment ): - param.fill_behavior.initial_prompt_fulfillment.webhook = webhooks_map[ # pylint: disable=line-too-long - param.fill_behavior.initial_prompt_fulfillment.webhook # pylint: disable=line-too-long + param.fill_behavior.initial_prompt_fulfillment.webhook = webhooks_map[ # noqa: E501 + param.fill_behavior.initial_prompt_fulfillment.webhook # noqa: E501 ] if "reprompt_event_handlers" in param.fill_behavior: @@ -445,7 +445,8 @@ def _create_entity_resources( for entity in resources_objects["entities"]: logging.info("Creating Entity %s...", entity.display_name) try: - self.entities.create_entity_type(agent_id=destination_agent, obj=entity) + self.entities.create_entity_type( + agent_id=destination_agent, obj=entity) resources_skip_list["entities"].append(entity.display_name) logging.info( "Entity %s created successfully.", entity.display_name diff --git a/src/dfcx_scrapi/tools/dataframe_functions.py b/src/dfcx_scrapi/tools/dataframe_functions.py index 65f1b4ad..b0404d6c 100644 --- a/src/dfcx_scrapi/tools/dataframe_functions.py +++ b/src/dfcx_scrapi/tools/dataframe_functions.py @@ -17,20 +17,20 @@ import json import logging import time -from typing import Dict, List, Any +from typing import Any, Dict, List + import gspread -import pandas as pd import numpy as np -from tabulate import tabulate -from gspread_dataframe import set_with_dataframe - +import pandas as pd from google.cloud.dialogflowcx_v3beta1 import types +from gspread_dataframe import set_with_dataframe +from tabulate import tabulate -from dfcx_scrapi.core.scrapi_base import ScrapiBase -from dfcx_scrapi.core.intents import Intents from dfcx_scrapi.core.entity_types import EntityTypes from dfcx_scrapi.core.flows import Flows +from dfcx_scrapi.core.intents import Intents from dfcx_scrapi.core.pages import Pages +from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.core.transition_route_groups import TransitionRouteGroups SHEETS_SCOPE = [ @@ -64,7 +64,10 @@ def __init__( self._check_and_update_sheets_scopes() - if hasattr(self.creds, "service_account_email") and self.creds.service_account_email: + if ( + hasattr(self.creds, "service_account_email") + and self.creds.service_account_email + ): self.sheets_client = gspread.authorize(self.creds) else: logging.warning( diff --git a/src/dfcx_scrapi/tools/datastore_evaluator.py b/src/dfcx_scrapi/tools/datastore_evaluator.py index 31d39a7f..b766fa44 100644 --- a/src/dfcx_scrapi/tools/datastore_evaluator.py +++ b/src/dfcx_scrapi/tools/datastore_evaluator.py @@ -15,23 +15,22 @@ # limitations under the License. import dataclasses -from datetime import datetime, timezone import io import itertools import json import math import os import re -import pandas as pd -from tqdm import tqdm +from datetime import datetime, timezone from typing import Union -import plotly.graph_objects as go import matplotlib.pyplot as plt - +import pandas as pd +import plotly.graph_objects as go from google.cloud import bigquery from googleapiclient.discovery import build from googleapiclient.http import MediaInMemoryUpload, MediaIoBaseDownload +from tqdm import tqdm from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.tools.agent_response import AgentResponse diff --git a/src/dfcx_scrapi/tools/datastore_scraper.py b/src/dfcx_scrapi/tools/datastore_scraper.py index 332bb3ab..94a07fee 100644 --- a/src/dfcx_scrapi/tools/datastore_scraper.py +++ b/src/dfcx_scrapi/tools/datastore_scraper.py @@ -17,16 +17,17 @@ import datetime import json import re +from typing import Any, Union + import gspread import pandas as pd -from tqdm.auto import tqdm -from typing import Union, Any from google.oauth2 import service_account +from tqdm.auto import tqdm -from dfcx_scrapi.tools.agent_response import AgentResponse +from dfcx_scrapi.core.agents import Agents from dfcx_scrapi.core.scrapi_base import ScrapiBase, retry_api_call from dfcx_scrapi.core.sessions import Sessions -from dfcx_scrapi.core.agents import Agents +from dfcx_scrapi.tools.agent_response import AgentResponse MAX_RETRIES = 5 INPUT_SCHEMA_REQUIRED_COLUMNS = [ diff --git a/src/dfcx_scrapi/tools/evaluations.py b/src/dfcx_scrapi/tools/evaluations.py index be7e5243..a22c2f75 100644 --- a/src/dfcx_scrapi/tools/evaluations.py +++ b/src/dfcx_scrapi/tools/evaluations.py @@ -14,30 +14,28 @@ # See the License for the specific language governing permissions and # limitations under the License. -from datetime import datetime import logging - from ast import literal_eval -import numpy as np -import pandas as pd -from tqdm import tqdm -from typing import Dict, List, Any from dataclasses import dataclass, field +from datetime import datetime +from typing import Any, Dict, List +import numpy as np +import pandas as pd +from google.cloud.dialogflowcx_v3beta1 import types from google.oauth2 import service_account +from tqdm import tqdm -from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.core.agents import Agents -from dfcx_scrapi.core.sessions import Sessions from dfcx_scrapi.core.conversation_history import ConversationHistory -from dfcx_scrapi.core.tools import Tools from dfcx_scrapi.core.playbooks import Playbooks -from dfcx_scrapi.tools.dataframe_functions import DataframeFunctions +from dfcx_scrapi.core.scrapi_base import ScrapiBase +from dfcx_scrapi.core.sessions import Sessions +from dfcx_scrapi.core.tools import Tools from dfcx_scrapi.tools.agent_response import AgentResponse +from dfcx_scrapi.tools.dataframe_functions import DataframeFunctions from dfcx_scrapi.tools.metrics import build_metrics -from google.cloud.dialogflowcx_v3beta1 import types - # logging config logging.basicConfig( level=logging.INFO, @@ -225,11 +223,11 @@ def append_row( def parse_tool_use_from_conversation_history( self, - tool_use: types.ToolUse) -> Dict[str, Any]: + tool_use: types.ToolUse) -> Dict[str, Any]: tool_name = self.tools_map.get(tool_use.tool, None) input_params = self.recurse_proto_marshal_to_dict( tool_use.input_action_parameters) - + # The DFCX proto for input params will add an extra top level key that # needs to be removed before writing to our output sheet. This only # applies to input_action_parameters @@ -238,7 +236,7 @@ def parse_tool_use_from_conversation_history( output_params = self.recurse_proto_marshal_to_dict( tool_use.output_action_parameters) - + return { "tool_name": tool_name, "action": tool_use.action, @@ -260,7 +258,7 @@ def append_user_query( ) self.action_counter += 1 - + def append_playbook( self, df_rows: List[Dict[str, Any]], @@ -291,7 +289,7 @@ def append_tools( df_rows=df_rows, eval_id=eval_id, action_id=self.action_counter + count, - action_type="Tool Invocation", + action_type="Tool Invocation", action_input=tool_name, action_input_parameters=input_params, tool_action=tool_action @@ -329,7 +327,7 @@ def parse_interactions_from_conversation_history( if not self.playbooks_map: self. playbooks_map = self.playbooks_client.get_playbooks_map( self.agent_id) - + for conv_interaction in conversation.interactions: interaction = Interaction( query=conv_interaction.request.query_input.text.text, @@ -344,19 +342,19 @@ def parse_interactions_from_conversation_history( action.tool_use) ) interaction.tool_calls.append(tool_calls) - + elif "agent_utterance" in action: response_text = action.agent_utterance.text interaction.responses.append(response_text) - + elif "playbook_invocation" in action: playbook_name = self.playbooks_map.get( action.playbook_invocation.playbook, None) interaction.playbook_invocation = playbook_name - + results.append(interaction) results.reverse() - + return results def add_response_columns(self, df: pd.DataFrame) -> pd.DataFrame: @@ -455,7 +453,7 @@ def create_dataset_from_conv_ids( self, conversation_ids: List) -> pd.DataFrame: columns = [ - 'eval_id', 'action_id', 'action_type', 'action_input', + 'eval_id', 'action_id', 'action_type', 'action_input', 'action_input_parameters', 'tool_action', 'notes' ] df_rows = [] @@ -466,19 +464,19 @@ def create_dataset_from_conv_ids( if not self.playbooks_map: self. playbooks_map = self.playbooks_client.get_playbooks_map( self.agent_id) - + for idx, conv_id in enumerate(conversation_ids, start=1): eval_id = f"{idx:03d}" convo = self.ch.get_conversation(conv_id) interactions = self.parse_interactions_from_conversation_history( convo) - + self.action_counter = 1 for interaction in interactions: self.append_user_query(df_rows, eval_id, interaction) self.append_playbook(df_rows, eval_id, interaction) - self.append_tools(df_rows, eval_id, interaction) + self.append_tools(df_rows, eval_id, interaction) self.append_responses(df_rows, eval_id, interaction) return pd.DataFrame(df_rows, columns=columns) @@ -640,7 +638,7 @@ def pair_playbook_calls(self, df: pd.DataFrame) -> pd.DataFrame: df.loc[pair[0], "playbook_pair"] = str(pair[1]) return df - + def pair_flow_calls(self, df: pd.DataFrame) -> pd.DataFrame: "Identifies pairings of agent_utterance/flow_invocation by eval_id." df["flow_pair"] = pd.Series(dtype="string") diff --git a/src/dfcx_scrapi/tools/gcs_utils.py b/src/dfcx_scrapi/tools/gcs_utils.py index a804a020..46a62c75 100644 --- a/src/dfcx_scrapi/tools/gcs_utils.py +++ b/src/dfcx_scrapi/tools/gcs_utils.py @@ -15,8 +15,10 @@ # limitations under the License. import json -from google.cloud import storage + from google.api_core.exceptions import NotFound +from google.cloud import storage + class GcsUtils: def __init__(self, gcs_path: str = None): diff --git a/src/dfcx_scrapi/tools/levenshtein.py b/src/dfcx_scrapi/tools/levenshtein.py index c659f465..5bbb9888 100644 --- a/src/dfcx_scrapi/tools/levenshtein.py +++ b/src/dfcx_scrapi/tools/levenshtein.py @@ -17,11 +17,12 @@ import logging from typing import Union -import pandas import numpy as np -from dfcx_scrapi.core.intents import Intents +import pandas from google.cloud.dialogflowcx_v3beta1 import types +from dfcx_scrapi.core.intents import Intents + # logging config logging.basicConfig( level=logging.INFO, diff --git a/src/dfcx_scrapi/tools/maker_util.py b/src/dfcx_scrapi/tools/maker_util.py index 5e61e15c..ee3c6b26 100644 --- a/src/dfcx_scrapi/tools/maker_util.py +++ b/src/dfcx_scrapi/tools/maker_util.py @@ -19,6 +19,7 @@ # PLEASE NOTE THAT THE /builders CLASSES WILL TAKE PRECEDENCE OVER THIS CLASS import logging + from google.cloud.dialogflowcx_v3beta1 import types # logging config diff --git a/src/dfcx_scrapi/tools/metrics.py b/src/dfcx_scrapi/tools/metrics.py index 41ee90b3..2c70790e 100644 --- a/src/dfcx_scrapi/tools/metrics.py +++ b/src/dfcx_scrapi/tools/metrics.py @@ -20,23 +20,25 @@ import json import logging import math +import statistics +from typing import Any, Dict, List, Optional, Union + import numpy as np import pandas as pd -import statistics +from rouge_score import rouge_scorer from tqdm.contrib import concurrent -from typing import Any, Union, List, Optional, Dict - from vertexai.generative_models import GenerativeModel from vertexai.language_models import ( - TextGenerationModel, TextEmbeddingInput, TextEmbeddingModel + TextEmbeddingInput, + TextEmbeddingModel, + TextGenerationModel, ) -from rouge_score import rouge_scorer from dfcx_scrapi.core.scrapi_base import ( + EMBEDDING_MODELS_NO_DIMENSIONALITY, + handle_api_error, ratelimit, retry_api_call, - handle_api_error, - EMBEDDING_MODELS_NO_DIMENSIONALITY ) # logging config @@ -360,9 +362,9 @@ def score(self, prompt: str) -> Union[dict[str, float], None]: for key, value in sorted( merged_top_log_probs.items(), key=lambda x: x[1], reverse=True ): - # checking containment instead of equality because sometimes the answer - # might be returned as "_" instead of "" due - # to the LLM's tokenizer + # checking containment instead of equality because sometimes the + # answer might be returned as "_" instead of + # "" due to the LLM's tokenizer if completion in key: result[completion] = value break @@ -524,7 +526,8 @@ def __call__(self, inputs: dict[str, Any]) -> dict[str, Any]: else: prediction_statements = ( self._statement_extractor.extract_statements( - question=inputs["query"], answer=inputs["query_result"].answer_text + question=inputs["query"], + answer=inputs["query_result"].answer_text ) ) precision_result = self._precision_answer_scorer.score( @@ -715,13 +718,14 @@ def run(self, inputs: pd.DataFrame) -> pd.DataFrame: columns=["reference_statements"], index=inputs.index ) if self._context_recall or self._answer_correctness: - reference_statements["reference_statements"] = concurrent.thread_map( - self._statement_extractor.extract_statements, - inputs["query"].tolist(), - inputs["expected_answer"].tolist(), - max_workers=4, - desc="Extracting statements: `expected_answer`", - ) + reference_statements[ + "reference_statements"] = concurrent.thread_map( + self._statement_extractor.extract_statements, + inputs["query"].tolist(), + inputs["expected_answer"].tolist(), + max_workers=4, + desc="Extracting statements: `expected_answer`", + ) prediction_statements = pd.DataFrame( columns=["prediction_statements"], index=inputs.index @@ -826,7 +830,7 @@ class MetricPrompts: question: {question} answer: {answer} -statements in json: """ +statements in json: """ # noqa: E501 ANSWER_CORRECTNESS_PROMPT_TEMPLATE = """You are provided with a question, an answer and a statement. Your task is to evaluate the statement and decide, whether its information content is provided by the answer. @@ -972,7 +976,7 @@ class MetricPrompts: END_ANSWER START_STATEMENT_EVALUATION statement: {statement} -provided: """ +provided: """ # noqa: E501 GROUNDING_PROMPT_TEMPLATE = """I need your help with "Natural language inference". Your task is to check if the hypothesis is true, given the premise. The answer should be a single `TRUE` or `FALSE`. @@ -1036,7 +1040,7 @@ class MetricPrompts: premise: {sources} hypothesis: {statement} -answer: """ +answer: """ # noqa: E501 class Metrics: diff --git a/src/dfcx_scrapi/tools/nlu_evals.py b/src/dfcx_scrapi/tools/nlu_evals.py index 3bcc1c3c..1e1efd2d 100644 --- a/src/dfcx_scrapi/tools/nlu_evals.py +++ b/src/dfcx_scrapi/tools/nlu_evals.py @@ -14,17 +14,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict +import datetime +import logging from dataclasses import dataclass +from typing import Dict -import logging -import datetime -import pandas as pd import gspread +import pandas as pd -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import agents -from dfcx_scrapi.core import conversation +from dfcx_scrapi.core import agents, conversation, scrapi_base from dfcx_scrapi.tools import dataframe_functions pd.options.display.max_colwidth = 200 @@ -119,7 +117,7 @@ def __init__( def get_agent_type(self, agent_id: str): """Return the Agent type for logging purposes.""" agent = self._a.get_agent(agent_id) - + if agent.start_flow: return "flow" elif agent.start_playbook: diff --git a/src/dfcx_scrapi/tools/nlu_util.py b/src/dfcx_scrapi/tools/nlu_util.py index a59122a7..0f79e070 100644 --- a/src/dfcx_scrapi/tools/nlu_util.py +++ b/src/dfcx_scrapi/tools/nlu_util.py @@ -15,20 +15,22 @@ # limitations under the License. import sys +from typing import Dict, Set + +import gspread import numpy as np import pandas as pd import scann -import gspread -from oauth2client.service_account import ServiceAccountCredentials -from typing import Dict, Set - import tensorflow_hub +from oauth2client.service_account import ServiceAccountCredentials -from dfcx_scrapi.core import flows -from dfcx_scrapi.core import intents -from dfcx_scrapi.core import pages -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import transition_route_groups +from dfcx_scrapi.core import ( + flows, + intents, + pages, + scrapi_base, + transition_route_groups, +) if "google.colab" in sys.modules: from google.colab import data_table diff --git a/src/dfcx_scrapi/tools/search_util.py b/src/dfcx_scrapi/tools/search_util.py index 9fc0ee0a..6b2a5ac6 100644 --- a/src/dfcx_scrapi/tools/search_util.py +++ b/src/dfcx_scrapi/tools/search_util.py @@ -16,20 +16,23 @@ import logging import time -from typing import Dict, List from operator import attrgetter -import pandas as pd -import numpy as np -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import intents -from dfcx_scrapi.core import flows -from dfcx_scrapi.core import pages -from dfcx_scrapi.core import entity_types -from dfcx_scrapi.core import transition_route_groups +from typing import Dict, List +import numpy as np +import pandas as pd from google.cloud.dialogflowcx_v3beta1 import types from google.oauth2 import service_account +from dfcx_scrapi.core import ( + entity_types, + flows, + intents, + pages, + scrapi_base, + transition_route_groups, +) + # logging config logging.basicConfig( level=logging.INFO, diff --git a/src/dfcx_scrapi/tools/semantic_clustering.py b/src/dfcx_scrapi/tools/semantic_clustering.py index 8e828ad4..f0f156bf 100644 --- a/src/dfcx_scrapi/tools/semantic_clustering.py +++ b/src/dfcx_scrapi/tools/semantic_clustering.py @@ -18,9 +18,10 @@ import logging import re + import pandas as pd -from sklearn.cluster import DBSCAN import tensorflow_hub as hub +from sklearn.cluster import DBSCAN # logging config logging.basicConfig( diff --git a/src/dfcx_scrapi/tools/stats_util.py b/src/dfcx_scrapi/tools/stats_util.py index 32493872..1d3fb5bb 100644 --- a/src/dfcx_scrapi/tools/stats_util.py +++ b/src/dfcx_scrapi/tools/stats_util.py @@ -16,14 +16,15 @@ from typing import Dict -from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.core.agents import Agents -from dfcx_scrapi.core.intents import Intents +from dfcx_scrapi.core.entity_types import EntityTypes from dfcx_scrapi.core.flows import Flows +from dfcx_scrapi.core.intents import Intents from dfcx_scrapi.core.pages import Pages -from dfcx_scrapi.core.entity_types import EntityTypes +from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.core.transition_route_groups import TransitionRouteGroups + class StatsUtil(ScrapiBase): """A util class to provide common stats for a CX Agent.""" diff --git a/src/dfcx_scrapi/tools/test_cases_util.py b/src/dfcx_scrapi/tools/test_cases_util.py index f6e4b573..aaf2ebe4 100644 --- a/src/dfcx_scrapi/tools/test_cases_util.py +++ b/src/dfcx_scrapi/tools/test_cases_util.py @@ -15,18 +15,14 @@ # limitations under the License. import logging -from typing import Dict, List, Union import time +from typing import Dict, List, Union -from google.cloud.dialogflowcx_v3beta1 import types from google.api_core import exceptions as core_exceptions +from google.cloud.dialogflowcx_v3beta1 import types from google.protobuf.struct_pb2 import Struct -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import flows -from dfcx_scrapi.core import pages -from dfcx_scrapi.core import intents -from dfcx_scrapi.core import test_cases +from dfcx_scrapi.core import flows, intents, pages, scrapi_base, test_cases logging.basicConfig( level=logging.INFO, diff --git a/src/dfcx_scrapi/tools/utterance_generator_util.py b/src/dfcx_scrapi/tools/utterance_generator_util.py index 67e1fe02..c616610e 100644 --- a/src/dfcx_scrapi/tools/utterance_generator_util.py +++ b/src/dfcx_scrapi/tools/utterance_generator_util.py @@ -16,13 +16,12 @@ import logging import string -from typing import List, Dict +from typing import Dict, List import pandas as pd - from google.oauth2 import service_account -from dfcx_scrapi.core import scrapi_base -from dfcx_scrapi.core import intents + +from dfcx_scrapi.core import intents, scrapi_base from dfcx_scrapi.core_ml import utterance_generator # logging config diff --git a/src/dfcx_scrapi/tools/validation_util.py b/src/dfcx_scrapi/tools/validation_util.py index 269fedca..5d4c8f59 100644 --- a/src/dfcx_scrapi/tools/validation_util.py +++ b/src/dfcx_scrapi/tools/validation_util.py @@ -17,11 +17,12 @@ import logging import re from typing import Dict + import pandas as pd -from dfcx_scrapi.core.scrapi_base import ScrapiBase from dfcx_scrapi.core.agents import Agents from dfcx_scrapi.core.flows import Flows +from dfcx_scrapi.core.scrapi_base import ScrapiBase SCOPES = [ "https://www.googleapis.com/auth/cloud-platform", diff --git a/src/dfcx_scrapi/tools/webhook_util.py b/src/dfcx_scrapi/tools/webhook_util.py index 197a93c8..e1bbefb7 100644 --- a/src/dfcx_scrapi/tools/webhook_util.py +++ b/src/dfcx_scrapi/tools/webhook_util.py @@ -162,4 +162,3 @@ def get_user_utterance(request, cleaned=False): user_utterance = request['text'] return user_utterance - \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 70b7e65d..a227b8e2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,6 +16,7 @@ import pytest + def pytest_addoption(parser): """Method to add option for creds in tests.""" parser.addoption("--creds", action="store") diff --git a/tests/dfcx_scrapi/builders/test_fulfillments.py b/tests/dfcx_scrapi/builders/test_fulfillments.py index af54f79a..247ff714 100644 --- a/tests/dfcx_scrapi/builders/test_fulfillments.py +++ b/tests/dfcx_scrapi/builders/test_fulfillments.py @@ -16,8 +16,7 @@ import pytest -from dfcx_scrapi.builders.fulfillments import Fulfillment -from dfcx_scrapi.builders.fulfillments import FulfillmentBuilder +from dfcx_scrapi.builders.fulfillments import Fulfillment, FulfillmentBuilder def test_create_new_proto_obj(): diff --git a/tests/dfcx_scrapi/core/test_agents.py b/tests/dfcx_scrapi/core/test_agents.py index ef37e245..b1aec918 100644 --- a/tests/dfcx_scrapi/core/test_agents.py +++ b/tests/dfcx_scrapi/core/test_agents.py @@ -14,18 +14,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest from typing import Dict -from unittest.mock import patch, MagicMock -from google.protobuf import field_mask_pb2 +from unittest.mock import MagicMock, patch +import pytest from google.cloud.dialogflowcx_v3beta1 import types from google.cloud.dialogflowcx_v3beta1.services.agents import ( - pagers, AgentsClient - ) + AgentsClient, + pagers, +) +from google.protobuf import field_mask_pb2 from dfcx_scrapi.core.agents import Agents + @pytest.fixture def test_config(): project_id = "my-project-id-1234" diff --git a/tests/dfcx_scrapi/core/test_conversation.py b/tests/dfcx_scrapi/core/test_conversation.py index a8c91440..a7dc8509 100644 --- a/tests/dfcx_scrapi/core/test_conversation.py +++ b/tests/dfcx_scrapi/core/test_conversation.py @@ -14,21 +14,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest +from unittest.mock import MagicMock, patch + import pandas as pd -from unittest.mock import patch, MagicMock -from google.oauth2.service_account import Credentials +import pytest from google.api_core.exceptions import InvalidArgument - -from google.cloud.dialogflowcx_v3beta1 import types -from google.cloud.dialogflowcx_v3beta1 import services +from google.cloud.dialogflowcx_v3beta1 import services, types +from google.oauth2.service_account import Credentials from dfcx_scrapi.builders.flows import FlowBuilder -from dfcx_scrapi.builders.routes import TransitionRouteBuilder from dfcx_scrapi.builders.fulfillments import FulfillmentBuilder from dfcx_scrapi.builders.response_messages import ResponseMessageBuilder +from dfcx_scrapi.builders.routes import TransitionRouteBuilder from dfcx_scrapi.core.conversation import DialogflowConversation + @pytest.fixture def test_config(): project_id = "my-project-id-1234" diff --git a/tests/dfcx_scrapi/core/test_conversation_history.py b/tests/dfcx_scrapi/core/test_conversation_history.py index 7fdf6309..77dbc494 100644 --- a/tests/dfcx_scrapi/core/test_conversation_history.py +++ b/tests/dfcx_scrapi/core/test_conversation_history.py @@ -18,15 +18,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os import json +import os +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock +from google.cloud.dialogflowcx_v3beta1 import services, types +from google.protobuf import timestamp_pb2 from dfcx_scrapi.core.conversation_history import ConversationHistory -from google.cloud.dialogflowcx_v3beta1 import types -from google.cloud.dialogflowcx_v3beta1 import services -from google.protobuf import timestamp_pb2 @pytest.fixture diff --git a/tests/dfcx_scrapi/core/test_examples.py b/tests/dfcx_scrapi/core/test_examples.py index f7ce5676..83413172 100644 --- a/tests/dfcx_scrapi/core/test_examples.py +++ b/tests/dfcx_scrapi/core/test_examples.py @@ -18,11 +18,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock +from google.cloud.dialogflowcx_v3beta1 import services, types + from dfcx_scrapi.core.examples import Examples -from google.cloud.dialogflowcx_v3beta1 import types -from google.cloud.dialogflowcx_v3beta1 import services + @pytest.fixture def test_config(): diff --git a/tests/dfcx_scrapi/core/test_flows.py b/tests/dfcx_scrapi/core/test_flows.py index d070d4fd..edb16650 100644 --- a/tests/dfcx_scrapi/core/test_flows.py +++ b/tests/dfcx_scrapi/core/test_flows.py @@ -14,15 +14,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest from typing import Dict -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock, patch +import pytest from google.cloud.dialogflowcx_v3beta1 import types -from google.cloud.dialogflowcx_v3beta1.services.flows import pagers, FlowsClient +from google.cloud.dialogflowcx_v3beta1.services.flows import FlowsClient, pagers from dfcx_scrapi.core.flows import Flows + @pytest.fixture def test_config(): project_id = "my-project-id-1234" diff --git a/tests/dfcx_scrapi/core/test_playbooks.py b/tests/dfcx_scrapi/core/test_playbooks.py index 3e22ed6e..159b4020 100644 --- a/tests/dfcx_scrapi/core/test_playbooks.py +++ b/tests/dfcx_scrapi/core/test_playbooks.py @@ -18,13 +18,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock -from dfcx_scrapi.core.playbooks import Playbooks -from google.cloud.dialogflowcx_v3beta1 import types -from google.cloud.dialogflowcx_v3beta1 import services +from google.cloud.dialogflowcx_v3beta1 import services, types from google.protobuf import field_mask_pb2 +from dfcx_scrapi.core.playbooks import Playbooks + + @pytest.fixture def test_config(): project_id = "my-project-id-1234" diff --git a/tests/dfcx_scrapi/core/test_scrapi_base.py b/tests/dfcx_scrapi/core/test_scrapi_base.py index 53d39532..f8f360bf 100644 --- a/tests/dfcx_scrapi/core/test_scrapi_base.py +++ b/tests/dfcx_scrapi/core/test_scrapi_base.py @@ -14,21 +14,25 @@ # See the License for the specific language governing permissions and # limitations under the License. +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock -from google.oauth2.credentials import Credentials as UserCredentials -from google.oauth2.service_account import Credentials as ServiceAccountCredentials from google.api_core import exceptions -from google.protobuf import field_mask_pb2, struct_pb2 from google.cloud.dialogflowcx_v3beta1 import types +from google.oauth2.credentials import Credentials as UserCredentials +from google.oauth2.service_account import ( + Credentials as ServiceAccountCredentials, +) +from google.protobuf import field_mask_pb2, struct_pb2 from dfcx_scrapi.core.scrapi_base import ( - api_call_counter_decorator, - should_retry, - retry_api_call, + ScrapiBase, + api_call_counter_decorator, handle_api_error, - ScrapiBase - ) + retry_api_call, + should_retry, +) + @pytest.fixture def test_config(): diff --git a/tests/dfcx_scrapi/core/test_test_cases.py b/tests/dfcx_scrapi/core/test_test_cases.py index 1fbcb81d..c2c46900 100644 --- a/tests/dfcx_scrapi/core/test_test_cases.py +++ b/tests/dfcx_scrapi/core/test_test_cases.py @@ -17,13 +17,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest +from unittest.mock import MagicMock, patch + import pandas as pd -from unittest.mock import patch, MagicMock -from dfcx_scrapi.core.test_cases import TestCases as PyTestCases +import pytest from google.cloud.dialogflowcx_v3beta1 import types from google.cloud.dialogflowcx_v3beta1.services import test_cases +from dfcx_scrapi.core.test_cases import TestCases as PyTestCases + @pytest.fixture def test_config(): diff --git a/tests/dfcx_scrapi/core/test_tools.py b/tests/dfcx_scrapi/core/test_tools.py index 2a268a48..3d347894 100644 --- a/tests/dfcx_scrapi/core/test_tools.py +++ b/tests/dfcx_scrapi/core/test_tools.py @@ -18,11 +18,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock +from google.cloud.dialogflowcx_v3beta1 import services, types + from dfcx_scrapi.core.tools import Tools -from google.cloud.dialogflowcx_v3beta1 import types -from google.cloud.dialogflowcx_v3beta1 import services + @pytest.fixture def test_config(): diff --git a/tests/dfcx_scrapi/tools/test_agent_task_generator.py b/tests/dfcx_scrapi/tools/test_agent_task_generator.py index 373e1f57..4cd954aa 100644 --- a/tests/dfcx_scrapi/tools/test_agent_task_generator.py +++ b/tests/dfcx_scrapi/tools/test_agent_task_generator.py @@ -15,15 +15,15 @@ # limitations under the License. import json -import pytest from unittest.mock import MagicMock +import pytest +from google.cloud.dialogflowcx_v3beta1 import types from google.oauth2.service_account import Credentials +from vertexai.generative_models import GenerationResponse, GenerativeModel -from google.cloud.dialogflowcx_v3beta1 import types -from vertexai.generative_models import GenerativeModel, GenerationResponse -from dfcx_scrapi.tools.gcs_utils import GcsUtils from dfcx_scrapi.tools.agent_task_generator import AgentTaskGenerator +from dfcx_scrapi.tools.gcs_utils import GcsUtils @pytest.fixture diff --git a/tests/dfcx_scrapi/tools/test_dataframe_functions.py b/tests/dfcx_scrapi/tools/test_dataframe_functions.py index 1fdf655e..5be74c4f 100644 --- a/tests/dfcx_scrapi/tools/test_dataframe_functions.py +++ b/tests/dfcx_scrapi/tools/test_dataframe_functions.py @@ -16,10 +16,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import pytest from unittest.mock import MagicMock +import pytest from google.oauth2.service_account import Credentials + from dfcx_scrapi.tools.dataframe_functions import DataframeFunctions