Skip to content

Commit

Permalink
Summarizer is now oop meaning, abstract with inherits classes per mod…
Browse files Browse the repository at this point in the history
…el, one for OpenAI, one for Claude and one for Perplexity.
  • Loading branch information
doribd committed Jun 11, 2024
1 parent d4c0725 commit 96efbe4
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 21 deletions.
14 changes: 0 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,6 @@ This file stores your OpenAI API key:
OPENAI_API_KEY=your_openai_api_key
```

## 🚦 Rate Limiting

To ensure fair usage and prevent any single user or client from consuming too many resources or making too many requests in a short amount of time, I have implemented rate limiting.

Each cloud endpoint (AWS, Azure, and GCP) has a rate limit of 1 request per minute. This means that each client can make up to 1 request per minute to each endpoint.

Here are the rate-limited endpoints:

- AWS News Report: http://localhost:8000/aws
- Azure News Report: http://localhost:8000/azure
- GCP News Report: http://localhost:8000/gcp

If a client exceeds this limit, they will receive a `429 Too Many Requests` response until enough time has passed for the rate limit to reset.

## 🔒 Security

This project uses the following open source Static Application Security Testing (SAST) tools to ensure the quality and
Expand Down
5 changes: 4 additions & 1 deletion feeds/AWSFeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from feeds.RSSFeed import RSSFeed
from summarizer import summarize_text
from summarizers.OpenAISummarizer import OpenAISummarizer


class AWSFeed(RSSFeed):
Expand All @@ -17,6 +18,8 @@ class AWSFeed(RSSFeed):

def __init__(self, filtered_entries):
super().__init__(filtered_entries)
self.summarizer = OpenAISummarizer()


@overrides
def process_entry(self, entry, one_week_ago):
Expand All @@ -29,7 +32,7 @@ def process_entry(self, entry, one_week_ago):
published_date = datetime.strptime(entry.published, '%a, %d %b %Y %H:%M:%S %Z')

if published_date >= one_week_ago:
summary = summarize_text(entry.summary)
summary = self.summarizer.summarize_text(entry.summary)
return {
'title': entry.title,
'link': entry.link,
Expand Down
4 changes: 3 additions & 1 deletion feeds/AzureFeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from feeds.RSSFeed import RSSFeed
from summarizer import summarize_text
from summarizers.OpenAISummarizer import OpenAISummarizer


class AzureFeed(RSSFeed):
Expand All @@ -18,6 +19,7 @@ class AzureFeed(RSSFeed):

def __init__(self, url):
super().__init__(url)
self.summarizer = OpenAISummarizer()

@overrides
def process_entry(self, entry, one_week_ago):
Expand All @@ -35,7 +37,7 @@ def process_entry(self, entry, one_week_ago):
one_week_ago = one_week_ago.replace(tzinfo=utc)

if published_date >= one_week_ago:
summary = summarize_text(entry.summary)
summary = self.summarizer.summarize_text(entry.summary)
return {
'title': entry.title,
'link': entry.link,
Expand Down
5 changes: 4 additions & 1 deletion feeds/GCPFeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from feeds.RSSFeed import RSSFeed
from summarizer import summarize_text
from summarizers.OpenAISummarizer import OpenAISummarizer


class GCPFeed(RSSFeed):
Expand All @@ -19,6 +20,8 @@ class GCPFeed(RSSFeed):

def __init__(self, filtered_entries):
super().__init__(filtered_entries)
self.summarizer = OpenAISummarizer()


@overrides
def process_entry(self, entry, one_week_ago):
Expand All @@ -32,7 +35,7 @@ def process_entry(self, entry, one_week_ago):
now = datetime.now(timezone.utc)
one_week_ago = now - timedelta(days=7)
if updated_date >= one_week_ago:
content_type = summarize_text(entry['content'])
content_type = self.summarizer.summarize_text(entry['content'])
return {
'title': entry.title,
'link': entry.link,
Expand Down
4 changes: 0 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging

import limiter
from fastapi import FastAPI, HTTPException
from fastapi.responses import HTMLResponse

Expand Down Expand Up @@ -34,18 +33,15 @@ def generate_report(feed_class, feed_name):


@app.get("/aws", response_class=HTMLResponse)
@limiter.limit("1/minute")
def aws_report():
return generate_report(AWSFeed, "AWS")


@app.get("/gcp", response_class=HTMLResponse)
@limiter.limit("1/minute")
def gcp_report():
return generate_report(GCPFeed, "GCP")


@app.get("/azure", response_class=HTMLResponse)
@limiter.limit("1/minute")
def azure_report():
return generate_report(AzureFeed, "Azure")
12 changes: 12 additions & 0 deletions summarizers/BaseSummarizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from abc import ABC, abstractmethod
from configparser import ConfigParser


class BaseSummarizer(ABC):
def __init__(self):
self.config = ConfigParser()
self.config.read('config.ini')

@abstractmethod
def summarize_text(self, text):
pass
41 changes: 41 additions & 0 deletions summarizers/ClaudeSummarizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import requests

from summarizers.BaseSummarizer import BaseSummarizer


class ClaudeSummarizer(BaseSummarizer):
def __init__(self):
super().__init__()
self.api_key = self.config.get('CLAUDE', 'api_key')

def summarize_text(self, text):
"""
This function uses the Claude API to summarize provided text.
:param text: the text which will be summarized
:return: summarized text
"""
# Define the API endpoint
url = "https://api.claude.ai/summarize"

# Define the headers for the API request
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}"
}

# Define the body of the API request
data = {
"text": text
}

# Make the API request
response = requests.post(url, headers=headers, json=data)

# Check the response status code
if response.status_code == 200:
# If the request was successful, return the summarized text
return response.json()["summary"]
else:
# If the request was not successful, raise an exception
raise Exception(f"Claude API request failed with status code {response.status_code}")
29 changes: 29 additions & 0 deletions summarizers/OpenAISummarizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import openai

from summarizers.BaseSummarizer import BaseSummarizer


class OpenAISummarizer(BaseSummarizer):
def summarize_text(self, text):
model = self.config.get('OPENAI', 'model')
temperature = self.config.getfloat('OPENAI', 'temperature')
max_tokens = self.config.getint('OPENAI', 'max_tokens')
top_p = self.config.getint('OPENAI', 'top_p')

response = openai.chat.completions.create(
model=model,
messages=[
{
"role": "system",
"content": "Summarize content you are provided with for a second-grade student."
},
{
"role": "user",
"content": f"Summarize the following text in one sentence:\n\n{text}"
}
],
temperature=temperature,
max_tokens=max_tokens,
top_p=top_p
)
return response.choices[0].message.content
41 changes: 41 additions & 0 deletions summarizers/PerplexitySummarizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import requests

from summarizers.BaseSummarizer import BaseSummarizer


class PerplexitySummarizer(BaseSummarizer):
def __init__(self):
super().__init__()
self.api_key = self.config.get('PERPLEXITY', 'api_key')

def summarize_text(self, text):
"""
This function uses the Perplexity API to summarize provided text.
:param text: the text which will be summarized
:return: summarized text
"""
# Define the API endpoint
url = "https://api.perplexity.ai/summarize"

# Define the headers for the API request
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}"
}

# Define the body of the API request
data = {
"text": text
}

# Make the API request
response = requests.post(url, headers=headers, json=data)

# Check the response status code
if response.status_code == 200:
# If the request was successful, return the summarized text
return response.json()["summary"]
else:
# If the request was not successful, raise an exception
raise Exception(f"Perplexity API request failed with status code {response.status_code}")
27 changes: 27 additions & 0 deletions summarizers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Summarizers

This directory contains the classes responsible for text summarization in the project. Each class represents a different
summarization API.

## BaseSummarizer

`BaseSummarizer` is an abstract base class that defines the common interface for all summarizers. It handles the common
functionality such as reading from the `config.ini` file. Any class that inherits from `BaseSummarizer` must implement
the `summarize_text` method.

## [OpenAISummarizer](https://openai.com)

`OpenAISummarizer` is a class that uses the OpenAI API for text summarization. It inherits from `BaseSummarizer` and
implements the `summarize_text` method.

## [ClaudeSummarizer](https://www.example.com)

`ClaudeSummarizer` is a class that uses the Claude API for text summarization. It inherits from `BaseSummarizer` and
implements the `summarize_text` method. The implementation is currently a placeholder and needs to be filled in with the
actual code to call the Claude API and summarize the text.

## [PerplexitySummarizer](https://www.perplexity.ai)

`PerplexitySummarizer` is a class that uses the Perplexity API for text summarization. It inherits from `BaseSummarizer` and
implements the `summarize_text` method.

Empty file added summarizers/__init__.py
Empty file.

0 comments on commit 96efbe4

Please sign in to comment.