coulibaly-b commited on
Commit
240310d
1 Parent(s): d605c1e

login page

Browse files
AI_generator.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_community.llms import HuggingFaceHub
2
+ from langchain.chains import SequentialChain
3
+ from langchain.prompts import ChatPromptTemplate
4
+ from langchain.chains import LLMChain
5
+ from dotenv import load_dotenv
6
+ import streamlit as st
7
+ import plotly.express as px
8
+ import plotly.graph_objects as go
9
+ import os
10
+ import hashlib
11
+
12
+ load_dotenv()
13
+
14
+
15
+ HUGGINGFACE_HUB_API_TOKEN = os.getenv("HUGGINGFACE_HUB_API_TOKEN")
16
+
17
+
18
+ SCHEMA_STR = """ Table Name: sensitive_areas
19
+
20
+ !important : data_path = data/biodiv_sports.db
21
+
22
+ Columns:
23
+
24
+ 1. `id` (INTEGER): Unique identifier for the sensitive area and record.
25
+ 2. `name` (TEXT): Name of the sensitive area.
26
+ 3. `description` (TEXT): Description of the sensitive area.
27
+ 4. `practices` (INTEGER): Sporting activities related to the sensitive area.
28
+ 5. `structure` (TEXT): Name or acronym of the organization that provided the data for this sensitive area.
29
+ 6. `species_id` (INTEGER): Identifier for the species associated with the sensitive area, or NULL if it is a regulatory zone.
30
+ 7. `update_datetime` (TIMESTAMP): Date and time when the sensitive area was last updated.
31
+ 8. `create_datetime` (TIMESTAMP): Date and time when the sensitive area was created.
32
+ 9. `region` (TEXT): Region where the sensitive area is located.
33
+ 10. `departement` (TEXT): Department where the sensitive area is located.
34
+ 11. `pays` (TEXT): Country where the sensitive area is located.
35
+ 12. `months` (TEXT): Month during which the species is present in the sensitive area.
36
+
37
+ Other information:
38
+ - category='spece' if species_id else'regulatory zone'
39
+ category is not a column name.
40
+
41
+ - Each id represents a single record.
42
+ """
43
+
44
+
45
+ class SqlToPlotlyStreamlit:
46
+ @staticmethod
47
+ def chat_prompt_template() -> list:
48
+ first_prompt = ChatPromptTemplate.from_template(
49
+ """Generate the optimal SQL query considering the following table schema and the user's question.
50
+ !IMPORTANT: Generate exactly one query and ensure that the query can be used directly without further \
51
+ modification with sqlite3. Ensure that the columns used in the generated query match the table schema."""
52
+ "!Important: if there are aggregations arroundi the result to 2 decimal places always"
53
+ """Table schema:\n{schema}\nQuestion: {question}"""
54
+ )
55
+
56
+ second_prompt = ChatPromptTemplate.from_template(
57
+ "Convert the provided SQL query {query} into a Python best graph code snippet. Use the plotly library otherwise seaborn with error handling for visualization."
58
+ "!IMPORTANT : Provide detailed instructions about loading necessary libraries very important, setting up credentials,"
59
+ "and configuring parameters needed for connecting to the database, creating the figure, and showing the plot."
60
+ "the graph will part of an streamlit app so import streamlit, pandas and all librairie that will be use."
61
+ "Follow the following step:"
62
+ "1 - import all neccessary librairies"
63
+ "2 - settting up database connection with sqlite.connect"
64
+ "3 - Use pandas read_sql_query to retrieve data from database"
65
+ "4 - close database connection"
66
+ "5 - try Plotly to build the graph if error use seaborn"
67
+ "6 - Use distinct color in the graph"
68
+ "7 - Display the dataframe in table format"
69
+ "8 - Never use statment if __name__ == '__main__' "
70
+ )
71
+
72
+ third_prompt = ChatPromptTemplate.from_template(
73
+ """Return a JSON object containing the original {question}, extracted SQL query {query}, and extracted corresponding Python code {python_graph} snippet separated by two newlines ('\n')."""
74
+ )
75
+
76
+ fourth_prompt = ChatPromptTemplate.from_template(
77
+ """Generate another type of graphic for the {query} different from {python_graph}."""
78
+ )
79
+
80
+ return [first_prompt, second_prompt, third_prompt, fourth_prompt]
81
+
82
+ @staticmethod
83
+ def generate_anwers() -> list:
84
+ first_prompt, second_prompt, third_prompt, fourth_prompt = (
85
+ SqlToPlotlyStreamlit.chat_prompt_template()
86
+ )
87
+
88
+ chain_one = LLMChain(llm=llm, prompt=first_prompt, output_key="query")
89
+ chain_two = LLMChain(llm=llm, prompt=second_prompt, output_key="python_graph")
90
+ chain_three = LLMChain(llm=llm, prompt=third_prompt, output_key="json")
91
+ chain_four = LLMChain(
92
+ llm=llm, prompt=fourth_prompt, output_key="reformulated_query"
93
+ )
94
+
95
+ return [chain_one, chain_two, chain_three, chain_four]
96
+
97
+ @staticmethod
98
+ def format_python_code_string(code_str: str) -> str:
99
+ import re
100
+
101
+ # Supprimer les espaces inutiles
102
+ code_str = re.sub(r"^\s+", "", code_str, flags=re.MULTILINE)
103
+ code_str = re.sub(r"\s+", " ", code_str)
104
+ code_str = re.sub(r"\s+$", "", code_str, flags=re.MULTILINE)
105
+
106
+ # Ajouter des espaces avant et après les opérateurs
107
+ code_str = re.sub(r"(\+|\-|\*|\/|\=|\(|\))", r" \1 ", code_str)
108
+ code_str = re.sub(r"(\w+)\s*(\w+)", r"\1 \2", code_str)
109
+
110
+ # Ajouter des espaces après les virgules
111
+ code_str = re.sub(r",\s*", ", ", code_str)
112
+
113
+ # Ajouter des espaces après les deux-points
114
+ code_str = re.sub(r":\s*", ": ", code_str)
115
+
116
+ # Ajouter des espaces avant les crochets et accolades
117
+ code_str = re.sub(r"(\w+)\s*(\{|\[)", r"\1 \2", code_str)
118
+ code_str = re.sub(r"(\}|\])", r" \1", code_str)
119
+
120
+ # Aligner les indentations
121
+ lines = code_str.split("\n")
122
+ indentation_levels = []
123
+ for line in lines:
124
+ indentation_level = len(line) - len(line.lstrip())
125
+ indentation_levels.append(indentation_level)
126
+ max_indentation_level = max(indentation_levels)
127
+ indentation_spaces = " " * max_indentation_level
128
+ code_str = "\n".join(indentation_spaces + line.lstrip() for line in lines)
129
+
130
+ # Ajouter des espaces entre les mots-clés et les identifiants
131
+ code_str = re.sub(r"(\b(and|or|not|is|in)\b)\s*(\w+)", r"\1 \3", code_str)
132
+
133
+ return code_str
134
+
135
+ @staticmethod
136
+ def code_execution(code_str):
137
+
138
+ code_str = SqlToPlotlyStreamlit.format_python_code_string(code_str)
139
+ # Exécuter le code dans un environnement isolé
140
+ namespace = {}
141
+ exec(code_str, namespace)
142
+
143
+ # Récupérer la figure du namespace
144
+ fig = namespace.get("fig")
145
+
146
+ if isinstance(fig, go.Figure):
147
+
148
+ st.plotly_chart(fig)
149
+
150
+ def __init__(self, schema: str, question: str):
151
+ self.schema = schema
152
+ self.question = question
153
+ self.llm = HuggingFaceHub(
154
+ repo_id="mistralai/MixTraL-8x7B-Instruct-v0.1",
155
+ model_kwargs={
156
+ "temperature": 0.001,
157
+ "max_length": 5000,
158
+ "max_new_tokens": 1024,
159
+ },
160
+ huggingfacehub_api_token=HUGGINGFACE_HUB_API_TOKEN,
161
+ )
162
+
163
+ def execute_overall_flow(self):
164
+ error_occurred = False
165
+
166
+ try:
167
+ overall_chain = SequentialChain(
168
+ chains=list(SqlToPlotlyStreamlit.generate_anwers()),
169
+ input_variables=["schema", "question"],
170
+ output_variables=["query", "python_graph", "json"],
171
+ verbose=True,
172
+ )
173
+ result = overall_chain({"schema": self.schema, "question": self.question})
174
+ self.generated_python_code = (
175
+ result["json"].split("```python")[-1].split("```")[0].replace("```", "")
176
+ )
177
+ # self.code_execution(self.generated_python_code)
178
+
179
+ except Exception as e:
180
+ error_message = f"\nAttempt: An exception occurred while executing the generated code:{e}"
181
+ st.write(error_message)
182
+ error_occurred = True
183
+
184
+ if not error_occurred:
185
+ # st.write("## Generated Query")
186
+ # st.code(result["json"].split("```sql")[-1].split("```")[0].replace("```", ""))
187
+ st.write("## Generated Python")
188
+ st.code(self.generated_python_code)
189
+
190
+
191
+ def main():
192
+ st.set_page_config(layout="wide")
193
+ st.title("SQL Query Visualizer")
194
+
195
+ schema = SCHEMA_STR
196
+ question = st.text_input(
197
+ "Enter Question:", "what is the total of zones for each category ?"
198
+ )
199
+ if st.button("Run"):
200
+ obj = SqlToPlotlyStreamlit(schema, question)
201
+ obj.execute_overall_flow()
202
+ exec(obj.generated_python_code)
LPO_AI.egg-info/PKG-INFO ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: LPO_AI
3
+ Version: 0.0.0
LPO_AI.egg-info/SOURCES.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ README.md
2
+ setup.py
3
+ LPO_AI.egg-info/PKG-INFO
4
+ LPO_AI.egg-info/SOURCES.txt
5
+ LPO_AI.egg-info/dependency_links.txt
6
+ LPO_AI.egg-info/top_level.txt
LPO_AI.egg-info/dependency_links.txt ADDED
@@ -0,0 +1 @@
 
 
1
+
LPO_AI.egg-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+
__pycache__/AI_generator.cpython-312.pyc ADDED
Binary file (9.79 kB). View file
 
