Upload 8 files
Browse files- .gitattributes +1 -0
- LICENSE +201 -0
- LinkedIn_company_info_modified.json +0 -0
- LinkedIn_profiles_info_modified.json +0 -0
- README.md +93 -14
- app.py +510 -0
- chat_history.db +0 -0
- leads.db +3 -0
- requirements.txt +6 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
leads.db filter=lfs diff=lfs merge=lfs -text
|
LICENSE
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Apache License
|
2 |
+
Version 2.0, January 2004
|
3 |
+
http://www.apache.org/licenses/
|
4 |
+
|
5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6 |
+
|
7 |
+
1. Definitions.
|
8 |
+
|
9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
11 |
+
|
12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
13 |
+
the copyright owner that is granting the License.
|
14 |
+
|
15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
16 |
+
other entities that control, are controlled by, or are under common
|
17 |
+
control with that entity. For the purposes of this definition,
|
18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
19 |
+
direction or management of such entity, whether by contract or
|
20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
22 |
+
|
23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
24 |
+
exercising permissions granted by this License.
|
25 |
+
|
26 |
+
"Source" form shall mean the preferred form for making modifications,
|
27 |
+
including but not limited to software source code, documentation
|
28 |
+
source, and configuration files.
|
29 |
+
|
30 |
+
"Object" form shall mean any form resulting from mechanical
|
31 |
+
transformation or translation of a Source form, including but
|
32 |
+
not limited to compiled object code, generated documentation,
|
33 |
+
and conversions to other media types.
|
34 |
+
|
35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
36 |
+
Object form, made available under the License, as indicated by a
|
37 |
+
copyright notice that is included in or attached to the work
|
38 |
+
(an example is provided in the Appendix below).
|
39 |
+
|
40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
41 |
+
form, that is based on (or derived from) the Work and for which the
|
42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
44 |
+
of this License, Derivative Works shall not include works that remain
|
45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
46 |
+
the Work and Derivative Works thereof.
|
47 |
+
|
48 |
+
"Contribution" shall mean any work of authorship, including
|
49 |
+
the original version of the Work and any modifications or additions
|
50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
54 |
+
means any form of electronic, verbal, or written communication sent
|
55 |
+
to the Licensor or its representatives, including but not limited to
|
56 |
+
communication on electronic mailing lists, source code control systems,
|
57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
59 |
+
excluding communication that is conspicuously marked or otherwise
|
60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
61 |
+
|
62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
64 |
+
subsequently incorporated within the Work.
|
65 |
+
|
66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
71 |
+
Work and such Derivative Works in Source or Object form.
|
72 |
+
|
73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
76 |
+
(except as stated in this section) patent license to make, have made,
|
77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
78 |
+
where such license applies only to those patent claims licensable
|
79 |
+
by such Contributor that are necessarily infringed by their
|
80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
82 |
+
institute patent litigation against any entity (including a
|
83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
84 |
+
or a Contribution incorporated within the Work constitutes direct
|
85 |
+
or contributory patent infringement, then any patent licenses
|
86 |
+
granted to You under this License for that Work shall terminate
|
87 |
+
as of the date such litigation is filed.
|
88 |
+
|
89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
90 |
+
Work or Derivative Works thereof in any medium, with or without
|
91 |
+
modifications, and in Source or Object form, provided that You
|
92 |
+
meet the following conditions:
|
93 |
+
|
94 |
+
(a) You must give any other recipients of the Work or
|
95 |
+
Derivative Works a copy of this License; and
|
96 |
+
|
97 |
+
(b) You must cause any modified files to carry prominent notices
|
98 |
+
stating that You changed the files; and
|
99 |
+
|
100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
101 |
+
that You distribute, all copyright, patent, trademark, and
|
102 |
+
attribution notices from the Source form of the Work,
|
103 |
+
excluding those notices that do not pertain to any part of
|
104 |
+
the Derivative Works; and
|
105 |
+
|
106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
107 |
+
distribution, then any Derivative Works that You distribute must
|
108 |
+
include a readable copy of the attribution notices contained
|
109 |
+
within such NOTICE file, excluding those notices that do not
|
110 |
+
pertain to any part of the Derivative Works, in at least one
|
111 |
+
of the following places: within a NOTICE text file distributed
|
112 |
+
as part of the Derivative Works; within the Source form or
|
113 |
+
documentation, if provided along with the Derivative Works; or,
|
114 |
+
within a display generated by the Derivative Works, if and
|
115 |
+
wherever such third-party notices normally appear. The contents
|
116 |
+
of the NOTICE file are for informational purposes only and
|
117 |
+
do not modify the License. You may add Your own attribution
|
118 |
+
notices within Derivative Works that You distribute, alongside
|
119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
120 |
+
that such additional attribution notices cannot be construed
|
121 |
+
as modifying the License.
|
122 |
+
|
123 |
+
You may add Your own copyright statement to Your modifications and
|
124 |
+
may provide additional or different license terms and conditions
|
125 |
+
for use, reproduction, or distribution of Your modifications, or
|
126 |
+
for any such Derivative Works as a whole, provided Your use,
|
127 |
+
reproduction, and distribution of the Work otherwise complies with
|
128 |
+
the conditions stated in this License.
|
129 |
+
|
130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
132 |
+
by You to the Licensor shall be under the terms and conditions of
|
133 |
+
this License, without any additional terms or conditions.
|
134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
135 |
+
the terms of any separate license agreement you may have executed
|
136 |
+
with Licensor regarding such Contributions.
|
137 |
+
|
138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
140 |
+
except as required for reasonable and customary use in describing the
|
141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
142 |
+
|
143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
144 |
+
agreed to in writing, Licensor provides the Work (and each
|
145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147 |
+
implied, including, without limitation, any warranties or conditions
|
148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
150 |
+
appropriateness of using or redistributing the Work and assume any
|
151 |
+
risks associated with Your exercise of permissions under this License.
|
152 |
+
|
153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
154 |
+
whether in tort (including negligence), contract, or otherwise,
|
155 |
+
unless required by applicable law (such as deliberate and grossly
|
156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
157 |
+
liable to You for damages, including any direct, indirect, special,
|
158 |
+
incidental, or consequential damages of any character arising as a
|
159 |
+
result of this License or out of the use or inability to use the
|
160 |
+
Work (including but not limited to damages for loss of goodwill,
|
161 |
+
work stoppage, computer failure or malfunction, or any and all
|
162 |
+
other commercial damages or losses), even if such Contributor
|
163 |
+
has been advised of the possibility of such damages.
|
164 |
+
|
165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
168 |
+
or other liability obligations and/or rights consistent with this
|
169 |
+
License. However, in accepting such obligations, You may act only
|
170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
171 |
+
of any other Contributor, and only if You agree to indemnify,
|
172 |
+
defend, and hold each Contributor harmless for any liability
|
173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
174 |
+
of your accepting any such warranty or additional liability.
|
175 |
+
|
176 |
+
END OF TERMS AND CONDITIONS
|
177 |
+
|
178 |
+
APPENDIX: How to apply the Apache License to your work.
|
179 |
+
|
180 |
+
To apply the Apache License to your work, attach the following
|
181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
182 |
+
replaced with your own identifying information. (Don't include
|
183 |
+
the brackets!) The text should be enclosed in the appropriate
|
184 |
+
comment syntax for the file format. We also recommend that a
|
185 |
+
file or class name and description of purpose be included on the
|
186 |
+
same "printed page" as the copyright notice for easier
|
187 |
+
identification within third-party archives.
|
188 |
+
|
189 |
+
Copyright [yyyy] [name of copyright owner]
|
190 |
+
|
191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
192 |
+
you may not use this file except in compliance with the License.
|
193 |
+
You may obtain a copy of the License at
|
194 |
+
|
195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
196 |
+
|
197 |
+
Unless required by applicable law or agreed to in writing, software
|
198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
200 |
+
See the License for the specific language governing permissions and
|
201 |
+
limitations under the License.
|
LinkedIn_company_info_modified.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
LinkedIn_profiles_info_modified.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
README.md
CHANGED
@@ -1,14 +1,93 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# LeadGenAI - LinkedIn Lead Generation and Business Optimization App
|
2 |
+
|
3 |
+
LeadGenAI is a Streamlit-based application that empowers users to generate leads from LinkedIn and optimize their business strategies using the power of IBM Watsonx AI. This application offers two core functionalities: lead generation based on specific criteria and AI-powered business plan generation.
|
4 |
+
|
5 |
+
## Features
|
6 |
+
|
7 |
+
**Lead Generation:**
|
8 |
+
|
9 |
+
* **Targeted Search:** Filter LinkedIn profiles based on criteria like country, industry, and company.
|
10 |
+
* **Data Extraction:** Extract key information such as name, location, company, position, and about section.
|
11 |
+
* **Data Export:** Download leads as CSV and PDF files for easy access and sharing.
|
12 |
+
* **Session History:** Access and download previous lead generation sessions.
|
13 |
+
|
14 |
+
**Business Optimization:**
|
15 |
+
|
16 |
+
* **AI-Powered Business Plans:** Generate comprehensive business plans based on user-provided requirements.
|
17 |
+
* **Detailed Insights:** Receive detailed business plans including concept, target audience, revenue model, key differentiators, and potential challenges.
|
18 |
+
* **Lead Targeting:** Get specific lead suggestions with links to Twitter, LinkedIn, and company websites.
|
19 |
+
* **Session History:** Review and download past business plan generation sessions.
|
20 |
+
|
21 |
+
## Installation
|
22 |
+
|
23 |
+
1. **Clone the Repository:**
|
24 |
+
```bash
|
25 |
+
git clone https://github.com/your-username/LeadGenAI.git
|
26 |
+
```
|
27 |
+
|
28 |
+
2. **Create a Virtual Environment (Recommended):**
|
29 |
+
```bash
|
30 |
+
python3 -m venv .venv
|
31 |
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
32 |
+
```
|
33 |
+
|
34 |
+
3. **Install Dependencies:**
|
35 |
+
```bash
|
36 |
+
pip install -r requirements.txt
|
37 |
+
```
|
38 |
+
`requirements.txt` should contain the following:
|
39 |
+
```
|
40 |
+
streamlit
|
41 |
+
pandas
|
42 |
+
fpdf
|
43 |
+
ibm-watsonx-ai
|
44 |
+
sqlite3
|
45 |
+
json
|
46 |
+
```
|
47 |
+
|
48 |
+
4. **IBM Watsonx Credentials:**
|
49 |
+
You will need an IBM Watsonx account and API key. Store these credentials securely. The app currently stores credentials directly in the `get_credentials()` function, but this should be updated to a more secure method such as environment variables or a secrets management tool. Update the placeholder values in the `get_credentials()` function with your actual credentials:
|
50 |
+
```python
|
51 |
+
def get_credentials():
|
52 |
+
return {
|
53 |
+
"url": "YOUR_WATSONX_URL",
|
54 |
+
"apikey": "YOUR_WATSONX_API_KEY"
|
55 |
+
}
|
56 |
+
```
|
57 |
+
|
58 |
+
5. **Data Files:**
|
59 |
+
Ensure the `LinkedIn_profiles_info_modified.json` and `LinkedIn_company_info_modified.json` files are present in the same directory as the application. These files contain the LinkedIn data. The format is expected to be JSON. If the files do not start with `[`, the app will attempt to convert them to a valid JSON array.
|
60 |
+
|
61 |
+
## Usage
|
62 |
+
|
63 |
+
1. **Run the App:**
|
64 |
+
```bash
|
65 |
+
streamlit run app.py
|
66 |
+
```
|
67 |
+
|
68 |
+
2. **Lead Generation:**
|
69 |
+
- Enter your lead search criteria in the text area.
|
70 |
+
- Select the desired number of leads.
|
71 |
+
- Click "Generate Leads".
|
72 |
+
|
73 |
+
3. **Business Optimization:**
|
74 |
+
- Enter your business idea requirements in the text area.
|
75 |
+
- Click "Generate Idea & Leads".
|
76 |
+
- Download the generated business plan as a PDF.
|
77 |
+
|
78 |
+
4. **Accessing Past Sessions:**
|
79 |
+
Use the tabs to navigate to "Lead Sessions" or "Plan Sessions" to view and download data from previous runs.
|
80 |
+
|
81 |
+
|
82 |
+
## Technologies Used
|
83 |
+
|
84 |
+
* **Streamlit:** For building the interactive web application.
|
85 |
+
* **Pandas:** For data manipulation and analysis.
|
86 |
+
* **FPDF:** For generating PDF reports.
|
87 |
+
* **IBM Watsonx AI:** For generating business plans and ideas.
|
88 |
+
* **SQLite:** For storing session data.
|
89 |
+
* **JSON:** For data storage and exchange.
|
90 |
+
|
91 |
+
## License
|
92 |
+
|
93 |
+
Apache License Version 2.0
|
app.py
ADDED
@@ -0,0 +1,510 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sqlite3
|
3 |
+
import streamlit as st
|
4 |
+
import pandas as pd
|
5 |
+
import json
|
6 |
+
from fpdf import FPDF
|
7 |
+
from ibm_watsonx_ai.foundation_models import ModelInference
|
8 |
+
|
9 |
+
# Function to get IBM Watsonx credentials
|
10 |
+
def get_credentials():
|
11 |
+
return {
|
12 |
+
"url": "https://us-south.ml.cloud.ibm.com",
|
13 |
+
"apikey": "e8jfiewbLaLuUoz_4ZAybPHwwrBOosuNGXipuP9Mwmu2"
|
14 |
+
}
|
15 |
+
|
16 |
+
# Initialize the IBM Watsonx model
|
17 |
+
def initialize_model():
|
18 |
+
model_id = "ibm/granite-3-8b-instruct"
|
19 |
+
parameters = {
|
20 |
+
"decoding_method": "greedy",
|
21 |
+
"max_new_tokens": 900,
|
22 |
+
"min_new_tokens": 0,
|
23 |
+
"repetition_penalty": 1
|
24 |
+
}
|
25 |
+
project_id = "e6b523ca-d2f8-412d-9f70-8bc99c542b68"
|
26 |
+
model = ModelInference(
|
27 |
+
model_id=model_id,
|
28 |
+
params=parameters,
|
29 |
+
credentials=get_credentials(),
|
30 |
+
project_id=project_id
|
31 |
+
)
|
32 |
+
return model
|
33 |
+
|
34 |
+
# Function to load JSON data
|
35 |
+
def load_json_data(file_path):
|
36 |
+
with open(file_path, 'r') as file:
|
37 |
+
content = file.read()
|
38 |
+
if not content.strip().startswith('['):
|
39 |
+
content = '[' + content.replace('}\n{', '},{') + ']'
|
40 |
+
return json.loads(content)
|
41 |
+
|
42 |
+
# Function to initialize SQLite database for leads
|
43 |
+
def init_leads_db():
|
44 |
+
conn = sqlite3.connect('leads.db')
|
45 |
+
c = conn.cursor()
|
46 |
+
c.execute('''CREATE TABLE IF NOT EXISTS user_leads
|
47 |
+
(id INTEGER PRIMARY KEY, name TEXT, city TEXT, country_code TEXT, region TEXT,
|
48 |
+
current_company_company_id TEXT, current_company_name TEXT, position TEXT,
|
49 |
+
following INTEGER, about TEXT, posts INTEGER, groups INTEGER,
|
50 |
+
current_company TEXT, experience TEXT, url TEXT,
|
51 |
+
people_also_viewed TEXT, educations_details TEXT, education TEXT,
|
52 |
+
avatar TEXT, languages TEXT, certifications TEXT,
|
53 |
+
recommendations TEXT, recommendations_count INTEGER,
|
54 |
+
volunteer_experience TEXT, courses TEXT)''')
|
55 |
+
c.execute('''CREATE TABLE IF NOT EXISTS company_leads
|
56 |
+
(id INTEGER PRIMARY KEY, name TEXT, country_code TEXT, locations TEXT,
|
57 |
+
formatted_locations TEXT, followers INTEGER, employees_in_linkedin INTEGER,
|
58 |
+
about TEXT, specialties TEXT, company_size TEXT, organization_type TEXT,
|
59 |
+
industries TEXT, website TEXT, crunchbase_url TEXT, founded TEXT,
|
60 |
+
company_id TEXT, employees TEXT, headquarters TEXT, image TEXT,
|
61 |
+
logo TEXT, similar TEXT, sphere TEXT, url TEXT, type TEXT,
|
62 |
+
updates TEXT, slogan TEXT, affiliated TEXT, funding TEXT,
|
63 |
+
stock_info TEXT, investors TEXT)''')
|
64 |
+
conn.commit()
|
65 |
+
return conn
|
66 |
+
|
67 |
+
# Function to save leads to SQLite database
|
68 |
+
def save_leads_to_db(conn, leads, table_name):
|
69 |
+
c = conn.cursor()
|
70 |
+
for lead in leads:
|
71 |
+
if table_name == 'user_leads':
|
72 |
+
c.execute('''INSERT INTO user_leads
|
73 |
+
(name, city, country_code, region, current_company_company_id,
|
74 |
+
current_company_name, position, following, about, posts, groups,
|
75 |
+
current_company, experience, url, people_also_viewed,
|
76 |
+
educations_details, education, avatar, languages, certifications,
|
77 |
+
recommendations, recommendations_count, volunteer_experience, courses)
|
78 |
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
|
79 |
+
(lead['name'], lead['city'], lead['country_code'], lead['region'],
|
80 |
+
lead['current_company:company_id'], lead['current_company:name'],
|
81 |
+
lead['position'], lead['following'], lead['about'], lead['posts'],
|
82 |
+
lead['groups'], lead['current_company'], lead['experience'],
|
83 |
+
lead['url'], str(lead['people_also_viewed']), lead['educations_details'],
|
84 |
+
lead['education'], lead['avatar'], str(lead['languages']),
|
85 |
+
str(lead['certifications']), str(lead['recommendations']),
|
86 |
+
lead['recommendations_count'], lead['volunteer_experience'],
|
87 |
+
str(lead['сourses'])))
|
88 |
+
elif table_name == 'company_leads':
|
89 |
+
c.execute('''INSERT INTO company_leads
|
90 |
+
(name, country_code, locations, formatted_locations, followers,
|
91 |
+
employees_in_linkedin, about, specialties, company_size,
|
92 |
+
organization_type, industries, website, crunchbase_url, founded,
|
93 |
+
company_id, employees, headquarters, image, logo, similar,
|
94 |
+
sphere, url, type, updates, slogan, affiliated, funding,
|
95 |
+
stock_info, investors)
|
96 |
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
|
97 |
+
(lead['name'], lead['country_code'], str(lead['locations']),
|
98 |
+
str(lead['formatted_locations']), lead['followers'],
|
99 |
+
lead['employees_in_linkedin'], lead['about'], lead['specialties'],
|
100 |
+
lead['company_size'], lead['organization_type'], str(lead['industries']),
|
101 |
+
lead['website'], lead['crunchbase_url'], lead['founded'],
|
102 |
+
lead['company_id'], lead['employees'], lead['headquarters'],
|
103 |
+
lead['image'], lead['logo'], str(lead['similar']), lead['sphere'],
|
104 |
+
lead['url'], lead['type'], lead['updates'], lead['slogan'],
|
105 |
+
lead['affiliated'], lead['funding'], lead['stock_info'],
|
106 |
+
str(lead['investors'])))
|
107 |
+
conn.commit()
|
108 |
+
|
109 |
+
# Function to filter leads based on user input
|
110 |
+
def filter_leads(leads, filter_key, filter_value):
|
111 |
+
filtered_leads = []
|
112 |
+
for lead in leads:
|
113 |
+
if filter_key in lead and lead[filter_key] == filter_value:
|
114 |
+
filtered_leads.append(lead)
|
115 |
+
return filtered_leads
|
116 |
+
|
117 |
+
# Function to extract filtering criteria from user input
|
118 |
+
def extract_filter_criteria(user_input):
|
119 |
+
country_mapping = {
|
120 |
+
"afghanistan": "AF", "albania": "AL", "algeria": "DZ", "andorra": "AD", "angola": "AO",
|
121 |
+
"antigua and barbuda": "AG", "argentina": "AR", "armenia": "AM", "australia": "AU", "austria": "AT",
|
122 |
+
"azerbaijan": "AZ", "bahamas": "BS", "bahrain": "BH", "bangladesh": "BD", "barbados": "BB",
|
123 |
+
"belarus": "BY", "belgium": "BE", "belize": "BZ", "benin": "BJ", "bhutan": "BT",
|
124 |
+
"bolivia": "BO", "bosnia and herzegovina": "BA", "botswana": "BW", "brazil": "BR", "brunei": "BN",
|
125 |
+
"bulgaria": "BG", "burkina faso": "BF", "burundi": "BI", "cabo verde": "CV", "cambodia": "KH",
|
126 |
+
"cameroon": "CM", "canada": "CA", "central african republic": "CF", "chad": "TD", "chile": "CL",
|
127 |
+
"china": "CN", "colombia": "CO", "comoros": "KM", "congo": "CG", "costa rica": "CR",
|
128 |
+
"croatia": "HR", "cuba": "CU", "cyprus": "CY", "czech republic": "CZ", "denmark": "DK",
|
129 |
+
"djibouti": "DJ", "dominica": "DM", "dominican republic": "DO", "ecuador": "EC", "egypt": "EG",
|
130 |
+
"el salvador": "SV", "equatorial guinea": "GQ", "eritrea": "ER", "estonia": "EE", "eswatini": "SZ",
|
131 |
+
"ethiopia": "ET", "fiji": "FJ", "finland": "FI", "france": "FR", "gabon": "GA",
|
132 |
+
"gambia": "GM", "georgia": "GE", "germany": "DE", "ghana": "GH", "greece": "GR",
|
133 |
+
"grenada": "GD", "guatemala": "GT", "guinea": "GN", "guinea-bissau": "GW", "guyana": "GY",
|
134 |
+
"haiti": "HT", "honduras": "HN", "hungary": "HU", "iceland": "IS", "india": "IN",
|
135 |
+
"indonesia": "ID", "iran": "IR", "iraq": "IQ", "ireland": "IE", "israel": "IL",
|
136 |
+
"italy": "IT", "jamaica": "JM", "japan": "JP", "jordan": "JO", "kazakhstan": "KZ",
|
137 |
+
"kenya": "KE", "kiribati": "KI", "korea, north": "KP", "korea, south": "KR", "kosovo": "XK",
|
138 |
+
"kuwait": "KW", "kyrgyzstan": "KG", "laos": "LA", "latvia": "LV", "lebanon": "LB",
|
139 |
+
"lesotho": "LS", "liberia": "LR", "libya": "LY", "liechtenstein": "LI", "lithuania": "LT",
|
140 |
+
"luxembourg": "LU", "madagascar": "MG", "malawi": "MW", "malaysia": "MY", "maldives": "MV",
|
141 |
+
"mali": "ML", "malta": "MT", "marshall islands": "MH", "mauritania": "MR", "mauritius": "MU",
|
142 |
+
"mexico": "MX", "micronesia": "FM", "moldova": "MD", "monaco": "MC", "mongolia": "MN",
|
143 |
+
"montenegro": "ME", "morocco": "MA", "mozambique": "MZ", "myanmar": "MM", "namibia": "NA",
|
144 |
+
"nauru": "NR", "nepal": "NP", "netherlands": "NL", "new zealand": "NZ", "nicaragua": "NI",
|
145 |
+
"niger": "NE", "nigeria": "NG", "north macedonia": "MK", "norway": "NO", "oman": "OM",
|
146 |
+
"pakistan": "PK", "palau": "PW", "panama": "PA", "papua new guinea": "PG", "paraguay": "PY",
|
147 |
+
"peru": "PE", "philippines": "PH", "poland": "PL", "portugal": "PT", "qatar": "QA",
|
148 |
+
"romania": "RO", "russia": "RU", "rwanda": "RW", "saint kitts and nevis": "KN", "saint lucia": "LC",
|
149 |
+
"saint vincent and the grenadines": "VC", "samoa": "WS", "san marino": "SM", "sao tome and principe": "ST",
|
150 |
+
"saudi arabia": "SA", "senegal": "SN", "serbia": "RS", "seychelles": "SC", "sierra leone": "SL",
|
151 |
+
"singapore": "SG", "slovakia": "SK", "slovenia": "SI", "solomon islands": "SB", "somalia": "SO",
|
152 |
+
"south africa": "ZA", "south sudan": "SS", "spain": "ES", "sri lanka": "LK", "sudan": "SD",
|
153 |
+
"suriname": "SR", "sweden": "SE", "switzerland": "CH", "syria": "SY", "taiwan": "TW",
|
154 |
+
"tajikistan": "TJ", "tanzania": "TZ", "thailand": "TH", "timor-leste": "TL", "togo": "TG",
|
155 |
+
"tonga": "TO", "trinidad and tobago": "TT", "tunisia": "TN", "turkey": "TR", "turkmenistan": "TM",
|
156 |
+
"tuvalu": "TV", "uganda": "UG", "ukraine": "UA", "united arab emirates": "AE", "united kingdom": "GB",
|
157 |
+
"united states": "US", "uruguay": "UY", "uzbekistan": "UZ", "vanuatu": "VU", "vatican city": "VA",
|
158 |
+
"venezuela": "VE", "vietnam": "VN", "yemen": "YE", "zambia": "ZM", "zimbabwe": "ZW"
|
159 |
+
}
|
160 |
+
|
161 |
+
user_input_lower = user_input.lower()
|
162 |
+
|
163 |
+
for country, code in country_mapping.items():
|
164 |
+
if country in user_input_lower:
|
165 |
+
return {"filter_key": "country_code", "filter_value": code}
|
166 |
+
|
167 |
+
if "business" in user_input_lower or "industry" in user_input_lower:
|
168 |
+
business_types = ["tech", "finance", "healthcare", "education", "manufacturing"]
|
169 |
+
for business_type in business_types:
|
170 |
+
if business_type in user_input_lower:
|
171 |
+
return {"filter_key": "industries", "filter_value": business_type.capitalize()}
|
172 |
+
|
173 |
+
if "company" in user_input_lower:
|
174 |
+
company_names = ["google", "microsoft", "apple", "amazon", "facebook"]
|
175 |
+
for company_name in company_names:
|
176 |
+
if company_name in user_input_lower:
|
177 |
+
return {"filter_key": "name", "filter_value": company_name.capitalize()}
|
178 |
+
|
179 |
+
return None
|
180 |
+
|
181 |
+
# Function to create PDF from DataFrame
|
182 |
+
def create_pdf(df, title):
|
183 |
+
pdf = FPDF()
|
184 |
+
pdf.add_page()
|
185 |
+
pdf.set_font("Arial", size=12)
|
186 |
+
pdf.cell(200, 10, txt=title, ln=True, align='C')
|
187 |
+
pdf.ln(10)
|
188 |
+
|
189 |
+
for index, row in df.iterrows():
|
190 |
+
for col in df.columns:
|
191 |
+
text = f"{col}: {row[col]}"
|
192 |
+
try:
|
193 |
+
text.encode('latin1')
|
194 |
+
except UnicodeEncodeError:
|
195 |
+
text = text.encode('latin1', errors='replace').decode('latin1')
|
196 |
+
pdf.cell(200, 10, txt=text, ln=True)
|
197 |
+
pdf.ln(5)
|
198 |
+
|
199 |
+
return pdf.output(dest='S').encode('latin1')
|
200 |
+
|
201 |
+
# Function to generate business ideas
|
202 |
+
def generate_business_idea(model, prompt_input, user_input):
|
203 |
+
formatted_question = f"""<|start_of_role|>user<|end_of_role|>{user_input}<|end_of_text|>
|
204 |
+
<|start_of_role|>assistant<|end_of_role|>"""
|
205 |
+
prompt = f"""{prompt_input}{formatted_question}"""
|
206 |
+
generated_response = model.generate_text(prompt=prompt, guardrails=False)
|
207 |
+
return generated_response
|
208 |
+
|
209 |
+
# Function to save text as a modern PDF
|
210 |
+
def save_as_pdf(text, filename="business_plan.pdf"):
|
211 |
+
pdf = FPDF()
|
212 |
+
pdf.add_page()
|
213 |
+
pdf.set_font("Arial", size=16, style="B")
|
214 |
+
pdf.cell(0, 10, txt="Business Plan Report", ln=True, align="C")
|
215 |
+
pdf.set_font("Arial", size=12)
|
216 |
+
pdf.ln(10)
|
217 |
+
pdf.multi_cell(0, 10, txt=text)
|
218 |
+
pdf.set_font("Arial", size=10)
|
219 |
+
pdf.cell(0, 10, txt=f"Page {pdf.page_no()}", align="C")
|
220 |
+
pdf.output(filename)
|
221 |
+
return filename
|
222 |
+
|
223 |
+
# Function to initialize SQLite database for chat history
|
224 |
+
def initialize_chat_db():
|
225 |
+
if not os.path.exists("chat_history.db"):
|
226 |
+
conn = sqlite3.connect("chat_history.db")
|
227 |
+
cursor = conn.cursor()
|
228 |
+
cursor.execute("""
|
229 |
+
CREATE TABLE IF NOT EXISTS chat_sessions (
|
230 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
231 |
+
user_input TEXT,
|
232 |
+
ai_response TEXT
|
233 |
+
)
|
234 |
+
""")
|
235 |
+
conn.commit()
|
236 |
+
conn.close()
|
237 |
+
|
238 |
+
# Function to save chat session to database
|
239 |
+
def save_chat_session(user_input, ai_response):
|
240 |
+
conn = sqlite3.connect("chat_history.db")
|
241 |
+
cursor = conn.cursor()
|
242 |
+
cursor.execute("""
|
243 |
+
INSERT INTO chat_sessions (user_input, ai_response)
|
244 |
+
VALUES (?, ?)
|
245 |
+
""", (user_input, ai_response))
|
246 |
+
conn.commit()
|
247 |
+
conn.close()
|
248 |
+
|
249 |
+
# Function to fetch all chat sessions from database
|
250 |
+
def fetch_chat_sessions():
|
251 |
+
conn = sqlite3.connect("chat_history.db")
|
252 |
+
cursor = conn.cursor()
|
253 |
+
cursor.execute("SELECT * FROM chat_sessions")
|
254 |
+
sessions = cursor.fetchall()
|
255 |
+
conn.close()
|
256 |
+
return sessions
|
257 |
+
|
258 |
+
# Streamlit App
|
259 |
+
def main():
|
260 |
+
# App Name
|
261 |
+
st.sidebar.title("LeadGenAI")
|
262 |
+
# Sidebar navigation
|
263 |
+
st.sidebar.header("Main Navigation")
|
264 |
+
|
265 |
+
# Use buttons for navigation
|
266 |
+
if st.sidebar.button("Lead Generation"):
|
267 |
+
st.session_state.app_mode = "Lead Generation"
|
268 |
+
|
269 |
+
if st.sidebar.button("Business Optimization"):
|
270 |
+
st.session_state.app_mode = "Business Optimization"
|
271 |
+
|
272 |
+
# Initialize session state for app mode if not already set
|
273 |
+
if "app_mode" not in st.session_state:
|
274 |
+
st.session_state.app_mode = "Lead Generation"
|
275 |
+
|
276 |
+
if st.session_state.app_mode == "Lead Generation":
|
277 |
+
st.title("LinkedIn Lead Generation")
|
278 |
+
|
279 |
+
# Create tabs
|
280 |
+
tab1, tab2 = st.tabs(["Lead Generation", "Lead Sessions"])
|
281 |
+
|
282 |
+
with tab1:
|
283 |
+
st.header("Lead Generation")
|
284 |
+
user_input = st.text_area("Enter your lead requirements (e.g. Finance professionals in Canada):", height=150)
|
285 |
+
num_leads = st.slider("Number of leads to generate (1-1000):", 1, 1000, 10)
|
286 |
+
|
287 |
+
if st.button("Generate Leads"):
|
288 |
+
# Load JSON data
|
289 |
+
user_profiles = load_json_data("LinkedIn_profiles_info_modified.json")
|
290 |
+
company_profiles = load_json_data("LinkedIn_company_info_modified.json")
|
291 |
+
|
292 |
+
# Extract filtering criteria from user input
|
293 |
+
filter_criteria = extract_filter_criteria(user_input)
|
294 |
+
|
295 |
+
# Filter leads based on extracted criteria
|
296 |
+
if filter_criteria:
|
297 |
+
selected_user_leads = filter_leads(user_profiles, filter_criteria["filter_key"], filter_criteria["filter_value"])[:num_leads]
|
298 |
+
selected_company_leads = filter_leads(company_profiles, filter_criteria["filter_key"], filter_criteria["filter_value"])[:num_leads]
|
299 |
+
else:
|
300 |
+
selected_user_leads = user_profiles[:num_leads]
|
301 |
+
selected_company_leads = company_profiles[:num_leads]
|
302 |
+
|
303 |
+
# Display leads in cards format
|
304 |
+
st.header("LinkedIn User Profile Leads")
|
305 |
+
for lead in selected_user_leads:
|
306 |
+
st.write(f"**Name:** {lead['name']}")
|
307 |
+
st.write(f"**City:** {lead['city']}")
|
308 |
+
st.write(f"**Country Code:** {lead['country_code']}")
|
309 |
+
st.write(f"**Region:** {lead['region']}")
|
310 |
+
st.write(f"**Current Company:** {lead['current_company:name']}")
|
311 |
+
st.write(f"**Position:** {lead['position']}")
|
312 |
+
st.write(f"**About:** {lead['about']}")
|
313 |
+
st.write(f"**URL:** {lead['url']}")
|
314 |
+
st.write("---")
|
315 |
+
|
316 |
+
st.header("LinkedIn Company Profile Leads")
|
317 |
+
for lead in selected_company_leads:
|
318 |
+
st.write(f"**Name:** {lead['name']}")
|
319 |
+
st.write(f"**Country Code:** {lead['country_code']}")
|
320 |
+
st.write(f"**Locations:** {lead['locations']}")
|
321 |
+
st.write(f"**Website:** {lead['website']}")
|
322 |
+
st.write(f"**About:** {lead['about']}")
|
323 |
+
st.write(f"**URL:** {lead['url']}")
|
324 |
+
st.write("---")
|
325 |
+
|
326 |
+
# Save leads to SQLite database
|
327 |
+
conn = init_leads_db()
|
328 |
+
save_leads_to_db(conn, selected_user_leads, 'user_leads')
|
329 |
+
save_leads_to_db(conn, selected_company_leads, 'company_leads')
|
330 |
+
conn.close()
|
331 |
+
|
332 |
+
# Download leads as CSV and PDF
|
333 |
+
user_leads_df = pd.DataFrame(selected_user_leads)
|
334 |
+
company_leads_df = pd.DataFrame(selected_company_leads)
|
335 |
+
|
336 |
+
st.download_button(
|
337 |
+
label="Download User Leads as CSV",
|
338 |
+
data=user_leads_df.to_csv(index=False),
|
339 |
+
file_name='user_leads.csv',
|
340 |
+
mime='text/csv',
|
341 |
+
key="user_leads_csv"
|
342 |
+
)
|
343 |
+
|
344 |
+
st.download_button(
|
345 |
+
label="Download Company Leads as CSV",
|
346 |
+
data=company_leads_df.to_csv(index=False),
|
347 |
+
file_name='company_leads.csv',
|
348 |
+
mime='text/csv',
|
349 |
+
key="company_leads_csv"
|
350 |
+
)
|
351 |
+
|
352 |
+
user_pdf = create_pdf(user_leads_df, "LinkedIn User Profile Leads")
|
353 |
+
company_pdf = create_pdf(company_leads_df, "LinkedIn Company Profile Leads")
|
354 |
+
|
355 |
+
st.download_button(
|
356 |
+
label="Download User Leads as PDF",
|
357 |
+
data=user_pdf,
|
358 |
+
file_name='user_leads.pdf',
|
359 |
+
mime='application/pdf',
|
360 |
+
key="user_leads_pdf"
|
361 |
+
)
|
362 |
+
|
363 |
+
st.download_button(
|
364 |
+
label="Download Company Leads as PDF",
|
365 |
+
data=company_pdf,
|
366 |
+
file_name='company_leads.pdf',
|
367 |
+
mime='application/pdf',
|
368 |
+
key="company_leads_pdf"
|
369 |
+
)
|
370 |
+
|
371 |
+
with tab2:
|
372 |
+
st.header("Lead Sessions")
|
373 |
+
try:
|
374 |
+
conn = init_leads_db()
|
375 |
+
user_leads_df = pd.read_sql_query("SELECT * FROM user_leads", conn)
|
376 |
+
company_leads_df = pd.read_sql_query("SELECT * FROM company_leads", conn)
|
377 |
+
conn.close()
|
378 |
+
|
379 |
+
st.header("User Leads from Previous Sessions")
|
380 |
+
with st.expander("View User Leads"):
|
381 |
+
st.dataframe(user_leads_df)
|
382 |
+
user_pdf = create_pdf(user_leads_df, "LinkedIn User Profile Leads")
|
383 |
+
st.download_button(
|
384 |
+
label="Download User Leads as PDF",
|
385 |
+
data=user_pdf,
|
386 |
+
file_name='user_leads.pdf',
|
387 |
+
mime='application/pdf',
|
388 |
+
key="user_leads_pdf_session"
|
389 |
+
)
|
390 |
+
st.download_button(
|
391 |
+
label="Download User Leads as CSV",
|
392 |
+
data=user_leads_df.to_csv(index=False),
|
393 |
+
file_name='user_leads.csv',
|
394 |
+
mime='text/csv',
|
395 |
+
key="user_leads_csv_session"
|
396 |
+
)
|
397 |
+
|
398 |
+
st.header("Company Leads from Previous Sessions")
|
399 |
+
with st.expander("View Company Leads"):
|
400 |
+
st.dataframe(company_leads_df)
|
401 |
+
company_pdf = create_pdf(company_leads_df, "LinkedIn Company Profile Leads")
|
402 |
+
st.download_button(
|
403 |
+
label="Download Company Leads as PDF",
|
404 |
+
data=company_pdf,
|
405 |
+
file_name='company_leads.pdf',
|
406 |
+
mime='application/pdf',
|
407 |
+
key="company_leads_pdf_session"
|
408 |
+
)
|
409 |
+
st.download_button(
|
410 |
+
label="Download Company Leads as CSV",
|
411 |
+
data=company_leads_df.to_csv(index=False),
|
412 |
+
file_name='company_leads.csv',
|
413 |
+
mime='text/csv',
|
414 |
+
key="company_leads_csv_session"
|
415 |
+
)
|
416 |
+
except sqlite3.OperationalError as e:
|
417 |
+
st.error(f"Database error: {e}. Please ensure the database is initialized.")
|
418 |
+
|
419 |
+
elif st.session_state.app_mode == "Business Optimization":
|
420 |
+
st.title("Business Optimization")
|
421 |
+
|
422 |
+
# Initialize SQLite database for chat history
|
423 |
+
initialize_chat_db()
|
424 |
+
|
425 |
+
# Initialize session state for chat history
|
426 |
+
if "chat_history" not in st.session_state:
|
427 |
+
st.session_state.chat_history = []
|
428 |
+
|
429 |
+
# Initialize the IBM Watsonx model
|
430 |
+
model = initialize_model()
|
431 |
+
|
432 |
+
# Enhanced system prompt for business optimization
|
433 |
+
prompt_input = """<|start_of_role|>system<|end_of_role|>
|
434 |
+
You are Granite, an AI language model developed by IBM in 2024. You are an expert in generating innovative and practical business ideas and plans.
|
435 |
+
Your task is to provide detailed, actionable, and creative business ideas and plans based on user input.
|
436 |
+
Each idea and plan should include:
|
437 |
+
1. A clear business concept.
|
438 |
+
2. Target audience.
|
439 |
+
3. Revenue model.
|
440 |
+
4. Key differentiators.
|
441 |
+
5. Potential challenges and solutions.
|
442 |
+
6. Target specific leads with at least 20 authentic Twitter links, LinkedIn profile links and 20 website URLs.
|
443 |
+
Be concise, professional, and creative in your responses.
|
444 |
+
<|end_of_text|>"""
|
445 |
+
|
446 |
+
# Create tabs
|
447 |
+
tab1, tab2 = st.tabs(["Plan", "Plan Sessions"])
|
448 |
+
|
449 |
+
with tab1:
|
450 |
+
st.write("Welcome to the Business Planner! Enter your requirements below and get innovative business plans or ideas.")
|
451 |
+
|
452 |
+
# User input with resizable text area
|
453 |
+
user_input = st.text_area(
|
454 |
+
"Enter your business plan or idea requirements:",
|
455 |
+
height=150,
|
456 |
+
placeholder="Example: I want to start a sustainable fashion brand targeting millennials."
|
457 |
+
)
|
458 |
+
|
459 |
+
# Generate business idea on button click
|
460 |
+
if st.button("Generate Idea & Leads"):
|
461 |
+
if user_input:
|
462 |
+
with st.spinner("Generating your business plan..."):
|
463 |
+
business_idea = generate_business_idea(model, prompt_input, user_input)
|
464 |
+
st.session_state.chat_history.append(("You", user_input))
|
465 |
+
st.session_state.chat_history.append(("AI", business_idea))
|
466 |
+
save_chat_session(user_input, business_idea)
|
467 |
+
else:
|
468 |
+
st.warning("Please enter your business idea requirements.")
|
469 |
+
|
470 |
+
# Display the final plan/idea and allow downloading as PDF
|
471 |
+
if st.session_state.chat_history:
|
472 |
+
latest_idea = st.session_state.chat_history[-1][1]
|
473 |
+
st.write("### Business Plan")
|
474 |
+
st.write(latest_idea)
|
475 |
+
if st.button("Download Business Plan as PDF"):
|
476 |
+
pdf_filename = save_as_pdf(latest_idea)
|
477 |
+
st.success(f"Business plan saved as {pdf_filename}!")
|
478 |
+
with open(pdf_filename, "rb") as file:
|
479 |
+
st.download_button(
|
480 |
+
label="Download PDF",
|
481 |
+
data=file,
|
482 |
+
file_name=pdf_filename,
|
483 |
+
mime="application/pdf"
|
484 |
+
)
|
485 |
+
|
486 |
+
with tab2:
|
487 |
+
st.write("### Plan Sessions")
|
488 |
+
sessions = fetch_chat_sessions()
|
489 |
+
if sessions:
|
490 |
+
for idx, session in enumerate(sessions):
|
491 |
+
session_id, user_input, ai_response = session
|
492 |
+
with st.expander(f"Session {session_id}"):
|
493 |
+
st.write(f"**Input:** {user_input}")
|
494 |
+
st.write(f"**Plan:** {ai_response}")
|
495 |
+
if st.button(f"Download Session {session_id} as PDF", key=f"download_{session_id}"):
|
496 |
+
pdf_filename = save_as_pdf(f"Input: {user_input}\n\nPlan: {ai_response}", filename=f"business_plan_session_{session_id}.pdf")
|
497 |
+
st.success(f"Business plan saved as {pdf_filename}!")
|
498 |
+
with open(pdf_filename, "rb") as file:
|
499 |
+
st.download_button(
|
500 |
+
label="Download PDF",
|
501 |
+
data=file,
|
502 |
+
file_name=pdf_filename,
|
503 |
+
mime="application/pdf",
|
504 |
+
key=f"download_button_{session_id}"
|
505 |
+
)
|
506 |
+
else:
|
507 |
+
st.write("No plan sessions available yet.")
|
508 |
+
|
509 |
+
if __name__ == "__main__":
|
510 |
+
main()
|
chat_history.db
ADDED
Binary file (24.6 kB). View file
|
|
leads.db
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:9f0e1a929d362ebd78371cb1d3556543c21b0a5145ea80cc34ad36b556e435c8
|
3 |
+
size 401408
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
pandas
|
3 |
+
fpdf
|
4 |
+
ibm-watsonx-ai
|
5 |
+
sqlite3
|
6 |
+
json
|