mariagrandury commited on
Commit
c5fed00
·
1 Parent(s): 8b23f41

implement basic structure by resource type

Browse files
.gitignore CHANGED
@@ -1 +1,2 @@
1
- venv
 
 
1
+ venv/
2
+ __pycache__/
app.py CHANGED
@@ -1,68 +1,64 @@
1
  import gradio as gr
2
- import pandas as pd
3
 
4
- df = pd.read_csv("eventos_pln_es.csv")
 
 
 
 
 
5
 
 
 
6
 
7
- def update_table(search_query):
8
- if search_query == "":
9
- return df
10
- else:
11
- # Filter the dataframe based on the search query
12
- filtered_df = df[
13
- df.apply(
14
- lambda row: row.astype(str)
15
- .str.contains(search_query, case=False)
16
- .any(),
17
- axis=1,
18
- )
19
- ]
20
- return filtered_df
21
-
22
-
23
- with gr.Blocks() as app:
24
-
25
  gr.Markdown(
26
  """
27
- # 🚀 Recursos de PLN en español
28
-
29
- Descubre recursos gratuitos online de PLN en español.
30
-
31
- Ayúdanos a expandir esta lista, [comenta](https://huggingface.co/spaces/somosnlp/spanish-nlp-initiatives/discussions) y contribuye para hacerla lo más completa posible ¡Gracias!
32
- """
33
  )
34
- with gr.Accordion(label="Leer más", open=False, visible=False):
35
- gr.Markdown(
36
- """
37
- En los últimos años han surgido iniciativas para impulsar el PLN en español. El objetivo de esta lista es dar a conocer los recursos creados por estas iniciativas y facilitar la formación de personas apasionadas por el PLN en todo el mundo.
38
 
39
- La lista no es exhaustiva y son más que bienvenidas las contribuciones vía [comentarios o PRs](https://huggingface.co/spaces/somosnlp/spanish-nlp-initiatives/discussions).
40
-
41
- Estructura:
42
- - Recurso: Nombre del recurso
43
- - Categoría: Charla, taller aplicado, notebook, artículo de blog
44
- - Etiqueta: LLM, traducción, ética, ...
45
- - Creado por: Organización o persona que lo ha creado/organizado
46
- - Web: Página web del recurso
47
- """
48
- )
49
 
50
- with gr.Row():
51
- search_box = gr.Textbox(
52
- placeholder="Buscar...",
53
- label="Filtra la tabla",
54
- show_label=False,
55
- )
56
- with gr.Row():
57
- table = gr.Dataframe(
58
- value=df,
59
- label="Recursos de PLN en español",
60
- show_label=False,
61
- interactive=False,
62
- wrap=False,
63
- # column_widths=["30%", "15%", "20%", "15%", "15%"],
64
- )
65
- search_box.change(fn=update_table, inputs=search_box, outputs=table)
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
- app.launch()
 
 
 
1
  import gradio as gr
 
2
 
3
+ # Import the resource type modules
4
+ import datasets_resource
5
+ import events_resource
6
+ import initiatives_resource
7
+ import models_resource
8
+ import shared_tasks_resource
9
 
10
+ # Create the main Gradio interface
11
+ with gr.Blocks(title="Recursos de PLN en español", theme=gr.themes.Soft()) as app:
12
 
13
+ # Header
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  gr.Markdown(
15
  """
16
+ # 🚀 Recursos de PLN en español
17
+
18
+ Descubre y contribuye con recursos gratuitos online de PLN en español.
19
+
20
+ Explora datasets, modelos, tareas compartidas, eventos e iniciativas. ¡Ayúdanos a expandir esta colección para hacerla lo más completa posible!
21
+ """
22
  )
 
 
 
 
23
 
24
+ # Main tabs for resource types
25
+ with gr.Tabs() as main_tabs:
 
 
 
 
 
 
 
 
26
 
27
+ # Create tabs for each resource type
28
+ datasets_tab = datasets_resource.create_tab()
29
+ models_tab = models_resource.create_tab()
30
+ shared_tasks_tab = shared_tasks_resource.create_tab()
31
+ events_tab = events_resource.create_tab()
32
+ initiatives_tab = initiatives_resource.create_tab()
 
 
 
 
 
 
 
 
 
 
33
 