__pycache__/dashboard.cpython-312.pyc ADDED
Binary file (4.69 kB). View file
 
app.py CHANGED
@@ -1,209 +1,82 @@
1
- from langchain_community.llms import HuggingFaceHub
2
- from langchain.chains import SequentialChain
3
- from langchain.prompts import ChatPromptTemplate
4
- from langchain.chains import LLMChain
5
- from dotenv import load_dotenv
6
  import streamlit as st
7
- import matplotlib.pyplot as plt
8
- import plotly.express as px
9
- import plotly.graph_objects as go
 
10
  import os
 
11
 
12
  load_dotenv()
13
- HUGGINGFACE_HUB_API_TOKEN = os.getenv("HUGGINGFACE_HUB_API_TOKEN")
14
-
15
- llm = HuggingFaceHub(
16
- repo_id="mistralai/MixTraL-8x7B-Instruct-v0.1",
17
- model_kwargs={
18
- "temperature": 0.001,
19
- "max_length": 5000,
20
- "max_new_tokens": 1024,
21
- },
22
- huggingfacehub_api_token=HUGGINGFACE_HUB_API_TOKEN,
23
- )
24
-
25
- SCHEMA_STR = """ Table Name: sensitive_areas
26
-
27
- !important : data_path = data/biodiv_sports.db
28
-
29
- Columns:
30
-
31
- 1. `id` (INTEGER): Unique identifier for the sensitive area.
32
- 2. `name` (TEXT): Name of the sensitive area.
33
- 3. `description` (TEXT): Description of the sensitive area.
34
- 4. `practices` (INTEGER): Sporting activities related to the sensitive area.
35
- 5. `structure` (TEXT): Name or acronym of the organization that provided the data for this sensitive area.
36
- 6. `species_id` (INTEGER): Identifier for the species associated with the sensitive area, or NULL if it is a regulatory zone.
37
- 7. `update_datetime` (TIMESTAMP): Date and time when the sensitive area was last updated.
38
- 8. `create_datetime` (TIMESTAMP): Date and time when the sensitive area was created.
39
- 9. `region` (TEXT): Region where the sensitive area is located.
40
- 10. `departement` (TEXT): Department where the sensitive area is located.
41
- 11. `pays` (TEXT): Country where the sensitive area is located.
42
- 12. `months` (TEXT): Month during which the species is present in the sensitive area.
43
-
44
- Other information: category='spece' if species_id else'regulatory zone'
45
- category is not a column name."""
46
-
47
-
48
- class SqlToPlotlyStreamlit:
49
- @staticmethod
50
- def chat_prompt_template() -> list:
51
- first_prompt = ChatPromptTemplate.from_template(
52
- """Generate the optimal SQL query considering the following table schema and the user's question.
53
- !IMPORTANT: Generate exactly one query and ensure that the query can be used directly without further \
54
- modification with sqlite3. Ensure that the columns used in the generated query match the table schema."""
55
- "!Important: if there are aggregations arroundi the result to 2 decimal places always"
56
- """Table schema:\n{schema}\nQuestion: {question}"""
57
- )
58
-
59
- second_prompt = ChatPromptTemplate.from_template(
60
- "Convert the provided SQL query {query} into a Python best graph code snippet. Use the plotly library otherwise seaborn with error handling for visualization."
61
- "!IMPORTANT : Provide detailed instructions about loading necessary libraries very important, setting up credentials,"
62
- "and configuring parameters needed for connecting to the database, creating the figure, and showing the plot."
63
- "the graph will part of an streamlit app so import streamlit, pandas and all librairie that will be use."
64
- "Follow the following step:"
65
- "1 - import all neccessary librairies"
66
- "2 - settting up database connection with sqlite.connect"
67
- "3 - Use pandas read_sql_query to retrieve data from database"
68
- "4 - close database connection"
69
- "5 - try Plotly to build the graph if error use seaborn"
70
- "6 - Use distinct color in the graph"
71
- "7 - Display the dataframe in table format"
72
- "8 - Never use statment if __name__ == '__main__' "
73
- )
74
-
75
- third_prompt = ChatPromptTemplate.from_template(
76
- """Return a JSON object containing the original {question}, extracted SQL query {query}, and extracted corresponding Python code {python_graph} snippet separated by two newlines ('\n')."""
77
- )
78
 
