MuhammadAhmad332 commited on
Commit
c30d67e
Β·
verified Β·
1 Parent(s): f0a034e

Upload 3 files

Browse files
Files changed (3) hide show
  1. .env +3 -0
  2. app.py +186 -69
  3. requirements.txt +6 -0
.env ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ GROQ_API_KEY=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
2
+ BRIGHT_API_KEY=ded1bc00-4d84-4dee-b4d6-c896cadf2417
3
+ BRIGHT_ZONE=web_unlocker2
app.py CHANGED
@@ -1,69 +1,186 @@
1
- import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
-
5
- def respond(
6
- message,
7
- history: list[dict[str, str]],
8
- system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
13
- ):
14
- """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
16
- """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
18
-
19
- messages = [{"role": "system", "content": system_message}]
20
-
21
- messages.extend(history)
22
-
23
- messages.append({"role": "user", "content": message})
24
-
25
- response = ""
26
-
27
- for message in client.chat_completion(
28
- messages,
29
- max_tokens=max_tokens,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
33
- ):
34
- choices = message.choices
35
- token = ""
36
- if len(choices) and choices[0].delta.content:
37
- token = choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
60
- )
61
-
62
- with gr.Blocks() as demo:
63
- with gr.Sidebar():
64
- gr.LoginButton()
65
- chatbot.render()
66
-
67
-
68
- if __name__ == "__main__":
69
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from bs4 import BeautifulSoup
4
+ from groq import Groq
5
+ import gradio as gr
6
+ from dotenv import load_dotenv
7
+
8
+ load_dotenv()
9
+
10
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
11
+ BRIGHT_API_KEY = os.getenv("BRIGHT_API_KEY")
12
+ BRIGHT_ZONE = os.getenv("BRIGHT_ZONE")
13
+
14
+ client = Groq(api_key=GROQ_API_KEY)
15
+
16
+ # -------------------------------
17
+ # BRIGHT DATA WEB UNLOCKER
18
+ # -------------------------------
19
+
20
+ def brightdata_request(target_url):
21
+ try:
22
+ response = requests.post(
23
+ "https://api.brightdata.com/request",
24
+ headers={
25
+ "Content-Type": "application/json",
26
+ "Authorization": f"Bearer {BRIGHT_API_KEY}"
27
+ },
28
+ json={
29
+ "zone": BRIGHT_ZONE,
30
+ "url": target_url,
31
+ "format": "raw"
32
+ },
33
+ timeout=60
34
+ )
35
+
36
+ response.raise_for_status()
37
+ return response.text
38
+
39
+ except Exception as e:
40
+ return f"ERROR: {str(e)}"
41
+
42
+
43
+ # -------------------------------
44
+ # SCRAPER
45
+ # -------------------------------
46
+
47
+ def scrape_goodreads(url):
48
+ html = brightdata_request(url)
49
+
50
+ if html.startswith("ERROR"):
51
+ return [], html
52
+
53
+ soup = BeautifulSoup(html, "html.parser")
54
+ books = []
55
+
56
+ rows = soup.find_all("tr")
57
+
58
+ for row in rows:
59
+ title_tag = row.find("a", class_="bookTitle")
60
+ author_tag = row.find("a", class_="authorName")
61
+ rating_tag = row.find("span", class_="minirating")
62
+
63
+ if title_tag and author_tag and rating_tag:
64
+ books.append({
65
+ "title": title_tag.get_text(strip=True),
66
+ "author": author_tag.get_text(strip=True),
67
+ "rating": rating_tag.get_text(strip=True)
68
+ })
69
+
70
+ if not books:
71
+ return [], "No books found. Make sure the URL is a Goodreads list page."
72
+
73
+ return books[:10], None
74
+
75
+
76
+ # -------------------------------
77
+ # AI Q&A
78
+ # -------------------------------
79
+
80
+ def qa_bot(url, question):
81
+ books, error = scrape_goodreads(url)
82
+
83
+ if error:
84
+ return f"❌ {error}"
85
+
86
+ context = "\n".join(
87
+ [f"{i+1}. {b['title']} by {b['author']} - {b['rating']}"
88
+ for i, b in enumerate(books)]
89
+ )
90
+
91
+ system_prompt = f"""
92
+ You are a helpful assistant.
93
+
94
+ Here is book data scraped from Goodreads:
95
+
96
+ {context}
97
+
98
+ Answer questions ONLY using this data.
99
+ If the answer is not present, say "The data does not contain that information."
100
+ """
101
+
102
+ try:
103
+ response = client.chat.completions.create(
104
+ model="llama-3.1-8b-instant",
105
+ messages=[
106
+ {"role": "system", "content": system_prompt},
107
+ {"role": "user", "content": question}
108
+ ]
109
+ )
110
+
111
+ return response.choices[0].message.content
112
+
113
+ except Exception as e:
114
+ return f"❌ AI Error: {str(e)}"
115
+
116
+
117
+ # -------------------------------
118
+ # UI LOGIC FUNCTIONS
119
+ # -------------------------------
120
+
121
+ def scrape_and_display(url):
122
+ books, error = scrape_goodreads(url)
123
+
124
+ if error:
125
+ return gr.update(value=[]), error
126
+
127
+ table_data = [[b["title"], b["author"], b["rating"]] for b in books]
128
+
129
+ return table_data, "βœ… Successfully scraped top 10 books."
130
+
131
+
132
+ # -------------------------------
133
+ # GRADIO UI
134
+ # -------------------------------
135
+
136
+ with gr.Blocks(theme=gr.themes.Soft(), title="Goodreads AI Explorer") as demo:
137
+
138
+ gr.Markdown("""
139
+ # πŸ“š Goodreads AI Explorer
140
+ Scrape book data from a Goodreads list and ask AI questions about it.
141
+ """)
142
+
143
+ with gr.Row():
144
+ with gr.Column(scale=2):
145
+ url_input = gr.Textbox(
146
+ label="πŸ”— Goodreads URL",
147
+ placeholder="Paste a Goodreads list URL here..."
148
+ )
149
+
150
+ scrape_btn = gr.Button("πŸ“₯ Scrape Books", variant="primary")
151
+
152
+ status_output = gr.Markdown()
153
+
154
+ books_table = gr.Dataframe(
155
+ headers=["Title", "Author", "Rating"],
156
+ datatype=["str", "str", "str"],
157
+ interactive=False,
158
+ wrap=True
159
+ )
160
+
161
+ with gr.Column(scale=3):
162
+ question_input = gr.Textbox(
163
+ label="πŸ’¬ Ask a Question",
164
+ placeholder="Which book has the highest rating?"
165
+ )
166
+
167
+ ask_btn = gr.Button("πŸ€– Ask AI", variant="secondary")
168
+
169
+ answer_output = gr.Markdown()
170
+
171
+ # Button Actions
172
+
173
+ scrape_btn.click(
174
+ fn=scrape_and_display,
175
+ inputs=url_input,
176
+ outputs=[books_table, status_output]
177
+ )
178
+
179
+ ask_btn.click(
180
+ fn=qa_bot,
181
+ inputs=[url_input, question_input],
182
+ outputs=answer_output
183
+ )
184
+
185
+ if __name__ == "__main__":
186
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio
2
+ requests
3
+ beautifulsoup4
4
+ pandas
5
+ groq
6
+ python-dotenv