-
Notifications
You must be signed in to change notification settings - Fork 510
wsgiref #4950
-
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment · 8 replies
-
Kind of old package: https://pypi.org/project/wsgiref/#files But looks like its pure Python package. Add |
Beta Was this translation helpful? Give feedback.
All reactions
-
No Success. First I try:
Then:
So I try:
The app is created, but show:
My pyproject.toml file contains: (even with the wsgiref, don't work):
I need to download the wsgiref source file? |
Beta Was this translation helpful? Give feedback.
All reactions
-
In Flet 0.26 you have to set env variable:
|
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks for helping me, but it still doesn't work. I updated Flet and tried both ways, but only an infinite "Packaging Python app..." loading terminal output occurred. I was trying to make an attendance app for teachers syncing client storage with Google Sheets, but it seems that some main.py: import flet as ft
import gspread
import requests
import datetime
scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive']
creds = { omitted }
gc = gspread.service_account_from_dict(creds)
freq_sh = gc.open('omitted')
act_sh = gc.open('omitted')
schedule_sh = gc.open('omitted')
freq_7a_worksheet = freq_sh.worksheet('7a')
freq_8a_worksheet = freq_sh.worksheet('8a')
freq_8b_worksheet = freq_sh.worksheet('8b')
freq_9a_worksheet = freq_sh.worksheet('9a')
freq_9b_worksheet = freq_sh.worksheet('9b')
act_7a_worksheet = act_sh.worksheet('7a')
act_8a_worksheet = act_sh.worksheet('8a')
act_8b_worksheet = act_sh.worksheet('8b')
act_9a_worksheet = act_sh.worksheet('9a')
act_9b_worksheet = act_sh.worksheet('9b')
schedule_worksheet = schedule_sh.sheet1
FREQ_WORKSHEETS = {
"7a": freq_7a_worksheet,
"8a": freq_8a_worksheet,
"8b": freq_8b_worksheet,
"9a": freq_9a_worksheet,
"9b": freq_9b_worksheet,
}
ACT_WORKSHEETS = {
"7a": act_7a_worksheet,
"8a": act_8a_worksheet,
"8b": act_8b_worksheet,
"9a": act_9a_worksheet,
"9b": act_9b_worksheet,
}
PASSWORD = "omitted"
def main(page: ft.Page):
page.title = "Attendance App"
password_input = ft.TextField(password=True, label="Password", width=200)
loading_progress = ft.ProgressBar(value=0, visible=False)
no_connection_text = ft.Text("No connection!", color='red', visible=False)
def check_connection():
"""Checks for internet connectivity."""
try:
requests.get("http://www.google.com", timeout=5)
return True
except requests.ConnectionError:
return False
def check_password():
"""Checks if the entered password is correct."""
return password_input.value == PASSWORD
def load_class_data(worksheet):
"""Loads student data from a given worksheet."""
data_all = worksheet.get_all_records()
student_data = []
for row in data_all:
if 'name' in row:
student_data.append({
'Name': row['name'],
'Presence': 'P',
'Behavior': 'Good',
'Activity': 'NA',
'Observations': ''
})
return student_data
schedule_data = schedule_worksheet.get_all_values()
page.client_storage.set('schedule_data', schedule_data)
def create_schedule_table():
"""Creates the schedule table from client storage."""
no_connection_text.visible = False
if not check_connection():
no_connection_text.visible = True
loading_progress.visible = False
page.update()
return
schedule_data = page.client_storage.get('schedule_data')
if not schedule_data:
return ft.DataTable(columns=[ft.DataColumn(ft.Text("No Data"))])
# Create columns from the first row (header)
columns = [ft.DataColumn(ft.Text(header)) for header in schedule_data[0]]
# Create rows from the remaining data
rows = []
for row_data in schedule_data[1:]:
cells = [ft.DataCell(ft.Text(cell)) for cell in row_data]
rows.append(ft.DataRow(cells=cells))
return ft.DataTable(columns=columns, rows=rows, heading_row_color=ft.Colors.BLACK87)
def load_data_from_sheets():
"""Loads data from all worksheets and stores it in client storage."""
if not check_password():
page.update()
return
no_connection_text.visible = False
if not check_connection():
no_connection_text.visible = True
loading_progress.visible = False
page.update()
return
loading_progress.visible = True
page.update()
for i, (class_name, worksheet) in enumerate(FREQ_WORKSHEETS.items()):
class_data = load_class_data(worksheet)
page.client_storage.set(f'freq_{class_name}_data', class_data)
page.client_storage.set(f'act_name_{class_name}', "")
page.client_storage.set(f'note_name_{class_name}', "")
loading_progress.value = (i + 1) / len(FREQ_WORKSHEETS)
page.update()
loading_progress.visible = False
password_input.value = ""
page.update()
def get_class_data(storage_key):
"""Retrieves class data from client storage; returns None if not found."""
return page.client_storage.get(storage_key)
def create_attendance_table(class_data, storage_key):
"""Creates an attendance table with data from class data list."""
if class_data is None:
return ft.DataTable(columns=[
ft.DataColumn(ft.Text(label)) for label in ["Name", "Presence", "Behavior", "Activity", "Observations"]
])
def create_dropdown_factory(index_, field, options):
"""Creates a dropdown change handler factory."""
def dropdown_changed(e):
class_data_list = page.client_storage.get(storage_key)
if class_data_list and isinstance(class_data_list, list) and len(class_data_list) > index_:
class_data_list[index_][field] = e.control.value
page.client_storage.set(storage_key, class_data_list)
page.update()
return dropdown_changed
def create_text_changed(index_, field):
def on_text_changed(e):
class_data_list = page.client_storage.get(storage_key)
if class_data_list and isinstance(class_data_list, list) and len(class_data_list) > index_:
class_data_list[index_][field] = e.control.value
page.client_storage.set(storage_key, class_data_list)
page.update()
return on_text_changed
rows = []
for index, student_data in enumerate(class_data):
rows.append(
ft.DataRow(
cells=[
ft.DataCell(ft.Text(student_data['Name'])),
ft.DataCell(
ft.Dropdown(
value=student_data.get('Presence', 'P'),
bgcolor=ft.Colors.GREY_200,
border_radius=5,
content_padding=2,
text_size=12,
color='black',
on_change=create_dropdown_factory(index, 'Presence', ["P", "F", "NA"]),
options=[ft.dropdown.Option(option) for option in ["P", "F", "NA"]],
),
),
ft.DataCell(
ft.Dropdown(
value=student_data.get('Behavior', 'Good'),
bgcolor=ft.Colors.GREY_200,
content_padding=2,
text_size=12,
border_radius=5,
color='black',
on_change=create_dropdown_factory(index, 'Behavior', ["Good", "Bad", "Very bad", "Worst"]),
options=[ft.dropdown.Option(option) for option in ["Good", "Bad", "Very bad", "Worst"]],
),
),
ft.DataCell(
ft.Dropdown(
value=student_data.get('Activity', 'NA'),
bgcolor=ft.Colors.GREY_200,
content_padding=2,
text_size=12,
border_radius=5,
color='black',
on_change=create_dropdown_factory(index, 'Activity', ["NA", "Yes", "No"]),
options=[ft.dropdown.Option(option) for option in ["NA", "Yes", "No"]],
),
),
ft.DataCell(
ft.TextField(
value=student_data.get('Observations', ''),
bgcolor=ft.Colors.GREY_200,
content_padding=2,
text_size=12,
border_radius=5,
max_lines=3,
color='black',
on_change=create_text_changed(index, 'Observations'),
)
),
],
)
)
return ft.ResponsiveRow(controls=[ft.DataTable(
columns=[
ft.DataColumn(ft.Text(label)) for label in ["Name", "Presence", "Behavior", "Activity", "Observations"]
],
rows=rows,
heading_row_color=ft.Colors.BLACK87,
)])
def get_column_letter(col_index):
"""Converts a column index (1-based) to a column letter (A, B, C...) without string library."""
if col_index <= 0:
raise ValueError("Column index must be positive")
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
letters = ''
while col_index > 0:
col_index, remainder = divmod(col_index - 1, 26)
letters = alphabet[remainder] + letters
return letters
def save_data(class_name):
"""Saves the data for a specific class to Google Sheets, both Frequency and Activity sheets."""
if not check_password():
page.update()
return
no_connection_text.visible = False
if not check_connection():
no_connection_text.visible = True
loading_progress.visible = False
page.update()
return
class_data = get_class_data(f'freq_{class_name}_data')
if not class_data:
return
today = datetime.date.today().strftime("%Y-%m-%d")
freq_worksheet = FREQ_WORKSHEETS[class_name]
freq_data_to_insert = [today]
freq_notes_to_insert = {}
note_name = page.client_storage.get(f'note_name_{class_name}')
for index, student in enumerate(class_data):
if student['Presence'] == "NA":
freq_data_to_insert.append("NA")
elif student['Presence'] == "F":
freq_data_to_insert.append("F")
else:
freq_data_to_insert.append(student['Behavior'])
if student['Observations']:
col_letter = get_column_letter(len(freq_worksheet.row_values(1)) + 1)
cell_pos = f"{col_letter}{index + 2}"
freq_notes_to_insert[cell_pos] = student['Observations']
freq_worksheet.insert_cols([freq_data_to_insert], len(freq_worksheet.row_values(1)) + 1)
if freq_notes_to_insert:
freq_worksheet.insert_notes(freq_notes_to_insert)
if note_name:
col_letter = get_column_letter(len(freq_worksheet.row_values(1)))
header_cell_pos = f"{col_letter}1"
freq_notes_to_insert[header_cell_pos] = note_name
if freq_notes_to_insert:
freq_worksheet.insert_notes(freq_notes_to_insert)
act_worksheet = ACT_WORKSHEETS[class_name]
act_class_data = [student.copy() for student in class_data]
has_activity = any(s['Activity'] in ['Yes', 'No'] for s in act_class_data)
if has_activity:
for s in act_class_data:
if s['Presence'] == 'P' and s['Activity'] == 'NA':
s['Activity'] = 'No'
act_data_to_insert = [today]
act_notes_to_insert = {}
activity_name = page.client_storage.get(f'act_name_{class_name}')
for index, student in enumerate(act_class_data):
if student['Presence'] == "NA":
act_data_to_insert.append("NA")
elif student['Presence'] == "F":
act_data_to_insert.append("F")
else:
act_data_to_insert.append(student['Activity'])
if student['Observations']:
col_letter = get_column_letter(len(act_worksheet.row_values(1)) + 1)
cell_pos = f"{col_letter}{index + 2}"
act_notes_to_insert[cell_pos] = student['Observations']
act_worksheet.insert_cols([act_data_to_insert], len(act_worksheet.row_values(1)) + 1)
if activity_name:
col_letter = get_column_letter(len(act_worksheet.row_values(1)))
header_cell_pos = f"{col_letter}1"
act_notes_to_insert[header_cell_pos] = activity_name
if act_notes_to_insert:
act_worksheet.insert_notes(act_notes_to_insert)
password_input.value = ""
page.update()
def create_class_view(class_name):
"""Creates a view for a specific class, including the attendance table and save button."""
class_data = get_class_data(f'freq_{class_name}_data')
table = create_attendance_table(class_data, f'freq_{class_name}_data')
current_act_name = page.client_storage.get(f'act_name_{class_name}') or ""
current_note_name = page.client_storage.get(f'note_name_{class_name}') or ""
act_input = ft.TextField(
label="Activity Name",
width=300,
text_size=12,
value=current_act_name,
on_change=lambda e: page.client_storage.set(f'act_name_{class_name}', e.control.value)
)
note_input = ft.TextField(
label="Note Name",
width=300,
text_size=12,
value=current_note_name,
on_change=lambda e: page.client_storage.set(f'note_name_{class_name}', e.control.value)
)
return ft.View(
f"/{class_name}",
[
ft.Row(
[
password_input,
ft.ElevatedButton(f"Save Data", on_click=lambda _: save_data(class_name)),
],
),
no_connection_text,
act_input,
note_input,
ft.AppBar(title=ft.Text(f"{class_name[0]}º ano {class_name[-1].upper()} Frequency")),
table,
],
scroll='always'
)
def route_change(e):
page.views.clear()
schedule_table = create_schedule_table()
page.views.append(
ft.View(
"/",
[
ft.AppBar(title=ft.Text("Home")),
ft.ResponsiveRow(controls=[
ft.Row(
[
password_input,
ft.ElevatedButton("Load Data", on_click=lambda _: load_data_from_sheets()),
],
),
no_connection_text,
loading_progress,
ft.Text("Schedule", text_align='center', size=20, weight='bold'),
schedule_table,
ft.Text("Classes", text_align='center', size=20, weight='bold'),
*[ft.ElevatedButton(f"{class_name[0]}º ano {class_name[-1].upper()}", on_click=lambda _, name=class_name: page.go(f"/{name}"))
for class_name in FREQ_WORKSHEETS],]
)
],
scroll='always',
)
)
if page.route.startswith('/'):
class_name = page.route[1:]
if class_name in FREQ_WORKSHEETS:
page.views.append(create_class_view(class_name))
page.update()
def view_pop(e):
page.views.pop()
top_view = page.views[-1]
page.go(top_view.route)
page.on_route_change = route_change
page.on_view_pop = view_pop
page.go(page.route)
ft.app(target=main) pyproject.toml: # ...
dependencies = [
"flet==0.27.1",
"gspread",
"requests",
"datetime",
"wsgiref",
]
requires = [
"--find-links", "/dist",
"gspread",
]
# .... |
Beta Was this translation helpful? Give feedback.
All reactions
-
The package is so old Python 3.12 does not support print without braces: "SyntaxError: Missing parentheses in call to 'print'." Seems you need to fork it and adopt for latest Python versions. |
Beta Was this translation helpful? Give feedback.
All reactions
-
...or you can download the package and include its contents into your project (if the license permits). |
Beta Was this translation helpful? Give feedback.
All reactions
-
It worked. But I noticed that the version available on PyPi is very outdated, so I found the local Python installation folder and copied the "wsgiref" folder into the |
Beta Was this translation helpful? Give feedback.
All reactions
-
I Have the same problem can you help me? |
Beta Was this translation helpful? Give feedback.
All reactions
-
Sure @YosifMK . These were the steps I followed:
I'm not sure if this is the best approach, but it works for me. |
Beta Was this translation helpful? Give feedback.
--source-packages wsgiref
(whilewsgiref
in dependencies too!) worked in Flet 0.27, but I'm getting this error while installing package from source distro: