joshuadunlop commited on
Commit
1793d7d
·
verified ·
1 Parent(s): a905e36

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -72
app.py CHANGED
@@ -9,43 +9,28 @@ import csv
9
 
10
  def get_backlinks(api_login, api_key, target_url, filters):
11
  encoded_credentials = base64.b64encode(f"{api_login}:{api_key}".encode()).decode()
12
- headers = {
13
- 'Authorization': f'Basic {encoded_credentials}'
14
- }
15
- post_data = {
16
- 0: {
17
- "target": target_url,
18
- "limit": 1000,
19
- "mode": "as_is",
20
- "filters": filters
21
- }
22
- }
23
  response = requests.post("https://api.dataforseo.com/v3/backlinks/backlinks/live", json=post_data, headers=headers)
24
  if response.status_code == 200:
25
  response_data = response.json()
26
- if 'tasks' in response_data:
27
- task_result = response_data['tasks'][0]['result']
28
- if task_result and 'items' in task_result[0]:
29
- items = task_result[0]['items']
30
- df = pd.json_normalize(items)
31
- return df
32
- else:
33
- st.error("Received empty 'result' from API or missing 'items'.")
34
- return None
35
  else:
36
- st.error(f"No 'tasks' key in response JSON. Full response: {response_data}")
37
- return None
38
  else:
39
- error_message = response.json().get('status_message', 'No specific error message provided')
40
- st.error(f"Error: Code: {response.status_code} Message: {error_message}")
41
- return None
42
 
43
  def convert_df_to_csv(df):
44
  return df.to_csv(index=False).encode('utf-8')
45
 
46
  class BacklinkWorker(threading.Thread):
47
  def __init__(self, jobs, results, api_login, api_key):
48
- super().__init__()
49
  self.jobs = jobs
50
  self.results = results
51
  self.api_login = api_login
@@ -54,16 +39,18 @@ class BacklinkWorker(threading.Thread):
54
  def run(self):
55
  while True:
56
  job = self.jobs.get()
57
- if job is None:
 
58
  break
59
  url_id, target_url, filters = job
60
  df = get_backlinks(self.api_login, self.api_key, target_url, filters)
61
- self.results.put((url_id, df))
 
62
 
63
  def process_pasted_data(data):
64
- data_io = StringIO(data.strip())
65
- reader = csv.reader(data_io, delimiter='\n', quotechar='"')
66
- return [row[0] for row in reader]
67
 
68
  st.sidebar.title("DataForSEO API Parameters")
69
  api_login = st.sidebar.text_input("API Login", value="[email protected]")
@@ -126,63 +113,49 @@ add_row = st.sidebar.button("Add Row")
126
  reset = st.sidebar.button("Reset")
127
 
128
  if paste_data:
129
- pasted_urls = process_pasted_data(data_section)
130
- for i, url in enumerate(pasted_urls):
131
- st.session_state[f"target_url_{i}"] = url
132
- st.session_state["row_count"] = len(pasted_urls)
133
 
134
  if add_row:
135
- row_count = st.session_state.get("row_count", 0) + 1
136
- st.session_state["row_count"] = row_count
 
 
137
 
138
  if reset:
139
  st.session_state.clear()
140
 
141
- row_count = st.session_state.get("row_count", 1)
142
- for i in range(row_count):
143
- col1, col2 = st.columns([3, 1])
144
- target_url_key = f"target_url_{i}"
145
- with col1:
146
- target_url = st.text_input(f"Enter the target URL {i + 1}", key=target_url_key)
147
- df_key = f"df_{i}"
148
- df = st.session_state.get(df_key)
149
- with col2:
150
- if df is not None:
151
- csv = convert_df_to_csv(df)
152
- st.download_button(
153
- label=f"Download CSV for URL {i + 1}",
154
- data=csv,
155
- file_name=f'backlinks_{i + 1}.csv',
156
- mime='text/csv',
157
- )
158
- elif df is None and st.sidebar.button("Generate All"):
159
- st.error(f"Failed for URL {i + 1}: No data or error.")
160
-
161
- if 'generate_clicked' not in st.session_state:
162
- st.session_state['generate_clicked'] = False
163
-
164
- generate_button = st.sidebar.button("Generate All", key="generate_all")
165
-
166
- if generate_button or st.session_state['generate_clicked']:
167
- st.session_state['generate_clicked'] = True
168
  jobs = Queue()
169
- results = Queue()
170
  workers = [BacklinkWorker(jobs, results, api_login, api_key) for _ in range(num_concurrent_calls)]
171
 
172
  for worker in workers:
173
  worker.start()
174
 
