Skip to content

Commit

Permalink
Merge pull request #5 from lpm0073/next
Browse files Browse the repository at this point in the history
add unit tests and refactor credentials
  • Loading branch information
lpm0073 committed Nov 30, 2023
2 parents 5fac60e + 283b8b2 commit a3b1c17
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 60 deletions.
30 changes: 30 additions & 0 deletions models/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# pylint: disable=too-few-public-methods
"""Sales Support Model (SSM) for the LangChain project."""

import os

from dotenv import find_dotenv, load_dotenv


# pylint: disable=duplicate-code
dotenv_path = find_dotenv()
if os.path.exists(dotenv_path):
load_dotenv(dotenv_path=dotenv_path, verbose=True)
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
OPENAI_API_ORGANIZATION = os.environ["OPENAI_API_ORGANIZATION"]
PINECONE_API_KEY = os.environ["PINECONE_API_KEY"]
PINECONE_ENVIRONMENT = os.environ["PINECONE_ENVIRONMENT"]
PINECONE_INDEX_NAME = os.environ["PINECONE_INDEX_NAME"]
else:
raise FileNotFoundError("No .env file found in root directory of repository")


class Credentials:
"""Credentials."""

OPENAI_API_KEY = OPENAI_API_KEY
OPENAI_API_ORGANIZATION = OPENAI_API_ORGANIZATION
PINECONE_API_KEY = PINECONE_API_KEY
PINECONE_ENVIRONMENT = PINECONE_ENVIRONMENT
PINECONE_INDEX_NAME = PINECONE_INDEX_NAME
3 changes: 2 additions & 1 deletion models/examples/training_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"""Sales Support Model (SSM) for the LangChain project."""
import argparse

from ..ssm import NetecPromptTemplates, SalesSupportModel
from ..prompt_templates import NetecPromptTemplates
from ..ssm import SalesSupportModel


ssm = SalesSupportModel()
Expand Down
3 changes: 2 additions & 1 deletion models/examples/training_services_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"""Sales Support Model (SSM) for the LangChain project."""
import argparse

from ..ssm import NetecPromptTemplates, SalesSupportModel
from ..prompt_templates import NetecPromptTemplates
from ..ssm import SalesSupportModel


ssm = SalesSupportModel()
Expand Down
46 changes: 46 additions & 0 deletions models/prompt_templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# pylint: disable=too-few-public-methods
"""Sales Support Model (SSM) prompt templates"""

from langchain.prompts import PromptTemplate


class NetecPromptTemplates:
"""Netec Prompt Templates."""

sales_role: str = """You are a helpful sales assistant at Netec who sells
specialized training and exam preparation services to existing customers.
You provide concise explanations of the services that Netec offers in 100
words or less."""

@classmethod
def get_properties(cls):
"""return a list of properties of this class."""
return [attr for attr in dir(cls) if isinstance(getattr(cls, attr), property)]

@property
def training_services(self) -> PromptTemplate:
"""Get prompt."""
template = (
self.sales_role
+ """
Explain the training services that Netec offers about {concept}
"""
)
return PromptTemplate(input_variables=["concept"], template=template)

@property
def oracle_training_services(self) -> PromptTemplate:
"""Get prompt."""
template = (
self.sales_role
+ """
Note that Netec is the exclusive provide of Oracle training services
for the 6 levels of Oracle Certification credentials: Oracle Certified Junior Associate (OCJA),
Oracle Certified Associate (OCA), Oracle Certified Professional (OCP),
Oracle Certified Master (OCM), Oracle Certified Expert (OCE) and
Oracle Certified Specialist (OCS).
Summarize their programs for {concept}
"""
)
return PromptTemplate(input_variables=["concept"], template=template)
61 changes: 4 additions & 57 deletions models/ssm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
# pylint: disable=too-few-public-methods
"""Sales Support Model (SSM) for the LangChain project."""

import os
from typing import ClassVar, List

import pinecone
from dotenv import find_dotenv, load_dotenv
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.llms.openai import OpenAI
Expand All @@ -16,62 +14,11 @@
from langchain.vectorstores.pinecone import Pinecone
from pydantic import BaseModel, ConfigDict, Field # ValidationError