34
+ # Footer
35
+ gr.Markdown(
36
+ """
37
+ ---
38
+
39
+ ### 📖 About
40
+
41
+ Esta plataforma forma parte de la iniciativa [SomosNLP](https://somosnlp.org) para democratizar el acceso
42
+ a recursos de procesamiento de lenguaje natural en español.
43
+
44
+ **¿Cómo contribuir?**
45
+ 1. Ve a la pestaña del tipo de recurso que quieras añadir
46
+ 2. Haz clic en la sub-pestaña "Contribute"
47
+ 3. Haz login con tu cuenta de Hugging Face
48
+ 4. Rellena el formulario con la información del recurso
49
+ 5. ¡Envía tu contribución!
50
+
51
+ Los recursos enviados se almacenan en datasets públicos de Hugging Face y están disponibles para toda la comunidad.
52
+
53
+ **Tipos de recursos:**
54
+ - **Datasets**: Conjuntos de datos para entrenar y evaluar modelos de PLN
55
+ - **Models**: Modelos pre-entrenados y fine-tuned para tareas de PLN
56
+ - **Shared Tasks**: Competiciones y evaluaciones compartidas
57
+ - **Events**: Conferencias, workshops, charlas y eventos relacionados con PLN
58
+ - **Initiatives**: Proyectos, organizaciones e iniciativas que impulsan el PLN en español
59
+ """
60
+ )
61
 
