Skip to content

Commit

Permalink
feat: Add email provider for integrations
Browse files Browse the repository at this point in the history
Signed-off-by: Diwank Singh Tomer <[email protected]>
  • Loading branch information
creatorrr committed Oct 7, 2024
1 parent 43382e1 commit d253b84
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 214 deletions.
140 changes: 70 additions & 70 deletions agents-api/poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion agents-api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ openai = "^1.41.0"
httpx = "^0.27.0"
sentry-sdk = {extras = ["fastapi"], version = "^2.13.0"}
temporalio = "^1.7.0"
pydantic = {extras = ["email"], version = "^2.8.2"}
pydantic = {extras = ["email"], version = "^2.9.2"}
arrow = "^1.3.0"
jinja2 = "^3.1.4"
jinja2schema = "^0.1.4"
Expand Down
1 change: 1 addition & 0 deletions integrations-service/integrations/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
BrowserBaseLoadOutput,
BrowserBaseSetup,
)
from .email import EmailArguments, EmailOutput, EmailSetup
from .hacker_news import HackerNewsFetchArguments, HackerNewsFetchOutput
from .spider import SpiderFetchArguments, SpiderFetchOutput, SpiderSetup
from .weather import WeatherGetArguments, WeatherGetOutput, WeatherSetup
Expand Down
6 changes: 3 additions & 3 deletions integrations-service/integrations/models/base_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class BaseOutput(BaseModel): ...


class ProviderInfo(BaseModel):
url: Optional[Url]
docs: Optional[Url]
icon: Optional[Url]
url: Optional[Url] = None
docs: Optional[Url] = None
icon: Optional[Url] = None
friendly_name: str


Expand Down
25 changes: 25 additions & 0 deletions integrations-service/integrations/models/email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from pydantic import EmailStr, Field

from .base_models import (
BaseArguments,
BaseOutput,
BaseSetup,
)


class EmailSetup(BaseSetup):
host: str = Field(..., description="The host of the email server")
port: int = Field(..., description="The port of the email server")
user: str = Field(..., description="The username of the email server")
password: str = Field(..., description="The password of the email server")


class EmailArguments(BaseArguments):
to: EmailStr = Field(..., description="The email address to send the email to")
from_: EmailStr = Field(..., alias="from", description="The email address to send the email from")
subject: str = Field(..., description="The subject of the email")
body: str = Field(..., description="The body of the email")


class EmailOutput(BaseOutput):
success: bool = Field(..., description="Whether the email was sent successfully")
4 changes: 4 additions & 0 deletions integrations-service/integrations/models/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
BrowserBaseLoadOutput,
BrowserBaseSetup,
)
from .email import EmailArguments, EmailOutput, EmailSetup
from .hacker_news import HackerNewsFetchArguments, HackerNewsFetchOutput
from .spider import SpiderFetchArguments, SpiderFetchOutput, SpiderSetup
from .weather import WeatherGetArguments, WeatherGetOutput, WeatherSetup
from .wikipedia import WikipediaSearchArguments, WikipediaSearchOutput

ExecutionSetup = Union[
EmailSetup,
SpiderSetup,
WeatherSetup,
BraveSearchSetup,
Expand All @@ -23,6 +25,7 @@
ExecutionArguments = Union[
SpiderFetchArguments,
WeatherGetArguments,
EmailArguments,
HackerNewsFetchArguments,
WikipediaSearchArguments,
BraveSearchArguments,
Expand All @@ -32,6 +35,7 @@
ExecutionResponse = Union[
SpiderFetchOutput,
WeatherGetOutput,
EmailOutput,
HackerNewsFetchOutput,
WikipediaSearchOutput,
BraveSearchOutput,
Expand Down
20 changes: 20 additions & 0 deletions integrations-service/integrations/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
BrowserBaseLoadArguments,
BrowserBaseLoadOutput,
BrowserBaseSetup,
EmailArguments,
EmailOutput,
EmailSetup,
HackerNewsFetchArguments,
HackerNewsFetchOutput,
ProviderInfo,
Expand Down Expand Up @@ -134,11 +137,28 @@
),
)

email = BaseProvider(
provider="email",
setup=EmailSetup,
methods=[
BaseProviderMethod(
method="send",
description="Send an email",
arguments=EmailArguments,
output=EmailOutput,
),
],
info=ProviderInfo(
friendly_name="Email",
),
)

providers = {
"wikipedia": wikipedia,
"weather": weather,
"hacker_news": hacker_news,
"spider": spider,
"brave": brave,
"browserbase": browserbase,
"email": email,
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,15 @@ async def execute_integration(

if setup:
setup_class = provider.setup
if setup_class:
if setup_class and not isinstance(setup, setup_class):
setup = setup_class(**setup.model_dump())

arguments_class = next(m for m in provider.methods if m.method == method).arguments
parsed_arguments = arguments_class(**arguments.model_dump())

if not isinstance(arguments, arguments_class):
parsed_arguments = arguments_class(**arguments.model_dump())
else:
parsed_arguments = arguments

if setup:
return await execution_function(setup=setup, arguments=parsed_arguments)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .brave import search
from .browserbase import load
from .email import send
from .hacker_news import fetch
from .spider import crawl
from .weather import get
Expand Down
27 changes: 27 additions & 0 deletions integrations-service/integrations/utils/integrations/email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from email.message import EmailMessage
from smtplib import SMTP

from beartype import beartype

from ...models import EmailArguments, EmailOutput, EmailSetup


# @beartype
async def send(
setup: EmailSetup, arguments: EmailArguments
) -> EmailOutput:
"""
Sends an email with the provided details.
"""

message = EmailMessage()
message.set_content(arguments.body)
message["Subject"] = arguments.subject
message["From"] = arguments.from_
message["To"] = arguments.to

with SMTP(setup.host, setup.port) as server:
server.login(setup.user, setup.password)
server.send_message(message)

return EmailOutput(success=True)
Loading

0 comments on commit d253b84

Please sign in to comment.