Spaces:
Running
Running
Add more examples
Browse files- Dockerfile +1 -0
- public/data/contacts.csv +100 -0
- pyproject.toml +2 -0
- src/tutorial/_03_click_to_load.py +1 -1
- src/tutorial/_08_infinite_scroll.py +44 -0
- src/tutorial/_09_active_search.py +56 -0
- src/tutorial/_10_progress_bar.py +94 -0
- src/tutorial/_11_cascading_select.py +60 -0
- src/tutorial/__init__.py +8 -0
- uv.lock +159 -0
Dockerfile
CHANGED
@@ -11,6 +11,7 @@ ADD pyproject.toml /app/pyproject.toml
|
|
11 |
|
12 |
RUN uv sync --frozen --no-install-project
|
13 |
|
|
|
14 |
COPY --chown=user src ./src
|
15 |
RUN touch README.md
|
16 |
|
|
|
11 |
|
12 |
RUN uv sync --frozen --no-install-project
|
13 |
|
14 |
+
COPY --chown=user public ./public
|
15 |
COPY --chown=user src ./src
|
16 |
RUN touch README.md
|
17 |
|
public/data/contacts.csv
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Venus,Grimes,lectus.rutrum@Duisa.edu
|
2 |
+
Fletcher,Owen,metus@Aenean.org
|
3 |
+
William,Hale,eu.dolor@risusodio.edu
|
4 |
+
TaShya,Cash,tincidunt.orci.quis@nuncnullavulputate.co.uk
|
5 |
+
Kevyn,Hoover,tristique.pellentesque.tellus@Cumsociis.co.uk
|
6 |
+
Jakeem,Walker,Morbi.vehicula.Pellentesque@faucibusorci.org
|
7 |
+
Malcolm,Trujillo,sagittis@velit.edu
|
8 |
+
Wynne,Rice,augue.id@felisorciadipiscing.edu
|
9 |
+
Evangeline,Klein,adipiscing.lobortis@sem.org
|
10 |
+
Jennifer,Russell,sapien.Aenean.massa@risus.com
|
11 |
+
Rama,Freeman,Proin@quamPellentesquehabitant.net
|
12 |
+
Jena,Mathis,non.cursus.non@Phaselluselit.com
|
13 |
+
Alexandra,Maynard,porta.elit.a@anequeNullam.ca
|
14 |
+
Tallulah,Haley,ligula@id.net
|
15 |
+
Timon,Small,velit.Quisque.varius@gravidaPraesent.org
|
16 |
+
Randall,Pena,facilisis@Donecconsectetuer.edu
|
17 |
+
Conan,Vaughan,luctus.sit@Classaptenttaciti.edu
|
18 |
+
Dora,Allen,est.arcu.ac@Vestibulumante.co.uk
|
19 |
+
Aiko,Little,quam.dignissim@convallisest.net
|
20 |
+
Jessamine,Bauer,taciti.sociosqu@nibhvulputatemauris.co.uk
|
21 |
+
Gillian,Livingston,justo@atiaculisquis.com
|
22 |
+
Laith,Nicholson,elit.pellentesque.a@diam.org
|
23 |
+
Paloma,Alston,cursus@metus.org
|
24 |
+
Freya,Dunn,Vestibulum.accumsan@metus.co.uk
|
25 |
+
Griffin,Rice,justo@tortordictumeu.net
|
26 |
+
Catherine,West,malesuada.augue@elementum.com
|
27 |
+
Jena,Chambers,erat.Etiam.vestibulum@quamelementumat.net
|
28 |
+
Neil,Rodriguez,enim@facilisis.com
|
29 |
+
Freya,Charles,metus@nec.net
|
30 |
+
Anastasia,Strong,sit@vitae.edu
|
31 |
+
Bell,Simon,mollis.nec.cursus@disparturientmontes.ca
|
32 |
+
Minerva,Allison,Donec@nequeIn.edu
|
33 |
+
Yoko,Dawson,neque.sed@semper.net
|
34 |
+
Nadine,Justice,netus@et.edu
|
35 |
+
Hoyt,Rosa,Nullam.ut.nisi@Aliquam.co.uk
|
36 |
+
Shafira,Noel,tincidunt.nunc@non.edu
|
37 |
+
Jin,Nunez,porttitor.tellus.non@venenatisamagna.net
|
38 |
+
Barbara,Gay,est.congue.a@elit.com
|
39 |
+
Riley,Hammond,tempor.diam@sodalesnisi.net
|
40 |
+
Molly,Fulton,semper@Naminterdumenim.net
|
41 |
+
Dexter,Owen,non.ante@odiosagittissemper.ca
|
42 |
+
Kuame,Merritt,ornare.placerat.orci@nisinibh.ca
|
43 |
+
Maggie,Delgado,Nam.ligula.elit@Cum.org
|
44 |
+
Hanae,Washington,nec.euismod@adipiscingelit.org
|
45 |
+
Jonah,Cherry,ridiculus.mus.Proin@quispede.edu
|
46 |
+
Cheyenne,Munoz,at@molestiesodalesMauris.edu
|
47 |
+
India,Mack,sem.mollis@Inmi.co.uk
|
48 |
+
Lael,Mcneil,porttitor@risusDonecegestas.com
|
49 |
+
Jillian,Mckay,vulputate.eu.odio@amagnaLorem.co.uk
|
50 |
+
Shaine,Wright,malesuada@pharetraQuisqueac.org
|
51 |
+
Keane,Richmond,nostra.per.inceptos@euismodurna.org
|
52 |
+
Samuel,Davis,felis@euenim.com
|
53 |
+
Zelenia,Sheppard,Quisque.nonummy@antelectusconvallis.org
|
54 |
+
Giacomo,Cole,aliquet.libero@urnaUttincidunt.ca
|
55 |
+
Mason,Hinton,est@Nunc.co.uk
|
56 |
+
Katelyn,Koch,velit.Aliquam@Suspendisse.edu
|
57 |
+
Olga,Spencer,faucibus@Praesenteudui.net
|
58 |
+
Erasmus,Strong,dignissim.lacus@euarcu.net
|
59 |
+
Regan,Cline,vitae.erat.vel@lacusEtiambibendum.co.uk
|
60 |
+
Stone,Holt,eget.mollis.lectus@Aeneanegestas.ca
|
61 |
+
Deanna,Branch,turpis@estMauris.net
|
62 |
+
Rana,Green,metus@conguea.edu
|
63 |
+
Caryn,Henson,Donec.sollicitudin.adipiscing@sed.net
|
64 |
+
Clarke,Stein,nec@mollis.co.uk
|
65 |
+
Kelsie,Porter,Cum@gravidaAliquam.com
|
66 |
+
Cooper,Pugh,Quisque.ornare.tortor@dictum.co.uk
|
67 |
+
Paul,Spencer,ac@InfaucibusMorbi.com
|
68 |
+
Cassady,Farrell,Suspendisse.non@venenatisa.net
|
69 |
+
Sydnee,Velazquez,mollis@loremfringillaornare.com
|
70 |
+
Felix,Boyle,id.libero.Donec@aauctor.org
|
71 |
+
Ryder,House,molestie@natoquepenatibus.org
|
72 |
+
Hadley,Holcomb,penatibus@nisi.ca
|
73 |
+
Marsden,Nunez,Nulla.eget.metus@facilisisvitaeorci.org
|
74 |
+
Alana,Powell,non.lobortis.quis@interdumfeugiatSed.net
|
75 |
+
Dennis,Wyatt,Morbi.non@nibhQuisquenonummy.ca
|
76 |
+
Karleigh,Walton,nascetur.ridiculus@quamdignissimpharetra.com
|
77 |
+
Brielle,Donovan,placerat@at.edu
|
78 |
+
Donna,Dickerson,lacus.pede.sagittis@lacusvestibulum.com
|
79 |
+
Eagan,Pate,est.Nunc@cursusNunc.ca
|
80 |
+
Carlos,Ramsey,est.ac.facilisis@duinec.co.uk
|
81 |
+
Regan,Murphy,lectus.Cum@aptent.com
|
82 |
+
Claudia,Spence,Nunc.lectus.pede@aceleifend.co.uk
|
83 |
+
Genevieve,Parker,ultrices@inaliquetlobortis.net
|
84 |
+
Marshall,Allison,erat.semper.rutrum@odio.org
|
85 |
+
Reuben,Davis,Donec@auctorodio.edu
|
86 |
+
Ralph,Doyle,pede.Suspendisse.dui@Curabitur.org
|
87 |
+
Constance,Gilliam,mollis@Nulla.edu
|
88 |
+
Serina,Jacobson,dictum.augue@ipsum.net
|
89 |
+
Charity,Byrd,convallis.ante.lectus@scelerisquemollisPhasellus.co.uk
|
90 |
+
Hyatt,Bird,enim.Nunc.ut@nonmagnaNam.com
|
91 |
+
Brent,Dunn,ac.sem@nuncid.com
|
92 |
+
Casey,Bonner,id@ornareelitelit.edu
|
93 |
+
Hakeem,Gill,dis@nonummyipsumnon.org
|
94 |
+
Stewart,Meadows,Nunc.pulvinar.arcu@convallisdolorQuisque.net
|
95 |
+
Nomlanga,Wooten,inceptos@turpisegestas.ca
|
96 |
+
Sebastian,Watts,Sed.diam.lorem@lorem.co.uk
|
97 |
+
Chelsea,Larsen,ligula@Nam.net
|
98 |
+
Cameron,Humphrey,placerat@id.org
|
99 |
+
Juliet,Bush,consectetuer.euismod@vitaeeratVivamus.co.uk
|
100 |
+
Caryn,Hooper,eu.enim.Etiam@ridiculus.org
|
pyproject.toml
CHANGED
@@ -18,6 +18,8 @@ build-backend = "hatchling.build"
|
|
18 |
[tool.uv]
|
19 |
dev-dependencies = [
|
20 |
"ipykernel>=6.29.5",
|
|
|
|
|
21 |
"pytest-cov>=5.0.0",
|
22 |
"pytest>=8.3.2",
|
23 |
"ruff>=0.6.3",
|
|
|
18 |
[tool.uv]
|
19 |
dev-dependencies = [
|
20 |
"ipykernel>=6.29.5",
|
21 |
+
"lxml>=5.3.0",
|
22 |
+
"pandas>=2.2.2",
|
23 |
"pytest-cov>=5.0.0",
|
24 |
"pytest>=8.3.2",
|
25 |
"ruff>=0.6.3",
|
src/tutorial/_03_click_to_load.py
CHANGED
@@ -18,7 +18,7 @@ def contact_table():
|
|
18 |
|
19 |
@app.get("/contacts")
|
20 |
def load_contacts(page: int, limit: int = 5):
|
21 |
-
rows = [Tr(Td("Smith"), Td(page * limit + i)) for i in range(limit)]
|
22 |
return *rows, make_last_row(page)
|
23 |
|
24 |
|
|
|
18 |
|
19 |
@app.get("/contacts")
|
20 |
def load_contacts(page: int, limit: int = 5):
|
21 |
+
rows = [Tr(Td("Smith"), Td((page - 1) * limit + i)) for i in range(limit)]
|
22 |
return *rows, make_last_row(page)
|
23 |
|
24 |
|
src/tutorial/_08_infinite_scroll.py
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fasthtml.common import Div, Table, Tbody, Td, Th, Thead, Tr, fast_app
|
2 |
+
|
3 |
+
app, rt = fast_app()
|
4 |
+
|
5 |
+
|
6 |
+
# fmt: off
|
7 |
+
@app.get("/table")
|
8 |
+
def contact_table():
|
9 |
+
return Div(
|
10 |
+
Table(
|
11 |
+
Thead(Tr(Th("Name"), Th("ID"))),
|
12 |
+
Tbody(load_contacts(page=1)),
|
13 |
+
),
|
14 |
+
cls="container",
|
15 |
+
)
|
16 |
+
# fmt: on
|
17 |
+
|
18 |
+
|
19 |
+
@app.get("/contacts")
|
20 |
+
def load_contacts(page: int, limit: int = 5):
|
21 |
+
rows = [Tr(Td("Smith"), Td((page - 1) * limit + i)) for i in range(1, limit)]
|
22 |
+
return *rows, make_last_row(page, limit)
|
23 |
+
|
24 |
+
|
25 |
+
def make_last_row(page, limit):
|
26 |
+
return Tr(
|
27 |
+
Td("Smith"),
|
28 |
+
Td(page * limit),
|
29 |
+
hx_trigger="revealed",
|
30 |
+
hx_swap="afterend",
|
31 |
+
hx_get=f"/contacts?page={page + 1}",
|
32 |
+
)
|
33 |
+
|
34 |
+
|
35 |
+
DESC = "Demonstrates infinite scrolling of a page"
|
36 |
+
DOC = """
|
37 |
+
The infinite scroll pattern provides a way to load content dynamically on user scrolling action.
|
38 |
+
|
39 |
+
Let’s focus on the final row (or the last element of your content):
|
40 |
+
::make_last_row load_contacts::
|
41 |
+
This last element contains a listener which, when scrolled into view, will trigger a request. The result is then appended after it. The last element of the results will itself contain the listener to load the next page of results, and so on.
|
42 |
+
|
43 |
+
<blockquote><ins>revealed</ins> triggered when an element is scrolled into the viewport (also useful for lazy-loading). If you are using overflow in css like overflow-y: scroll you should use intersect once instead of revealed.</blockquote>
|
44 |
+
"""
|
src/tutorial/_09_active_search.py
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import time
|
2 |
+
from pathlib import Path
|
3 |
+
|
4 |
+
from fasthtml.common import H3, Div, Img, Input, Span, Table, Tbody, Td, Th, Thead, Tr, fast_app
|
5 |
+
|
6 |
+
app, rt = fast_app()
|
7 |
+
|
8 |
+
|
9 |
+
# fmt: off
|
10 |
+
@app.get("/page")
|
11 |
+
def main_page():
|
12 |
+
return Div(
|
13 |
+
H3("Search Contacts"),
|
14 |
+
Input(
|
15 |
+
type="search",
|
16 |
+
name="query",
|
17 |
+
placeholder="Begin Typing To Search Users...",
|
18 |
+
hx_post="/search",
|
19 |
+
hx_trigger="input changed delay:500ms, search",
|
20 |
+
hx_target="#search-results",
|
21 |
+
hx_indicator=".htmx-indicator",
|
22 |
+
cls="form-control",
|
23 |
+
),
|
24 |
+
Span(Img(src="/img/bars.svg"), "Searching...", cls="htmx-indicator"),
|
25 |
+
Table(
|
26 |
+
Thead(Tr(Th("First Name"), Th("Last Name"), Th("Email"))),
|
27 |
+
Tbody(id="search-results"),
|
28 |
+
),
|
29 |
+
)
|
30 |
+
# fmt: on
|
31 |
+
|
32 |
+
|
33 |
+
@app.post("/search")
|
34 |
+
def search(query: str, limit: int = 10):
|
35 |
+
time.sleep(0.5)
|
36 |
+
data = [x.split(",") for x in LINES if query.lower() in x.lower()]
|
37 |
+
return [Tr(Td(x[0]), Td(x[1]), Td(x[2])) for x in data[:limit]]
|
38 |
+
|
39 |
+
|
40 |
+
LINES = Path("public/data/contacts.csv").read_text().splitlines()
|
41 |
+
|
42 |
+
|
43 |
+
DESC = "Demonstrates the active search box pattern"
|
44 |
+
DOC = """
|
45 |
+
This example actively searches a contacts database as the user enters text.
|
46 |
+
|
47 |
+
We start with a search input and an empty table:
|
48 |
+
::main_page::
|
49 |
+
The input issues a POST to /search on the input event and sets the body of the table to be the resulting content. Note that the keyup event could be used as well, but would not fire if the user pasted text with their mouse (or any other non-keyboard method).
|
50 |
+
|
51 |
+
We add the delay:500ms modifier to the trigger to delay sending the query until the user stops typing. Additionally, we add the changed modifier to the trigger to ensure we don’t send new queries when the user doesn’t change the value of the input (e.g. they hit an arrow key, or pasted the same value).
|
52 |
+
|
53 |
+
Since we use a search type input we will get an x in the input field to clear the input. To make this trigger a new POST we have to specify another trigger. We specify another trigger by using a comma to separate them. The search trigger will be run when the field is cleared but it also makes it possible to override the 500 ms input event delay by just pressing enter.
|
54 |
+
|
55 |
+
Finally, we show an indicator when the search is in flight with the hx-indicator attribute.
|
56 |
+
"""
|
src/tutorial/_10_progress_bar.py
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fasthtml.common import H3, Button, Div, HttpHeader, Style, fast_app
|
2 |
+
|
3 |
+
css = """
|
4 |
+
.progress {
|
5 |
+
height: 20px;
|
6 |
+
margin-bottom: 20px;
|
7 |
+
overflow: hidden;
|
8 |
+
background-color: #f5f5f5;
|
9 |
+
border-radius: 4px;
|
10 |
+
box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
|
11 |
+
}
|
12 |
+
.progress-bar {
|
13 |
+
float: left;
|
14 |
+
width: 0%;
|
15 |
+
height: 100%;
|
16 |
+
font-size: 12px;
|
17 |
+
line-height: 20px;
|
18 |
+
color: #fff;
|
19 |
+
text-align: center;
|
20 |
+
background-color: #337ab7;
|
21 |
+
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
|
22 |
+
box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
|
23 |
+
-webkit-transition: width .6s ease;
|
24 |
+
-o-transition: width .6s ease;
|
25 |
+
transition: width .6s ease;
|
26 |
+
}
|
27 |
+
"""
|
28 |
+
|
29 |
+
app, rt = fast_app(hdrs=[Style(css)])
|
30 |
+
|
31 |
+
current = 1
|
32 |
+
|
33 |
+
|
34 |
+
@app.get("/page")
|
35 |
+
def main_page():
|
36 |
+
return Div(
|
37 |
+
H3("Start Progress"),
|
38 |
+
Button("Start Job", hx_post="/start", cls="btn primary"),
|
39 |
+
hx_target="this",
|
40 |
+
hx_swap="outerHTML",
|
41 |
+
)
|
42 |
+
|
43 |
+
|
44 |
+
@app.post("/start")
|
45 |
+
def start_job():
|
46 |
+
global current
|
47 |
+
current = 1
|
48 |
+
return Div(
|
49 |
+
H3("Running", role="status", id="pblabel", tabindex="-1", autofocus=""),
|
50 |
+
Div(
|
51 |
+
get_progress(),
|
52 |
+
hx_get="/job/progress",
|
53 |
+
hx_trigger="every 600ms",
|
54 |
+
hx_target="this",
|
55 |
+
hx_swap="innerHTML",
|
56 |
+
),
|
57 |
+
hx_trigger="done",
|
58 |
+
hx_get="/job",
|
59 |
+
hx_swap="outerHTML",
|
60 |
+
hx_target="this",
|
61 |
+
)
|
62 |
+
|
63 |
+
|
64 |
+
@app.get("/job/progress")
|
65 |
+
def get_progress():
|
66 |
+
global current
|
67 |
+
if current <= 100:
|
68 |
+
current += 10
|
69 |
+
return Div(Div(style=f"width:{current - 10}%", cls="progress-bar"), cls="progress")
|
70 |
+
return HttpHeader("HX-Trigger", "done")
|
71 |
+
|
72 |
+
|
73 |
+
@app.get("/job")
|
74 |
+
def view_completed():
|
75 |
+
return Div(
|
76 |
+
H3("Complete", role="status", id="pblabel", tabindex="-1", autofocus=""),
|
77 |
+
Div(Div(style="width:100%", cls="progress-bar"), cls="progress"),
|
78 |
+
Button("Restart Job", hx_post="/start", cls="btn primary show"),
|
79 |
+
hx_swap="outerHTML",
|
80 |
+
hx_target="this",
|
81 |
+
)
|
82 |
+
|
83 |
+
|
84 |
+
DESC = "Demonstrates a job-runner like progress bar"
|
85 |
+
DOC = """
|
86 |
+
This example shows how to implement a smoothly scrolling progress bar.
|
87 |
+
|
88 |
+
We start with an initial state with a button that issues a POST to /start to begin the job:
|
89 |
+
::main_page::
|
90 |
+
This progress bar is updated every 600 milliseconds, with the “width” style attribute and aria-valuenow attributed set to current progress value. Because there is an id on the progress bar div, htmx will smoothly transition between requests by settling the style attribute into its new value. This, when coupled with CSS transitions, makes the visual transition continuous rather than jumpy.
|
91 |
+
::start_job get_progress::
|
92 |
+
Finally, when the process is complete, a server returns HX-Trigger: done header, which triggers an update of the UI to “Complete” state with a restart button added to the UI:
|
93 |
+
::view_completed::
|
94 |
+
"""
|
src/tutorial/_11_cascading_select.py
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import time
|
2 |
+
|
3 |
+
from fasthtml.common import H3, Div, Form, Img, Label, Option, Select, fast_app
|
4 |
+
|
5 |
+
app, rt = fast_app()
|
6 |
+
|
7 |
+
|
8 |
+
@app.get("/page")
|
9 |
+
def main_page():
|
10 |
+
return Div(
|
11 |
+
H3("Pick A Make/Model"),
|
12 |
+
Form(
|
13 |
+
Div(
|
14 |
+
Label("Make"),
|
15 |
+
Select(
|
16 |
+
Option("Audi", value="audi"),
|
17 |
+
Option("Toyota", value="toyota"),
|
18 |
+
Option("BMW", value="bmw"),
|
19 |
+
name="make",
|
20 |
+
hx_get="/models?sleep=1",
|
21 |
+
hx_target="#models",
|
22 |
+
hx_indicator=".htmx-indicator",
|
23 |
+
),
|
24 |
+
),
|
25 |
+
Div(
|
26 |
+
Label("Model"),
|
27 |
+
Select(load_models("audi"), id="models"),
|
28 |
+
Img(width="20", src="/img/bars.svg", cls="htmx-indicator"),
|
29 |
+
),
|
30 |
+
),
|
31 |
+
cls="container",
|
32 |
+
)
|
33 |
+
|
34 |
+
|
35 |
+
@app.get("/models")
|
36 |
+
def load_models(make: str, sleep: int = 0):
|
37 |
+
time.sleep(sleep)
|
38 |
+
cars = {
|
39 |
+
"audi": ["A1", "A4", "A6"],
|
40 |
+
"toyota": ["Landcruiser", "Tacoma", "Yaris"],
|
41 |
+
"bmw": ["325i", "325ix", "X5"],
|
42 |
+
}
|
43 |
+
return tuple(Option(v, value=v) for v in cars[make])
|
44 |
+
|
45 |
+
|
46 |
+
DESC = "Demonstrates making the values of a select dependent on another select"
|
47 |
+
HTMX_URL = "https://htmx.org/examples/value-select/"
|
48 |
+
DOC = """
|
49 |
+
In this example we show how to make the values in one select depend on the value selected in another select.
|
50 |
+
|
51 |
+
To begin we start with a default value for the make select: Audi. We render the model select for this make. We then have the make select trigger a GET to /models to retrieve the models options and target the models select.
|
52 |
+
|
53 |
+
Here is the code:
|
54 |
+
::main_page::
|
55 |
+
|
56 |
+
When a request is made to the /models end point, we return the models for that make:
|
57 |
+
::load_models::
|
58 |
+
|
59 |
+
And they become available in the model select.
|
60 |
+
"""
|
src/tutorial/__init__.py
CHANGED
@@ -37,10 +37,18 @@ app, rt = fast_app(hdrs=hdrs, static_path="public")
|
|
37 |
examples = sorted([f.stem for f in Path(__file__).parent.glob("*.py") if f.stem not in ["__init__"]])
|
38 |
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
@app.get("/")
|
41 |
def homepage():
|
42 |
ls = [get_example(name) for name in examples]
|
43 |
return Main(
|
|
|
44 |
Table(
|
45 |
Thead(Tr(Th("Pattern"), Th("Description"))),
|
46 |
Tbody(tuple(Tr(Td(A(ex.title, href="/" + ex.slug)), Td(ex.desc)) for ex in ls)),
|
|
|
37 |
examples = sorted([f.stem for f in Path(__file__).parent.glob("*.py") if f.stem not in ["__init__"]])
|
38 |
|
39 |
|
40 |
+
INTRO = """
|
41 |
+
# HTMX examples with FastHTML
|
42 |
+
|
43 |
+
Reproduction of HTMX official [examples](https://htmx.org/examples/) in Python with [FastHTML](https://docs.fastht.ml/)
|
44 |
+
"""
|
45 |
+
|
46 |
+
|
47 |
@app.get("/")
|
48 |
def homepage():
|
49 |
ls = [get_example(name) for name in examples]
|
50 |
return Main(
|
51 |
+
Div(INTRO, cls="marked"),
|
52 |
Table(
|
53 |
Thead(Tr(Th("Pattern"), Th("Description"))),
|
54 |
Tbody(tuple(Tr(Td(A(ex.title, href="/" + ex.slug)), Td(ex.desc)) for ex in ls)),
|
uv.lock
CHANGED
@@ -1,5 +1,9 @@
|
|
1 |
version = 1
|
2 |
requires-python = ">=3.11"
|
|
|
|
|
|
|
|
|
3 |
|
4 |
[[package]]
|
5 |
name = "anyio"
|
@@ -421,6 +425,65 @@ wheels = [
|
|
421 |
{ url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 },
|
422 |
]
|
423 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
424 |
[[package]]
|
425 |
name = "matplotlib-inline"
|
426 |
version = "0.1.7"
|
@@ -442,6 +505,52 @@ wheels = [
|
|
442 |
{ url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195 },
|
443 |
]
|
444 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
[[package]]
|
446 |
name = "oauthlib"
|
447 |
version = "3.2.2"
|
@@ -460,6 +569,34 @@ wheels = [
|
|
460 |
{ url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 },
|
461 |
]
|
462 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
463 |
[[package]]
|
464 |
name = "parso"
|
465 |
version = "0.8.4"
|
@@ -643,6 +780,15 @@ wheels = [
|
|
643 |
{ url = "https://files.pythonhosted.org/packages/3d/47/444768600d9e0ebc82f8e347775d24aef8f6348cf00e9fa0e81910814e6d/python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215", size = 22299 },
|
644 |
]
|
645 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
646 |
[[package]]
|
647 |
name = "pywin32"
|
648 |
version = "306"
|
@@ -884,6 +1030,8 @@ dependencies = [
|
|
884 |
[package.dev-dependencies]
|
885 |
dev = [
|
886 |
{ name = "ipykernel" },
|
|
|
|
|
887 |
{ name = "pytest" },
|
888 |
{ name = "pytest-cov" },
|
889 |
{ name = "ruff" },
|
@@ -895,6 +1043,8 @@ requires-dist = [{ name = "python-fasthtml", specifier = ">=0.5.1" }]
|
|
895 |
[package.metadata.requires-dev]
|
896 |
dev = [
|
897 |
{ name = "ipykernel", specifier = ">=6.29.5" },
|
|
|
|
|
898 |
{ name = "pytest", specifier = ">=8.3.2" },
|
899 |
{ name = "pytest-cov", specifier = ">=5.0.0" },
|
900 |
{ name = "ruff", specifier = ">=0.6.3" },
|
@@ -909,6 +1059,15 @@ wheels = [
|
|
909 |
{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
|
910 |
]
|
911 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
912 |
[[package]]
|
913 |
name = "uvicorn"
|
914 |
version = "0.30.6"
|
|
|
1 |
version = 1
|
2 |
requires-python = ">=3.11"
|
3 |
+
resolution-markers = [
|
4 |
+
"python_full_version < '3.12'",
|
5 |
+
"python_full_version >= '3.12'",
|
6 |
+
]
|
7 |
|
8 |
[[package]]
|
9 |
name = "anyio"
|
|
|
425 |
{ url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 },
|
426 |
]
|
427 |
|
428 |
+
[[package]]
|
429 |
+
name = "lxml"
|
430 |
+
version = "5.3.0"
|
431 |
+
source = { registry = "https://pypi.org/simple" }
|
432 |
+
sdist = { url = "https://files.pythonhosted.org/packages/e7/6b/20c3a4b24751377aaa6307eb230b66701024012c29dd374999cc92983269/lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f", size = 3679318 }
|
433 |
+
wheels = [
|
434 |
+
{ url = "https://files.pythonhosted.org/packages/5c/a8/449faa2a3cbe6a99f8d38dcd51a3ee8844c17862841a6f769ea7c2a9cd0f/lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b", size = 8141056 },
|
435 |
+
{ url = "https://files.pythonhosted.org/packages/ac/8a/ae6325e994e2052de92f894363b038351c50ee38749d30cc6b6d96aaf90f/lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18", size = 4425238 },
|
436 |
+
{ url = "https://files.pythonhosted.org/packages/f8/fb/128dddb7f9086236bce0eeae2bfb316d138b49b159f50bc681d56c1bdd19/lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442", size = 5095197 },
|
437 |
+
{ url = "https://files.pythonhosted.org/packages/b4/f9/a181a8ef106e41e3086629c8bdb2d21a942f14c84a0e77452c22d6b22091/lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4", size = 4809809 },
|
438 |
+
{ url = "https://files.pythonhosted.org/packages/25/2f/b20565e808f7f6868aacea48ddcdd7e9e9fb4c799287f21f1a6c7c2e8b71/lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f", size = 5407593 },
|
439 |
+
{ url = "https://files.pythonhosted.org/packages/23/0e/caac672ec246d3189a16c4d364ed4f7d6bf856c080215382c06764058c08/lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e", size = 4866657 },
|
440 |
+
{ url = "https://files.pythonhosted.org/packages/67/a4/1f5fbd3f58d4069000522196b0b776a014f3feec1796da03e495cf23532d/lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c", size = 4967017 },
|
441 |
+
{ url = "https://files.pythonhosted.org/packages/ee/73/623ecea6ca3c530dd0a4ed0d00d9702e0e85cd5624e2d5b93b005fe00abd/lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16", size = 4810730 },
|
442 |
+
{ url = "https://files.pythonhosted.org/packages/1d/ce/fb84fb8e3c298f3a245ae3ea6221c2426f1bbaa82d10a88787412a498145/lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79", size = 5455154 },
|
443 |
+
{ url = "https://files.pythonhosted.org/packages/b1/72/4d1ad363748a72c7c0411c28be2b0dc7150d91e823eadad3b91a4514cbea/lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080", size = 4969416 },
|
444 |
+
{ url = "https://files.pythonhosted.org/packages/42/07/b29571a58a3a80681722ea8ed0ba569211d9bb8531ad49b5cacf6d409185/lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654", size = 5013672 },
|
445 |
+
{ url = "https://files.pythonhosted.org/packages/b9/93/bde740d5a58cf04cbd38e3dd93ad1e36c2f95553bbf7d57807bc6815d926/lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d", size = 4878644 },
|
446 |
+
{ url = "https://files.pythonhosted.org/packages/56/b5/645c8c02721d49927c93181de4017164ec0e141413577687c3df8ff0800f/lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763", size = 5511531 },
|
447 |
+
{ url = "https://files.pythonhosted.org/packages/85/3f/6a99a12d9438316f4fc86ef88c5d4c8fb674247b17f3173ecadd8346b671/lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec", size = 5402065 },
|
448 |
+
{ url = "https://files.pythonhosted.org/packages/80/8a/df47bff6ad5ac57335bf552babfb2408f9eb680c074ec1ba412a1a6af2c5/lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be", size = 5069775 },
|
449 |
+
{ url = "https://files.pythonhosted.org/packages/08/ae/e7ad0f0fbe4b6368c5ee1e3ef0c3365098d806d42379c46c1ba2802a52f7/lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9", size = 3474226 },
|
450 |
+
{ url = "https://files.pythonhosted.org/packages/c3/b5/91c2249bfac02ee514ab135e9304b89d55967be7e53e94a879b74eec7a5c/lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1", size = 3814971 },
|
451 |
+
{ url = "https://files.pythonhosted.org/packages/eb/6d/d1f1c5e40c64bf62afd7a3f9b34ce18a586a1cccbf71e783cd0a6d8e8971/lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859", size = 8171753 },
|
452 |
+
{ url = "https://files.pythonhosted.org/packages/bd/83/26b1864921869784355459f374896dcf8b44d4af3b15d7697e9156cb2de9/lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e", size = 4441955 },
|
453 |
+
{ url = "https://files.pythonhosted.org/packages/e0/d2/e9bff9fb359226c25cda3538f664f54f2804f4b37b0d7c944639e1a51f69/lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f", size = 5050778 },
|
454 |
+
{ url = "https://files.pythonhosted.org/packages/88/69/6972bfafa8cd3ddc8562b126dd607011e218e17be313a8b1b9cc5a0ee876/lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e", size = 4748628 },
|
455 |
+
{ url = "https://files.pythonhosted.org/packages/5d/ea/a6523c7c7f6dc755a6eed3d2f6d6646617cad4d3d6d8ce4ed71bfd2362c8/lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179", size = 5322215 },
|
456 |
+
{ url = "https://files.pythonhosted.org/packages/99/37/396fbd24a70f62b31d988e4500f2068c7f3fd399d2fd45257d13eab51a6f/lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a", size = 4813963 },
|
457 |
+
{ url = "https://files.pythonhosted.org/packages/09/91/e6136f17459a11ce1757df864b213efbeab7adcb2efa63efb1b846ab6723/lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3", size = 4923353 },
|
458 |
+
{ url = "https://files.pythonhosted.org/packages/1d/7c/2eeecf87c9a1fca4f84f991067c693e67340f2b7127fc3eca8fa29d75ee3/lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1", size = 4740541 },
|
459 |
+
{ url = "https://files.pythonhosted.org/packages/3b/ed/4c38ba58defca84f5f0d0ac2480fdcd99fc7ae4b28fc417c93640a6949ae/lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d", size = 5346504 },
|
460 |
+
{ url = "https://files.pythonhosted.org/packages/a5/22/bbd3995437e5745cb4c2b5d89088d70ab19d4feabf8a27a24cecb9745464/lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c", size = 4898077 },
|
461 |
+
{ url = "https://files.pythonhosted.org/packages/0a/6e/94537acfb5b8f18235d13186d247bca478fea5e87d224644e0fe907df976/lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99", size = 4946543 },
|
462 |
+
{ url = "https://files.pythonhosted.org/packages/8d/e8/4b15df533fe8e8d53363b23a41df9be907330e1fa28c7ca36893fad338ee/lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff", size = 4816841 },
|
463 |
+
{ url = "https://files.pythonhosted.org/packages/1a/e7/03f390ea37d1acda50bc538feb5b2bda6745b25731e4e76ab48fae7106bf/lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a", size = 5417341 },
|
464 |
+
{ url = "https://files.pythonhosted.org/packages/ea/99/d1133ab4c250da85a883c3b60249d3d3e7c64f24faff494cf0fd23f91e80/lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8", size = 5327539 },
|
465 |
+
{ url = "https://files.pythonhosted.org/packages/7d/ed/e6276c8d9668028213df01f598f385b05b55a4e1b4662ee12ef05dab35aa/lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d", size = 5012542 },
|
466 |
+
{ url = "https://files.pythonhosted.org/packages/36/88/684d4e800f5aa28df2a991a6a622783fb73cf0e46235cfa690f9776f032e/lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30", size = 3486454 },
|
467 |
+
{ url = "https://files.pythonhosted.org/packages/fc/82/ace5a5676051e60355bd8fb945df7b1ba4f4fb8447f2010fb816bfd57724/lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f", size = 3816857 },
|
468 |
+
{ url = "https://files.pythonhosted.org/packages/94/6a/42141e4d373903bfea6f8e94b2f554d05506dfda522ada5343c651410dc8/lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a", size = 8156284 },
|
469 |
+
{ url = "https://files.pythonhosted.org/packages/91/5e/fa097f0f7d8b3d113fb7312c6308af702f2667f22644441715be961f2c7e/lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd", size = 4432407 },
|
470 |
+
{ url = "https://files.pythonhosted.org/packages/2d/a1/b901988aa6d4ff937f2e5cfc114e4ec561901ff00660c3e56713642728da/lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51", size = 5048331 },
|
471 |
+
{ url = "https://files.pythonhosted.org/packages/30/0f/b2a54f48e52de578b71bbe2a2f8160672a8a5e103df3a78da53907e8c7ed/lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b", size = 4744835 },
|
472 |
+
{ url = "https://files.pythonhosted.org/packages/82/9d/b000c15538b60934589e83826ecbc437a1586488d7c13f8ee5ff1f79a9b8/lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002", size = 5316649 },
|
473 |
+
{ url = "https://files.pythonhosted.org/packages/e3/ee/ffbb9eaff5e541922611d2c56b175c45893d1c0b8b11e5a497708a6a3b3b/lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4", size = 4812046 },
|
474 |
+
{ url = "https://files.pythonhosted.org/packages/15/ff/7ff89d567485c7b943cdac316087f16b2399a8b997007ed352a1248397e5/lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492", size = 4918597 },
|
475 |
+
{ url = "https://files.pythonhosted.org/packages/c6/a3/535b6ed8c048412ff51268bdf4bf1cf052a37aa7e31d2e6518038a883b29/lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3", size = 4738071 },
|
476 |
+
{ url = "https://files.pythonhosted.org/packages/7a/8f/cbbfa59cb4d4fd677fe183725a76d8c956495d7a3c7f111ab8f5e13d2e83/lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4", size = 5342213 },
|
477 |
+
{ url = "https://files.pythonhosted.org/packages/5c/fb/db4c10dd9958d4b52e34d1d1f7c1f434422aeaf6ae2bbaaff2264351d944/lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367", size = 4893749 },
|
478 |
+
{ url = "https://files.pythonhosted.org/packages/f2/38/bb4581c143957c47740de18a3281a0cab7722390a77cc6e610e8ebf2d736/lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832", size = 4945901 },
|
479 |
+
{ url = "https://files.pythonhosted.org/packages/fc/d5/18b7de4960c731e98037bd48fa9f8e6e8f2558e6fbca4303d9b14d21ef3b/lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff", size = 4815447 },
|
480 |
+
{ url = "https://files.pythonhosted.org/packages/97/a8/cd51ceaad6eb849246559a8ef60ae55065a3df550fc5fcd27014361c1bab/lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd", size = 5411186 },
|
481 |
+
{ url = "https://files.pythonhosted.org/packages/89/c3/1e3dabab519481ed7b1fdcba21dcfb8832f57000733ef0e71cf6d09a5e03/lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb", size = 5324481 },
|
482 |
+
{ url = "https://files.pythonhosted.org/packages/b6/17/71e9984cf0570cd202ac0a1c9ed5c1b8889b0fc8dc736f5ef0ffb181c284/lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b", size = 5011053 },
|
483 |
+
{ url = "https://files.pythonhosted.org/packages/69/68/9f7e6d3312a91e30829368c2b3217e750adef12a6f8eb10498249f4e8d72/lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957", size = 3485634 },
|
484 |
+
{ url = "https://files.pythonhosted.org/packages/7d/db/214290d58ad68c587bd5d6af3d34e56830438733d0d0856c0275fde43652/lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d", size = 3814417 },
|
485 |
+
]
|
486 |
+
|
487 |
[[package]]
|
488 |
name = "matplotlib-inline"
|
489 |
version = "0.1.7"
|
|
|
505 |
{ url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195 },
|
506 |
]
|
507 |
|
508 |
+
[[package]]
|
509 |
+
name = "numpy"
|
510 |
+
version = "2.1.1"
|
511 |
+
source = { registry = "https://pypi.org/simple" }
|
512 |
+
sdist = { url = "https://files.pythonhosted.org/packages/59/5f/9003bb3e632f2b58f5e3a3378902dcc73c5518070736c6740fe52454e8e1/numpy-2.1.1.tar.gz", hash = "sha256:d0cf7d55b1051387807405b3898efafa862997b4cba8aa5dbe657be794afeafd", size = 18874860 }
|
513 |
+
wheels = [
|
514 |
+
{ url = "https://files.pythonhosted.org/packages/f7/86/2c01070424a42b286ea0271203682c3d3e81e10ce695545b35768307b383/numpy-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0d07841fd284718feffe7dd17a63a2e6c78679b2d386d3e82f44f0108c905550", size = 21154850 },
|
515 |
+
{ url = "https://files.pythonhosted.org/packages/ef/4e/d3426d9e620a18bbb979f28e4dc7f9a2c35eb7cf726ffcb33545ebdd3e6a/numpy-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b5613cfeb1adfe791e8e681128f5f49f22f3fcaa942255a6124d58ca59d9528f", size = 13789477 },
|
516 |
+
{ url = "https://files.pythonhosted.org/packages/c6/6e/fb6b1b2da9f4c757f55b202f10b6af0fe4fee87ace6e830228a12ab8ae5d/numpy-2.1.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0b8cc2715a84b7c3b161f9ebbd942740aaed913584cae9cdc7f8ad5ad41943d0", size = 5351769 },
|
517 |
+
{ url = "https://files.pythonhosted.org/packages/58/9a/07c8a9dc7254f3265ae014e33768d1cfd8eb73ee6cf215f4ec3b497e4255/numpy-2.1.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:b49742cdb85f1f81e4dc1b39dcf328244f4d8d1ded95dea725b316bd2cf18c95", size = 6890872 },
|
518 |
+
{ url = "https://files.pythonhosted.org/packages/08/4e/3b50fa3b1e045793056ed5a1fc6f89dd897ff9cb00900ca6377fe552d442/numpy-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8d5f8a8e3bc87334f025194c6193e408903d21ebaeb10952264943a985066ca", size = 13984256 },
|
519 |
+
{ url = "https://files.pythonhosted.org/packages/d9/37/108d692f7e2544b9ae972c7bfa06c26717871c273ccec86470bc3132b04d/numpy-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d51fc141ddbe3f919e91a096ec739f49d686df8af254b2053ba21a910ae518bf", size = 16337778 },
|
520 |
+
{ url = "https://files.pythonhosted.org/packages/95/2d/df81a1be3be6d3a92fd12dfd6c26a0dc026b276136ec1056562342a484a2/numpy-2.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:98ce7fb5b8063cfdd86596b9c762bf2b5e35a2cdd7e967494ab78a1fa7f8b86e", size = 16710448 },
|
521 |
+
{ url = "https://files.pythonhosted.org/packages/8f/34/4b2e604c5c44bd64b6c85e89d88871b41e60233b3ddf97419b37ae5b0c72/numpy-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24c2ad697bd8593887b019817ddd9974a7f429c14a5469d7fad413f28340a6d2", size = 14489002 },
|
522 |
+
{ url = "https://files.pythonhosted.org/packages/9f/0d/67c04b6bfefd0abbe7f60f7e4f11e3aca15d688faec1d1df089966105a9a/numpy-2.1.1-cp311-cp311-win32.whl", hash = "sha256:397bc5ce62d3fb73f304bec332171535c187e0643e176a6e9421a6e3eacef06d", size = 6533215 },
|
523 |
+
{ url = "https://files.pythonhosted.org/packages/94/7a/4c00332a3ca79702bbc86228afd0e84e6f91b47222ec8cdf00677dd16481/numpy-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:ae8ce252404cdd4de56dcfce8b11eac3c594a9c16c231d081fb705cf23bd4d9e", size = 12870550 },
|
524 |
+
{ url = "https://files.pythonhosted.org/packages/36/11/c573ef66c004f991989c2c6218229d9003164525549409aec5ec9afc0285/numpy-2.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c803b7934a7f59563db459292e6aa078bb38b7ab1446ca38dd138646a38203e", size = 20884403 },
|
525 |
+
{ url = "https://files.pythonhosted.org/packages/6b/6c/a9fbef5fd2f9685212af2a9e47485cde9357c3e303e079ccf85127516f2d/numpy-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6435c48250c12f001920f0751fe50c0348f5f240852cfddc5e2f97e007544cbe", size = 13493375 },
|
526 |
+
{ url = "https://files.pythonhosted.org/packages/34/f2/1316a6b08ad4c161d793abe81ff7181e9ae2e357a5b06352a383b9f8e800/numpy-2.1.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3269c9eb8745e8d975980b3a7411a98976824e1fdef11f0aacf76147f662b15f", size = 5088823 },
|
527 |
+
{ url = "https://files.pythonhosted.org/packages/be/15/fabf78a6d4a10c250e87daf1cd901af05e71501380532ac508879cc46a7e/numpy-2.1.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:fac6e277a41163d27dfab5f4ec1f7a83fac94e170665a4a50191b545721c6521", size = 6619825 },
|
528 |
+
{ url = "https://files.pythonhosted.org/packages/9f/8a/76ddef3e621541ddd6984bc24d256a4e3422d036790cbbe449e6cad439ee/numpy-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fcd8f556cdc8cfe35e70efb92463082b7f43dd7e547eb071ffc36abc0ca4699b", size = 13696705 },
|
529 |
+
{ url = "https://files.pythonhosted.org/packages/cb/22/2b840d297183916a95847c11f82ae11e248fa98113490b2357f774651e1d/numpy-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b9cd92c8f8e7b313b80e93cedc12c0112088541dcedd9197b5dee3738c1201", size = 16041649 },
|
530 |
+
{ url = "https://files.pythonhosted.org/packages/c7/e8/6f4825d8f576cfd5e4d6515b9eec22bd618868bdafc8a8c08b446dcb65f0/numpy-2.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:afd9c680df4de71cd58582b51e88a61feed4abcc7530bcd3d48483f20fc76f2a", size = 16409358 },
|
531 |
+
{ url = "https://files.pythonhosted.org/packages/bf/f8/5edf1105b0dc24fd66fc3e9e7f3bca3d920cde571caaa4375ec1566073c3/numpy-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8661c94e3aad18e1ea17a11f60f843a4933ccaf1a25a7c6a9182af70610b2313", size = 14172488 },
|
532 |
+
{ url = "https://files.pythonhosted.org/packages/f4/c2/dddca3e69a024d2f249a5b68698328163cbdafb7e65fbf6d36373bbabf12/numpy-2.1.1-cp312-cp312-win32.whl", hash = "sha256:950802d17a33c07cba7fd7c3dcfa7d64705509206be1606f196d179e539111ed", size = 6237195 },
|
533 |
+
{ url = "https://files.pythonhosted.org/packages/b7/98/5640a09daa3abf0caeaefa6e7bf0d10c0aa28a77c84e507d6a716e0e23df/numpy-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:3fc5eabfc720db95d68e6646e88f8b399bfedd235994016351b1d9e062c4b270", size = 12568082 },
|
534 |
+
{ url = "https://files.pythonhosted.org/packages/6b/9e/8bc6f133bc6d359ccc9ec051853aded45504d217685191f31f46d36b7065/numpy-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:046356b19d7ad1890c751b99acad5e82dc4a02232013bd9a9a712fddf8eb60f5", size = 20834810 },
|
535 |
+
{ url = "https://files.pythonhosted.org/packages/32/1b/429519a2fa28681814c511574017d35f3aab7136d554cc65f4c1526dfbf5/numpy-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6e5a9cb2be39350ae6c8f79410744e80154df658d5bea06e06e0ac5bb75480d5", size = 13507739 },
|
536 |
+
{ url = "https://files.pythonhosted.org/packages/25/18/c732d7dd9896d11e4afcd487ac65e62f9fa0495563b7614eb850765361fa/numpy-2.1.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:d4c57b68c8ef5e1ebf47238e99bf27657511ec3f071c465f6b1bccbef12d4136", size = 5074465 },
|
537 |
+
{ url = "https://files.pythonhosted.org/packages/3e/37/838b7ae9262c370ab25312bab365492016f11810ffc03ebebbd54670b669/numpy-2.1.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:8ae0fd135e0b157365ac7cc31fff27f07a5572bdfc38f9c2d43b2aff416cc8b0", size = 6606418 },
|
538 |
+
{ url = "https://files.pythonhosted.org/packages/8b/b9/7ff3bfb71e316a5b43a124c4b7a5881ab12f3c32636014bef1f757f19dbd/numpy-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:981707f6b31b59c0c24bcda52e5605f9701cb46da4b86c2e8023656ad3e833cb", size = 13692464 },
|
539 |
+
{ url = "https://files.pythonhosted.org/packages/42/78/75bcf16e6737cd196ff7ecf0e1fd3f953293a34dff4fd93fb488e8308536/numpy-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ca4b53e1e0b279142113b8c5eb7d7a877e967c306edc34f3b58e9be12fda8df", size = 16037763 },
|
540 |
+
{ url = "https://files.pythonhosted.org/packages/23/99/36bf5ffe034d06df307bc783e25cf164775863166dcd878879559fe0379f/numpy-2.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e097507396c0be4e547ff15b13dc3866f45f3680f789c1a1301b07dadd3fbc78", size = 16410374 },
|
541 |
+
{ url = "https://files.pythonhosted.org/packages/7f/16/04c5dab564887d4cd31a9ed30e51467fa70d52a4425f5a9bd1eed5b3d34c/numpy-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7506387e191fe8cdb267f912469a3cccc538ab108471291636a96a54e599556", size = 14169873 },
|
542 |
+
{ url = "https://files.pythonhosted.org/packages/09/e0/d1b5adbf1731886c4186c59a9fa208585df9452a43a2b60e79af7c649717/numpy-2.1.1-cp313-cp313-win32.whl", hash = "sha256:251105b7c42abe40e3a689881e1793370cc9724ad50d64b30b358bbb3a97553b", size = 6234118 },
|
543 |
+
{ url = "https://files.pythonhosted.org/packages/d0/9c/2391ee6e9ebe77232ddcab29d92662b545e99d78c3eb3b4e26d59b9ca1ca/numpy-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:f212d4f46b67ff604d11fff7cc62d36b3e8714edf68e44e9760e19be38c03eb0", size = 12561742 },
|
544 |
+
{ url = "https://files.pythonhosted.org/packages/38/0e/c4f754f9e73f9bb520e8bf418c646f2c4f70c5d5f2bc561e90f884593193/numpy-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:920b0911bb2e4414c50e55bd658baeb78281a47feeb064ab40c2b66ecba85553", size = 20858403 },
|
545 |
+
{ url = "https://files.pythonhosted.org/packages/32/fc/d69092b9171efa0cb8079577e71ce0cac0e08f917d33f6e99c916ed51d44/numpy-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:bab7c09454460a487e631ffc0c42057e3d8f2a9ddccd1e60c7bb8ed774992480", size = 13519851 },
|
546 |
+
{ url = "https://files.pythonhosted.org/packages/14/2a/d7cf2cd9f15b23f623075546ea64a2c367cab703338ca22aaaecf7e704df/numpy-2.1.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:cea427d1350f3fd0d2818ce7350095c1a2ee33e30961d2f0fef48576ddbbe90f", size = 5115444 },
|
547 |
+
{ url = "https://files.pythonhosted.org/packages/8e/00/e87b2cb4afcecca3b678deefb8fa53005d7054f3b5c39596e5554e5d98f8/numpy-2.1.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:e30356d530528a42eeba51420ae8bf6c6c09559051887196599d96ee5f536468", size = 6628903 },
|
548 |
+
{ url = "https://files.pythonhosted.org/packages/ab/9d/337ae8721b3beec48c3413d71f2d44b2defbf3c6f7a85184fc18b7b61f4a/numpy-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8dfa9e94fc127c40979c3eacbae1e61fda4fe71d84869cc129e2721973231ef", size = 13665945 },
|
549 |
+
{ url = "https://files.pythonhosted.org/packages/c0/90/ee8668e84c5d5cc080ef3beb622c016adf19ca3aa51afe9dbdcc6a9baf59/numpy-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910b47a6d0635ec1bd53b88f86120a52bf56dcc27b51f18c7b4a2e2224c29f0f", size = 16023473 },
|
550 |
+
{ url = "https://files.pythonhosted.org/packages/38/a0/57c24b2131879183051dc698fbb53fd43b77c3fa85b6e6311014f2bc2973/numpy-2.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:13cc11c00000848702322af4de0147ced365c81d66053a67c2e962a485b3717c", size = 16400624 },
|
551 |
+
{ url = "https://files.pythonhosted.org/packages/bb/4c/14a41eb5c9548c6cee6af0936eabfd985c69230ffa2f2598321431a9aa0a/numpy-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53e27293b3a2b661c03f79aa51c3987492bd4641ef933e366e0f9f6c9bf257ec", size = 14155072 },
|
552 |
+
]
|
553 |
+
|
554 |
[[package]]
|
555 |
name = "oauthlib"
|
556 |
version = "3.2.2"
|
|
|
569 |
{ url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 },
|
570 |
]
|
571 |
|
572 |
+
[[package]]
|
573 |
+
name = "pandas"
|
574 |
+
version = "2.2.2"
|
575 |
+
source = { registry = "https://pypi.org/simple" }
|
576 |
+
dependencies = [
|
577 |
+
{ name = "numpy" },
|
578 |
+
{ name = "python-dateutil" },
|
579 |
+
{ name = "pytz" },
|
580 |
+
{ name = "tzdata" },
|
581 |
+
]
|
582 |
+
sdist = { url = "https://files.pythonhosted.org/packages/88/d9/ecf715f34c73ccb1d8ceb82fc01cd1028a65a5f6dbc57bfa6ea155119058/pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54", size = 4398391 }
|
583 |
+
wheels = [
|
584 |
+
{ url = "https://files.pythonhosted.org/packages/1b/70/61704497903d43043e288017cb2b82155c0d41e15f5c17807920877b45c2/pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288", size = 12574808 },
|
585 |
+
{ url = "https://files.pythonhosted.org/packages/16/c6/75231fd47afd6b3f89011e7077f1a3958441264aca7ae9ff596e3276a5d0/pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151", size = 11304876 },
|
586 |
+
{ url = "https://files.pythonhosted.org/packages/97/2d/7b54f80b93379ff94afb3bd9b0cd1d17b48183a0d6f98045bc01ce1e06a7/pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b", size = 15602548 },
|
587 |
+
{ url = "https://files.pythonhosted.org/packages/fc/a5/4d82be566f069d7a9a702dcdf6f9106df0e0b042e738043c0cc7ddd7e3f6/pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee", size = 13031332 },
|
588 |
+
{ url = "https://files.pythonhosted.org/packages/92/a2/b79c48f530673567805e607712b29814b47dcaf0d167e87145eb4b0118c6/pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db", size = 16286054 },
|
589 |
+
{ url = "https://files.pythonhosted.org/packages/40/c7/47e94907f1d8fdb4868d61bd6c93d57b3784a964d52691b77ebfdb062842/pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1", size = 13879507 },
|
590 |
+
{ url = "https://files.pythonhosted.org/packages/ab/63/966db1321a0ad55df1d1fe51505d2cdae191b84c907974873817b0a6e849/pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24", size = 11634249 },
|
591 |
+
{ url = "https://files.pythonhosted.org/packages/dd/49/de869130028fb8d90e25da3b7d8fb13e40f5afa4c4af1781583eb1ff3839/pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef", size = 12500886 },
|
592 |
+
{ url = "https://files.pythonhosted.org/packages/db/7c/9a60add21b96140e22465d9adf09832feade45235cd22f4cb1668a25e443/pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce", size = 11340320 },
|
593 |
+
{ url = "https://files.pythonhosted.org/packages/b0/85/f95b5f322e1ae13b7ed7e97bd999160fa003424711ab4dc8344b8772c270/pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad", size = 15204346 },
|
594 |
+
{ url = "https://files.pythonhosted.org/packages/40/10/79e52ef01dfeb1c1ca47a109a01a248754ebe990e159a844ece12914de83/pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad", size = 12733396 },
|
595 |
+
{ url = "https://files.pythonhosted.org/packages/35/9d/208febf8c4eb5c1d9ea3314d52d8bd415fd0ef0dd66bb24cc5bdbc8fa71a/pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76", size = 15858913 },
|
596 |
+
{ url = "https://files.pythonhosted.org/packages/99/d1/2d9bd05def7a9e08a92ec929b5a4c8d5556ec76fae22b0fa486cbf33ea63/pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32", size = 13417786 },
|
597 |
+
{ url = "https://files.pythonhosted.org/packages/22/a5/a0b255295406ed54269814bc93723cfd1a0da63fb9aaf99e1364f07923e5/pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23", size = 11498828 },
|
598 |
+
]
|
599 |
+
|
600 |
[[package]]
|
601 |
name = "parso"
|
602 |
version = "0.8.4"
|
|
|
780 |
{ url = "https://files.pythonhosted.org/packages/3d/47/444768600d9e0ebc82f8e347775d24aef8f6348cf00e9fa0e81910814e6d/python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215", size = 22299 },
|
781 |
]
|
782 |
|
783 |
+
[[package]]
|
784 |
+
name = "pytz"
|
785 |
+
version = "2024.1"
|
786 |
+
source = { registry = "https://pypi.org/simple" }
|
787 |
+
sdist = { url = "https://files.pythonhosted.org/packages/90/26/9f1f00a5d021fff16dee3de13d43e5e978f3d58928e129c3a62cf7eb9738/pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812", size = 316214 }
|
788 |
+
wheels = [
|
789 |
+
{ url = "https://files.pythonhosted.org/packages/9c/3d/a121f284241f08268b21359bd425f7d4825cffc5ac5cd0e1b3d82ffd2b10/pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319", size = 505474 },
|
790 |
+
]
|
791 |
+
|
792 |
[[package]]
|
793 |
name = "pywin32"
|
794 |
version = "306"
|
|
|
1030 |
[package.dev-dependencies]
|
1031 |
dev = [
|
1032 |
{ name = "ipykernel" },
|
1033 |
+
{ name = "lxml" },
|
1034 |
+
{ name = "pandas" },
|
1035 |
{ name = "pytest" },
|
1036 |
{ name = "pytest-cov" },
|
1037 |
{ name = "ruff" },
|
|
|
1043 |
[package.metadata.requires-dev]
|
1044 |
dev = [
|
1045 |
{ name = "ipykernel", specifier = ">=6.29.5" },
|
1046 |
+
{ name = "lxml", specifier = ">=5.3.0" },
|
1047 |
+
{ name = "pandas", specifier = ">=2.2.2" },
|
1048 |
{ name = "pytest", specifier = ">=8.3.2" },
|
1049 |
{ name = "pytest-cov", specifier = ">=5.0.0" },
|
1050 |
{ name = "ruff", specifier = ">=0.6.3" },
|
|
|
1059 |
{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
|
1060 |
]
|
1061 |
|
1062 |
+
[[package]]
|
1063 |
+
name = "tzdata"
|
1064 |
+
version = "2024.1"
|
1065 |
+
source = { registry = "https://pypi.org/simple" }
|
1066 |
+
sdist = { url = "https://files.pythonhosted.org/packages/74/5b/e025d02cb3b66b7b76093404392d4b44343c69101cc85f4d180dd5784717/tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd", size = 190559 }
|
1067 |
+
wheels = [
|
1068 |
+
{ url = "https://files.pythonhosted.org/packages/65/58/f9c9e6be752e9fcb8b6a0ee9fb87e6e7a1f6bcab2cdc73f02bb7ba91ada0/tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252", size = 345370 },
|
1069 |
+
]
|
1070 |
+
|
1071 |
[[package]]
|
1072 |
name = "uvicorn"
|
1073 |
version = "0.30.6"
|