62
+ # Launch the app
63
+ if __name__ == "__main__":
64
+ app.launch(share=False, server_name="0.0.0.0", server_port=7860)
datasets_resource.py ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timezone
2
+
3
+ import gradio as gr
4
+ import pandas as pd
5
+ from datasets import Dataset, load_dataset
6
+
7
+ # Dataset configuration
8
+ DATASET_NAME = "somosnlp/recursos-pln-es-datasets"
9
+ RESOURCE_TYPE = "datasets"
10
+ RESOURCE_TITLE = "Datasets"
11
+
12
+
13
+ def load_data() -> pd.DataFrame:
14
+ """Load data from HuggingFace dataset or return empty DataFrame."""
15
+ try:
16
+ dataset = load_dataset(DATASET_NAME, split="train")
17
+ return dataset.to_pandas()
18
+ except Exception as e:
19
+ print(f"Could not load {RESOURCE_TYPE} dataset: {e}")
20
+ # Return empty DataFrame with required columns
21
+ return pd.DataFrame(
22
+ columns=["name", "url", "country", "submitted_by", "date_submitted"]
23
+ )
24
+
25
+
26
+ def search_and_filter_data(df: pd.DataFrame, search_query: str) -> pd.DataFrame:
27
+ """Filter dataframe based on search query."""
28
+ if search_query == "":
29
+ return df
30
+ else:
31
+ filtered_df = df[
32
+ df.apply(
33
+ lambda row: row.astype(str)
34
+ .str.contains(search_query, case=False)
35
+ .any(),
36
+ axis=1,
37
+ )
38
+ ]
39
+ return filtered_df
40
+
41
+
42
+ def check_login(profile: gr.OAuthProfile | None) -> bool:
43
+ """Check if a user is logged in."""
44
+ return profile is not None
45
+
46
+
47
+ def submit_resource(name: str, url: str, country: str, profile: gr.OAuthProfile | None):
48
+ """Submit a new resource to the corresponding dataset."""
49
+
50
+ # Check if user is logged in
51
+ if not check_login(profile):
52
+ return "❌ Error: You need to be logged in to submit a resource."
53
+
54
+ # Validate inputs
55
+ if not name or not url or not country:
56
+ return "❌ Error: All fields (name, url, country) are required."
57
+
58
+ try:
59
+ username = profile.username
60
+ current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
61
+
62
+ # Create new row data
63
+ new_data = {
64
+ "name": name,
65
+ "url": url,
66
+ "country": country,
67
+ "submitted_by": username,
68
+ "date_submitted": current_time,
69
+ }
70
+
71
+ # Try to load existing dataset, or create new one
72
+ try:
73
+ existing_dataset = load_dataset(DATASET_NAME, split="train")
74
+ existing_df = existing_dataset.to_pandas()
75
+ # Add new row
76
+ updated_df = pd.concat(
77
+ [existing_df, pd.DataFrame([new_data])], ignore_index=True
78
+ )
79
+ except:
80
+ # Create new dataset if it doesn't exist
81
+ updated_df = pd.DataFrame([new_data])
82
+
83
+ # Convert back to Dataset and push to hub
84
+ updated_dataset = Dataset.from_pandas(updated_df)
85
+ updated_dataset.push_to_hub(
86
+ DATASET_NAME,
87
+ commit_message=f"Add {name} by {username}",
88
+ token=True, # Use the user's token
89
+ )
90
+
91
+ return f"✅ Success: {name} has been submitted successfully!"
92
+
93
+ except Exception as e:
94
+ return f"❌ Error: Failed to submit resource. {str(e)}"
95
+
96
+
97
+ def create_all_tab():
98
+ """Create the 'All' tab for this resource type."""
99
+ with gr.TabItem("📋 All", id=f"{RESOURCE_TYPE}_all"):
100
+ gr.Markdown(f"### All {RESOURCE_TITLE}")
101
+
102
+ search_box = gr.Textbox(
103
+ placeholder=f"Search {RESOURCE_TYPE}...",
104
+ label="Filter the table",
105
+ show_label=False,
106
+ )
107
+
108
+ # Load initial data
109
+ initial_df = load_data()
110
+
111
+ table = gr.Dataframe(
112
+ value=initial_df,
113
+ label=RESOURCE_TITLE,
114
+ show_label=False,
115
+ interactive=False,
116
+ wrap=True,
117
+ )
118
+
119
+ # Connect search functionality
120
+ search_box.change(
121
+ fn=lambda query: search_and_filter_data(initial_df, query),
122
+ inputs=search_box,
123
+ outputs=table,
124
+ )
125
+
126
+ # Refresh button to reload data
127
+ refresh_btn = gr.Button("🔄 Refresh Data", variant="secondary")
128
+ refresh_btn.click(fn=lambda: load_data(), outputs=table)
129
+
130
+ return table
131
+
132
+
133
+ def create_contribute_tab():
134
+ """Create the 'Contribute' tab for this resource type."""
135
+ with gr.TabItem("➕ Contribute", id=f"{RESOURCE_TYPE}_contribute"):
136
+ gr.Markdown(f"### Contribute a New {RESOURCE_TITLE[:-1]}")
137
+
138
+ # Login section
139
+ gr.Markdown("Please log in to contribute resources:")
140
+ login_button = gr.LoginButton(elem_id=f"{RESOURCE_TYPE}-oauth-button")
141
+
142
+ gr.Markdown("Please fill in the information below to add a new dataset:")
143
+
144
+ with gr.Column():
145
+ name_input = gr.Textbox(
146
+ label="Name",
147
+ placeholder="Enter the name of the dataset",
148
+ info="The name or title of the resource",
149
+ )
150
+ url_input = gr.Textbox(
151
+ label="URL", placeholder="https://...", info="Link to the resource"
152
+ )
153
+ country_input = gr.Textbox(
154
+ label="Country",
155
+ placeholder="e.g., Spain, Mexico, Argentina",
156
+ info="Country of origin or primary focus",
157
+ )
158
+
159
+ submit_btn = gr.Button(f"Submit {RESOURCE_TITLE[:-1]}", variant="primary")
160
+ result_msg = gr.Markdown()
161
+
162
+ # Submit function
163
+ submit_btn.click(
164
+ fn=submit_resource,
165
+ inputs=[name_input, url_input, country_input],
166
+ outputs=[result_msg],
167
+ )
168
+
169
+ return name_input, url_input, country_input, submit_btn, result_msg
170
+
171
+
172
+ def create_tab():
173
+ """Create the complete tab for this resource type."""
174
+ with gr.TabItem(f"📊 {RESOURCE_TITLE}", id=RESOURCE_TYPE):
175
+ with gr.Tabs():
176
+ table = create_all_tab()
177
+ inputs = create_contribute_tab()
178
+ return table, inputs
events_resource.py ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timezone
2
+
3
+ import gradio as gr
4
+ import pandas as pd
5
+ from datasets import Dataset, load_dataset
6
+
7
+ # Dataset configuration
8
+ DATASET_NAME = "somosnlp/recursos-pln-es-events"
9
+ RESOURCE_TYPE = "events"
10
+ RESOURCE_TITLE = "Events"
11
+
12
+
13
+ def load_data() -> pd.DataFrame:
14
+ """Load data from HuggingFace dataset or return empty DataFrame."""
15
+ try:
16
+ dataset = load_dataset(DATASET_NAME, split="train")
17
+ return dataset.to_pandas()
18
+ except Exception as e:
19
+ print(f"Could not load {RESOURCE_TYPE} dataset: {e}")
20
+ # Return empty DataFrame with required columns
21
+ return pd.DataFrame(
22
+ columns=["name", "url", "country", "submitted_by", "date_submitted"]
23
+ )
24
+
25
+
26
+ def search_and_filter_data(df: pd.DataFrame, search_query: str) -> pd.DataFrame:
27
+ """Filter dataframe based on search query."""
28
+ if search_query == "":
29
+ return df
30
+ else:
31
+ filtered_df = df[
32
+ df.apply(
33
+ lambda row: row.astype(str)
34
+ .str.contains(search_query, case=False)
35
+ .any(),
36
+ axis=1,
37
+ )
38
+ ]
39
+ return filtered_df
40
+
41
+
42
+ def check_login(profile: gr.OAuthProfile | None) -> bool:
43
+ """Check if a user is logged in."""
44
+ return profile is not None
45
+
46
+
47
+ def submit_resource(name: str, url: str, country: str, profile: gr.OAuthProfile | None):
48
+ """Submit a new resource to the corresponding dataset."""
49
+
50
+ # Check if user is logged in
51
+ if not check_login(profile):
52
+ return "❌ Error: You need to be logged in to submit a resource."
53
+
54
+ # Validate inputs
55
+ if not name or not url or not country:
56
+ return "❌ Error: All fields (name, url, country) are required."
57
+
58
+ try:
59
+ username = profile.username
60
+ current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
61
+
62
+ # Create new row data
63
+ new_data = {
64
+ "name": name,
65
+ "url": url,
66
+ "country": country,
67
+ "submitted_by": username,
68
+ "date_submitted": current_time,
69
+ }
70
+
71
+ # Try to load existing dataset, or create new one
72
+ try:
73
+ existing_dataset = load_dataset(DATASET_NAME, split="train")
74
+ existing_df = existing_dataset.to_pandas()
75
+ # Add new row
76
+ updated_df = pd.concat(
77
+ [existing_df, pd.DataFrame([new_data])], ignore_index=True
78
+ )
79
+ except:
80
+ # Create new dataset if it doesn't exist
81
+ updated_df = pd.DataFrame([new_data])
82
+
83
+ # Convert back to Dataset and push to hub
84
+ updated_dataset = Dataset.from_pandas(updated_df)
85
+ updated_dataset.push_to_hub(
86
+ DATASET_NAME,
87
+ commit_message=f"Add {name} by {username}",
88
+ token=True, # Use the user's token
89
+ )
90
+
91
+ return f"✅ Success: {name} has been submitted successfully!"
92
+
93
+ except Exception as e:
94
+ return f"❌ Error: Failed to submit resource. {str(e)}"
95
+
96
+
97
+ def create_all_tab():
98
+ """Create the 'All' tab for this resource type."""
99
+ with gr.TabItem("📋 All", id=f"{RESOURCE_TYPE}_all"):
100
+ gr.Markdown(f"### All {RESOURCE_TITLE}")
101
+
102
+ search_box = gr.Textbox(
103
+ placeholder=f"Search {RESOURCE_TYPE}...",
104
+ label="Filter the table",
105
+ show_label=False,
106
+ )
107
+
108
+ # Load initial data
109
+ initial_df = load_data()
110
+
111
+ table = gr.Dataframe(
112
+ value=initial_df,
113
+ label=RESOURCE_TITLE,
114
+ show_label=False,
115
+ interactive=False,
116
+ wrap=True,
117
+ )
118
+
119
+ # Connect search functionality
120
+ search_box.change(
121
+ fn=lambda query: search_and_filter_data(initial_df, query),
122
+ inputs=search_box,
123
+ outputs=table,
124
+ )
125
+
126
+ # Refresh button to reload data
127
+ refresh_btn = gr.Button("🔄 Refresh Data", variant="secondary")
128
+ refresh_btn.click(fn=lambda: load_data(), outputs=table)
129
+
130
+ return table
131
+
132
+
133
+ def create_contribute_tab():
134
+ """Create the 'Contribute' tab for this resource type."""
135
+ with gr.TabItem("➕ Contribute", id=f"{RESOURCE_TYPE}_contribute"):
136
+ gr.Markdown(f"### Contribute a New {RESOURCE_TITLE[:-1]}")
137
+
138
+ # Login section
139
+ gr.Markdown("Please log in to contribute resources:")
140
+ login_button = gr.LoginButton(elem_id=f"{RESOURCE_TYPE}-oauth-button")
141
+
142
+ gr.Markdown("Please fill in the information below to add a new event:")
143
+
144
+ with gr.Column():
145
+ name_input = gr.Textbox(
146
+ label="Name",
147
+ placeholder="Enter the name of the event",
148
+ info="The name or title of the resource",
149
+ )
150
+ url_input = gr.Textbox(
151
+ label="URL", placeholder="https://...", info="Link to the resource"
152
+ )
153
+ country_input = gr.Textbox(
154
+ label="Country",
155
+ placeholder="e.g., Spain, Mexico, Argentina",
156
+ info="Country of origin or primary focus",
157
+ )
158
+
159
+ submit_btn = gr.Button(f"Submit {RESOURCE_TITLE[:-1]}", variant="primary")
160
+ result_msg = gr.Markdown()
161
+
162
+ # Submit function
163
+ submit_btn.click(
164
+ fn=submit_resource,
165
+ inputs=[name_input, url_input, country_input],
166
+ outputs=[result_msg],
167
+ )
168
+
169
+ return name_input, url_input, country_input, submit_btn, result_msg
170
+
171
+
172
+ def create_tab():
173
+ """Create the complete tab for this resource type."""
174
+ with gr.TabItem(f"📅 {RESOURCE_TITLE}", id=RESOURCE_TYPE):
175
+ with gr.Tabs():
176
+ table = create_all_tab()
177
+ inputs = create_contribute_tab()
178
+ return table, inputs
initiatives_resource.py ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timezone
2
+
3
+ import gradio as gr
4
+ import pandas as pd
5
+ from datasets import Dataset, load_dataset
6
+
7
+ # Dataset configuration
8
+ DATASET_NAME = "somosnlp/recursos-pln-es-initiatives"
9
+ RESOURCE_TYPE = "initiatives"
10
+ RESOURCE_TITLE = "Initiatives"
11
+
12
+
13
+ def load_data() -> pd.DataFrame:
14
+ """Load data from HuggingFace dataset or return empty DataFrame."""
15
+ try:
16
+ dataset = load_dataset(DATASET_NAME, split="train")
17
+ return dataset.to_pandas()
18
+ except Exception as e:
19
+ print(f"Could not load {RESOURCE_TYPE} dataset: {e}")
20
+ # Return empty DataFrame with required columns
21
+ return pd.DataFrame(
22
+ columns=["name", "url", "country", "submitted_by", "date_submitted"]
23
+ )
24
+
25
+
26
+ def search_and_filter_data(df: pd.DataFrame, search_query: str) -> pd.DataFrame:
27
+ """Filter dataframe based on search query."""
28
+ if search_query == "":
29
+ return df
30
+ else:
31
+ filtered_df = df[
32
+ df.apply(
33
+ lambda row: row.astype(str)
34
+ .str.contains(search_query, case=False)
35
+ .any(),
36
+ axis=1,
37
+ )
38
+ ]
39
+ return filtered_df
40
+
41
+
42
+ def check_login(profile: gr.OAuthProfile | None) -> bool:
43
+ """Check if a user is logged in."""
44
+ return profile is not None
45
+
46
+
47
+ def submit_resource(name: str, url: str, country: str, profile: gr.OAuthProfile | None):
48
+ """Submit a new resource to the corresponding dataset."""
49
+
50
+ # Check if user is logged in
51
+ if not check_login(profile):
52
+ return "❌ Error: You need to be logged in to submit a resource."
53
+
54
+ # Validate inputs
55
+ if not name or not url or not country:
56
+ return "❌ Error: All fields (name, url, country) are required."
57
+
58
+ try:
59
+ username = profile.username
60
+ current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
61
+
62
+ # Create new row data
63
+ new_data = {
64
+ "name": name,
65
+ "url": url,
66
+ "country": country,
67
+ "submitted_by": username,
68
+ "date_submitted": current_time,
69
+ }
70
+
71
+ # Try to load existing dataset, or create new one
72
+ try:
73
+ existing_dataset = load_dataset(DATASET_NAME, split="train")
74
+ existing_df = existing_dataset.to_pandas()
75
+ # Add new row
76
+ updated_df = pd.concat(
77
+ [existing_df, pd.DataFrame([new_data])], ignore_index=True
78
+ )
79
+ except:
80
+ # Create new dataset if it doesn't exist
81
+ updated_df = pd.DataFrame([new_data])
82
+
83
+ # Convert back to Dataset and push to hub
84
+ updated_dataset = Dataset.from_pandas(updated_df)
85
+ updated_dataset.push_to_hub(
86
+ DATASET_NAME,
87
+ commit_message=f"Add {name} by {username}",
88
+ token=True, # Use the user's token
89
+ )
90
+
91
+ return f"✅ Success: {name} has been submitted successfully!"
92
+
93
+ except Exception as e:
94
+ return f"❌ Error: Failed to submit resource. {str(e)}"
95
+
96
+
97
+ def create_all_tab():
98
+ """Create the 'All' tab for this resource type."""
99
+ with gr.TabItem("📋 All", id=f"{RESOURCE_TYPE}_all"):
100
+ gr.Markdown(f"### All {RESOURCE_TITLE}")
101
+
102
+ search_box = gr.Textbox(
103
+ placeholder=f"Search {RESOURCE_TYPE}...",
104
+ label="Filter the table",
105
+ show_label=False,
106
+ )
107
+
108
+ # Load initial data
109
+ initial_df = load_data()
110
+
111
+ table = gr.Dataframe(
112
+ value=initial_df,
113
+ label=RESOURCE_TITLE,
114
+ show_label=False,
115
+ interactive=False,
116
+ wrap=True,
117
+ )
118
+
119
+ # Connect search functionality
120
+ search_box.change(
121
+ fn=lambda query: search_and_filter_data(initial_df, query),
122
+ inputs=search_box,
123
+ outputs=table,
124
+ )
125
+
126
+ # Refresh button to reload data
127
+ refresh_btn = gr.Button("🔄 Refresh Data", variant="secondary")
128
+ refresh_btn.click(fn=lambda: load_data(), outputs=table)
129
+
130
+ return table
131
+
132
+
133
+ def create_contribute_tab():
134
+ """Create the 'Contribute' tab for this resource type."""
135
+ with gr.TabItem("➕ Contribute", id=f"{RESOURCE_TYPE}_contribute"):
136
+ gr.Markdown(f"### Contribute a New {RESOURCE_TITLE[:-1]}")
137
+
138
+ # Login section
139
+ gr.Markdown("Please log in to contribute resources:")
140
+ login_button = gr.LoginButton(elem_id=f"{RESOURCE_TYPE}-oauth-button")
141
+
142
+ gr.Markdown("Please fill in the information below to add a new initiative:")
143
+
144
+ with gr.Column():
145
+ name_input = gr.Textbox(
146
+ label="Name",
147
+ placeholder="Enter the name of the initiative",
148
+ info="The name or title of the resource",
149
+ )
150
+ url_input = gr.Textbox(
151
+ label="URL", placeholder="https://...", info="Link to the resource"
152
+ )
153
+ country_input = gr.Textbox(
154
+ label="Country",
155
+ placeholder="e.g., Spain, Mexico, Argentina",
156
+ info="Country of origin or primary focus",
157
+ )
158
+
159
+ submit_btn = gr.Button(f"Submit {RESOURCE_TITLE[:-1]}", variant="primary")
160
+ result_msg = gr.Markdown()
161
+
162
+ # Submit function
163
+ submit_btn.click(
164
+ fn=submit_resource,
165
+ inputs=[name_input, url_input, country_input],
166
+ outputs=[result_msg],
167
+ )
168
+
169
+ return name_input, url_input, country_input, submit_btn, result_msg
170
+
171
+
172
+ def create_tab():
173
+ """Create the complete tab for this resource type."""
174
+ with gr.TabItem(f"🌟 {RESOURCE_TITLE}", id=RESOURCE_TYPE):
175
+ with gr.Tabs():
176
+ table = create_all_tab()
177
+ inputs = create_contribute_tab()
178
+ return table, inputs
models_resource.py ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timezone
2
+
3
+ import gradio as gr
4
+ import pandas as pd
5
+ from datasets import Dataset, load_dataset
6
+
7
+ # Dataset configuration
8
+ DATASET_NAME = "somosnlp/recursos-pln-es-models"
9
+ RESOURCE_TYPE = "models"
10
+ RESOURCE_TITLE = "Models"
11
+
12
+
13
+ def load_data() -> pd.DataFrame:
14
+ """Load data from HuggingFace dataset or return empty DataFrame."""
15
+ try:
16
+ dataset = load_dataset(DATASET_NAME, split="train")
17
+ return dataset.to_pandas()
18
+ except Exception as e:
19
+ print(f"Could not load {RESOURCE_TYPE} dataset: {e}")
20
+ # Return empty DataFrame with required columns
21
+ return pd.DataFrame(
22
+ columns=["name", "url", "country", "submitted_by", "date_submitted"]
23
+ )
24
+
25
+
26
+ def search_and_filter_data(df: pd.DataFrame, search_query: str) -> pd.DataFrame:
27
+ """Filter dataframe based on search query."""
28
+ if search_query == "":
29
+ return df
30
+ else:
31
+ filtered_df = df[
32
+ df.apply(
33
+ lambda row: row.astype(str)
34
+ .str.contains(search_query, case=False)
35
+ .any(),
36
+ axis=1,
37
+ )
38
+ ]
39
+ return filtered_df
40
+
41
+
42
+ def check_login(profile: gr.OAuthProfile | None) -> bool:
43
+ """Check if a user is logged in."""
44
+ return profile is not None
45
+
46
+
47
+ def submit_resource(name: str, url: str, country: str, profile: gr.OAuthProfile | None):
48
+ """Submit a new resource to the corresponding dataset."""
49
+
50
+ # Check if user is logged in
51
+ if not check_login(profile):
52
+ return "❌ Error: You need to be logged in to submit a resource."
53
+
54
+ # Validate inputs
55
+ if not name or not url or not country:
56
+ return "❌ Error: All fields (name, url, country) are required."
57
+
58
+ try:
59
+ username = profile.username
60
+ current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
61
+
62
+ # Create new row data
63
+ new_data = {
64
+ "name": name,
65
+ "url": url,
66
+ "country": country,
67
+ "submitted_by": username,
68
+ "date_submitted": current_time,
69
+ }
70
+
71
+ # Try to load existing dataset, or create new one
72
+ try:
73
+ existing_dataset = load_dataset(DATASET_NAME, split="train")
74
+ existing_df = existing_dataset.to_pandas()
75
+ # Add new row
76
+ updated_df = pd.concat(
77
+ [existing_df, pd.DataFrame([new_data])], ignore_index=True
78
+ )
79
+ except:
80
+ # Create new dataset if it doesn't exist
81
+ updated_df = pd.DataFrame([new_data])
82
+
83
+ # Convert back to Dataset and push to hub
84
+ updated_dataset = Dataset.from_pandas(updated_df)
85
+ updated_dataset.push_to_hub(
86
+ DATASET_NAME,
87
+ commit_message=f"Add {name} by {username}",
88
+ token=True, # Use the user's token
89
+ )
90
+
91
+ return f"✅ Success: {name} has been submitted successfully!"
92
+
93
+ except Exception as e:
94
+ return f"❌ Error: Failed to submit resource. {str(e)}"
95
+
96
+
97
+ def create_all_tab():
98
+ """Create the 'All' tab for this resource type."""
99
+ with gr.TabItem("📋 All", id=f"{RESOURCE_TYPE}_all"):
100
+ gr.Markdown(f"### All {RESOURCE_TITLE}")
101
+
102
+ search_box = gr.Textbox(
103
+ placeholder=f"Search {RESOURCE_TYPE}...",
104
+ label="Filter the table",
105
+ show_label=False,
106
+ )
107
+
108
+ # Load initial data
109
+ initial_df = load_data()
110
+
111
+ table = gr.Dataframe(
112
+ value=initial_df,
113
+ label=RESOURCE_TITLE,
114
+ show_label=False,
115
+ interactive=False,
116
+ wrap=True,
117
+ )
118
+
119
+ # Connect search functionality
120
+ search_box.change(
121
+ fn=lambda query: search_and_filter_data(initial_df, query),
122
+ inputs=search_box,
123
+ outputs=table,
124
+ )
125
+
126
+ # Refresh button to reload data
127
+ refresh_btn = gr.Button("🔄 Refresh Data", variant="secondary")
128
+ refresh_btn.click(fn=lambda: load_data(), outputs=table)
129
+
130
+ return table
131
+
132
+
133
+ def create_contribute_tab():
134
+ """Create the 'Contribute' tab for this resource type."""
135
+ with gr.TabItem("➕ Contribute", id=f"{RESOURCE_TYPE}_contribute"):
136
+ gr.Markdown(f"### Contribute a New {RESOURCE_TITLE[:-1]}")
137
+
138
+ # Login section
139
+ gr.Markdown("Please log in to contribute resources:")
140
+ login_button = gr.LoginButton(elem_id=f"{RESOURCE_TYPE}-oauth-button")
141
+
142
+ gr.Markdown("Please fill in the information below to add a new model:")
143
+
144
+ with gr.Column():
145
+ name_input = gr.Textbox(
146
+ label="Name",
147
+ placeholder="Enter the name of the model",
148
+ info="The name or title of the resource",
149
+ )
150
+ url_input = gr.Textbox(
151
+ label="URL", placeholder="https://...", info="Link to the resource"
152
+ )
153
+ country_input = gr.Textbox(
154
+ label="Country",
155
+ placeholder="e.g., Spain, Mexico, Argentina",
156
+ info="Country of origin or primary focus",
157
+ )
158
+
159
+ submit_btn = gr.Button(f"Submit {RESOURCE_TITLE[:-1]}", variant="primary")
160
+ result_msg = gr.Markdown()
161
+
162
+ # Submit function
163
+ submit_btn.click(
164
+ fn=submit_resource,
165
+ inputs=[name_input, url_input, country_input],
166
+ outputs=[result_msg],
167
+ )
168
+
169
+ return name_input, url_input, country_input, submit_btn, result_msg
170
+
171
+
172
+ def create_tab():
173
+ """Create the complete tab for this resource type."""
174
+ with gr.TabItem(f"🤖 {RESOURCE_TITLE}", id=RESOURCE_TYPE):
175
+ with gr.Tabs():
176
+ table = create_all_tab()
177
+ inputs = create_contribute_tab()
178
+ return table, inputs
requirements.txt CHANGED
@@ -1,2 +1,5 @@
1
  gradio==4.26.0
