geeksiddhant commited on
Commit
fe8e5bf
·
1 Parent(s): 5d267ad

Update app.py

Browse files
Files changed (4) hide show
  1. README.md +4 -3
  2. app.py +219 -0
  3. packages.txt +2 -0
  4. requirements.txt +3 -1
README.md CHANGED
@@ -1,12 +1,13 @@
1
  ---
2
  title: 100xdiscovery
3
  emoji: 🐨
4
- colorFrom: red
5
- colorTo: gray
6
  sdk: streamlit
7
- sdk_version: 1.41.1
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
  title: 100xdiscovery
3
  emoji: 🐨
4
+ colorFrom: blue
5
+ colorTo: indigo
6
  sdk: streamlit
7
+ sdk_version: 1.29.0
8
  app_file: app.py
9
  pinned: false
10
+ license: mit
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ from typing import Dict, List
4
+ import os
5
+ from dotenv import load_dotenv
6
+
7
+ # Load environment variables
8
+ load_dotenv()
9
+
10
+ # Page config
11
+ st.set_page_config(
12
+ page_title="100xEngineers Discovery Platform",
13
+ page_icon="🚀",
14
+ layout="wide",
15
+ initial_sidebar_state="expanded"
16
+ )
17
+
18
+ # API client setup
19
+ class APIClient:
20
+ def __init__(self):
21
+ # Get the Hugging Face Space URL from environment or use localhost
22
+ space_url = os.getenv("SPACE_ID") # Hugging Face Spaces provides this automatically
23
+ if space_url:
24
+ # In Hugging Face Spaces, the FastAPI service will be available at port 8000
25
+ self.base_url = f"https://{space_url}-8000.hf.space"
26
+ else:
27
+ # Local development
28
+ self.base_url = "http://localhost:8000"
29
+
30
+ st.sidebar.text(f"API URL: {self.base_url}")
31
+
32
+ def _handle_response(self, response):
33
+ if response.ok:
34
+ return response.json()
35
+ st.error(f"Error: {response.status_code} - {response.text}")
36
+ return None
37
+
38
+ def get(self, endpoint: str):
39
+ try:
40
+ response = requests.get(f"{self.base_url}{endpoint}")
41
+ return self._handle_response(response)
42
+ except Exception as e:
43
+ st.error(f"API Error: {str(e)}")
44
+ return None
45
+
46
+ api = APIClient()
47
+
48
+ def create_profile(profile_data: dict):
49
+ # Validate and clean the data before sending
50
+ if profile_data.get("portfolio_url"):
51
+ url = profile_data["portfolio_url"].strip()
52
+ if not (url.startswith("http://") or url.startswith("https://")):
53
+ url = f"https://{url}"
54
+ try:
55
+ # Basic URL validation
56
+ if not url.replace("https://", "").replace("http://", ""):
57
+ profile_data.pop("portfolio_url", None)
58
+ else:
59
+ profile_data["portfolio_url"] = url
60
+ except Exception:
61
+ profile_data.pop("portfolio_url", None)
62
+ else:
63
+ profile_data.pop("portfolio_url", None)
64
+
65
+ try:
66
+ response = requests.post(f"{api.base_url}/api/profiles", json=profile_data)
67
+ if response.status_code == 422:
68
+ error_detail = response.json().get('detail', [])
69
+ if isinstance(error_detail, list):
70
+ for error in error_detail:
71
+ st.error(f"Validation Error: {error.get('msg')}")
72
+ else:
73
+ st.error(f"Validation Error: {error_detail}")
74
+ return None
75
+ elif not response.ok:
76
+ st.error(f"Server Error: {response.status_code}")
77
+ return None
78
+ return response.json()
79
+ except requests.exceptions.ConnectionError:
80
+ st.error("Could not connect to the server. Please make sure the backend is running.")
81
+ return None
82
+ except Exception as e:
83
+ st.error(f"An unexpected error occurred: {str(e)}")
84
+ return None
85
+
86
+ def search_profiles(query: str):
87
+ try:
88
+ response = requests.post(
89
+ f"{api.base_url}/api/search",
90
+ json={"query": query} # Send query in correct format
91
+ )
92
+ if not response.ok:
93
+ if response.status_code == 422:
94
+ st.error("Invalid search query format")
95
+ else:
96
+ st.error(f"Search failed with status code: {response.status_code}")
97
+ return []
98
+ return response.json()
99
+ except requests.exceptions.ConnectionError:
100
+ st.error("Could not connect to the server. Please make sure the backend is running.")
101
+ return []
102
+ except Exception as e:
103
+ st.error(f"An unexpected error occurred during search: {str(e)}")
104
+ return []
105
+
106
+ def list_profiles():
107
+ try:
108
+ response = requests.get(f"{api.base_url}/api/profiles")
109
+ if not response.ok:
110
+ st.error(f"Failed to fetch profiles: {response.status_code}")
111
+ return []
112
+ return response.json()
113
+ except requests.exceptions.ConnectionError:
114
+ st.error("Could not connect to the server. Please make sure the backend is running.")
115
+ return []
116
+ except Exception as e:
117
+ st.error(f"An unexpected error occurred while fetching profiles: {str(e)}")
118
+ return []
119
+
120
+ # UI Components
121
+ st.title("100xEngineers Discovery Platform 🚀")
122
+
123
+ # Sidebar navigation
124
+ page = st.sidebar.radio("Navigation", ["Search Profiles", "Create Profile", "View All Profiles"])
125
+
126
+ if page == "Create Profile":
127
+ st.header("Create Your Profile")
128
+
129
+ with st.form("profile_form"):
130
+ name = st.text_input("Name", help="Enter your full name (minimum 2 characters)")
131
+ technical_skills = st.text_input("Technical Skills (comma-separated)",
132
+ help="Enter your technical skills, separated by commas")
133
+ projects = st.text_input("Projects (comma-separated)",
134
+ help="List your notable projects, separated by commas")
135
+ ai_expertise = st.text_input("AI Expertise (comma-separated)",
136
+ help="List your AI-related skills and expertise")
137
+ mentoring_preferences = st.text_area("Mentoring Preferences",
138
+ help="Describe your mentoring preferences (minimum 10 characters)")
139
+ collaboration_interests = st.text_input("Collaboration Interests (comma-separated)",
140
+ help="List your interests for collaboration")
141
+ portfolio_url = st.text_input("Portfolio URL",
142
+ help="Enter your portfolio URL (optional)")
143
+
144
+ submitted = st.form_submit_button("Create Profile")
145
+
146
+ if submitted:
147
+ if len(name.strip()) < 2:
148
+ st.error("Name must be at least 2 characters long")
149
+ elif len(mentoring_preferences.strip()) < 10:
150
+ st.error("Mentoring preferences must be at least 10 characters long")
151
+ else:
152
+ profile_data = {
153
+ "name": name.strip(),
154
+ "technical_skills": [s.strip() for s in technical_skills.split(",") if s.strip()],
155
+ "projects": [p.strip() for p in projects.split(",") if p.strip()],
156
+ "ai_expertise": [a.strip() for a in ai_expertise.split(",") if a.strip()],
157
+ "mentoring_preferences": mentoring_preferences.strip(),
158
+ "collaboration_interests": [c.strip() for c in collaboration_interests.split(",") if c.strip()],
159
+ "portfolio_url": portfolio_url.strip() if portfolio_url.strip() else None
160
+ }
161
+
162
+ if profile := create_profile(profile_data):
163
+ st.success("Profile created successfully!")
164
+ st.json(profile)
165
+
166
+ elif page == "Search Profiles":
167
+ st.header("Search Profiles")
168
+
169
+ st.markdown("""
170
+ Search for engineers using natural language. Examples:
171
+ - "Find someone experienced in machine learning and NLP"
172
+ - "Looking for a mentor in backend development"
173
+ - "Need a collaborator for an open source AI project"
174
+ """)
175
+
176
+ query = st.text_input("Enter your search query in natural language")
177
+
178
+ if query:
179
+ results = search_profiles(query)
180
+
181
+ if results:
182
+ st.subheader(f"Found {len(results)} matches")
183
+ for result in results:
184
+ profile = result['profile']
185
+ explanation = result['explanation']
186
+
187
+ with st.expander(f"{profile['name']}"):
188
+ # Display match explanation
189
+ st.markdown(f"**Match Analysis:**\n{explanation}")
190
+ st.markdown("---")
191
+
192
+ # Display profile details
193
+ st.write("**Technical Skills:**", ", ".join(profile["technical_skills"]))
194
+ st.write("**AI Expertise:**", ", ".join(profile["ai_expertise"]))
195
+ st.write("**Projects:**", ", ".join(profile["projects"]))
196
+ st.write("**Mentoring Preferences:**", profile["mentoring_preferences"])
197
+ st.write("**Collaboration Interests:**", ", ".join(profile["collaboration_interests"]))
198
+ if profile.get("portfolio_url"):
199
+ st.write("**Portfolio:**", profile["portfolio_url"])
200
+ else:
201
+ st.info("No matching profiles found. Try adjusting your search query.")
202
+
203
+ else: # View All Profiles
204
+ st.header("All Profiles")
205
+
206
+ profiles = list_profiles()
207
+
208
+ if profiles:
209
+ for profile in profiles:
210
+ with st.expander(f"{profile['name']}"):
211
+ st.write("**Technical Skills:**", ", ".join(profile["technical_skills"]))
212
+ st.write("**AI Expertise:**", ", ".join(profile["ai_expertise"]))
213
+ st.write("**Projects:**", ", ".join(profile["projects"]))
214
+ st.write("**Mentoring Preferences:**", profile["mentoring_preferences"])
215
+ st.write("**Collaboration Interests:**", ", ".join(profile["collaboration_interests"]))
216
+ if profile.get("portfolio_url"):
217
+ st.write("**Portfolio:**", profile["portfolio_url"])
218
+ else:
219
+ st.info("No profiles found. Create one to get started!")
packages.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ python3-dev
2
+ build-essential
requirements.txt CHANGED
@@ -8,4 +8,6 @@ python-jose[cryptography]==3.3.0
8
  passlib[bcrypt]==1.7.4
9
  python-dotenv==1.0.0
10
  groq==0.4.2
11
- python-dotenv==1.0.0
 
 
 
8
  passlib[bcrypt]==1.7.4
9
  python-dotenv==1.0.0
10
  groq==0.4.2
11
+ httpx==0.24.0
12
+ watchfiles==0.21.0
13
+ websockets==11.0.3