79
- fourth_prompt = ChatPromptTemplate.from_template(
80
- """Generate another type of graphic for the {query} different from {python_graph}."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  )
 
 
 
 
82
 
83
- return [first_prompt, second_prompt, third_prompt, fourth_prompt]
84
-
85
- @staticmethod
86
- def generate_anwers() -> list:
87
- first_prompt, second_prompt, third_prompt, fourth_prompt = (
88
- SqlToPlotlyStreamlit.chat_prompt_template()
89
- )
90
-
91
- chain_one = LLMChain(llm=llm, prompt=first_prompt, output_key="query")
92
- chain_two = LLMChain(llm=llm, prompt=second_prompt, output_key="python_graph")
93
- chain_three = LLMChain(llm=llm, prompt=third_prompt, output_key="json")
94
- chain_four = LLMChain(
95
- llm=llm, prompt=fourth_prompt, output_key="reformulated_query"
96
- )
97
-
98
- return [chain_one, chain_two, chain_three, chain_four]
99
-
100
- @staticmethod
101
- def format_python_code_string(code_str: str) -> str:
102
- import re
103
-
104
- # Supprimer les espaces inutiles
105
- code_str = re.sub(r"^\s+", "", code_str, flags=re.MULTILINE)
106
- code_str = re.sub(r"\s+", " ", code_str)
107
- code_str = re.sub(r"\s+$", "", code_str, flags=re.MULTILINE)
108
-
109
- # Ajouter des espaces avant et après les opérateurs
110
- code_str = re.sub(r"(\+|\-|\*|\/|\=|\(|\))", r" \1 ", code_str)
111
- code_str = re.sub(r"(\w+)\s*(\w+)", r"\1 \2", code_str)
112
-
113
- # Ajouter des espaces après les virgules
114
- code_str = re.sub(r",\s*", ", ", code_str)
115
-
116
- # Ajouter des espaces après les deux-points
117
- code_str = re.sub(r":\s*", ": ", code_str)
118
-
119
- # Ajouter des espaces avant les crochets et accolades
120
- code_str = re.sub(r"(\w+)\s*(\{|\[)", r"\1 \2", code_str)
121
- code_str = re.sub(r"(\}|\])", r" \1", code_str)
122
-
123
- # Aligner les indentations
124
- lines = code_str.split("\n")
125
- indentation_levels = []
126
- for line in lines:
127
- indentation_level = len(line) - len(line.lstrip())
128
- indentation_levels.append(indentation_level)
129
- max_indentation_level = max(indentation_levels)
130
- indentation_spaces = " " * max_indentation_level
131
- code_str = "\n".join(indentation_spaces + line.lstrip() for line in lines)
132
-
133
- # Ajouter des espaces entre les mots-clés et les identifiants
134
- code_str = re.sub(r"(\b(and|or|not|is|in)\b)\s*(\w+)", r"\1 \3", code_str)
135
-
136
- return code_str
137
-
138
- @staticmethod
139
- def code_execution(code_str):
140
-
141
- code_str = SqlToPlotlyStreamlit.format_python_code_string(code_str)
142
- # Exécuter le code dans un environnement isolé
143
- namespace = {}
144
- exec(code_str, namespace)
145
-
146
- # Récupérer la figure du namespace
147
- fig = namespace.get("fig")
148
-
149
- if isinstance(fig, go.Figure):
150
-
151
- st.plotly_chart(fig)
152
-
153
- def __init__(self, schema: str, question: str):
154
- self.schema = schema
155
- self.question = question
156
- self.llm = HuggingFaceHub(
157
- repo_id="mistralai/MixTraL-8x7B-Instruct-v0.1",
158
- model_kwargs={
159
- "temperature": 0.001,
160
- "max_length": 5000,
161
- "max_new_tokens": 1024,
162
- },
163
- huggingfacehub_api_token=HUGGINGFACE_HUB_API_TOKEN,
164
- )
165
 
166
- def execute_overall_flow(self):
167
- error_occurred = False
168
-
169
- try:
170
- overall_chain = SequentialChain(
171
- chains=list(SqlToPlotlyStreamlit.generate_anwers()),
172
- input_variables=["schema", "question"],
173
- output_variables=["query", "python_graph", "json"],
174
- verbose=True,
175
- )
176
- result = overall_chain({"schema": self.schema, "question": self.question})
177
- self.generated_python_code = (
178
- result["json"].split("```python")[-1].split("```")[0].replace("```", "")
179
- )
180
- # self.code_execution(self.generated_python_code)
181
-
182
- except Exception as e:
183
- error_message = f"\nAttempt: An exception occurred while executing the generated code:{e}"
184
- st.write(error_message)
185
- error_occurred = True
186
-
187
- if not error_occurred:
188
- # st.write("## Generated Query")
189
- # st.code(result["json"].split("```sql")[-1].split("```")[0].replace("```", ""))
190
- st.write("## Generated Python")
191
- st.code(self.generated_python_code)
192
-
193
-
194
- def main():
195
- st.set_page_config(layout="wide")
196
- st.title("SQL Query Visualizer")
197
-
198
- schema = SCHEMA_STR
199
- question = st.text_input(
200
- "Enter Question:", "what is the total of zones for each category ?"
201
- )
202
- if st.button("Run"):
203
- obj = SqlToPlotlyStreamlit(schema, question)
204
- obj.execute_overall_flow()
205
- exec(obj.generated_python_code)
206
 
207
 
 
208
  if __name__ == "__main__":
209
- main()
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import hashlib
3
+ from AI_generator import SCHEMA_STR, SqlToPlotlyStreamlit
4
+ from dashboard import dashboard
5
+ from dotenv import load_dotenv
6
  import os
7
+ import hashlib
8
 
9
  load_dotenv()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ username = os.getenv("USERNAME")
12
+ password = os.getenv("PASSWORD")
13
+
14
+
15
+ st.sidebar.markdown("""
16
+ <footer style="position: fixed; bottom: 0; text-align: center; background-color: #002b36; border-top: 1px solid #ddd;">
17
+ &copy; 2023 LPO. All rights reserved.
18
+ </footer>
19
+ """, unsafe_allow_html=True)
20
+
21
+
22
+ # Create an authentication function
23
+ def authenticate(username, password):
24
+
25
+ users = {
26
+ username: hashlib.sha256(password.encode()).hexdigest()
27
+ }
28
+ hashed_password = hashlib.sha256(password.encode()).hexdigest()
29
+ if username in users and users[username] == hashed_password:
30
+ return True
31
+ return False
32
+
33
+
34
+ # Create a login form
35
+ @st.cache_resource()
36
+ def login_cache():
37
+ return {"authenticated": False}
38
+
39
+
40
+ def login():
41
+ st.title("Login")
42
+ form = st.form("login_form")
43
+ username = form.text_input("Username")
44
+ password = form.text_input("Password", type="password")
45
+ if form.form_submit_button("Login"):
46
+ if authenticate(username, password):
47
+ login_cache()["authenticated"] = True
48
+ st.experimental_rerun()
49
+ else:
50
+ st.error("Invalid username or password")
51
+
52
+
53
+ # Protect your app content
54
+ def home():
55
+ if not login_cache()["authenticated"]:
56
+ login()
57
+ else:
58
+ # Your app content here
59
+ st.title("SQL Query Visualizer")
60
+ schema = SCHEMA_STR
61
+ question = st.text_input(
62
+ "Enter Question:", "what is the total of zones for each category?"
63
  )
64
+ if st.button("Run"):
65
+ obj = SqlToPlotlyStreamlit(schema, question)
66
+ obj.execute_overall_flow()
67
+ exec(obj.generated_python_code)
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
+ def page2():
71
+ if not login_cache()["authenticated"]:
72
+ login()
73
+ else:
74
+ dashboard()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
 
77
+ # Run the app
78
  if __name__ == "__main__":
79
+ pages = {"AI Generator": home, "Analytic Dashboard": page2}
80
+ st.sidebar.markdown("<h2> Select a page </h2>", unsafe_allow_html=True)
81
+ page = st.sidebar.selectbox("", list(pages.keys()))
82
+ pages[page]()
dashboard.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+ import sqlite3
4
+ import plotly.express as px
5
+
6
+ # Database connection
7
+ conn = sqlite3.connect("data/biodiv_sports.db")
8
+
9
+ # Queries
10
+ query_zone_catg_prop = """
11
+ SELECT
12
+ CASE
13
+ WHEN species_id IS NOT NULL THEN 'Espèces'
14
+ ELSE 'Réglementaire'
15
+ END AS zone_category,
16
+ ROUND(COUNT(DISTINCT id)*1.0/(
17
+ SELECT
18
+ COUNT(DISTINCT id)
19
+ FROM
20
+ sensitive_areas
21
+ ), 2) AS proportion
22
+ FROM
23
+ sensitive_areas
24
+ GROUP BY
25
+ zone_category;
26
+ """
27
+
28
+ query_mon_wise_prop = """
29
+ SELECT
30
+ months,
31
+ species_id,
32
+ ROUND(COUNT(DISTINCT id)*1.0/(
33
+ SELECT
34
+ COUNT(DISTINCT id)
35
+ FROM
36
+ sensitive_areas
37
+ ), 2) AS proportion
38
+ FROM
39
+ sensitive_areas
40
+ GROUP BY
41
+ months
42
+ ORDER BY
43
+ months;
44
+ """
45
+
46
+ query_practice_mon_wise = """
47
+ SELECT
48
+ practices,
49
+ months,
50
+ species_id,
51
+ COUNT(DISTINCT id) AS nombre_zone
52
+ FROM
53
+ sensitive_areas
54
+ GROUP BY
55
+ 1,
56
+ 2,
57
+ 3;
58
+ """
59
+
60
+ query_zone_per_species = """
61
+ SELECT
62
+ name,
63
+ COUNT(DISTINCT id)/12.0 AS number_of_zones
64
+ FROM
65
+ sensitive_areas
66
+ WHERE
67
+ species_id IS NOT NULL
68
+ GROUP BY
69
+ 1;
70
+ """
71
+
72
+
73
+ def dashboard():
74
+ conn = sqlite3.connect("data/biodiv_sports.db")
75
+
76
+ # Read query results into Pandas DataFrames
77
+ df_zone_catg_prop = pd.read_sql_query(query_zone_catg_prop, conn)
78
+ df_mon_wise_prop = pd.read_sql_query(query_mon_wise_prop, conn)
79
+ df_practice_mon_wise = pd.read_sql_query(query_practice_mon_wise, conn)
80
+ df_zone_per_species = pd.read_sql_query(query_zone_per_species, conn)
81
+
82
+ # Map month names to their corresponding numbers
83
+ MONTHS = [
84
+ "janvier",
85
+ "fevrier",
86
+ "mars",
87
+ "avril",
88
+ "mai",
89
+ "juin",
90
+ "juillet",
91
+ "août",
92
+ "septembre",
93
+ "octobre",
94
+ "novembre",
95
+ "decembre",
96
+ ]
97
+ MONTH_MAPPING = {k: v + 1 for v, k in enumerate(MONTHS)}
98
+
99
+ # Add a numeric_months column based on MONTH_MAPPING
100
+ df_practice_mon_wise["numeric_months"] = df_practice_mon_wise["months"].map(
101
+ MONTH_MAPPING
102
+ )
103
+ df_mon_wise_prop["numeric_months"] = df_mon_wise_prop["months"].map(MONTH_MAPPING)
104
+
105
+ # Sort by numeric_months and reset index before dropping it
106
+ df_practice_mon_wise = df_practice_mon_wise.sort_values(
107
+ ["numeric_months", "species_id"]
108
+ ).reset_index(drop=True)
109
+ df_practice_mon_wise.drop("numeric_months", axis=1, inplace=True)
110
+
111
+ df_mon_wise_prop = df_mon_wise_prop.sort_values(
112
+ ["numeric_months", "proportion"]
113
+ ).reset_index(drop=True)
114
+ df_mon_wise_prop.drop("numeric_months", axis=1, inplace=True)
115
+
116
+ st.markdown(
117
+ """<h1 style='text-align: center'>Visualization of Biodiv-Sport
118
+ Database</h1>""",
119
+ unsafe_allow_html=True,
120
+ )
121
+
122
+ # Charts
123
+ fig_pie = px.pie(df_zone_catg_prop, values="proportion", names="zone_category")
124
+ fig_pie.update_layout(
125
+ paper_bgcolor="#002b36",
126
+ plot_bgcolor="#586e75",
127
+ font_color="#fafafa",
128
+ title={"text": "<b>Proportions of Zone Categories</b>", "x": 0.0, "y": 1},
129
+ )
130
+
131
+ fig_bar = px.bar(df_zone_per_species, x="name", y="number_of_zones")
132
+ fig_bar.update_layout(
133
+ paper_bgcolor="#002b36",
134
+ plot_bgcolor="#586e75",
135
+ font_color="#fafafa",
136
+ title={"text": "<b>Total Number of Zones Per Species</b>", "x": 0.0, "y": 1},
137
+ )
138
+
139
+ fig_line = px.line(df_mon_wise_prop, x="months", y="proportion", color="species_id")
140
+ fig_line.update_layout(
141
+ paper_bgcolor="#002b36",
142
+ plot_bgcolor="#586e75",
143
+ font_color="#fafafa",
144
+ title={
145
+ "text": "<b>Monthly Proportion Distribution Across Year</b>",
146
+ "x": 0.0,
147
+ "y": 1,
148
+ },
149
+ )
150
+
151
+ fig_heatmap = px.density_heatmap(
152
+ df_practice_mon_wise,
153
+ x="months",
154
+ y="practices",
155
+ z="nombre_zone",
156
+ color_continuous_scale="OrRd",
157
+ nbinsx=12, # Set the number of bins in the x direction (months)
158
+ nbinsy=10,
159
+ )
160
+ fig_heatmap.update_layout(
161
+ xaxis={
162
+ "tickmode": "array",
163
+ "tickvals": list(MONTH_MAPPING.keys()),
164
+ },
165
+ paper_bgcolor="#002b36",
166
+ plot_bgcolor="#586e75",
167
+ font_color="#fafafa",
168
+ title={
169
+ "text": "Number of Zones According to Activity Practiced and By Month",
170
+ "x": 0.0,
171
+ "y": 1.0,
172
+ },
173
+ )
174
+
175
+ st.plotly_chart(fig_pie)
176
+
177
+ st.plotly_chart(fig_bar)
178
+
179
+ st.plotly_chart(fig_line)
180
+
181
+ st.plotly_chart(fig_heatmap)
pages/dashboard.py DELETED
@@ -1,177 +0,0 @@
1
- import pandas as pd
2
- import streamlit as st
3
- import sqlite3
4
- import plotly.express as px
5
-
6
- # Database connection
7
- conn = sqlite3.connect("data/biodiv_sports.db")
8
-
9
- # Queries
10
- query_zone_catg_prop = """
11
- SELECT
12
- CASE
13
- WHEN species_id IS NOT NULL THEN 'Espèces'
14
- ELSE 'Réglementaire'
15
- END AS zone_category,
16
- ROUND(COUNT(DISTINCT id)*1.0/(
17
- SELECT
18
- COUNT(DISTINCT id)
19
- FROM
20
- sensitive_areas
21
- ), 2) AS proportion
22
- FROM
23
- sensitive_areas
24
- GROUP BY
25
- zone_category;
26
- """
27
-
28
- query_mon_wise_prop = """
29
- SELECT
30
- months,
31
- species_id,
32
- ROUND(COUNT(DISTINCT id)*1.0/(
33
- SELECT
34
- COUNT(DISTINCT id)
35
- FROM
36
- sensitive_areas
37
- ), 2) AS proportion
38
- FROM
39
- sensitive_areas
40
- GROUP BY
41
- months
42
- ORDER BY
43
- months;
44
- """
45
-
46
- query_practice_mon_wise = """
47
- SELECT
48
- practices,
49
- months,
50
- species_id,
51
- COUNT(DISTINCT id) AS nombre_zone
52
- FROM
53
- sensitive_areas
54
- GROUP BY
55
- 1,
56
- 2,
57
- 3;
58
- """
59
-
60
- query_zone_per_species = """
61
- SELECT
62
- name,
63
- COUNT(DISTINCT id) AS number_of_zones
64
- FROM
65
- sensitive_areas
66
- WHERE
67
- species_id IS NOT NULL
68
- GROUP BY
69
- 1;
70
- """
71
-
72
- # Read query results into Pandas DataFrames
73
- df_zone_catg_prop = pd.read_sql_query(query_zone_catg_prop, conn)
74
- df_mon_wise_prop = pd.read_sql_query(query_mon_wise_prop, conn)
75
- df_practice_mon_wise = pd.read_sql_query(query_practice_mon_wise, conn)
76
- df_zone_per_species = pd.read_sql_query(query_zone_per_species, conn)
77
-
78
- # Map month names to their corresponding numbers
79
- MONTHS = ['janvier', 'fevrier', 'mars', 'avril', 'mai', 'juin',
80
- 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'decembre']
81
- MONTH_MAPPING = {k: v+1 for v, k in enumerate(MONTHS)}
82
-
83
- # Add a numeric_months column based on MONTH_MAPPING
84
- df_practice_mon_wise['numeric_months'] = df_practice_mon_wise['months'].map(
85
- MONTH_MAPPING
86
- )
87
- df_mon_wise_prop['numeric_months'] = df_mon_wise_prop['months'].map(
88
- MONTH_MAPPING
89
- )
90
-
91
- # Sort by numeric_months and reset index before dropping it
92
- df_practice_mon_wise = df_practice_mon_wise.sort_values(['numeric_months',
93
- 'species_id']
94
- ).reset_index(
95
- drop=True
96
- )
97
- df_practice_mon_wise.drop('numeric_months', axis=1, inplace=True)
98
-
99
- df_mon_wise_prop = df_mon_wise_prop.sort_values(['numeric_months',
100
- 'proportion']
101
- ).reset_index(
102
- drop=True
103
- )
104
- df_mon_wise_prop.drop('numeric_months', axis=1, inplace=True)
105
-
106
-
107
- st.markdown("""<h1 style='text-align: center'>Visualization of Biodiv-Sport
108
- Database</h1>""", unsafe_allow_html=True)
109
-
110
- # Charts
111
- fig_pie = px.pie(df_zone_catg_prop, values="proportion", names="zone_category")
112
- fig_pie.update_layout(
113
- paper_bgcolor="#002b36",
114
- plot_bgcolor="#586e75",
115
- font_color="#fafafa",
116
- title={
117
- "text": "<b>Proportions of Zone Categories</b>",
118
- "x": 0.,
119
- "y": 1
120
- })
121
-
122
- fig_bar = px.bar(df_zone_per_species, x="name", y="number_of_zones")
123
- fig_bar.update_layout(
124
- paper_bgcolor="#002b36",
125
- plot_bgcolor="#586e75",
126
- font_color="#fafafa",
127
- title={
128
- "text": "<b>Total Number of Zones Per Species</b>",
129
- "x": 0.,
130
- "y": 1
131
- })
132
-
133
- fig_line = px.line(df_mon_wise_prop, x="months",
134
- y="proportion",
135
- color="species_id")
136
- fig_line.update_layout(
137
- paper_bgcolor="#002b36",
138
- plot_bgcolor="#586e75",
139
- font_color="#fafafa",
140
- title={
141
- "text": "<b>Monthly Proportion Distribution Across Year</b>",
142
- "x": 0.,
143
- "y": 1
144
- })
145
-
146
-
147
- fig_heatmap = px.density_heatmap(df_practice_mon_wise,
148
- x="months",
149
- y="practices",
150
- z="nombre_zone",
151
- color_continuous_scale="OrRd",
152
- nbinsx=12, # Set the number of bins in the x direction (months)
153
- nbinsy=10
154
- )
155
- fig_heatmap.update_layout(
156
- xaxis={
157
- "tickmode": "array",
158
- "tickvals": list(MONTH_MAPPING.keys()),
159
- },
160
- paper_bgcolor="#002b36",
161
- plot_bgcolor="#586e75",
162
- font_color="#fafafa",
163
- title={
164
- "text": "Number of Zones According to Activity Practiced and By Month",
165
- "x": 0.,
166
- "y": 1.0
167
- }
168
- )
169
-
170
- st.plotly_chart(fig_pie)
171
-
172
- st.plotly_chart(fig_bar)
173
-
174
-
175
- st.plotly_chart(fig_line)
176
-
177
- st.plotly_chart(fig_heatmap)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
setup.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(name="LPO_AI", packages=find_packages())