2
  pandas==2.2.1
 
 
 
 
1
  gradio==4.26.0
2
  pandas==2.2.1
3
+ huggingface_hub>=0.20.0
4
+ datasets>=2.17.0
5
+ gradio[oauth]
shared_tasks_resource.py ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timezone
2
+
3
+ import gradio as gr
4
+ import pandas as pd
5
+ from datasets import Dataset, load_dataset
6
+
7
+ # Dataset configuration
8
+ DATASET_NAME = "somosnlp/recursos-pln-es-shared-tasks"
9
+ RESOURCE_TYPE = "shared_tasks"
10
+ RESOURCE_TITLE = "Shared Tasks"
11
+
12
+
13
+ def load_data() -> pd.DataFrame:
14
+ """Load data from HuggingFace dataset or return empty DataFrame."""
15
+ try:
16
+ dataset = load_dataset(DATASET_NAME, split="train")
17
+ return dataset.to_pandas()
18
+ except Exception as e:
19
+ print(f"Could not load {RESOURCE_TYPE} dataset: {e}")
20
+ # Return empty DataFrame with required columns
21
+ return pd.DataFrame(
22
+ columns=["name", "url", "country", "submitted_by", "date_submitted"]
23
+ )
24
+
25
+
26
+ def search_and_filter_data(df: pd.DataFrame, search_query: str) -> pd.DataFrame:
27
+ """Filter dataframe based on search query."""
28
+ if search_query == "":
29
+ return df
30
+ else:
31
+ filtered_df = df[
32
+ df.apply(
33
+ lambda row: row.astype(str)
34
+ .str.contains(search_query, case=False)
35
+ .any(),
36
+ axis=1,
37
+ )
38
+ ]
39
+ return filtered_df
40
+
41
+
42
+ def check_login(profile: gr.OAuthProfile | None) -> bool:
43
+ """Check if a user is logged in."""
44
+ return profile is not None
45
+
46
+
47
+ def submit_resource(name: str, url: str, country: str, profile: gr.OAuthProfile | None):
48
+ """Submit a new resource to the corresponding dataset."""
49
+
50
+ # Check if user is logged in
51
+ if not check_login(profile):
52
+ return "❌ Error: You need to be logged in to submit a resource."
53
+
54
+ # Validate inputs
55
+ if not name or not url or not country:
56
+ return "❌ Error: All fields (name, url, country) are required."
57
+
58
+ try:
59
+ username = profile.username
60
+ current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
61
+
62
+ # Create new row data
63
+ new_data = {
64
+ "name": name,
65
+ "url": url,
66
+ "country": country,
67
+ "submitted_by": username,
68
+ "date_submitted": current_time,
69
+ }
70
+
71
+ # Try to load existing dataset, or create new one
72
+ try:
73
+ existing_dataset = load_dataset(DATASET_NAME, split="train")
74
+ existing_df = existing_dataset.to_pandas()
75
+ # Add new row
76
+ updated_df = pd.concat(
77
+ [existing_df, pd.DataFrame([new_data])], ignore_index=True
78
+ )
79
+ except:
80
+ # Create new dataset if it doesn't exist
81
+ updated_df = pd.DataFrame([new_data])
82
+
83
+ # Convert back to Dataset and push to hub
84
+ updated_dataset = Dataset.from_pandas(updated_df)
85
+ updated_dataset.push_to_hub(
86
+ DATASET_NAME,
87
+ commit_message=f"Add {name} by {username}",
88
+ token=True, # Use the user's token
89
+ )
90
+
91
+ return f"✅ Success: {name} has been submitted successfully!"
92
+
93
+ except Exception as e:
94
+ return f"❌ Error: Failed to submit resource. {str(e)}"
95
+
96
+
97
+ def create_all_tab():
98
+ """Create the 'All' tab for this resource type."""
99
+ with gr.TabItem("📋 All", id=f"{RESOURCE_TYPE}_all"):
100
+ gr.Markdown(f"### All {RESOURCE_TITLE}")
101
+
102
+ search_box = gr.Textbox(
103
+ placeholder=f"Search {RESOURCE_TYPE}...",
104
+ label="Filter the table",
105
+ show_label=False,
106
+ )
107
+
108
+ # Load initial data
109
+ initial_df = load_data()
110
+
111
+ table = gr.Dataframe(
112
+ value=initial_df,
113
+ label=RESOURCE_TITLE,
114
+ show_label=False,
115
+ interactive=False,
116
+ wrap=True,
117
+ )
118
+
119
+ # Connect search functionality
120
+ search_box.change(
121
+ fn=lambda query: search_and_filter_data(initial_df, query),
122
+ inputs=search_box,
123
+ outputs=table,
124
+ )
125
+
126
+ # Refresh button to reload data
127
+ refresh_btn = gr.Button("🔄 Refresh Data", variant="secondary")
128
+ refresh_btn.click(fn=lambda: load_data(), outputs=table)
129
+
130
+ return table
131
+
132
+
133
+ def create_contribute_tab():
134
+ """Create the 'Contribute' tab for this resource type."""
135
+ with gr.TabItem("➕ Contribute", id=f"{RESOURCE_TYPE}_contribute"):
136
+ gr.Markdown(f"### Contribute a New {RESOURCE_TITLE[:-1]}")
137
+
138
+ # Login section
139
+ gr.Markdown("Please log in to contribute resources:")
140
+ login_button = gr.LoginButton(elem_id=f"{RESOURCE_TYPE}-oauth-button")
141
+
142
+ gr.Markdown("Please fill in the information below to add a new shared task:")
143
+
144
+ with gr.Column():
145
+ name_input = gr.Textbox(
146
+ label="Name",
147
+ placeholder="Enter the name of the shared task",
148
+ info="The name or title of the resource",
149
+ )
150
+ url_input = gr.Textbox(
151
+ label="URL", placeholder="https://...", info="Link to the resource"
152
+ )
153
+ country_input = gr.Textbox(
154
+ label="Country",
155
+ placeholder="e.g., Spain, Mexico, Argentina",
156
+ info="Country of origin or primary focus",
157
+ )
158
+
159
+ submit_btn = gr.Button(f"Submit {RESOURCE_TITLE[:-1]}", variant="primary")
160
+ result_msg = gr.Markdown()
161
+
162
+ # Submit function
163
+ submit_btn.click(
164
+ fn=submit_resource,
165
+ inputs=[name_input, url_input, country_input],
166
+ outputs=[result_msg],
167
+ )
168
+
169
+ return name_input, url_input, country_input, submit_btn, result_msg
170
+
171
+
172
+ def create_tab():
173
+ """Create the complete tab for this resource type."""
174
+ with gr.TabItem(f"🏆 {RESOURCE_TITLE}", id=RESOURCE_TYPE):
175
+ with gr.Tabs():
176
+ table = create_all_tab()
177
+ inputs = create_contribute_tab()
178
+ return table, inputs