Spaces:
Sleeping
Sleeping
Commit
·
7c467fb
0
Parent(s):
Initial commit
Browse files- README.md +25 -0
- eventbrite_summarizer.py +88 -0
README.md
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Event(brite) Summarizer
|
2 |
+
|
3 |
+
Tool for summarizing Eventbrite events for inclusion in event calendars. Takes in a URL and a generic prompt, which are fed into a Large Language Model (in this case OpenAI) along with the event scrapes the title, subtitle, and event details
|
4 |
+
|
5 |
+
Environment Requirements:
|
6 |
+
- Python 3.10
|
7 |
+
- Environment variables `OPENAI_API_KEY` and `EVENTBRITE_API_KEY`, available through the [Eventbrite API Page](https://www.eventbrite.com/platform/api).
|
8 |
+
|
9 |
+
## Eventbrite-specific notes
|
10 |
+
|
11 |
+
The API does not return the event title or subtitle, so we use Beautifulsoup to extract them.
|
12 |
+
|
13 |
+
The user-generated event description can be hard to parse from raw HTML, but is served succinctly via the API. The Eventbrite API appears to use `utf-8-sig` encoding. To handle that encoding, we replace `\uffef` with a null string.
|
14 |
+
|
15 |
+
These inputs (title, subtitle, details) are combined and fed in along with the prompt.
|
16 |
+
|
17 |
+
|
18 |
+
# TODO:
|
19 |
+
|
20 |
+
[ ] Handle Facebook events
|
21 |
+
[ ] Handle errors - will currently error gracelessly on expired events
|
22 |
+
[ ] Meaningfully use feedback / integrate with Weights & Biases
|
23 |
+
[ ] Allow auto-regeneration of text if output does not meet expectation (exclusion characters, etc)
|
24 |
+
[ ] Dropdown for model type
|
25 |
+
|
eventbrite_summarizer.py
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
from bs4 import BeautifulSoup
|
3 |
+
import json
|
4 |
+
import os
|
5 |
+
|
6 |
+
from langchain.llms import OpenAI
|
7 |
+
from langchain.prompts import PromptTemplate
|
8 |
+
import gradio as gr
|
9 |
+
|
10 |
+
EVENTBRITE_API_KEY = os.environ['EVENTBRITE_API_KEY']
|
11 |
+
|
12 |
+
def get_event_id(url):
|
13 |
+
uid = url.split('?')[0]
|
14 |
+
uid = uid.split('/')[-1]
|
15 |
+
uid = uid.split('-')[-1]
|
16 |
+
return uid
|
17 |
+
|
18 |
+
def get_title_subtitle_from_event(event_url):
|
19 |
+
# Get the title and subtitle
|
20 |
+
res = requests.get(url=event_url)
|
21 |
+
soup = BeautifulSoup(res.content, 'html.parser')
|
22 |
+
tag_classes = {'title': 'event-title',
|
23 |
+
'subtitle': 'summary',
|
24 |
+
'details': 'has-user-generated-content'}
|
25 |
+
title = soup.find(class_ = tag_classes['title']).text
|
26 |
+
subtitle = soup.find(class_ = tag_classes['subtitle']).text
|
27 |
+
return title, subtitle
|
28 |
+
|
29 |
+
def get_event_details(event_url):
|
30 |
+
# Now get details:
|
31 |
+
|
32 |
+
event_id = get_event_id(event_url)
|
33 |
+
headers = {'Authorization': 'Bearer {}'.format(EVENTBRITE_API_KEY)}
|
34 |
+
params = {}
|
35 |
+
|
36 |
+
base_url = "https://www.eventbriteapi.com/v3/events/{id}/structured_content/"
|
37 |
+
|
38 |
+
r = requests.get(base_url.format(id=event_id), headers=headers, params=params)
|
39 |
+
effective_encoding = 'utf-8-sig' #r.apparent_encoding #
|
40 |
+
r.encoding = effective_encoding
|
41 |
+
|
42 |
+
res_tree = json.loads(r.text)
|
43 |
+
|
44 |
+
content = res_tree['modules'][0]['data']['body']['text']
|
45 |
+
content = content.replace('\ufeff', '') # Remove byte order mark for utf-8-sig decoding.
|
46 |
+
|
47 |
+
soup = BeautifulSoup(content, 'html.parser')
|
48 |
+
|
49 |
+
details = soup.get_text(separator=' ')
|
50 |
+
return details
|
51 |
+
|
52 |
+
def get_eventbrite_summary(event_url, top_level_prompt_stub):
|
53 |
+
|
54 |
+
title, subtitle = get_title_subtitle_from_event(event_url)
|
55 |
+
details = get_event_details(event_url)
|
56 |
+
|
57 |
+
temperature = 0.3
|
58 |
+
openai_modeltype = "text-davinci-003"
|
59 |
+
|
60 |
+
top_level_prompt = top_level_prompt_stub + """
|
61 |
+
Event Title:{title}
|
62 |
+
Event Subtitle: {subtitle}
|
63 |
+
Event Description:
|
64 |
+
{description}"""
|
65 |
+
|
66 |
+
prompt = PromptTemplate(
|
67 |
+
input_variables=['title', 'subtitle', 'description'],
|
68 |
+
template=top_level_prompt,
|
69 |
+
)
|
70 |
+
|
71 |
+
chat_prompt = prompt.format_prompt(title=title, subtitle=subtitle, description=details)
|
72 |
+
|
73 |
+
llm = OpenAI(model_name=openai_modeltype, temperature=temperature)
|
74 |
+
res = llm(chat_prompt.to_messages()[0].content)
|
75 |
+
return res.strip()
|
76 |
+
|
77 |
+
top_level_prompt_stub = """You are a journalist writing a calendar of events, and need to create succinct, fun, and energizing summaries of events in 1-2 sentences. You will be given a description of an event you need to summarize; please respond with your brief, fun, and engaging summary."""
|
78 |
+
|
79 |
+
|
80 |
+
prompt_textbox = gr.Textbox(value=top_level_prompt_stub)
|
81 |
+
url_textbox = gr.Textbox(value='https://www.eventbrite.com/e/greenermind-summit-2023-tickets-576308392917',
|
82 |
+
placeholder='full eventbrite url')
|
83 |
+
|
84 |
+
demo = gr.Interface(fn=get_eventbrite_summary,
|
85 |
+
inputs=[url_textbox, prompt_textbox],
|
86 |
+
outputs=['text']
|
87 |
+
)
|
88 |
+
demo.launch()
|