Build Flet Material component gallery
This commit is contained in:
commit
e8830e846a
20 changed files with 1327 additions and 0 deletions
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
.venv/
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
.pytest_cache/
|
||||
.ruff_cache/
|
||||
build/
|
||||
dist/
|
||||
.DS_Store
|
||||
|
||||
2
.python-version
Normal file
2
.python-version
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
3.13
|
||||
|
||||
50
README.md
Normal file
50
README.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Flet Component Gallery
|
||||
|
||||
Интерактивная галерея компонентов Flet в духе Google Compose Material Catalog.
|
||||
Каждый пример — рабочий интерфейс и отдельная читаемая Python-функция; кнопка
|
||||
`</>` рядом с примером открывает точную строку исходного кода в репозитории.
|
||||
|
||||
В каталоге 27 интерактивных примеров: кнопки, поля ввода, controls выбора,
|
||||
типографика, карточки, списки, адаптивные layouts, навигация, таблицы, progress,
|
||||
dialogs, snackbar и bottom sheet. Постоянная кнопка настроек позволяет менять
|
||||
светлую/тёмную/системную тему, Material 3 accent color и видимость кнопок кода.
|
||||
|
||||
## Запуск
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
uv run flet run src/main.py
|
||||
```
|
||||
|
||||
В браузере:
|
||||
|
||||
```bash
|
||||
uv run flet run --web src/main.py
|
||||
```
|
||||
|
||||
## Проверки и ссылки на код
|
||||
|
||||
```bash
|
||||
uv run python tools/generate_source_manifest.py
|
||||
uv run ruff check .
|
||||
uv run pytest -q
|
||||
```
|
||||
|
||||
Генератор разбирает учебные функции через AST и записывает точные строки в
|
||||
`src/gallery/source_manifest.json`. Манифест следует обновлять перед коммитом и
|
||||
сборкой.
|
||||
|
||||
## Android ARMv8
|
||||
|
||||
ARMv8 в Android соответствует ABI `arm64-v8a`:
|
||||
|
||||
```bash
|
||||
uv run flet build apk src --arch arm64-v8a --yes \
|
||||
--project flet_component_gallery \
|
||||
--product "Flet Material Catalog" \
|
||||
--org su.snw
|
||||
```
|
||||
|
||||
APK появится в `src/build/apk/`. Платформенные controls, требующие permissions,
|
||||
нативных сервисов или внешних расширений (камера, карта, WebView), намеренно не
|
||||
имитируются: каталог сфокусирован на стандартных визуальных Flet controls.
|
||||
26
pyproject.toml
Normal file
26
pyproject.toml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
[project]
|
||||
name = "flet-component-gallery"
|
||||
version = "0.1.0"
|
||||
description = "Composer-inspired interactive gallery of Flet controls"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
"flet==1.0.1",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"pytest>=8.4.0",
|
||||
"ruff>=0.13.0",
|
||||
]
|
||||
|
||||
[tool.uv]
|
||||
package = false
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
target-version = "py311"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
pythonpath = ["src"]
|
||||
2
src/gallery/__init__.py
Normal file
2
src/gallery/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"""Flet Component Gallery package."""
|
||||
|
||||
231
src/gallery/app.py
Normal file
231
src/gallery/app.py
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
import flet as ft
|
||||
|
||||
from gallery.examples import ALL_EXAMPLES
|
||||
from gallery.models import Example, GallerySettings
|
||||
from gallery.source_links import source_url
|
||||
|
||||
SEED_COLORS = {
|
||||
"Фиолетовый": "#6750A4",
|
||||
"Синий": "#0061A4",
|
||||
"Зелёный": "#006D3B",
|
||||
"Оранжевый": "#8B5000",
|
||||
"Розовый": "#984061",
|
||||
}
|
||||
|
||||
|
||||
class GalleryApp:
|
||||
def __init__(self, page: ft.Page) -> None:
|
||||
self.page = page
|
||||
self.settings = GallerySettings()
|
||||
self.selected_category = "Обзор"
|
||||
self.query = ""
|
||||
|
||||
@property
|
||||
def categories(self) -> list[str]:
|
||||
return ["Обзор", *dict.fromkeys(example.category for example in ALL_EXAMPLES)]
|
||||
|
||||
def apply_theme(self) -> None:
|
||||
self.page.theme_mode = self.settings.theme_mode
|
||||
self.page.theme = ft.Theme(color_scheme_seed=self.settings.seed_color, use_material3=True)
|
||||
self.page.dark_theme = ft.Theme(color_scheme_seed=self.settings.seed_color, use_material3=True)
|
||||
|
||||
def settings_dialog(self) -> ft.AlertDialog:
|
||||
theme_group = ft.RadioGroup(
|
||||
value=self.settings.theme_mode.value,
|
||||
content=ft.Column(
|
||||
controls=[
|
||||
ft.Radio(value="system", label="Как в системе"),
|
||||
ft.Radio(value="light", label="Светлая"),
|
||||
ft.Radio(value="dark", label="Тёмная"),
|
||||
],
|
||||
tight=True,
|
||||
),
|
||||
)
|
||||
color_group = ft.RadioGroup(
|
||||
value=self.settings.seed_color,
|
||||
content=ft.Row(
|
||||
controls=[
|
||||
ft.Radio(value=color, label=name, fill_color=color)
|
||||
for name, color in SEED_COLORS.items()
|
||||
],
|
||||
spacing=8,
|
||||
wrap=True,
|
||||
),
|
||||
)
|
||||
source_toggle = ft.Switch(
|
||||
label="Показывать кнопки исходного кода",
|
||||
value=self.settings.show_source_buttons,
|
||||
)
|
||||
|
||||
def save(e: ft.Event[ft.FilledButton]) -> None:
|
||||
self.settings.theme_mode = ft.ThemeMode(theme_group.value)
|
||||
self.settings.seed_color = color_group.value
|
||||
self.settings.show_source_buttons = source_toggle.value
|
||||
self.page.pop_dialog()
|
||||
self.apply_theme()
|
||||
self.render()
|
||||
|
||||
return ft.AlertDialog(
|
||||
icon=ft.Icon(ft.Icons.PALETTE_OUTLINED),
|
||||
title="Внешний вид каталога",
|
||||
content=ft.Container(
|
||||
content=ft.Column(
|
||||
controls=[
|
||||
ft.Text("Тема", theme_style=ft.TextThemeStyle.TITLE_MEDIUM),
|
||||
theme_group,
|
||||
ft.Divider(),
|
||||
ft.Text("Акцентный цвет", theme_style=ft.TextThemeStyle.TITLE_MEDIUM),
|
||||
color_group,
|
||||
ft.Divider(),
|
||||
source_toggle,
|
||||
],
|
||||
tight=True,
|
||||
scroll=ft.ScrollMode.AUTO,
|
||||
),
|
||||
width=460,
|
||||
height=520,
|
||||
),
|
||||
actions=[
|
||||
ft.TextButton("Отмена", on_click=lambda e: self.page.pop_dialog()),
|
||||
ft.FilledButton("Применить", on_click=save),
|
||||
],
|
||||
)
|
||||
|
||||
def open_settings(self, _=None) -> None:
|
||||
self.page.show_dialog(self.settings_dialog())
|
||||
|
||||
def example_card(self, example: Example) -> ft.Control:
|
||||
actions: list[ft.Control] = []
|
||||
if self.settings.show_source_buttons:
|
||||
actions.append(
|
||||
ft.IconButton(
|
||||
icon=ft.Icons.CODE,
|
||||
tooltip="Показать код",
|
||||
url=source_url(example.id),
|
||||
)
|
||||
)
|
||||
return ft.Card(
|
||||
content=ft.Container(
|
||||
content=ft.Column(
|
||||
controls=[
|
||||
ft.Row(
|
||||
controls=[
|
||||
ft.Column(
|
||||
controls=[
|
||||
ft.Text(example.title, theme_style=ft.TextThemeStyle.TITLE_LARGE),
|
||||
ft.Text(example.description, color=ft.Colors.ON_SURFACE_VARIANT),
|
||||
],
|
||||
spacing=2,
|
||||
expand=True,
|
||||
),
|
||||
*actions,
|
||||
],
|
||||
vertical_alignment=ft.CrossAxisAlignment.START,
|
||||
),
|
||||
ft.Divider(),
|
||||
ft.Container(content=example.builder(), padding=ft.Padding.only(top=8)),
|
||||
],
|
||||
spacing=12,
|
||||
),
|
||||
padding=20,
|
||||
),
|
||||
margin=ft.Margin.only(bottom=12),
|
||||
)
|
||||
|
||||
def current_examples(self) -> list[Example]:
|
||||
examples = ALL_EXAMPLES
|
||||
if self.selected_category != "Обзор":
|
||||
examples = [e for e in examples if e.category == self.selected_category]
|
||||
query = self.query.casefold().strip()
|
||||
if query:
|
||||
examples = [
|
||||
e
|
||||
for e in examples
|
||||
if query in f"{e.title} {e.description} {e.category}".casefold()
|
||||
]
|
||||
return examples
|
||||
|
||||
def header(self) -> ft.Control:
|
||||
count = len(self.current_examples())
|
||||
return ft.Column(
|
||||
controls=[
|
||||
ft.Text(self.selected_category, theme_style=ft.TextThemeStyle.DISPLAY_SMALL),
|
||||
ft.Text(
|
||||
f"{count} интерактивных примеров · Flet 1.0.1",
|
||||
color=ft.Colors.ON_SURFACE_VARIANT,
|
||||
),
|
||||
],
|
||||
spacing=4,
|
||||
)
|
||||
|
||||
def navigation(self) -> ft.Control:
|
||||
icons = [
|
||||
ft.Icons.HOME_OUTLINED,
|
||||
ft.Icons.TOUCH_APP_OUTLINED,
|
||||
ft.Icons.TUNE,
|
||||
ft.Icons.ARTICLE_OUTLINED,
|
||||
ft.Icons.GRID_VIEW,
|
||||
ft.Icons.NAVIGATION_OUTLINED,
|
||||
ft.Icons.DATA_OBJECT,
|
||||
]
|
||||
|
||||
def select(e: ft.Event[ft.NavigationRail]) -> None:
|
||||
self.selected_category = self.categories[e.control.selected_index]
|
||||
self.render()
|
||||
|
||||
return ft.NavigationRail(
|
||||
selected_index=self.categories.index(self.selected_category),
|
||||
destinations=[
|
||||
ft.NavigationRailDestination(icon=icon, label=category)
|
||||
for category, icon in zip(self.categories, icons, strict=True)
|
||||
],
|
||||
label_type=ft.NavigationRailLabelType.ALL,
|
||||
on_change=select,
|
||||
min_width=96,
|
||||
)
|
||||
|
||||
def render(self) -> None:
|
||||
self.page.clean()
|
||||
self.page.title = "Flet Component Gallery"
|
||||
self.page.padding = 0
|
||||
self.apply_theme()
|
||||
|
||||
def search(e: ft.Event[ft.TextField]) -> None:
|
||||
self.query = e.control.value or ""
|
||||
self.render()
|
||||
|
||||
body = ft.ListView(
|
||||
controls=[
|
||||
self.header(),
|
||||
ft.TextField(
|
||||
value=self.query,
|
||||
hint_text="Найти компонент…",
|
||||
prefix_icon=ft.Icons.SEARCH,
|
||||
on_submit=search,
|
||||
suffix=ft.IconButton(ft.Icons.CLOSE, tooltip="Сбросить", on_click=lambda e: self.clear_search()),
|
||||
),
|
||||
*[self.example_card(example) for example in self.current_examples()],
|
||||
ft.Container(height=24),
|
||||
],
|
||||
expand=True,
|
||||
padding=ft.Padding.symmetric(horizontal=24, vertical=20),
|
||||
spacing=16,
|
||||
)
|
||||
self.page.appbar = ft.AppBar(
|
||||
leading=ft.Icon(ft.Icons.WIDGETS_OUTLINED),
|
||||
title=ft.Text("Flet Material Catalog"),
|
||||
actions=[
|
||||
ft.IconButton(ft.Icons.SETTINGS_OUTLINED, tooltip="Настройки", on_click=self.open_settings),
|
||||
ft.IconButton(ft.Icons.OPEN_IN_NEW, tooltip="Репозиторий", url="https://git.snw.su/snw/FletAppDemo"),
|
||||
],
|
||||
)
|
||||
self.page.add(ft.Row([self.navigation(), ft.VerticalDivider(width=1), body], expand=True, spacing=0))
|
||||
self.page.update()
|
||||
|
||||
def clear_search(self) -> None:
|
||||
self.query = ""
|
||||
self.render()
|
||||
|
||||
|
||||
def main(page: ft.Page) -> None:
|
||||
GalleryApp(page).render()
|
||||
9
src/gallery/examples/__init__.py
Normal file
9
src/gallery/examples/__init__.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
from gallery.examples.actions import EXAMPLES as ACTIONS
|
||||
from gallery.examples.content import EXAMPLES as CONTENT
|
||||
from gallery.examples.data_feedback import EXAMPLES as DATA_FEEDBACK
|
||||
from gallery.examples.inputs import EXAMPLES as INPUTS
|
||||
from gallery.examples.layout import EXAMPLES as LAYOUT
|
||||
from gallery.examples.navigation import EXAMPLES as NAVIGATION
|
||||
|
||||
ALL_EXAMPLES = ACTIONS + INPUTS + CONTENT + LAYOUT + NAVIGATION + DATA_FEEDBACK
|
||||
|
||||
68
src/gallery/examples/actions.py
Normal file
68
src/gallery/examples/actions.py
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import flet as ft
|
||||
|
||||
from gallery.models import Example
|
||||
|
||||
|
||||
def filled_buttons() -> ft.Control:
|
||||
return ft.Row(
|
||||
controls=[
|
||||
ft.FilledButton("Обычная", on_click=lambda e: None),
|
||||
ft.FilledButton("С иконкой", icon=ft.Icons.ADD, on_click=lambda e: None),
|
||||
ft.FilledButton("Отключена", disabled=True),
|
||||
],
|
||||
spacing=12,
|
||||
run_spacing=12,
|
||||
wrap=True,
|
||||
)
|
||||
|
||||
|
||||
def outlined_and_text_buttons() -> ft.Control:
|
||||
return ft.Row(
|
||||
controls=[
|
||||
ft.OutlinedButton("Outlined", icon=ft.Icons.FAVORITE_BORDER),
|
||||
ft.TextButton("Text button"),
|
||||
ft.TextButton("Отключена", disabled=True),
|
||||
],
|
||||
spacing=12,
|
||||
wrap=True,
|
||||
)
|
||||
|
||||
|
||||
def icon_buttons() -> ft.Control:
|
||||
return ft.Row(
|
||||
controls=[
|
||||
ft.IconButton(ft.Icons.FAVORITE, tooltip="Избранное"),
|
||||
ft.IconButton(ft.Icons.SHARE, tooltip="Поделиться"),
|
||||
ft.IconButton(ft.Icons.DELETE_OUTLINE, tooltip="Удалить", disabled=True),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def floating_action_button() -> ft.Control:
|
||||
return ft.Row(
|
||||
controls=[
|
||||
ft.FloatingActionButton(icon=ft.Icons.ADD, tooltip="Создать"),
|
||||
ft.FloatingActionButton(content="Создать", icon=ft.Icons.EDIT),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def chips() -> ft.Control:
|
||||
return ft.Row(
|
||||
controls=[
|
||||
ft.Chip("Python", leading=ft.Icon(ft.Icons.CODE), selected=True),
|
||||
ft.Chip("Flet", leading=ft.Icon(ft.Icons.WIDGETS)),
|
||||
ft.Chip("Удаляемый", delete_icon=ft.Icon(ft.Icons.CLOSE)),
|
||||
],
|
||||
spacing=8,
|
||||
wrap=True,
|
||||
)
|
||||
|
||||
|
||||
EXAMPLES = [
|
||||
Example("filled-buttons", "Filled buttons", "Основные кнопки и их состояния.", "Действия", filled_buttons),
|
||||
Example("outlined-buttons", "Outlined и text", "Кнопки с меньшим визуальным весом.", "Действия", outlined_and_text_buttons),
|
||||
Example("icon-buttons", "Icon buttons", "Компактные действия с подсказками.", "Действия", icon_buttons),
|
||||
Example("fab", "Floating action button", "Главное действие экрана.", "Действия", floating_action_button),
|
||||
Example("chips", "Chips", "Фильтры, теги и компактный выбор.", "Действия", chips),
|
||||
]
|
||||
88
src/gallery/examples/content.py
Normal file
88
src/gallery/examples/content.py
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import flet as ft
|
||||
|
||||
from gallery.models import Example
|
||||
|
||||
|
||||
def typography() -> ft.Control:
|
||||
return ft.Column(
|
||||
controls=[
|
||||
ft.Text("Display small", theme_style=ft.TextThemeStyle.DISPLAY_SMALL),
|
||||
ft.Text("Headline medium", theme_style=ft.TextThemeStyle.HEADLINE_MEDIUM),
|
||||
ft.Text("Title large", theme_style=ft.TextThemeStyle.TITLE_LARGE),
|
||||
ft.Text("Body medium — основной текст интерфейса."),
|
||||
ft.Text("Label small", theme_style=ft.TextThemeStyle.LABEL_SMALL),
|
||||
],
|
||||
spacing=8,
|
||||
)
|
||||
|
||||
|
||||
def icons_and_badges() -> ft.Control:
|
||||
return ft.Row(
|
||||
controls=[
|
||||
ft.Icon(ft.Icons.HOME, size=32),
|
||||
ft.Icon(ft.Icons.FAVORITE, color=ft.Colors.ERROR, size=32),
|
||||
ft.IconButton(ft.Icons.NOTIFICATIONS, badge=ft.Badge("3")),
|
||||
ft.CircleAvatar(content="FL", bgcolor=ft.Colors.PRIMARY_CONTAINER),
|
||||
],
|
||||
spacing=20,
|
||||
)
|
||||
|
||||
|
||||
def cards() -> ft.Control:
|
||||
return ft.ResponsiveRow(
|
||||
controls=[
|
||||
ft.Card(
|
||||
content=ft.Container(
|
||||
content=ft.Column(
|
||||
controls=[
|
||||
ft.Icon(ft.Icons.ROCKET_LAUNCH, size=36),
|
||||
ft.Text("Карточка", theme_style=ft.TextThemeStyle.TITLE_MEDIUM),
|
||||
ft.Text("Связывает содержимое в одну смысловую группу."),
|
||||
]
|
||||
),
|
||||
padding=20,
|
||||
),
|
||||
col={"sm": 12, "md": 6},
|
||||
),
|
||||
ft.Card(
|
||||
content=ft.ListTile(
|
||||
leading=ft.Icons.ALBUM,
|
||||
title="ListTile внутри Card",
|
||||
subtitle="Компактное представление данных",
|
||||
trailing=ft.Icons.MORE_VERT,
|
||||
),
|
||||
col={"sm": 12, "md": 6},
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def lists_and_expansion() -> ft.Control:
|
||||
return ft.Column(
|
||||
controls=[
|
||||
ft.ListTile(leading=ft.Icons.PERSON, title="Ada Lovelace", subtitle="admin@example.dev", trailing=ft.Icons.CHEVRON_RIGHT),
|
||||
ft.ExpansionTile(
|
||||
title="Подробнее",
|
||||
leading=ft.Icons.INFO_OUTLINE,
|
||||
controls=[ft.Container(ft.Text("Скрытое содержимое раскрывающегося блока."), padding=16)],
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def markdown() -> ft.Control:
|
||||
return ft.Markdown(
|
||||
"## Markdown\n\nFlet поддерживает **форматирование**, списки и `inline code`.\n\n- быстро\n- понятно\n- кроссплатформенно",
|
||||
selectable=True,
|
||||
extension_set=ft.MarkdownExtensionSet.GITHUB_WEB,
|
||||
)
|
||||
|
||||
|
||||
EXAMPLES = [
|
||||
Example("typography", "Typography", "Иерархия текстовых стилей темы.", "Контент", typography),
|
||||
Example("icons-badges", "Icons, badges и avatar", "Иконки, счётчики и идентичность.", "Контент", icons_and_badges),
|
||||
Example("cards", "Cards", "Поверхности для связанных данных.", "Контент", cards),
|
||||
Example("lists", "Lists и expansion", "Строки списков и раскрытие деталей.", "Контент", lists_and_expansion),
|
||||
Example("markdown", "Markdown", "Форматированный технический контент.", "Контент", markdown),
|
||||
]
|
||||
|
||||
71
src/gallery/examples/data_feedback.py
Normal file
71
src/gallery/examples/data_feedback.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import flet as ft
|
||||
|
||||
from gallery.models import Example
|
||||
|
||||
|
||||
def data_table() -> ft.Control:
|
||||
return ft.DataTable(
|
||||
columns=[ft.DataColumn(ft.Text("Компонент")), ft.DataColumn(ft.Text("Статус")), ft.DataColumn(ft.Text("Платформы"))],
|
||||
rows=[
|
||||
ft.DataRow(cells=[ft.DataCell(ft.Text("Button")), ft.DataCell(ft.Text("Stable")), ft.DataCell(ft.Text("All"))]),
|
||||
ft.DataRow(cells=[ft.DataCell(ft.Text("Camera")), ft.DataCell(ft.Text("Service")), ft.DataCell(ft.Text("Mobile"))]),
|
||||
ft.DataRow(cells=[ft.DataCell(ft.Text("WebView")), ft.DataCell(ft.Text("Extension")), ft.DataCell(ft.Text("Varies"))]),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def progress_indicators() -> ft.Control:
|
||||
return ft.Column(
|
||||
controls=[
|
||||
ft.Text("Determinate"),
|
||||
ft.ProgressBar(value=0.65, border_radius=8),
|
||||
ft.Row([ft.ProgressRing(value=0.72), ft.ProgressRing(), ft.Text("72% и бесконечная загрузка")], spacing=16),
|
||||
],
|
||||
spacing=12,
|
||||
)
|
||||
|
||||
|
||||
def alert_dialog() -> ft.Control:
|
||||
def show(e: ft.Event[ft.FilledButton]) -> None:
|
||||
e.control.page.show_dialog(
|
||||
ft.AlertDialog(
|
||||
icon=ft.Icon(ft.Icons.DELETE_OUTLINE),
|
||||
title="Удалить проект?",
|
||||
content=ft.Text("Это действие показано только для демонстрации."),
|
||||
actions=[ft.TextButton("Отмена", on_click=lambda event: event.control.page.pop_dialog()), ft.FilledButton("Удалить", on_click=lambda event: event.control.page.pop_dialog())],
|
||||
)
|
||||
)
|
||||
|
||||
return ft.FilledButton("Открыть диалог", icon=ft.Icons.OPEN_IN_NEW, on_click=show)
|
||||
|
||||
|
||||
def snackbar() -> ft.Control:
|
||||
def show(e: ft.Event[ft.FilledButton]) -> None:
|
||||
e.control.page.show_dialog(ft.SnackBar("Изменения сохранены", show_close_icon=True))
|
||||
|
||||
return ft.FilledButton("Показать snackbar", icon=ft.Icons.CHECK_CIRCLE, on_click=show)
|
||||
|
||||
|
||||
def bottom_sheet() -> ft.Control:
|
||||
def show(e: ft.Event[ft.FilledButton]) -> None:
|
||||
e.control.page.show_dialog(
|
||||
ft.BottomSheet(
|
||||
content=ft.Container(
|
||||
content=ft.Column([ft.Text("Bottom sheet", theme_style=ft.TextThemeStyle.HEADLINE_SMALL), ft.Text("Подходит для дополнительных действий на мобильном экране.")], tight=True),
|
||||
padding=24,
|
||||
),
|
||||
show_drag_handle=True,
|
||||
)
|
||||
)
|
||||
|
||||
return ft.FilledButton("Открыть bottom sheet", icon=ft.Icons.VERTICAL_ALIGN_TOP, on_click=show)
|
||||
|
||||
|
||||
EXAMPLES = [
|
||||
Example("data-table", "DataTable", "Табличные структурированные данные.", "Данные и feedback", data_table),
|
||||
Example("progress", "Progress indicators", "Определённая и бесконечная загрузка.", "Данные и feedback", progress_indicators),
|
||||
Example("dialog", "AlertDialog", "Модальное подтверждение важного действия.", "Данные и feedback", alert_dialog),
|
||||
Example("snackbar", "SnackBar", "Краткое неблокирующее сообщение.", "Данные и feedback", snackbar),
|
||||
Example("bottom-sheet", "BottomSheet", "Дополнительный мобильный слой.", "Данные и feedback", bottom_sheet),
|
||||
]
|
||||
|
||||
81
src/gallery/examples/inputs.py
Normal file
81
src/gallery/examples/inputs.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import flet as ft
|
||||
|
||||
from gallery.models import Example
|
||||
|
||||
|
||||
def text_fields() -> ft.Control:
|
||||
return ft.Column(
|
||||
controls=[
|
||||
ft.TextField(label="Имя", hint_text="Алексей", prefix_icon=ft.Icons.PERSON),
|
||||
ft.TextField(label="Пароль", password=True, can_reveal_password=True),
|
||||
ft.TextField(label="Комментарий", multiline=True, min_lines=2, max_lines=4),
|
||||
],
|
||||
spacing=12,
|
||||
)
|
||||
|
||||
|
||||
def dropdowns() -> ft.Control:
|
||||
return ft.Dropdown(
|
||||
label="Среда",
|
||||
value="web",
|
||||
options=[
|
||||
ft.DropdownOption(key="web", text="Web"),
|
||||
ft.DropdownOption(key="android", text="Android"),
|
||||
ft.DropdownOption(key="desktop", text="Desktop"),
|
||||
],
|
||||
width=300,
|
||||
)
|
||||
|
||||
|
||||
def selection_controls() -> ft.Control:
|
||||
return ft.Column(
|
||||
controls=[
|
||||
ft.Checkbox("Получать обновления", value=True),
|
||||
ft.Switch(label="Автоматическая тема", value=False),
|
||||
ft.RadioGroup(
|
||||
value="comfortable",
|
||||
content=ft.Row(
|
||||
controls=[
|
||||
ft.Radio(value="compact", label="Компактно"),
|
||||
ft.Radio(value="comfortable", label="Удобно"),
|
||||
]
|
||||
),
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def sliders() -> ft.Control:
|
||||
value_label = ft.Text("Громкость: 40")
|
||||
|
||||
def changed(e: ft.Event[ft.Slider]) -> None:
|
||||
value_label.value = f"Громкость: {int(e.control.value)}"
|
||||
value_label.update()
|
||||
|
||||
return ft.Column(
|
||||
controls=[
|
||||
value_label,
|
||||
ft.Slider(value=40, min=0, max=100, divisions=10, label="{value}", on_change=changed),
|
||||
ft.RangeSlider(start_value=20, end_value=75, min=0, max=100, divisions=20),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def segmented_choice() -> ft.Control:
|
||||
return ft.SegmentedButton(
|
||||
segments=[
|
||||
ft.Segment(value="day", label="День", icon=ft.Icons.LIGHT_MODE),
|
||||
ft.Segment(value="week", label="Неделя", icon=ft.Icons.DATE_RANGE),
|
||||
ft.Segment(value="month", label="Месяц", icon=ft.Icons.CALENDAR_MONTH),
|
||||
],
|
||||
selected=["week"],
|
||||
)
|
||||
|
||||
|
||||
EXAMPLES = [
|
||||
Example("text-fields", "Text fields", "Ввод текста, пароля и многострочного значения.", "Ввод", text_fields),
|
||||
Example("dropdowns", "Dropdown", "Выбор одного значения из меню.", "Ввод", dropdowns),
|
||||
Example("selection-controls", "Checkbox, switch и radio", "Булевы и взаимоисключающие варианты.", "Ввод", selection_controls),
|
||||
Example("sliders", "Sliders", "Одиночный и диапазонный выбор чисел.", "Ввод", sliders),
|
||||
Example("segmented", "Segmented button", "Компактный выбор режима.", "Ввод", segmented_choice),
|
||||
]
|
||||
60
src/gallery/examples/layout.py
Normal file
60
src/gallery/examples/layout.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import flet as ft
|
||||
|
||||
from gallery.models import Example
|
||||
|
||||
|
||||
def row_and_column() -> ft.Control:
|
||||
return ft.Column(
|
||||
controls=[
|
||||
ft.Text("Row распределяет элементы по горизонтали"),
|
||||
ft.Row(
|
||||
controls=[ft.Container(bgcolor=c, width=64, height=64, border_radius=12) for c in (ft.Colors.PRIMARY, ft.Colors.SECONDARY, ft.Colors.TERTIARY)],
|
||||
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def responsive_row() -> ft.Control:
|
||||
return ft.ResponsiveRow(
|
||||
controls=[
|
||||
ft.Container(content=ft.Text(f"col {i + 1}"), bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, padding=20, border_radius=12, col={"xs": 12, "sm": 6, "md": 4})
|
||||
for i in range(3)
|
||||
],
|
||||
spacing=12,
|
||||
run_spacing=12,
|
||||
)
|
||||
|
||||
|
||||
def stack() -> ft.Control:
|
||||
return ft.Stack(
|
||||
controls=[
|
||||
ft.Container(width=300, height=150, bgcolor=ft.Colors.PRIMARY_CONTAINER, border_radius=20),
|
||||
ft.Container(content=ft.Text("Слой поверх фона", weight=ft.FontWeight.BOLD), left=24, bottom=24),
|
||||
ft.Icon(ft.Icons.LAYERS, size=42, right=20, top=20),
|
||||
],
|
||||
width=300,
|
||||
height=150,
|
||||
)
|
||||
|
||||
|
||||
def grid_view() -> ft.Control:
|
||||
return ft.GridView(
|
||||
controls=[
|
||||
ft.Container(content=ft.Text(str(i + 1)), alignment=ft.Alignment.CENTER, bgcolor=ft.Colors.SECONDARY_CONTAINER, border_radius=12)
|
||||
for i in range(8)
|
||||
],
|
||||
max_extent=100,
|
||||
spacing=10,
|
||||
run_spacing=10,
|
||||
height=220,
|
||||
)
|
||||
|
||||
|
||||
EXAMPLES = [
|
||||
Example("row-column", "Row и Column", "Базовая раскладка по двум осям.", "Макет", row_and_column),
|
||||
Example("responsive-row", "ResponsiveRow", "Адаптивные колонки для разных экранов.", "Макет", responsive_row),
|
||||
Example("stack", "Stack", "Наложение и точное позиционирование.", "Макет", stack),
|
||||
Example("grid", "GridView", "Прокручиваемая сетка элементов.", "Макет", grid_view),
|
||||
]
|
||||
|
||||
48
src/gallery/examples/navigation.py
Normal file
48
src/gallery/examples/navigation.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import flet as ft
|
||||
|
||||
from gallery.models import Example
|
||||
|
||||
|
||||
def tabs() -> ft.Control:
|
||||
return ft.Tabs(
|
||||
length=3,
|
||||
selected_index=0,
|
||||
content=ft.Column(
|
||||
controls=[
|
||||
ft.TabBar(tabs=[ft.Tab(label="Обзор", icon=ft.Icons.DASHBOARD), ft.Tab(label="Код", icon=ft.Icons.CODE), ft.Tab(label="API", icon=ft.Icons.DATA_OBJECT)]),
|
||||
ft.TabBarView(controls=[ft.Container(ft.Text("Обзор компонента"), padding=20), ft.Container(ft.Text("Пример кода"), padding=20), ft.Container(ft.Text("Справка API"), padding=20)]),
|
||||
]
|
||||
),
|
||||
height=160,
|
||||
)
|
||||
|
||||
|
||||
def navigation_bar() -> ft.Control:
|
||||
return ft.NavigationBar(
|
||||
destinations=[
|
||||
ft.NavigationBarDestination(icon=ft.Icons.HOME_OUTLINED, selected_icon=ft.Icons.HOME, label="Главная"),
|
||||
ft.NavigationBarDestination(icon=ft.Icons.EXPLORE_OUTLINED, selected_icon=ft.Icons.EXPLORE, label="Обзор"),
|
||||
ft.NavigationBarDestination(icon=ft.Icons.PERSON_OUTLINE, selected_icon=ft.Icons.PERSON, label="Профиль"),
|
||||
],
|
||||
selected_index=1,
|
||||
)
|
||||
|
||||
|
||||
def popup_menu() -> ft.Control:
|
||||
return ft.PopupMenuButton(
|
||||
icon=ft.Icons.MORE_VERT,
|
||||
tooltip="Дополнительные действия",
|
||||
items=[
|
||||
ft.PopupMenuItem("Редактировать", icon=ft.Icons.EDIT),
|
||||
ft.PopupMenuItem("Дублировать", icon=ft.Icons.CONTENT_COPY),
|
||||
ft.PopupMenuItem("Удалить", icon=ft.Icons.DELETE_OUTLINE),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
EXAMPLES = [
|
||||
Example("tabs", "Tabs", "Переключение между равноправными разделами.", "Навигация", tabs),
|
||||
Example("navigation-bar", "NavigationBar", "Основные разделы мобильного приложения.", "Навигация", navigation_bar),
|
||||
Example("popup-menu", "PopupMenuButton", "Редкие действия в компактном меню.", "Навигация", popup_menu),
|
||||
]
|
||||
|
||||
21
src/gallery/models.py
Normal file
21
src/gallery/models.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
import flet as ft
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Example:
|
||||
id: str
|
||||
title: str
|
||||
description: str
|
||||
category: str
|
||||
builder: Callable[[], ft.Control]
|
||||
|
||||
|
||||
@dataclass
|
||||
class GallerySettings:
|
||||
theme_mode: ft.ThemeMode = ft.ThemeMode.SYSTEM
|
||||
seed_color: str = "#6750A4"
|
||||
show_source_buttons: bool = True
|
||||
|
||||
20
src/gallery/source_links.py
Normal file
20
src/gallery/source_links.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import json
|
||||
import os
|
||||
from importlib.resources import files
|
||||
|
||||
REPOSITORY = "https://git.snw.su/snw/FletAppDemo"
|
||||
|
||||
|
||||
def _manifest() -> dict[str, dict[str, str | int]]:
|
||||
resource = files("gallery").joinpath("source_manifest.json")
|
||||
return json.loads(resource.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
SOURCE_MANIFEST = _manifest()
|
||||
|
||||
|
||||
def source_url(example_id: str) -> str:
|
||||
anchor = SOURCE_MANIFEST[example_id]
|
||||
revision = os.getenv("FLET_GALLERY_REVISION", "main")
|
||||
return f"{REPOSITORY}/src/commit/{revision}/{anchor['path']}#L{anchor['line']}"
|
||||
|
||||
137
src/gallery/source_manifest.json
Normal file
137
src/gallery/source_manifest.json
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
{
|
||||
"bottom-sheet": {
|
||||
"function": "bottom_sheet",
|
||||
"line": 49,
|
||||
"path": "src/gallery/examples/data_feedback.py"
|
||||
},
|
||||
"cards": {
|
||||
"function": "cards",
|
||||
"line": 31,
|
||||
"path": "src/gallery/examples/content.py"
|
||||
},
|
||||
"chips": {
|
||||
"function": "chips",
|
||||
"line": 50,
|
||||
"path": "src/gallery/examples/actions.py"
|
||||
},
|
||||
"data-table": {
|
||||
"function": "data_table",
|
||||
"line": 6,
|
||||
"path": "src/gallery/examples/data_feedback.py"
|
||||
},
|
||||
"dialog": {
|
||||
"function": "alert_dialog",
|
||||
"line": 28,
|
||||
"path": "src/gallery/examples/data_feedback.py"
|
||||
},
|
||||
"dropdowns": {
|
||||
"function": "dropdowns",
|
||||
"line": 17,
|
||||
"path": "src/gallery/examples/inputs.py"
|
||||
},
|
||||
"fab": {
|
||||
"function": "floating_action_button",
|
||||
"line": 41,
|
||||
"path": "src/gallery/examples/actions.py"
|
||||
},
|
||||
"filled-buttons": {
|
||||
"function": "filled_buttons",
|
||||
"line": 6,
|
||||
"path": "src/gallery/examples/actions.py"
|
||||
},
|
||||
"grid": {
|
||||
"function": "grid_view",
|
||||
"line": 41,
|
||||
"path": "src/gallery/examples/layout.py"
|
||||
},
|
||||
"icon-buttons": {
|
||||
"function": "icon_buttons",
|
||||
"line": 31,
|
||||
"path": "src/gallery/examples/actions.py"
|
||||
},
|
||||
"icons-badges": {
|
||||
"function": "icons_and_badges",
|
||||
"line": 19,
|
||||
"path": "src/gallery/examples/content.py"
|
||||
},
|
||||
"lists": {
|
||||
"function": "lists_and_expansion",
|
||||
"line": 60,
|
||||
"path": "src/gallery/examples/content.py"
|
||||
},
|
||||
"markdown": {
|
||||
"function": "markdown",
|
||||
"line": 73,
|
||||
"path": "src/gallery/examples/content.py"
|
||||
},
|
||||
"navigation-bar": {
|
||||
"function": "navigation_bar",
|
||||
"line": 20,
|
||||
"path": "src/gallery/examples/navigation.py"
|
||||
},
|
||||
"outlined-buttons": {
|
||||
"function": "outlined_and_text_buttons",
|
||||
"line": 19,
|
||||
"path": "src/gallery/examples/actions.py"
|
||||
},
|
||||
"popup-menu": {
|
||||
"function": "popup_menu",
|
||||
"line": 31,
|
||||
"path": "src/gallery/examples/navigation.py"
|
||||
},
|
||||
"progress": {
|
||||
"function": "progress_indicators",
|
||||
"line": 17,
|
||||
"path": "src/gallery/examples/data_feedback.py"
|
||||
},
|
||||
"responsive-row": {
|
||||
"function": "responsive_row",
|
||||
"line": 18,
|
||||
"path": "src/gallery/examples/layout.py"
|
||||
},
|
||||
"row-column": {
|
||||
"function": "row_and_column",
|
||||
"line": 6,
|
||||
"path": "src/gallery/examples/layout.py"
|
||||
},
|
||||
"segmented": {
|
||||
"function": "segmented_choice",
|
||||
"line": 64,
|
||||
"path": "src/gallery/examples/inputs.py"
|
||||
},
|
||||
"selection-controls": {
|
||||
"function": "selection_controls",
|
||||
"line": 30,
|
||||
"path": "src/gallery/examples/inputs.py"
|
||||
},
|
||||
"sliders": {
|
||||
"function": "sliders",
|
||||
"line": 48,
|
||||
"path": "src/gallery/examples/inputs.py"
|
||||
},
|
||||
"snackbar": {
|
||||
"function": "snackbar",
|
||||
"line": 42,
|
||||
"path": "src/gallery/examples/data_feedback.py"
|
||||
},
|
||||
"stack": {
|
||||
"function": "stack",
|
||||
"line": 29,
|
||||
"path": "src/gallery/examples/layout.py"
|
||||
},
|
||||
"tabs": {
|
||||
"function": "tabs",
|
||||
"line": 6,
|
||||
"path": "src/gallery/examples/navigation.py"
|
||||
},
|
||||
"text-fields": {
|
||||
"function": "text_fields",
|
||||
"line": 6,
|
||||
"path": "src/gallery/examples/inputs.py"
|
||||
},
|
||||
"typography": {
|
||||
"function": "typography",
|
||||
"line": 6,
|
||||
"path": "src/gallery/examples/content.py"
|
||||
}
|
||||
}
|
||||
6
src/main.py
Normal file
6
src/main.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import flet as ft
|
||||
|
||||
from gallery.app import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
ft.run(main)
|
||||
27
tests/test_gallery.py
Normal file
27
tests/test_gallery.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from gallery.examples import ALL_EXAMPLES
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_example_ids_are_unique() -> None:
|
||||
ids = [example.id for example in ALL_EXAMPLES]
|
||||
assert len(ids) == len(set(ids))
|
||||
assert len(ids) >= 25
|
||||
|
||||
|
||||
def test_every_example_builds_a_control() -> None:
|
||||
for example in ALL_EXAMPLES:
|
||||
assert example.builder() is not None, example.id
|
||||
|
||||
|
||||
def test_source_manifest_is_complete_and_exact() -> None:
|
||||
manifest_path = ROOT / "src" / "gallery" / "source_manifest.json"
|
||||
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
||||
assert set(manifest) == {example.id for example in ALL_EXAMPLES}
|
||||
for anchor in manifest.values():
|
||||
source = (ROOT / anchor["path"]).read_text(encoding="utf-8").splitlines()
|
||||
assert source[anchor["line"] - 1].startswith(f"def {anchor['function']}(")
|
||||
|
||||
52
tools/generate_source_manifest.py
Normal file
52
tools/generate_source_manifest.py
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
"""Generate exact repository source anchors without importing application code."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
EXAMPLES_DIR = ROOT / "src" / "gallery" / "examples"
|
||||
OUTPUT = ROOT / "src" / "gallery" / "source_manifest.json"
|
||||
|
||||
|
||||
def collect() -> dict[str, dict[str, str | int]]:
|
||||
manifest: dict[str, dict[str, str | int]] = {}
|
||||
for path in sorted(EXAMPLES_DIR.glob("*.py")):
|
||||
if path.name == "__init__.py":
|
||||
continue
|
||||
tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
|
||||
functions = {
|
||||
node.name: node.lineno
|
||||
for node in tree.body
|
||||
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))
|
||||
}
|
||||
for node in ast.walk(tree):
|
||||
if not isinstance(node, ast.Call) or not isinstance(node.func, ast.Name):
|
||||
continue
|
||||
if node.func.id != "Example" or len(node.args) < 5:
|
||||
continue
|
||||
example_id, builder = node.args[0], node.args[4]
|
||||
if not isinstance(example_id, ast.Constant) or not isinstance(example_id.value, str):
|
||||
raise TypeError(f"Example id must be a string in {path}")
|
||||
if not isinstance(builder, ast.Name) or builder.id not in functions:
|
||||
raise ValueError(f"Example {example_id.value} must reference a local function")
|
||||
if example_id.value in manifest:
|
||||
raise ValueError(f"Duplicate example id: {example_id.value}")
|
||||
manifest[example_id.value] = {
|
||||
"path": path.relative_to(ROOT).as_posix(),
|
||||
"line": functions[builder.id],
|
||||
"function": builder.id,
|
||||
}
|
||||
return manifest
|
||||
|
||||
|
||||
def main() -> None:
|
||||
content = json.dumps(collect(), ensure_ascii=False, indent=2, sort_keys=True) + "\n"
|
||||
OUTPUT.write_text(content, encoding="utf-8")
|
||||
print(f"Generated {OUTPUT.relative_to(ROOT)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
319
uv.lock
generated
Normal file
319
uv.lock
generated
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.11"
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.15.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "idna" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.15'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a9/d2/f4d173e22df740bc37b1db102b386ba719b66e95b0f0d751f556b387e6d2/anyio-4.15.1.tar.gz", hash = "sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94", size = 276966, upload-time = "2026-09-05T10:42:39.44Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/12/b8/4bd346e22b28902df4d651910f5242c28d84e4a5c2435ca5c3f797ed7e2e/anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101", size = 132079, upload-time = "2026-09-05T10:42:37.923Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2026.7.22"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flet"
|
||||
version = "1.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "httpx", marker = "sys_platform != 'emscripten'" },
|
||||
{ name = "msgpack" },
|
||||
{ name = "oauthlib", marker = "sys_platform != 'emscripten'" },
|
||||
{ name = "repath" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5e/0f/ac7e2af03fd49dd28477a062f8022a362155a2608857c79d6a4272e4f4a3/flet-1.0.1.tar.gz", hash = "sha256:0c11ea010efbae34600556d964613324ea0ddc711bdac94d6592699b28dc0ba4", size = 571070, upload-time = "2026-09-22T20:24:47.549Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/86/6eaa2f957931ee03f9814838259d5df395295c7807673b9ea2a30f75f4c5/flet-1.0.1-py3-none-any.whl", hash = "sha256:94a15d75f587dc0b6a2479348f2e4b2bf40606469eb5a18dc62ab12a790f1ae2", size = 633955, upload-time = "2026-09-22T20:24:46.225Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flet-component-gallery"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "flet" },
|
||||
]
|
||||
|
||||
[package.dev-dependencies]
|
||||
dev = [
|
||||
{ name = "pytest" },
|
||||
{ name = "ruff" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "flet", specifier = "==1.0.1" }]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "pytest", specifier = ">=8.4.0" },
|
||||
{ name = "ruff", specifier = ">=0.13.0" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.16.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "h11" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.28.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "certifi" },
|
||||
{ name = "httpcore" },
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.20"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f5/08/8eea9d4b8302028f3abb2c0813953f7aec26d33b7a8960ed760e65ff29fa/idna-3.20.tar.gz", hash = "sha256:a7db850025b95ded1eae8a46181a1a6c56c92c96f0e2b005d9ff8dc0210cab44", size = 216463, upload-time = "2026-09-17T14:11:04.752Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/58/a2/bb081bab032533a855d44de1d56f8e8426114ff1ba5d1f07a438a0a654f8/idna-3.20-py3-none-any.whl", hash = "sha256:ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c", size = 69583, upload-time = "2026-09-17T14:11:03.168Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "msgpack"
|
||||
version = "1.2.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6d/44/ea2100ec54d30c46ee9dba10a3bfb79b655e96c6df237238a3234c75869b/msgpack-1.2.2.tar.gz", hash = "sha256:9eb0b0e602064527a045ea28c4f174ed69383587e29cebe28947e3b84106eb2a", size = 187025, upload-time = "2026-08-27T10:03:47.793Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/53/fd/a05ba8f84c5951c9aec2a19c1c81f6c4a67b8bec80af604ac5b23ccfa019/msgpack-1.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d7fb25b4442fae0cb2590272d06ab4f6caa526ee36a994edb81e946b874813e", size = 83498, upload-time = "2026-08-27T10:01:50.62Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/df/e20bcf5c149890545334743b212eb4b82e1a25fe0a34f99753a1755bfab5/msgpack-1.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7fe374ba76eb0ecca13a1703daa8fa85825a6ddddbb52d4c1a732fa524194683", size = 83896, upload-time = "2026-08-27T10:01:51.898Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/c3/00dcd902d66a641b9ba350783feb482ea5c1ca4a7ff6629db0c10c0ea982/msgpack-1.2.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9b0c1f2aa7b0026b4bd50718100e8b04175e4f36e160aa852502377b5e572e7", size = 413259, upload-time = "2026-08-27T10:01:53.296Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/15/17374efe9793f5332c7d4727ab40539f95a1dc9df653531795daca8c4281/msgpack-1.2.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f11e09f10210a91c169e39c7a5a1f9090eaa73ad75555fafad5023c3053c47ba", size = 422907, upload-time = "2026-08-27T10:01:54.786Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/af/2b567d684f912fedcefe3f7c37de604716ffa99336bd432688f9f040df92/msgpack-1.2.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8b1415d02e9bf722672af8a90f90813265a0cd0b14163187261e54a5592bc949", size = 389248, upload-time = "2026-08-27T10:01:56.55Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/fd/d8533fed473cc3e309a701e851d0e5fe36ada5552a3899025f5c69fbe877/msgpack-1.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:42fd9260416885b4815caca5bdd14dfd5dda6cdade732d6c09104ef8f6228761", size = 407099, upload-time = "2026-08-27T10:01:58.357Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/1b/57906337bfee0ead554571dc203ea17c3fad26d51e5eca6271ecd983f73b/msgpack-1.2.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:336525cc2688e43ea77dfb1a4ce012c8cde561835913801dbfcfdcf4111d8abb", size = 387201, upload-time = "2026-08-27T10:02:00.109Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/0f/5d1e6d68e516621697a9262b24917d678793e838cf3f331ed4656b3e959d/msgpack-1.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cdb6cc6e1127d15879c47a8b3270716243da82d3e7feab1f5946872c75b3d60f", size = 420765, upload-time = "2026-08-27T10:02:01.573Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/a6/07f9a4f3324d55c3567ab2a7e8d5325291bc95a31a374bb390a21b7c4e24/msgpack-1.2.2-cp311-cp311-win32.whl", hash = "sha256:cf66fb38703e61a486b01b56d43bb1f50698fbe99b6bd90feba10f24fab60b3b", size = 64785, upload-time = "2026-08-27T10:02:03.01Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/13/f748f0d59f355d196e71a0b32d48d386a9bd311f94d954e666cf7e5b2572/msgpack-1.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:0883a1578168929fd1640fbbc4614773f1a130e419a8a817dc2918d9af1b651c", size = 71258, upload-time = "2026-08-27T10:02:04.375Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/a6/10d979c4e76b18a9b9ebbd6499ff863474ffe5955028ea27e09b66f6833c/msgpack-1.2.2-cp311-cp311-win_arm64.whl", hash = "sha256:4955accbd87f27beebef5f3ecc27503aa74cb016fb4f640868e749fd93194a35", size = 65860, upload-time = "2026-08-27T10:02:05.735Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/78/90c15bebb1a72667349ca62d4507e9d9369e7f8f76b95f490b823d3622e5/msgpack-1.2.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a4348705be86e029d04e741cf9ed0dfe03e942d7d3b92e838fa80d3aa2c3ebc", size = 84275, upload-time = "2026-08-27T10:02:07.106Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/88/c2b6d8e81571da87aa232c0e34a3f3a0e618e6235892065ec82d1d81fc7a/msgpack-1.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a652ceeededf71d3fa40c303a02a149d42338d310162367b91c539d4bd6e0a3", size = 83970, upload-time = "2026-08-27T10:02:08.488Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/c0/d3ede9f5d16acb4c05a9281859f1e99ef9f877a928eb78454c37f70db001/msgpack-1.2.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90986cc9aab9d7d1d8f38bcbf65d3f7ac83bdd90c35765db7d691b4829698cba", size = 409401, upload-time = "2026-08-27T10:02:09.877Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/f0/29f591bea185616cf417645ac03bd3ad9b317483ad8572160e325f7fe777/msgpack-1.2.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:77c2e018417dc1d66f235e383877ee885b60ade9d29e494dd581e08af2cb1923", size = 420619, upload-time = "2026-08-27T10:02:11.526Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/8e/c70c8c9180c5ddf4440eb8658ebead98e22e7686fbf84f6b165031430750/msgpack-1.2.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0e91332144f69bc3018c91232fac26da580ef748fb8eaddd7914d4458001cc4f", size = 379747, upload-time = "2026-08-27T10:02:13.345Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/9a/f10ce11fa62700c9ab87a22e65b9ca272f7f673ddd31aeb2de6ae272ad35/msgpack-1.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e915d390d7068b257ca8b62f3fc59fad135c8631d1017ab03b0b924b07c5367", size = 398944, upload-time = "2026-08-27T10:02:15.006Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/fe/d7be978456ff8552e69a8e270d882e7530e01513c096b293d83df03753ea/msgpack-1.2.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c522420d78db2431887d45b518e304d86e27b9ad0b30f24e3806a6ad5d8bdbfc", size = 373979, upload-time = "2026-08-27T10:02:16.618Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/af/91b0d8d3fb3063e259daee3ea8515cea6282f68f4b0e5f0b6fea25762c6e/msgpack-1.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b554d8164ebb526892194f71dcd96ef1fefe0c250087498785d3ffc04a80be3", size = 417781, upload-time = "2026-08-27T10:02:18.293Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/3c/ce8e9efe1fd9e95c78b3705e4300ba7feba3dc6c00fb76259895db155518/msgpack-1.2.2-cp312-cp312-win32.whl", hash = "sha256:0e3315de5a4b2920ccef48d96b4448025e064a10d0f5a250f6584477d839c8d4", size = 65267, upload-time = "2026-08-27T10:02:19.869Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/98/a33b8b4af14e3476bb0da1b8c36ef7a0f28dcf95db1c5e68ff88cb89d591/msgpack-1.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:b68614fba0570349833b7dd999ff0aed4e5cc8d9eb6e3a7d4527be33c65e33d3", size = 72275, upload-time = "2026-08-27T10:02:21.141Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/5e/2f323a33a6aba5bd4b2d8b430e4fab21d92cd91c093b49ee287bc166ee54/msgpack-1.2.2-cp312-cp312-win_arm64.whl", hash = "sha256:59d5b93efa45fd09f620d0c9ba81cde339a2c9937af3eea42ee9653094ce6640", size = 65488, upload-time = "2026-08-27T10:02:22.575Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/eb/42f31c5a48811787ff59a9869721f70a49654d65ab6c455f4463c39b044e/msgpack-1.2.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8b2a281b556f120a43e591ea39915741b7ad54d4727b9c4350a0a11692252533", size = 83911, upload-time = "2026-08-27T10:02:24.06Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/54/10c6c16ddba8a5112e3680176b838e3694e4aad7284f9daa6d6d70d98817/msgpack-1.2.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1e8cdd1f3e7cc52c751092a9bf740e81e6919ab109cd376ae2d965dad0bbae34", size = 83734, upload-time = "2026-08-27T10:02:25.613Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/75/35823e4419df8792191b2a17ae3fe71b41d02c162b2c491c94d1a87f0caa/msgpack-1.2.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1814f92306ae7862908e9ece7cfd90e0dc87ded3e89b6ae7ffdd1175d6376fdc", size = 405635, upload-time = "2026-08-27T10:02:27.012Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/d3/6592e4064619b04f2dd0054c5fa13e37e3d55eb26044483d871fadb2f46b/msgpack-1.2.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d24b38a825bcca41bb956de50eb98451ef291304a8607fad99e619043d3e79b9", size = 417332, upload-time = "2026-08-27T10:02:28.776Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/a1/b21c6818a545e9a4a976ac954a5c250eecde9a02e0ec82f415473dab1324/msgpack-1.2.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34e83e345194a2a51d8bd447dea9de2104f91e75b247f4735f14f04529f0746b", size = 374378, upload-time = "2026-08-27T10:02:30.678Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/8b/7ada15c7b64151d6dbb562d1b091520efb2c37acf2403b1d4ae13797b27d/msgpack-1.2.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:682804bf31e43d46e51a9a33bd575b51e839d715ce6bd5612c055f7b28ad637b", size = 395809, upload-time = "2026-08-27T10:02:32.322Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/f7/96283e50f7020df4dfeacc55612b7a210c8cdf0dda48bc262f1f9b3e4c49/msgpack-1.2.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:9b659d77f8726fa5e7038967dda6b68d53cf34472c094cfa5b845454713b90d5", size = 373495, upload-time = "2026-08-27T10:02:33.832Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/fe/1548dede9d9ca482f2d424a2e110a9705d4e02627a16b8bc8d10ce0208a2/msgpack-1.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d9a562aec0a92fe536da2e533d313b3d2a6b929157b1dec7ff623446dc0a8ab", size = 414360, upload-time = "2026-08-27T10:02:35.396Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/9d/4419b8f86c219174b1fb8bbd7faaf84a548935f7b1916d028401b9433417/msgpack-1.2.2-cp313-cp313-win32.whl", hash = "sha256:a4161eee7799863aee237c35c90427861f7b994416dd81ae829f560b0a81bdcd", size = 65196, upload-time = "2026-08-27T10:02:37.007Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/f8/593f5caf0dacab41cde1564c5f0419e61af55ec9628006205e8fd5eb5e03/msgpack-1.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:b07c03f0da7e5279170df7745ddc732d526c8a198208936ec1a95c11ed2b2d5f", size = 72203, upload-time = "2026-08-27T10:02:38.28Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/9e/c6ef92046b4a2bbb9d3aa0cb581cbf4a4051afccf6e5fb301a1bd3086f39/msgpack-1.2.2-cp313-cp313-win_arm64.whl", hash = "sha256:d13d07efbf655f9ae7a2352b630c52727b359005b21ba08a507585c9ac8c0896", size = 65435, upload-time = "2026-08-27T10:02:39.534Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/50/3e92c403346652cabd08cb8faceef847bae917ea3b3c81b64a5b6d09ed41/msgpack-1.2.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e497ee34e8a3342bbde51b27c22d8db05a651df3361dd3daef5b3ab0d66f3e04", size = 84315, upload-time = "2026-08-27T10:02:41.181Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/dc/8efe6dd96a12ab043930cb4cffb40b6e7f061491d6ec7a3d2b75ef1fda42/msgpack-1.2.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0dd9173c5ebaf5ecc5ca86e7ae1db92934e1d57b856f3dd90698941431f4fd77", size = 84634, upload-time = "2026-08-27T10:02:42.621Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/89/996573095bf7b038c04dd65ddbc4f1a4d381b0f7a44ff9186f3c7b8325c2/msgpack-1.2.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8dc4487097571f7311188c3eca2a3e86cd1f1db4c37c7a017bcc3fd38486cbfe", size = 404194, upload-time = "2026-08-27T10:02:44.096Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/4e/46f5a5d949dbd054dab60cb15aac7ac6ae6774c134532893414689bf2f53/msgpack-1.2.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73b0e05c32c3cfc3cd84994908e57430c0ebc6813abf905d3f18ff115d54df3f", size = 412343, upload-time = "2026-08-27T10:02:45.747Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/e8/739a94197358a313307e6e9e7d8d22ef66add39222de911a44161aa96920/msgpack-1.2.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa1120c653b76d8eafa50423b5eba06b5c9737f8692c74fa3afe03e84b8978ea", size = 372620, upload-time = "2026-08-27T10:02:47.578Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/d4/09b92e1fcdccea9466bfae45455367ac52362ae445d96a602e51b7a8df73/msgpack-1.2.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccfd880988f8438d1c91c77d7edc58e70f4d2012e999167bc154c64c6f06ea6b", size = 394603, upload-time = "2026-08-27T10:02:49.172Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/db/d11bd6f258a60703dcdc7a3772818ad0c2f602ee4c2acfb24088c6c3ebc3/msgpack-1.2.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:6195257a107bf25872ef84aab7295078271eea3ac6413f0506b631f6c9586ed5", size = 372666, upload-time = "2026-08-27T10:02:50.886Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/cf/fbbbac0c6e5fbb9d51abc23e3b5fe8620f5c01e0588797cf664a623bb9e1/msgpack-1.2.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b8dd6c71d20c28d2d0eb0c51e7cccf3584afde3b1364f6629596186c9025bd54", size = 410889, upload-time = "2026-08-27T10:02:52.51Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/60/8366558da954095e04e7fbc351f9387d87a682feaee9a235ceda966f794b/msgpack-1.2.2-cp314-cp314-win32.whl", hash = "sha256:d242f3c4ccf55b056e6cf901720dccde58f1df117898f2bbf3bcd6e38ec7c248", size = 66774, upload-time = "2026-08-27T10:02:53.984Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/3d/1ce873c8057c65e4fbb076ffe1c99c9ae39d90a00a2540d7b06c652a292f/msgpack-1.2.2-cp314-cp314-win_amd64.whl", hash = "sha256:1510f24612d4b983dff6935d9273e02c320cfd525727fbcb58836a75f589fdbc", size = 73424, upload-time = "2026-08-27T10:02:55.277Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/55/e36f2a33e38657f33850d74e0bf256838a0d45802c298cc501a32bffcc08/msgpack-1.2.2-cp314-cp314-win_arm64.whl", hash = "sha256:7826f16edc763e768404f55605ef85dfcf5857e729c1ed29e0d7c180be4fe6d8", size = 67657, upload-time = "2026-08-27T10:02:56.493Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/58/7e764b957bae80ae281a9cb28761068c8bae8d5c6ac0873e43cc69d176c7/msgpack-1.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f466049b8e1ec0854287bbe9a074316826fe0e08dcf707245f98b1ae49e92650", size = 86594, upload-time = "2026-08-27T10:02:57.796Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/f0/250f5985b6ee533e60d357571a808aaae03c54118294dc3db7158e27feb1/msgpack-1.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f6b6f8deb07d49090e1808c6ef9cb7d23ca17bef3aa6ed3e5e03df16606e60c", size = 87374, upload-time = "2026-08-27T10:02:59.256Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/2c/126ec8f187877c5f688631c543d1d3a3d75b2e66b83fb9de3ed7c13a39b6/msgpack-1.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b542ffc0a5c531eedc40419f291f1bd659aa8d4223408a5b51c88a2796083fd3", size = 428157, upload-time = "2026-08-27T10:03:00.9Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/21/d2d81d50aaedb14147d01f22094185794db3ad8a8791b60afacba0627c89/msgpack-1.2.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d095df2627e5dd59ac7b0c5ad627a671c76e6020171e03cbe4621a61f0562c3", size = 426669, upload-time = "2026-08-27T10:03:02.457Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/fc/f7d484ee5b572719608e7ffad569bea22ff11309a96ca2fae85eec94226b/msgpack-1.2.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ffdd2f4950daf7815490f23087963e3420175b9609520b7ff5df64d351159c22", size = 380625, upload-time = "2026-08-27T10:03:04.244Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/c4/b924cbd5516676f4e612329f18602a833bd055ffbe27f808eeba0f01bfea/msgpack-1.2.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:652d1bf13d01bac8fd569def0fe76745e55bcda01e30aa6332d5947ea3788839", size = 411328, upload-time = "2026-08-27T10:03:05.869Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/9d/0c1d9683a951a80f270c3b7dac1022c18b9307617344dd44d904135d5e12/msgpack-1.2.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9bf452ff4d4981f25a18e9476e002bcc9263e7928024aa4d7148e25f7be3f929", size = 377892, upload-time = "2026-08-27T10:03:07.37Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/bb/bf22338cdd22e0b40c8f28468cea5f3d9c320244c095d8303364bc012c41/msgpack-1.2.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:55faa6f8395e23b848c535ad5dcb96b3462f37f5e7f4ac500d500434f7345da7", size = 419426, upload-time = "2026-08-27T10:03:09Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/42/6d02c19a01abd8d7ce817c321d2ee6af1a8e24d584dca619d1b6576a83bf/msgpack-1.2.2-cp314-cp314t-win32.whl", hash = "sha256:419a45c67a5c04213172a14b1864657e014665b77d7081b107a51707923dd39e", size = 71810, upload-time = "2026-08-27T10:03:10.498Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/df/fda3a204415dab0a8c0db5461ef7205416ea52bd8581c5cafd361be07f3b/msgpack-1.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:935b1cfad9b908b0fa845010f4271df4c2f04e1cd26e3f18acd61a45f93c9e36", size = 78919, upload-time = "2026-08-27T10:03:12.016Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/d4/4b4b0ef25a86deca91feaf7252ca885ba4f2ada40461379120122a04fe96/msgpack-1.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11e8c421e117d1c36728b423d0402555cccbf0c6f53e288f0e75b6b12100d70f", size = 71925, upload-time = "2026-08-27T10:03:13.332Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/92/4b44bc8f3243ef8cf9cb5368c17a299d45b9df858f6dfdd98a0482dbbb37/msgpack-1.2.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e1b99ad34613d5f8477fa5cf99bc4eaeaf27965588007c102370cd9a78fe9de5", size = 84293, upload-time = "2026-08-27T10:03:14.718Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/05/c992bb65744665a41b5bf531fc0e1619bae0901f57738228ded90023c151/msgpack-1.2.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:0fbc1bed8a535389b41882cfae66376e248cd1680eaa94fd83193c73e1d24986", size = 84490, upload-time = "2026-08-27T10:03:16.12Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/bf/7f53b9e6709a4df7f9b9b81dc65f9dfaa32caf65bee94986ec2cb8fa07f1/msgpack-1.2.2-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:06d95f61de7afe4f4ff908a6feebfcb070d0582ac87c9cf3cedf8551cf634516", size = 405332, upload-time = "2026-08-27T10:03:17.692Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/5a/305c4dca14b50d0b51fb88ef04ec125b8f0be3e2ce730dcc62dbaa651cc5/msgpack-1.2.2-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b5c696ae7cd7166b3657261adb855b461ff31f07823fdbae9de8bf80adfccc21", size = 416798, upload-time = "2026-08-27T10:03:19.389Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/df/a645102b4cdfd9a94201cac4e900e9c1429fc16d86aa311c06eef82528c9/msgpack-1.2.2-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0708afbf6a9587f0bfe479a9825c141d14d91e2f6a5c8103cf28bc96f4edb5d9", size = 377312, upload-time = "2026-08-27T10:03:20.928Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/26/c56d8d086d3fb1077bb48092b158b5ea2eee08b279e10c191275f13bc980/msgpack-1.2.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:226a62ffe99fe54c5c61d910ec64c3449b7766c3280bd286bf6c94838dde239a", size = 395182, upload-time = "2026-08-27T10:03:22.571Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/b5/3d46ba367a565e536d8d2a61eebcee71b1dc803da3ce74a22313b573d6fa/msgpack-1.2.2-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:9fd7f32e2f0fb334e7ecc5adb5cf0458785bd3a9d9d86f950e1715f101cebce5", size = 377945, upload-time = "2026-08-27T10:03:24.151Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/2c/d5d2df273ed5306357da25b69400fd8d7a53c4d87d8976604b677484d61c/msgpack-1.2.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:9db1ba1c1e6a84245a9dd866265b56b8a1e9461549cc72ed296d8cbfbd32961b", size = 413341, upload-time = "2026-08-27T10:03:25.85Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/fb/32613bced3cad47b40b1b73dd04d687121349d83f748efc2575929121903/msgpack-1.2.2-cp315-cp315-win32.whl", hash = "sha256:e2eb7ea0ac3911a7aac9d8aaa36d40f216d99455b3274cd3fac38181bcd910cf", size = 66730, upload-time = "2026-08-27T10:03:27.294Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/56/d86171f7251015e9312e5a7f9fdd4cf89752fc2114b88fed453d2a040c66/msgpack-1.2.2-cp315-cp315-win_amd64.whl", hash = "sha256:9352e6cdb510a7b1a5d3ccaccec730e82e50cf3484a3af7bdaab19e23b9589ff", size = 73477, upload-time = "2026-08-27T10:03:28.615Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/1a/56b90f6defef61700b86baca3637c15f62ac0f9b21ab0f16613ab9d1f101/msgpack-1.2.2-cp315-cp315-win_arm64.whl", hash = "sha256:29cc2d5291711a52956a79a51f41c732329df39ad727c886bd8f0b5b9237a808", size = 67660, upload-time = "2026-08-27T10:03:29.895Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/20/12751ca0d8ec874701b54c392c2b19f51af8dd1de40a92a10e356f0aaf58/msgpack-1.2.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:d886baa46b2532135e7320067e6a44edb09ba5883a6096b0f9c044533984b8a8", size = 86462, upload-time = "2026-08-27T10:03:31.348Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/4c/cf6d12a3d709fe5f9771dd917c35e6ebcd55597a5b792287382fde056c95/msgpack-1.2.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53679573c75cce5f82359e0bd4e6a97809a6b9a9b7a48fd1ba592f4a82cddc84", size = 87412, upload-time = "2026-08-27T10:03:32.74Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/0d/0aac5752d1708dcb458f8754db34a4999514db3df2d2b798b9381293f638/msgpack-1.2.2-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d3c247d457ae9079974c7ce3c665396754a6d2baff7eaa51332212a8a5a3f13b", size = 422057, upload-time = "2026-08-27T10:03:34.124Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/30/70f281a3685b04aaf235a5237da11b978a02a865a5a479186205177ad676/msgpack-1.2.2-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352ed831042549cca8be23780e1fe7c9177e65ff02bf183509c4b4d33f671782", size = 422696, upload-time = "2026-08-27T10:03:35.862Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/6d/f76e8425efb0aa38988cd778ae290bfa120491d80d26872d88bb52fedb3f/msgpack-1.2.2-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f80361592c13d7226b4379c8941529b63fe1a9d0e05d2de8f3306b70e522b53f", size = 376495, upload-time = "2026-08-27T10:03:37.339Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/77/0809aa9b52b2868f7d01862dc14073708f0440421a65197b48453480034c/msgpack-1.2.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:68df2947921d449f6dcfeafd86cb2cdde13327a8b447534bbe4ee5aaf32a5695", size = 404683, upload-time = "2026-08-27T10:03:38.87Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/d2/4e5ac915ba120172d210ef00165c5e6276c8a65db3a4a5cf36e946b83e23/msgpack-1.2.2-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:51dd39d23cfdea0400ed3ff2d29d1e83bd951d3aea79dc89be5b701a09edfe23", size = 375087, upload-time = "2026-08-27T10:03:40.486Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/e3/8051d53e5495c87c6cf27eb42fb680361017037f87f322bdaf525f71e4a2/msgpack-1.2.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:b13b59e66f107cca1ba708dd5307179870ca1b15b19fcee7ccf722e5308d9212", size = 414421, upload-time = "2026-08-27T10:03:42.308Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/4e/13783aa7c17414d7186c72c49bc718366f75e49f0ea58d4f81cb63ac3187/msgpack-1.2.2-cp315-cp315t-win32.whl", hash = "sha256:8c6321a414f8b4a8dc43976b2fa8349156434ca9adedd9a187b796f7e1d3d3fc", size = 71790, upload-time = "2026-08-27T10:03:43.715Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/9d/1d02994c7ae2603c98100984428ff0f67443572133bc18eca6058f732c1b/msgpack-1.2.2-cp315-cp315t-win_amd64.whl", hash = "sha256:6f53285f20d592ed309ee19e509cc4c77a3bda1db02ad67e8a0949bb227a5a6d", size = 78766, upload-time = "2026-08-27T10:03:45.036Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/54/89ed16e6f966a050dc78b0e94a545025211b07ce9f4bdfe07dff70c03fc2/msgpack-1.2.2-cp315-cp315t-win_arm64.whl", hash = "sha256:a378e12ccc06d76efde115caf4073b7e5ff3cc18291d1341f9e65fb882e3f754", size = 71819, upload-time = "2026-08-27T10:03:46.375Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oauthlib"
|
||||
version = "3.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0b/5f/19930f824ffeb0ad4372da4812c50edbd1434f678c90c2733e1188edfc63/oauthlib-3.3.1.tar.gz", hash = "sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9", size = 185918, upload-time = "2025-06-19T22:48:08.269Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl", hash = "sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1", size = 160065, upload-time = "2025-06-19T22:48:06.508Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "26.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.21.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "9.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
{ name = "iniconfig" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pluggy" },
|
||||
{ name = "pygments" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "repath"
|
||||
version = "0.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "six" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/65/e1/824989291d0f01886074fdf9504ba54598f5665bc4dd373b589b87e76608/repath-0.9.0.tar.gz", hash = "sha256:8292139bac6a0e43fd9d70605d4e8daeb25d46672e484ed31a24c7ce0aef0fb7", size = 5492, upload-time = "2019-10-08T00:25:22.3Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/87/ed/92e9b8a3ffc562f21df14ef2538f54e911df29730e1f0d79130a4edc86e7/repath-0.9.0-py3-none-any.whl", hash = "sha256:ee079d6c91faeb843274d22d8f786094ee01316ecfe293a1eb6546312bb6a318", size = 4738, upload-time = "2019-10-08T00:25:20.842Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.16.8"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ba/78/449cb84790bd5cc3823b2652ee405a4558856e5c4195aee3a16bf7b3eb5d/ruff-0.16.8.tar.gz", hash = "sha256:9247bf92b5f04d825c8639a4fe423ec2e4222acd9222e58412b0dab7e442798b", size = 4938814, upload-time = "2026-09-16T15:54:46.688Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/25/6071aabc530e9be7e2c195e8fe3f7aea2735405b6cf447212832d7811831/ruff-0.16.8-py3-none-linux_armv6l.whl", hash = "sha256:6ffbd6d87383c1edf5f6fa890f10200950240d7c1a16052a19a09d3a2307dd38", size = 10048966, upload-time = "2026-09-16T15:53:57.605Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/98/07f90ecbc74dd5fb5764f11f2bc774d6a7cffef92d2ff5f5b4e9e23c754e/ruff-0.16.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:42ed6b878ed61e3acca92f2730a17acff39286944ea82398544696366a6f925e", size = 10165498, upload-time = "2026-09-16T15:54:01.14Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/1f/e6a712e3b47cad4a40600134105ed193cb773f618a42eb7ba323cb812cc0/ruff-0.16.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7ea781c7f2afba8c6a505ea0fb3f994020249e0c450635f5381286fea6b46170", size = 9830004, upload-time = "2026-09-16T15:54:03.998Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/f2/311a08776d75d81c7676e20b6b020ae63cbe881fcdc7a8dd64e6e18bdd93/ruff-0.16.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8efeae3bbe414a5efefda11a792dfb51ef90ac48d50c4830de2f644caf3e8659", size = 9986558, upload-time = "2026-09-16T15:54:06.804Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/ed/37b6cb3d3ba8c73e68ae3eb1d502383beb5aa05a582bb7bb3a922f929f54/ruff-0.16.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a79b795469fef7fc6e908b218eed2eb17332afd85031db6480dc864560e69b2", size = 9877332, upload-time = "2026-09-16T15:54:09.552Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/cc/40873a8f36ad084cc540d55fcca7077264d5b13b24659e9180c176fb2b08/ruff-0.16.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fdc5563cdc50555e6fba39322850860e9267c1b3d12c26a74729d8604c3c812", size = 10507125, upload-time = "2026-09-16T15:54:12.152Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/e4/fc91a642b78ccbab6b9477720f3644ae7a10a9bcce69a934679cd64f62bc/ruff-0.16.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34508983c70665578dab88f5223d8e6228307e1135398ca8bfc8b7e9501e282b", size = 11336694, upload-time = "2026-09-16T15:54:15.489Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/3d/bbd2a9a600a4e73dc3e7548a249c8d1671273464b55822c6fae50f602dff/ruff-0.16.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:644bb578569e0ffc575741232bd385dacdd6fbe123f1a729e7a225f54aa3957f", size = 10774448, upload-time = "2026-09-16T15:54:18.16Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/41/d83af9879a7b6e8bf5fe16b1da0b134049d2f5d3afac12defb0897cb84bd/ruff-0.16.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15e7d226246961db9235098333caa13063906d3851136b84c2900b82f5daa1df", size = 10323796, upload-time = "2026-09-16T15:54:20.743Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/2c/cefd07bfe914b84943ea769ade8d607bd22750b965d3228eefd7cebd15d0/ruff-0.16.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a2bf6bc3e9ebdd4449abc6f06cf64b98051a2c61cf94d2fe9596518c881f1a1e", size = 10514115, upload-time = "2026-09-16T15:54:23.497Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/9d/76a2e26c79a23be6e6e3664c57bec9e9fc8de155cfb9e4b67ea91b64f9d7/ruff-0.16.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ca111ba0849539165e9e59d2b442542f3c1e8060ebbdea82494f1ffbccb1e1f", size = 10072582, upload-time = "2026-09-16T15:54:26.185Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/d4/f42edddb39668af1a559ceafa3823aedd65633a48dc9768e775485faa2c1/ruff-0.16.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:359a1e5b495448ee1e91018064382ebc86f90e8aac2fed222c7d0e4e8df85fd2", size = 9879644, upload-time = "2026-09-16T15:54:29.278Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/d4/913e3195d95e0378786c6656945c865f534a3560e29139da4882aff630d1/ruff-0.16.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:59e8f5681349474110b24d62e93cfda6593f5fa3473446ca3705200cac1a08b9", size = 10231569, upload-time = "2026-09-16T15:54:32.036Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/c4/8aa6ea0bdcedbd1bf87397e2fc4ed8406448ea5842f8660bc6e5f163039d/ruff-0.16.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:efa3e7a16d1baaa79957888dfdf8be9ef2e44db81cb032af06d76632ab59e773", size = 10663666, upload-time = "2026-09-16T15:54:34.838Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/02/7f10ef4700bc223c30a3fdd10631a29830c45524b810a3c7ed947af64591/ruff-0.16.8-py3-none-win32.whl", hash = "sha256:55793ba85c69921e89be061426d91a78652d6e50317c962240922747a4eb713f", size = 10093472, upload-time = "2026-09-16T15:54:37.47Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/5d/a509c07d714b6da88f2c518b4637cf6f1d46b074be8f0f1e5fb9ff5126fe/ruff-0.16.8-py3-none-win_amd64.whl", hash = "sha256:a6b85621fd3c81e31fc5f5add09c9c078b430db3595ca632efafdec9e64ebfaa", size = 10586899, upload-time = "2026-09-16T15:54:40.488Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/a0/50787329e4f20bf9dc9f6230015d46ec69c51a97ace5bc202dae4755365d/ruff-0.16.8-py3-none-win_arm64.whl", hash = "sha256:d075e820af612102ce217f07cc93e69f9490b10ec13ea85fa87bd03d996cef8a", size = 10386316, upload-time = "2026-09-16T15:54:43.332Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.17.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.16.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
|
||||
]
|
||||
Loading…
Add table
Reference in a new issue