175
- for i in range(row_count):
176
- target_url = st.session_state.get(f"target_url_{i}", "")
177
  if target_url:
178
- jobs.put((i, target_url, filters))
179
 
180
  for _ in workers:
181
- jobs.put(None)
182
 
183
  for worker in workers:
184
  worker.join()
185
 
186
- while not results.empty():
187
- url_id, df = results.get()
188
- st.session_state[f"df_{url_id}"] = df
 
 
 
 
 
 
 
9
 
10
  def get_backlinks(api_login, api_key, target_url, filters):
11
  encoded_credentials = base64.b64encode(f"{api_login}:{api_key}".encode()).decode()
12
+ headers = {'Authorization': f'Basic {encoded_credentials}'}
13
+ post_data = {0: {"target": target_url, "limit": 1000, "mode": "as_is", "filters": filters}}
 
 
 
 
 
 
 
 
 
14
  response = requests.post("https://api.dataforseo.com/v3/backlinks/backlinks/live", json=post_data, headers=headers)
15
  if response.status_code == 200:
16
  response_data = response.json()
17
+ if 'tasks' in response_data and 'result' in response_data['tasks'][0]:
18
+ items = response_data['tasks'][0]['result'][0]['items']
19
+ df = pd.json_normalize(items)
20
+ return df
 
 
 
 
 
21
  else:
22
+ st.error("No data found or an error occurred.")
23
+ return pd.DataFrame()
24
  else:
25
+ st.error(f"API Error: {response.status_code}")
26
+ return pd.DataFrame()
 
27
 
28
  def convert_df_to_csv(df):
29
  return df.to_csv(index=False).encode('utf-8')
30
 
31
  class BacklinkWorker(threading.Thread):
32
  def __init__(self, jobs, results, api_login, api_key):
33
+ threading.Thread.__init__(self)
34
  self.jobs = jobs
35
  self.results = results
36
  self.api_login = api_login
 
39
  def run(self):
40
  while True:
41
  job = self.jobs.get()
42
+ if job is None: # Sentinel value to end the thread
43
+ self.jobs.task_done()
44
  break
45
  url_id, target_url, filters = job
46
  df = get_backlinks(self.api_login, self.api_key, target_url, filters)
47
+ self.results[url_id] = df
48
+ self.jobs.task_done()
49
 
50
  def process_pasted_data(data):
51
+ data_io = StringIO(data)
52
+ reader = csv.reader(data_io, delimiter='\n')
53
+ return [row[0] for row in reader if row]
54
 
55
  st.sidebar.title("DataForSEO API Parameters")
56
  api_login = st.sidebar.text_input("API Login", value="[email protected]")
 
113
  reset = st.sidebar.button("Reset")
114
 
115
  if paste_data:
116
+ st.session_state.pasted_urls = process_pasted_data(data_section)
117
+ st.session_state.row_count = len(st.session_state.pasted_urls)
 
 
118
 
119
  if add_row:
120
+ if 'row_count' not in st.session_state:
121
+ st.session_state.row_count = 1
122
+ else:
123
+ st.session_state.row_count += 1
124
 
125
  if reset:
126
  st.session_state.clear()
127
 
128
+ # URL Input Fields
129
+ for i in range(st.session_state.get('row_count', 1)):
130
+ st.text_input(f"Enter the target URL {i + 1}", key=f"target_url_{i}")
131
+
132
+ # Generate All Button
133
+ if st.sidebar.button("Generate All", key="generate_all"):
134
+ st.session_state.generated = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  jobs = Queue()
136
+ results = {}
137
  workers = [BacklinkWorker(jobs, results, api_login, api_key) for _ in range(num_concurrent_calls)]
138
 
139
  for worker in workers:
140
  worker.start()
141
 
142
+ for i in range(st.session_state.get('row_count', 1)):
143
+ target_url = st.session_state.get(f"target_url_{i}")
144
  if target_url:
145
+ jobs.put((i, target_url, filters)) # Assume filters are defined elsewhere
146
 
147
  for _ in workers:
148
+ jobs.put(None) # Add sentinel values to stop the workers
149
 
150
  for worker in workers:
151
  worker.join()
152
 
153
+ for i, df in results.items():
154
+ st.session_state[f'df_{i}'] = df
155
+
156
+ # Display Download Buttons
157
+ for i in range(st.session_state.get('row_count', 1)):
158
+ df = st.session_state.get(f'df_{i}')
159
+ if df is not None and not df.empty:
160
+ csv = convert_df_to_csv(df)
161
+ st.download_button(f"Download CSV for URL {i + 1}", csv, f"backlinks_{i + 1}.csv", "text/csv", key=f"download_{i}")