from models.const import Credentials

# pylint: disable=duplicate-code
dotenv_path = find_dotenv()
if os.path.exists(dotenv_path):
load_dotenv(dotenv_path=dotenv_path, verbose=True)
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
OPENAI_API_ORGANIZATION = os.environ["OPENAI_API_ORGANIZATION"]
PINECONE_API_KEY = os.environ["PINECONE_API_KEY"]
PINECONE_ENVIRONMENT = os.environ["PINECONE_ENVIRONMENT"]
PINECONE_INDEX_NAME = os.environ["PINECONE_INDEX_NAME"]
else:
raise FileNotFoundError("No .env file found in root directory of repository")

DEFAULT_MODEL_NAME = "text-davinci-003"
pinecone.init(api_key=PINECONE_API_KEY, environment=PINECONE_ENVIRONMENT)


class NetecPromptTemplates:
"""Netec Prompt Templates."""

sales_role: str = """You are a helpful sales assistant at Netec who sells
specialized training and exam preparation services to existing customers.
You provide concise explanations of the services that Netec offers in 100
words or less."""

@classmethod
def get_properties(cls):
"""return a list of properties of this class."""
return [attr for attr in dir(cls) if isinstance(getattr(cls, attr), property)]

@property
def training_services(self) -> PromptTemplate:
"""Get prompt."""
template = (
self.sales_role
+ """
Explain the training services that Netec offers about {concept}
"""
)
return PromptTemplate(input_variables=["concept"], template=template)

@property
def oracle_training_services(self) -> PromptTemplate:
"""Get prompt."""
template = (
self.sales_role
+ """
Note that Netec is the exclusive provide of Oracle training services
for the 6 levels of Oracle Certification credentials: Oracle Certified Junior Associate (OCJA),
Oracle Certified Associate (OCA), Oracle Certified Professional (OCP),
Oracle Certified Master (OCM), Oracle Certified Expert (OCE) and
Oracle Certified Specialist (OCS).
Summarize their programs for {concept}
"""
)
return PromptTemplate(input_variables=["concept"], template=template)
pinecone.init(api_key=Credentials.PINECONE_API_KEY, environment=Credentials.PINECONE_ENVIRONMENT)


class SalesSupportModel(BaseModel):
Expand All @@ -82,8 +29,8 @@ class SalesSupportModel(BaseModel):
# prompting wrapper
chat: ChatOpenAI = Field(
default_factory=lambda: ChatOpenAI(
api_key=OPENAI_API_KEY,
organization=OPENAI_API_ORGANIZATION,
api_key=Credentials.OPENAI_API_KEY,
organization=Credentials.OPENAI_API_ORGANIZATION,
max_retries=3,
model="gpt-3.5-turbo",
temperature=0.3,
Expand Down
22 changes: 22 additions & 0 deletions models/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,35 @@
"""
import pytest # pylint: disable=unused-import

from ..prompt_templates import NetecPromptTemplates
from ..ssm import SalesSupportModel


class TestSalesSupportModel:
"""Test SalesSupportModel class."""

ssm = SalesSupportModel()
templates = NetecPromptTemplates()

def test_01_basic(self):
"""Test a basic request"""

SalesSupportModel()

def test_oracle_training_services(self):
"""Test a prompt with the Oracle training services template"""

prompt = self.templates.oracle_training_services
result = self.ssm.prompt_with_template(prompt=prompt, concept="Oracle database administrator")
assert result
assert "Oracle" in result
assert "training" in result

def test_training_services(self):
"""Test a prompt with the training services template"""

prompt = self.templates.training_services
result = self.ssm.prompt_with_template(prompt=prompt, concept="Microsoft certified Azure AI engineer associate")
assert result
assert "Microsoft" in result
assert "training" in result
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@ extend-exclude = "*__init__.py,*__version__.py,venv"
select = "C101"

[tool.codespell]
skip = '*.svg,models/ssm.py'
skip = '*.svg,models/prompt_templates.py'
ignore-words = 'codespell.txt'

0 comments on commit a3b1c17

Please sign in to comment.