Merge pull request #4 from genai-impact/feat/upgrade-ecologits-0.9
Browse files- app.py +1 -4
- assets/logo.png +0 -0
- data/electricity_mix.csv +0 -4
- pyproject.toml +9 -1
- src/__init__.py +1 -1
- src/calculator.py +111 -99
- src/constants.py +34 -63
- src/content.py +48 -54
- src/data/electricity_mix.csv +0 -4
- src/data/throughputs.json +244 -0
- src/electricity_mix.py +61 -161
- src/expert.py +115 -76
- src/impacts.py +26 -24
- src/latency_estimator.py +33 -0
- src/models.py +70 -7
- src/style.css +1 -1
- src/utils.py +97 -122
- uv.lock +160 -192
app.py
CHANGED
|
@@ -6,7 +6,6 @@ from src.content import (
|
|
| 6 |
CITATION_LABEL,
|
| 7 |
CITATION_TEXT,
|
| 8 |
LICENCE_TEXT,
|
| 9 |
-
INTRO_TEXT,
|
| 10 |
METHODOLOGY_TEXT,
|
| 11 |
SUPPORT_TEXT,
|
| 12 |
)
|
|
@@ -15,15 +14,13 @@ from src.expert import expert_mode
|
|
| 15 |
from src.calculator import calculator_mode
|
| 16 |
from src.token_estimator import token_estimator
|
| 17 |
|
| 18 |
-
st.set_page_config(layout="wide", page_title="
|
| 19 |
|
| 20 |
with open("src/style.css") as css:
|
| 21 |
st.markdown(f"<style>{css.read()}</style>", unsafe_allow_html=True)
|
| 22 |
|
| 23 |
st.html(HERO_TEXT)
|
| 24 |
|
| 25 |
-
st.success(INTRO_TEXT, icon="🌱")
|
| 26 |
-
|
| 27 |
tab_calculator, tab_expert, tab_token, tab_method, tab_about, tab_support = st.tabs(
|
| 28 |
[
|
| 29 |
"🧮 Calculator",
|
|
|
|
| 6 |
CITATION_LABEL,
|
| 7 |
CITATION_TEXT,
|
| 8 |
LICENCE_TEXT,
|
|
|
|
| 9 |
METHODOLOGY_TEXT,
|
| 10 |
SUPPORT_TEXT,
|
| 11 |
)
|
|
|
|
| 14 |
from src.calculator import calculator_mode
|
| 15 |
from src.token_estimator import token_estimator
|
| 16 |
|
| 17 |
+
st.set_page_config(layout="wide", page_title="EcoLogits Calculator", page_icon="🧮")
|
| 18 |
|
| 19 |
with open("src/style.css") as css:
|
| 20 |
st.markdown(f"<style>{css.read()}</style>", unsafe_allow_html=True)
|
| 21 |
|
| 22 |
st.html(HERO_TEXT)
|
| 23 |
|
|
|
|
|
|
|
| 24 |
tab_calculator, tab_expert, tab_token, tab_method, tab_about, tab_support = st.tabs(
|
| 25 |
[
|
| 26 |
"🧮 Calculator",
|
assets/logo.png
ADDED
|
data/electricity_mix.csv
DELETED
|
@@ -1,4 +0,0 @@
|
|
| 1 |
-
name,unit,source,WOR,EEE,ZWE,ZMB,ZAF,YEM,VNM,VEN,UZB,URY,USA,UKR,TZA,TWN,TTO,TUR,TUN,TKM,TJK,THA,TGO,SYR,SLV,SEN,SVK,SVN,SGP,SWE,SDN,SAU,RUS,SCG,ROU,QAT,PRY,PRT,POL,PAK,PHL,PER,PAN,OMN,NZL,NPL,NOR,NLD,NIC,NGA,NAM,MOZ,MYS,MEX,MLT,MNG,MMR,MKD,MDA,MAR,LBY,LVA,LUX,LTU,LKA,LBN,KAZ,KWT,KOR,PRK,KHM,KGZ,KEN,JPN,JOR,JAM,ITA,ISL,IRN,IRQ,IND,ISR,IRL,IDN,HUN,HTI,HRV,HND,HKG,GTM,GRC,GIB,GHA,GEO,GBR,GAB,FRA,FIN,ETH,ESP,ERI,EGY,EST,ECU,DZA,DOM,DNK,DEU,CZE,CYP,CUB,CRI,COL,CHN,CMR,CHL,CIV,CHE,COG,COD,CAN,BLR,BWA,BRA,BOL,BRN,BEN,BHR,BGR,BEL,BGD,BIH,AZE,AUS,AUT,ARG,AGO,ANT,ARM,ALB,ARE
|
| 2 |
-
adpe,kg éq. Sb,ADEME Base IMPACTS ®,0.0000000737708,0.0000000642317,0.000000109502,0.000000162193,0.0000000862445,0.0000000163908,0.0000000945573,0.000000112811,0.000000103681,0.000000104586,0.0000000985548,0.0000000647907,0.000000132261,0.0000000578088,0.000000064552,0.0000000749765,0.0000000177021,0.000000131822,0.000000152621,0.0000000569593,0.000000134255,0.0000000268396,0.0000000472135,0.0000000470662,0.0000000606109,0.0000000992283,0.0000000198459,0.0000000777062,0.0000000955701,0.0000000134206,0.0000000960312,0.000000132772,0.0000000981761,0.00000001324,0.000000149181,0.0000000341863,0.000000101946,0.0000000842952,0.0000000595304,0.0000000952688,0.0000000790553,0.0000000374073,0.0000000720474,0.000000238273,0.000000127486,0.0000000329318,0.0000000414983,0.0000000621,0.000000128285,0.000000148382,0.000000044938,0.0000000578358,0.000000049475,0.000000176361,0.000000152699,0.000000119873,0.000000110674,0.0000000641089,0.0000000206592,0.000000153757,0.000000105692,0.0000000294596,0.0000000986932,0.0000000182134,0.000000135386,0.0000000141168,0.0000000518017,0.000000117457,0.0000000319202,0.000000181827,0.0000000958533,0.0000000596578,0.0000000147031,0.0000000196047,0.00000005439,0.0000000781905,0.0000000220304,0.0000000404306,0.000000100099,0.0000000610194,0.0000000219257,0.0000000610451,0.0000000644587,0.0000000937057,0.000000153989,0.0000000649373,0.0000000816213,0.0000000803251,0.0000000691645,0.0000000286211,0.000000156003,0.000000137999,0.0000000370973,0.000000113843,0.0000000485798,0.0000000805114,0.000000174161,0.0000000518326,0.0000000512406,0.000000033925,0.0000000990171,0.000000127168,0.0000000216438,0.0000000429285,0.0000000157411,0.0000000878733,0.0000000817565,0.0000000448771,0.0000000299542,0.0000000863908,0.000000122031,0.0000000851552,0.000000146313,0.000000105851,0.0000000949004,0.000000100467,0.000000265575,0.000000174647,0.0000000993179,0.0000000840478,0.0000000866014,0.00000010962,0.0000000969793,0.0000000185641,0.0000000239702,0.0000000135014,0.0000000823611,0.0000000337201,0.0000000394158,0.000000148007,0.000000092567,0.0000000790846,0.000000141124,0.0000000768612,0.000000124074,0.0000000449103,0.0000000854245,0.000000229556,0.0000000141548
|
| 3 |
-
pe,MJ,ADPf / (1-%renewable_energy),9.988,12.873,16.122,1.798,11.732,16.250,11.238,15.163,17.367,107.570,11.358,12.936,9.305,11.439,14.289,16.150,12.902,23.300,19.165,10.414,21.978,16.989,13.012,14.516,11.680,12.146,10.477,11.026,29.629,14.058,13.200,14.242,15.585,11.916,0.020,14.153,13.178,16.175,11.120,8.211,16.364,22.306,24.731,0.396,4.952,8.511,24.696,11.279,468.150,0.206,12.268,11.775,19.374,15.114,14.132,19.120,18.429,11.702,19.116,8.249,10.128,21.043,12.116,12.341,13.260,12.753,10.199,32.793,34.655,15.380,68.996,10.718,13.677,14.799,12.656,0.013,15.022,20.372,20.363,10.023,10.706,11.603,11.784,20.167,18.548,15.762,,14.340,14.487,,10.097,10.425,13.579,28.341,11.289,11.275,36.133,12.090,13.289,10.195,16.334,20.908,16.376,12.412,16.824,16.260,12.517,13.118,17.317,45.996,7.312,14.119,10.807,11.348,14.783,11.782,34.147,0.097,11.987,13.194,19.642,9.031,11.587,15.689,14.337,14.036,14.375,10.776,12.935,21.705,12.831,16.908,11.036,10.049,16.972,,13.380,0.201,19.032
|
| 4 |
-
gwp,kg éq. CO2,ADEME Base IMPACTS ®,0.590478,0.509427,0.842811,0.0141304,1.17562,1.06777,0.555572,0.497373,0.81178,0.296953,0.67978,0.646745,0.475635,0.845351,0.933059,0.706988,0.80722,1.38296,0.0426743,0.646174,0.545455,1.08778,0.473128,1.1195,0.309341,0.498523,0.655825,0.0464664,1.12472,0.913677,0.66131,1.07808,0.664245,0.722125,0.241601,0.571172,1.15075,0.748727,0.761317,0.284364,0.53403,1.41292,0.293397,0.0841323,0.023754,0.544803,0.941626,0.693123,0.357253,0.00880732,0.832206,0.739214,1.31149,1.47192,0.48193,1.24074,1.04213,0.933694,1.35361,0.234273,0.490016,0.154229,0.709185,0.883627,1.128,0.885084,0.599585,0.797361,1.41054,0.156039,0.589603,0.540891,0.781372,1.07345,0.621329,0.0194609,0.930385,1.48728,1.58299,0.901842,0.648118,0.875394,0.541558,1.3858,0.535759,0.692837,0.95888,0.645801,1.13127,0.977477,0.540126,0.132046,0.602137,0.732511,0.0813225,0.322068,0.251299,0.467803,1.13153,0.587775,1.51492,0.627714,1.02318,0.909252,0.633534,0.657374,0.799077,0.978041,1.28325,0.224471,0.214014,1.05738,0.456622,0.574415,0.928583,0.0448568,0.904053,0.0613102,0.238191,0.795697,2.12572,0.278647,0.585131,0.997577,1.19128,0.804567,0.827087,0.256537,0.795168,1.56025,0.726126,1.12326,0.245573,0.476811,0.412014,1.13161,0.252002,0.0207635,1.09088
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pyproject.toml
CHANGED
|
@@ -5,9 +5,17 @@ description = "Add your description here"
|
|
| 5 |
readme = "README.md"
|
| 6 |
requires-python = ">=3.11"
|
| 7 |
dependencies = [
|
| 8 |
-
"ecologits>=0.
|
| 9 |
"pint>=0.24.4",
|
| 10 |
"plotly>=6.2.0",
|
| 11 |
"streamlit>=1.47.1",
|
| 12 |
"tiktoken>=0.9.0",
|
| 13 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
readme = "README.md"
|
| 6 |
requires-python = ">=3.11"
|
| 7 |
dependencies = [
|
| 8 |
+
"ecologits>=0.9.0,<0.10.0",
|
| 9 |
"pint>=0.24.4",
|
| 10 |
"plotly>=6.2.0",
|
| 11 |
"streamlit>=1.47.1",
|
| 12 |
"tiktoken>=0.9.0",
|
| 13 |
]
|
| 14 |
+
|
| 15 |
+
[tool.uv.sources]
|
| 16 |
+
ecologits = { git = "https://github.com/genai-impact/ecologits" }
|
| 17 |
+
|
| 18 |
+
[dependency-groups]
|
| 19 |
+
dev = [
|
| 20 |
+
"watchdog>=6.0.0",
|
| 21 |
+
]
|
src/__init__.py
CHANGED
|
@@ -4,6 +4,6 @@ from .expert import expert_mode
|
|
| 4 |
from .token_estimator import token_estimator
|
| 5 |
from .utils import *
|
| 6 |
from .calculator import calculator_mode
|
| 7 |
-
from .impacts import
|
| 8 |
from .models import load_models
|
| 9 |
from .electricity_mix import *
|
|
|
|
| 4 |
from .token_estimator import token_estimator
|
| 5 |
from .utils import *
|
| 6 |
from .calculator import calculator_mode
|
| 7 |
+
from .impacts import display_impacts
|
| 8 |
from .models import load_models
|
| 9 |
from .electricity_mix import *
|
src/calculator.py
CHANGED
|
@@ -1,99 +1,111 @@
|
|
| 1 |
-
import
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
from
|
| 5 |
-
from src.
|
| 6 |
-
from src.
|
| 7 |
-
from src.
|
| 8 |
-
|
| 9 |
-
from src.
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
(df["provider_clean"] == provider) & (df["name_clean"] == model)
|
| 52 |
-
]
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
with st.container(border=True):
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import math
|
| 2 |
+
import streamlit as st
|
| 3 |
+
|
| 4 |
+
from ecologits.tracers.utils import llm_impacts
|
| 5 |
+
from src.impacts import display_impacts, display_equivalent_ghg, display_equivalent_energy
|
| 6 |
+
from src.latency_estimator import latency_estimator
|
| 7 |
+
from src.utils import format_impacts
|
| 8 |
+
from src.content import WARNING_CLOSED_SOURCE, WARNING_MULTI_MODAL, WARNING_BOTH, HOW_TO_TEXT
|
| 9 |
+
from src.models import load_models
|
| 10 |
+
|
| 11 |
+
from src.constants import PROMPTS
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def calculator_mode():
|
| 15 |
+
|
| 16 |
+
st.expander("How to use this calculator?", expanded = False).markdown(HOW_TO_TEXT)
|
| 17 |
+
|
| 18 |
+
with st.container(border=True):
|
| 19 |
+
df = load_models(filter_main=True)
|
| 20 |
+
|
| 21 |
+
col1, col2, col3 = st.columns(3)
|
| 22 |
+
|
| 23 |
+
with col1:
|
| 24 |
+
providers_clean = [x for x in df["provider_clean"].unique()]
|
| 25 |
+
provider = st.selectbox(
|
| 26 |
+
label="Provider",
|
| 27 |
+
options=providers_clean,
|
| 28 |
+
index=providers_clean.index("OpenAI"),
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
with col2:
|
| 32 |
+
models_clean = [
|
| 33 |
+
x
|
| 34 |
+
for x in df["name_clean"].unique()
|
| 35 |
+
if x in df[df["provider_clean"] == provider]["name_clean"].unique()
|
| 36 |
+
]
|
| 37 |
+
model = st.selectbox(
|
| 38 |
+
label="Model",
|
| 39 |
+
options=models_clean,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
with col3:
|
| 43 |
+
output_tokens = st.selectbox(
|
| 44 |
+
label="Example prompt",
|
| 45 |
+
options=[x[0] for x in PROMPTS],
|
| 46 |
+
index=2
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
# WARNING DISPLAY
|
| 50 |
+
provider_raw = df[
|
| 51 |
+
(df["provider_clean"] == provider) & (df["name_clean"] == model)
|
| 52 |
+
]["provider"].values[0]
|
| 53 |
+
model_raw = df[
|
| 54 |
+
(df["provider_clean"] == provider) & (df["name_clean"] == model)
|
| 55 |
+
]["name"].values[0]
|
| 56 |
+
|
| 57 |
+
df_filtered = df[
|
| 58 |
+
(df["provider_clean"] == provider) & (df["name_clean"] == model)
|
| 59 |
+
]
|
| 60 |
+
|
| 61 |
+
if (
|
| 62 |
+
df_filtered["warning_arch"].values[0]
|
| 63 |
+
and not df_filtered["warning_multi_modal"].values[0]
|
| 64 |
+
):
|
| 65 |
+
st.warning(WARNING_CLOSED_SOURCE, icon="⚠️")
|
| 66 |
+
if (
|
| 67 |
+
df_filtered["warning_multi_modal"].values[0]
|
| 68 |
+
and not df_filtered["warning_arch"].values[0]
|
| 69 |
+
):
|
| 70 |
+
st.warning(WARNING_MULTI_MODAL, icon="⚠️")
|
| 71 |
+
if (
|
| 72 |
+
df_filtered["warning_arch"].values[0]
|
| 73 |
+
and df_filtered["warning_multi_modal"].values[0]
|
| 74 |
+
):
|
| 75 |
+
st.warning(WARNING_BOTH, icon="⚠️")
|
| 76 |
+
|
| 77 |
+
try:
|
| 78 |
+
output_tokens_count = [x[1] for x in PROMPTS if x[0] == output_tokens][0]
|
| 79 |
+
estimated_latency = latency_estimator.estimate(provider=provider_raw,
|
| 80 |
+
model_name=model_raw,
|
| 81 |
+
output_tokens=output_tokens_count)
|
| 82 |
+
impacts = llm_impacts(
|
| 83 |
+
provider=provider_raw,
|
| 84 |
+
model_name=model_raw,
|
| 85 |
+
output_token_count=output_tokens_count,
|
| 86 |
+
request_latency=estimated_latency
|
| 87 |
+
)
|
| 88 |
+
|
| 89 |
+
impacts, _, _ = format_impacts(impacts)
|
| 90 |
+
|
| 91 |
+
with st.container(border=True):
|
| 92 |
+
|
| 93 |
+
st.markdown('<h3 align = "center">Environmental impacts</h3>', unsafe_allow_html=True)
|
| 94 |
+
#st.markdown('<p align = "center">To understand how the environmental impacts are computed go to the 📖 Methodology tab.</p>', unsafe_allow_html=True)
|
| 95 |
+
display_impacts(impacts)
|
| 96 |
+
|
| 97 |
+
with st.container(border=False):
|
| 98 |
+
st.markdown('<h3 align = "center">Equivalences</h3>', unsafe_allow_html=True)
|
| 99 |
+
st.markdown('<p align = "center">Making this request to the LLM is equivalent to the following actions :</p>', unsafe_allow_html=True)
|
| 100 |
+
page = st.radio(' ', ['Energy' , 'GHG'], horizontal=True)
|
| 101 |
+
|
| 102 |
+
with st.container(border=True):
|
| 103 |
+
if page == 'Energy' :
|
| 104 |
+
display_equivalent_energy(impacts)
|
| 105 |
+
else :
|
| 106 |
+
display_equivalent_ghg(impacts)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
except Exception as e:
|
| 110 |
+
st.error('Could not find the model in the repository. Please try another model.')
|
| 111 |
+
raise e
|
src/constants.py
CHANGED
|
@@ -11,7 +11,6 @@ PROMPTS = [(s + f" ({v} output tokens)", v) for (s, v) in PROMPTS]
|
|
| 11 |
MODEL_REPOSITORY_URL = "https://raw.githubusercontent.com/genai-impact/ecologits/refs/heads/main/ecologits/data/models.json"
|
| 12 |
|
| 13 |
main_models_openai = [
|
| 14 |
-
"chatgpt-4o-latest",
|
| 15 |
"gpt-3.5-turbo",
|
| 16 |
"gpt-4",
|
| 17 |
"gpt-4-turbo",
|
|
@@ -19,93 +18,65 @@ main_models_openai = [
|
|
| 19 |
"gpt-4o-mini",
|
| 20 |
"o1",
|
| 21 |
"o1-mini",
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
"
|
| 26 |
-
"
|
| 27 |
-
"
|
| 28 |
-
"
|
| 29 |
-
"
|
| 30 |
-
"meta-llama/Meta-Llama-3-70B",
|
| 31 |
-
"meta-llama/Llama-2-7b",
|
| 32 |
-
"meta-llama/Llama-2-13b",
|
| 33 |
-
"meta-llama/Llama-2-70b",
|
| 34 |
-
"meta-llama/CodeLlama-7b-hf",
|
| 35 |
-
"meta-llama/CodeLlama-13b-hf",
|
| 36 |
-
"meta-llama/CodeLlama-34b-hf",
|
| 37 |
-
"meta-llama/CodeLlama-70b-hf",
|
| 38 |
-
]
|
| 39 |
-
|
| 40 |
-
main_models_msft = [
|
| 41 |
-
"microsoft/phi-1",
|
| 42 |
-
"microsoft/phi-1_5",
|
| 43 |
-
"microsoft/Phi-3-mini-128k-instruct",
|
| 44 |
-
"microsoft/Phi-3-small-128k-instruct",
|
| 45 |
-
"microsoft/Phi-3-medium-128k-instruct",
|
| 46 |
]
|
| 47 |
|
| 48 |
main_models_anthropic = [
|
| 49 |
-
"claude-2.0",
|
| 50 |
-
"claude-2.1",
|
| 51 |
"claude-3-5-haiku-latest",
|
| 52 |
"claude-3-5-sonnet-latest",
|
| 53 |
"claude-3-7-sonnet-latest",
|
| 54 |
-
"claude-
|
| 55 |
-
"claude-
|
| 56 |
-
"claude-
|
|
|
|
|
|
|
| 57 |
]
|
| 58 |
|
| 59 |
main_models_cohere = [
|
| 60 |
-
"
|
| 61 |
-
"c4ai-aya-expanse-32b",
|
| 62 |
-
"command",
|
| 63 |
-
"command-light",
|
| 64 |
"command-r",
|
| 65 |
-
"command-r-
|
|
|
|
|
|
|
| 66 |
]
|
| 67 |
|
| 68 |
main_models_google = [
|
| 69 |
-
"
|
| 70 |
-
"google/gemma-2-9b",
|
| 71 |
-
"google/gemma-2-27b",
|
| 72 |
-
"google/codegemma-2b",
|
| 73 |
-
"google/codegemma-7b",
|
| 74 |
-
"gemini-1.0-pro",
|
| 75 |
-
"gemini-1.5-pro",
|
| 76 |
-
"gemini-1.5-flash",
|
| 77 |
"gemini-2.0-flash",
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
"databricks/dolly-v1-6b",
|
| 82 |
-
"databricks/dolly-v2-12b",
|
| 83 |
-
"databricks/dolly-v2-7b",
|
| 84 |
-
"databricks/dolly-v2-3b",
|
| 85 |
-
"databricks/dbrx-base",
|
| 86 |
]
|
| 87 |
|
| 88 |
main_models_mistral = [
|
| 89 |
-
"
|
| 90 |
-
"
|
| 91 |
-
"
|
| 92 |
-
"
|
| 93 |
-
"
|
| 94 |
"ministral-3b-latest",
|
| 95 |
"ministral-8b-latest",
|
| 96 |
-
"mistral-tiny",
|
| 97 |
-
"mistral-small",
|
| 98 |
-
"mistral-medium",
|
| 99 |
"mistral-large-latest",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
]
|
| 101 |
|
| 102 |
MAIN_MODELS = (
|
| 103 |
-
|
| 104 |
-
+ main_models_openai
|
| 105 |
+ main_models_anthropic
|
| 106 |
+ main_models_cohere
|
| 107 |
-
+ main_models_msft
|
| 108 |
+ main_models_mistral
|
| 109 |
-
+ main_models_databricks
|
| 110 |
+ main_models_google
|
| 111 |
)
|
|
|
|
| 11 |
MODEL_REPOSITORY_URL = "https://raw.githubusercontent.com/genai-impact/ecologits/refs/heads/main/ecologits/data/models.json"
|
| 12 |
|
| 13 |
main_models_openai = [
|
|
|
|
| 14 |
"gpt-3.5-turbo",
|
| 15 |
"gpt-4",
|
| 16 |
"gpt-4-turbo",
|
|
|
|
| 18 |
"gpt-4o-mini",
|
| 19 |
"o1",
|
| 20 |
"o1-mini",
|
| 21 |
+
"o3-mini",
|
| 22 |
+
"gpt-4.1-nano",
|
| 23 |
+
"gpt-4.1-mini",
|
| 24 |
+
"gpt-4.1",
|
| 25 |
+
"o4-mini",
|
| 26 |
+
"gpt-5-nano",
|
| 27 |
+
"gpt-5-mini",
|
| 28 |
+
"gpt-5",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
]
|
| 30 |
|
| 31 |
main_models_anthropic = [
|
|
|
|
|
|
|
| 32 |
"claude-3-5-haiku-latest",
|
| 33 |
"claude-3-5-sonnet-latest",
|
| 34 |
"claude-3-7-sonnet-latest",
|
| 35 |
+
"claude-opus-4-0",
|
| 36 |
+
"claude-opus-4-1",
|
| 37 |
+
"claude-sonnet-4-0",
|
| 38 |
+
"claude-sonnet-4-5",
|
| 39 |
+
"claude-haiku-4-5"
|
| 40 |
]
|
| 41 |
|
| 42 |
main_models_cohere = [
|
| 43 |
+
"command-a-03-2025",
|
|
|
|
|
|
|
|
|
|
| 44 |
"command-r",
|
| 45 |
+
"command-r-08-2024",
|
| 46 |
+
"command-r-plus-08-2024",
|
| 47 |
+
"command-r7b-12-2024"
|
| 48 |
]
|
| 49 |
|
| 50 |
main_models_google = [
|
| 51 |
+
"gemini-2.0-flash-lite",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
"gemini-2.0-flash",
|
| 53 |
+
"gemini-2.5-flash-lite",
|
| 54 |
+
"gemini-2.5-flash",
|
| 55 |
+
"gemini-2.5-pro"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
]
|
| 57 |
|
| 58 |
main_models_mistral = [
|
| 59 |
+
"codestral-latest",
|
| 60 |
+
"devstral-medium-latest",
|
| 61 |
+
"devstral-small-latest",
|
| 62 |
+
"magistral-medium-latest",
|
| 63 |
+
"magistral-small-latest",
|
| 64 |
"ministral-3b-latest",
|
| 65 |
"ministral-8b-latest",
|
|
|
|
|
|
|
|
|
|
| 66 |
"mistral-large-latest",
|
| 67 |
+
"mistral-medium-latest",
|
| 68 |
+
"mistral-small-latest",
|
| 69 |
+
"mistral-tiny-latest",
|
| 70 |
+
"open-mistral-7b",
|
| 71 |
+
"open-mistral-nemo",
|
| 72 |
+
"open-mixtral-8x22b",
|
| 73 |
+
"open-mixtral-8x7b"
|
| 74 |
]
|
| 75 |
|
| 76 |
MAIN_MODELS = (
|
| 77 |
+
main_models_openai
|
|
|
|
| 78 |
+ main_models_anthropic
|
| 79 |
+ main_models_cohere
|
|
|
|
| 80 |
+ main_models_mistral
|
|
|
|
| 81 |
+ main_models_google
|
| 82 |
)
|
src/content.py
CHANGED
|
@@ -1,26 +1,20 @@
|
|
| 1 |
HERO_TEXT = """
|
| 2 |
-
<div align="center">
|
| 3 |
<a href="https://ecologits.ai/">
|
| 4 |
-
<img style="max-height: 200px" alt="EcoLogits" src="https://raw.githubusercontent.com/genai-impact/ecologits/main/
|
| 5 |
</a>
|
| 6 |
</div>
|
| 7 |
<div align="center">
|
| 8 |
<p style="max-width: 850px; text-align: left">
|
| 9 |
-
<b>EcoLogits</b> is
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
This Calculator allows a broader access to <b>EcoLogits</b> estimates through a visual application.</i>
|
| 13 |
-
|
| 14 |
</p>
|
| 15 |
|
| 16 |
</div>
|
| 17 |
<br>
|
| 18 |
"""
|
| 19 |
|
| 20 |
-
INTRO_TEXT = """
|
| 21 |
-
EcoLogits Calculator is developed and maintained by [GenAI Impact](https://genai-impact.org/) non-profit. To learn more about EcoLogits documentation visit [ecologits.ai](https://ecologits.ai).
|
| 22 |
-
"""
|
| 23 |
-
|
| 24 |
HOW_TO_TEXT = """
|
| 25 |
Chose a provider, a model and an example of usage (prompts).
|
| 26 |
|
|
@@ -74,7 +68,7 @@ When you're writing or interacting with an LLM, being aware of token count can h
|
|
| 74 |
"""
|
| 75 |
|
| 76 |
ABOUT_TEXT = r"""
|
| 77 |
-
|
| 78 |
|
| 79 |
**The main goal of the EcoLogits Calculator is to raise awareness on the environmental impacts of LLM inference.**
|
| 80 |
|
|
@@ -83,7 +77,7 @@ The rapid evolution of generative AI is reshaping numerous industries and aspect
|
|
| 83 |
At **[GenAI Impact](https://genai-impact.org/) we are dedicated to understanding and mitigating the environmental impacts of generative AI** through rigorous research, innovative tools, and community engagement. Especially, in early 2024 we have launched an new open-source tool called [EcoLogits](https://github.com/genai-impact/ecologits) that tracks the energy consumption and environmental footprint of using generative AI models through APIs.
|
| 84 |
|
| 85 |
|
| 86 |
-
|
| 87 |
|
| 88 |
**How we assess the impacts of closed-source models?**
|
| 89 |
|
|
@@ -115,88 +109,84 @@ To see the full list of **generative AI providers** currently supported by EcoLo
|
|
| 115 |
EcoLogits is focused on estimating the environmental impacts of generative AI (only LLMs for now) used **through API providers (such as OpenAI, Anthropic, Cloud APIs...)** whereas CodeCarbon is more general tool to measure energy consumption and estimate GHG emissions measurement. If you deploy LLMs locally we encourage you to use CodeCarbon to get real numbers of your energy consumption.
|
| 116 |
|
| 117 |
|
| 118 |
-
|
| 119 |
|
| 120 |
We are eager to get feedback from the community, don't hesitate to engage the discussion with us on this [GitHub thread](https://github.com/genai-impact/ecologits/discussions/45) or message us on [LinkedIn](https://www.linkedin.com/company/genai-impact/).
|
| 121 |
|
| 122 |
We also welcome any open-source contributions on 🌱 **[EcoLogits](https://github.com/genai-impact/ecologits)** or on 🧮 **EcoLogits Calculator**.
|
| 123 |
|
| 124 |
|
| 125 |
-
|
| 126 |
|
| 127 |
<p xmlns:cc="http://creativecommons.org/ns#" >
|
| 128 |
This work is licensed under
|
| 129 |
<a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">
|
| 130 |
CC BY-SA 4.0
|
| 131 |
</a>
|
| 132 |
-
<br>
|
| 133 |
-
<br>
|
| 134 |
-
<img style="display:inline-block;height:5px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" height="30" width="30" alt="">
|
| 135 |
-
<img style="display:inline-block;height:5px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" height="30" width="30" alt="">
|
| 136 |
-
<img style="display:inline-block;height:5px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" height="30" width="30" alt="">
|
| 137 |
</p>
|
| 138 |
|
| 139 |
-
|
| 140 |
|
| 141 |
We thank [Data For Good](https://dataforgood.fr/) and [Boavizta](https://boavizta.org/en) for supporting the development of this project. Their contributions of tools, best practices, and expertise in environmental impact assessment have been invaluable.
|
| 142 |
|
| 143 |
-
We also extend our gratitude to the open-source contributions of 🤗 [Hugging Face](huggingface.com) on the LLM-Perf Leaderboard.
|
| 144 |
|
| 145 |
-
|
| 146 |
-
## 🤝 Contact
|
| 147 |
|
| 148 |
For general question on the project, please use the [GitHub thread](https://github.com/genai-impact/ecologits/discussions/45).
|
| 149 |
Otherwise use our contact form on [genai-impact.org/contact](https://genai-impact.org/contact/).
|
| 150 |
"""
|
| 151 |
|
| 152 |
SUPPORT_TEXT = r"""
|
| 153 |
-
|
| 154 |
|
| 155 |
At GenAI Impact, our projects are powered by the passion and dedication of our team.
|
| 156 |
-
Since its first release in June 2024, this calculator has been **
|
| 157 |
-
We aim to keep this tool available as a free and open-source
|
|
|
|
|
|
|
| 158 |
|
| 159 |
-
|
| 160 |
-
3 easy ways to help this project :
|
| 161 |
- Give a ❤️ like to this space
|
| 162 |
-
- Give a ⭐ to the EcoLogits
|
| 163 |
- Follow us on [LinkedIn](https://fr.linkedin.com/company/genai-impact)
|
| 164 |
|
| 165 |
-
|
|
|
|
| 166 |
Share your feedback, ask questions, help other members of the community !
|
| 167 |
|
| 168 |
-
Engage the discussion with us
|
| 169 |
- Start a new discussion on this space or on this
|
| 170 |
[GitHub thread](https://github.com/genai-impact/ecologits/discussions/45)
|
| 171 |
- Use the contact form on [GenAI Impact website](https://genai-impact.org/contact/)
|
| 172 |
- message us on [LinkedIn](https://www.linkedin.com/company/genai-impact/).
|
| 173 |
|
| 174 |
-
|
|
|
|
|
|
|
| 175 |
|
| 176 |
-
##### As an individual
|
| 177 |
We welcome any open source contribution ! You can :
|
| 178 |
- Contribute on **[EcoLogits](https://github.com/genai-impact/ecologits)** or on
|
| 179 |
**EcoLogits Calculator**.
|
| 180 |
- Become a an active member of [GenAI Impact ](https://genai-impact.org/contact/) non profit. Get involved in our broader mission !
|
| 181 |
|
| 182 |
|
| 183 |
-
|
|
|
|
| 184 |
If EcoLogits Calculator brings value to your organization, customers or communities you can help finance this project.
|
| 185 |
- Become a **sponsor**
|
| 186 |
- Become a **benefactor member** if you are a public sector or non-profit organization or a university.
|
| 187 |
|
| 188 |
-
Contact us on [GenAI Impact
|
| 189 |
-
|
| 190 |
"""
|
| 191 |
|
| 192 |
METHODOLOGY_TEXT = r"""
|
| 193 |
-
|
| 194 |
|
| 195 |
We have developed a methodology to **estimate the energy consumption and environmental impacts for an LLM inference** based on request parameters and hypotheses on the data center location, the hardware used, the model architecture and more.
|
| 196 |
|
| 197 |
In this section we will only cover the principles of the methodology related to the 🧮 **EcoLogits Calculator**. If you wish to learn more on the environmental impacts modeling of an LLM request checkout the 🌱 [EcoLogits documentation page](https://ecologits.ai/methodology/).
|
| 198 |
|
| 199 |
-
|
| 200 |
|
| 201 |
The environmental impacts of an LLM inference are split into the **usage impacts** $I_{request}^u$ to account for electricity consumption and the **embodied impacts** $I_{request}^e$ that relates to resource extraction, hardware manufacturing and transportation. In general terms it can be expressed as follow:
|
| 202 |
|
|
@@ -216,8 +206,10 @@ Additionally, to ⚡️ **direct energy consumption** the environmental impacts
|
|
| 216 |
* 🌍 **Global Warming Potential** (GWP): Potential impact on global warming in kgCO2eq (commonly known as GHG/carbon emissions).
|
| 217 |
* 🪨 **Abiotic Depletion Potential for Elements** (ADPe): Impact on the depletion of non-living resources such as minerals or metals in kgSbeq.
|
| 218 |
* ⛽️ **Primary Energy** (PE): Total energy consumed from primary sources in MJ.
|
|
|
|
|
|
|
|
|
|
| 219 |
|
| 220 |
-
### Principles, Data and Hypotheses
|
| 221 |
We use a **bottom-up methodology** to model impacts, meaning that we will estimate the impacts of low-level physical components to then estimate the impacts at software level (in that case an LLM inference). We also rely on **Life Cycle Approach (LCA) proxies and approach** to model both usage and embodied phases with multi-criteria impacts. If you are interested in this approach we recommend you to read the following [Boavizta](https://boavizta.org/) resources.
|
| 222 |
|
| 223 |
* [Digital & environment: How to evaluate server manufacturing footprint, beyond greenhouse gas emissions?](https://boavizta.org/en/blog/empreinte-de-la-fabrication-d-un-serveur)
|
|
@@ -225,26 +217,27 @@ We use a **bottom-up methodology** to model impacts, meaning that we will estima
|
|
| 225 |
* [Boavizta API documentation](https://doc.api.boavizta.org/)
|
| 226 |
|
| 227 |
We leverage **open data to estimate the environmental impacts**, here is an exhaustive list of our data providers.
|
| 228 |
-
|
|
|
|
| 229 |
* [Boavizta API](https://github.com/Boavizta/boaviztapi) to estimate server embodied impacts and base energy consumption.
|
| 230 |
-
* [ADEME Base Empreinte®](https://base-empreinte.ademe.fr/) for electricity mix impacts per country.
|
| 231 |
|
| 232 |
Finally here are the **main hypotheses** we have made to compute the impacts.
|
| 233 |
|
| 234 |
* ⚠️ **We *"guesstimate"* the model architecture of proprietary LLMs when not disclosed by the provider.**
|
| 235 |
-
* Production setup: quantized models running on data center grade servers and GPUs such as
|
| 236 |
-
* Electricity
|
| 237 |
* Ignore the following impacts: unused cloud resources, data center building, network and end-user devices... (for now)
|
| 238 |
|
| 239 |
-
|
| 240 |
|
| 241 |
We have integrated impact equivalents to help people better understand the impacts and have reference points for standard use cases and everyday activities.
|
| 242 |
|
| 243 |
-
|
| 244 |
|
| 245 |
These equivalents are computed based on the request impacts only.
|
| 246 |
|
| 247 |
-
|
| 248 |
|
| 249 |
We compare the ⚡️ direct energy consumption with the energy consumption of someone 🚶♂️➡️ walking or 🏃♂️➡️ running. From [runningtools.com](https://www.runningtools.com/energyusage.htm) we consider the following energy values per physical activity (for someone weighing 70kg):
|
| 250 |
|
|
@@ -253,18 +246,19 @@ We compare the ⚡️ direct energy consumption with the energy consumption of s
|
|
| 253 |
|
| 254 |
We divide the request energy consumption by these values to compute the distance traveled.
|
| 255 |
|
| 256 |
-
|
|
|
|
| 257 |
We compare the ⚡️ direct energy consumption with the energy consumer by a EV car. From [selectra.info](https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040) or [tesla.com](https://www.tesla.com/fr_fr/support/power-consumption) we consider an average value of energy consumed per kilometer of: $ 0.17\ kWh/km $.
|
| 258 |
|
| 259 |
We divide the request energy consumption by this value to compute the distance driven by an EV.
|
| 260 |
|
| 261 |
-
|
| 262 |
|
| 263 |
We compare the 🌍 GHG emissions of the request and of streaming a video. From [impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo), we consider that $ 1\ kgCO2eq $ is equivalent to $ 15.6\ h $ of streaming.
|
| 264 |
|
| 265 |
We multiply that value by the GHG emissions of the request to get an equivalent in hours of video streaming.
|
| 266 |
|
| 267 |
-
|
| 268 |
|
| 269 |
These equivalents are computed based on the request impacts scaled to a worldwide adoption use case. We imply that the same request is done 1% of the planet everyday for 1 year, and then compute impact equivalents.
|
| 270 |
|
|
@@ -272,25 +266,25 @@ $$
|
|
| 272 |
I_{scaled} = I_{request} * [1 \% \ \text{of}\ 8B\ \text{people on earth}] * 365\ \text{days}
|
| 273 |
$$
|
| 274 |
|
| 275 |
-
|
| 276 |
|
| 277 |
We compare the ⚡️ direct energy consumption (scaled) by the energy production of wind turbines and nuclear power plants. From [ecologie.gouv.fr](https://www.ecologie.gouv.fr/eolien-terrestre) we consider that a $ 2\ MW $ wind turbine produces $ 4.2\ GWh $ a year. And from [edf.fr](https://www.edf.fr/groupe-edf/espaces-dedies/jeunes-enseignants/pour-les-jeunes/lenergie-de-a-a-z/produire-de-lelectricite/le-nucleaire-en-chiffres) we learn that a $ 900\ MW $ nuclear power plant produces $ 6\ TWh $ a year.
|
| 278 |
|
| 279 |
We divide the scaled energy consumption by these values to get the number of wind turbines or nuclear power plants needed.
|
| 280 |
|
| 281 |
-
|
| 282 |
|
| 283 |
We compare the ⚡️ direct energy consumption (scaled) by the electricity consumption of Ireland per year. From [wikipedia.org](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) we consider the Ireland electricity consumption to be $ 33\ TWh $ a year for a population of 5M.
|
| 284 |
|
| 285 |
We divide the scaled energy consumption by this value to get the equivalent number of "Ireland countries".
|
| 286 |
|
| 287 |
-
|
| 288 |
|
| 289 |
We compare the 🌍 GHG emissions (scaled) of the request and of a return flight Paris ↔ New York City. From [impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny) we consider that a return flight Paris → New York City → Paris for one passenger emits $ 1,770\ kgCO2eq $ and we consider an overall average load of 100 passengers per flight.
|
| 290 |
|
| 291 |
We divide the scaled GHG emissions by this value to get the equivalent number of return flights.
|
| 292 |
|
| 293 |
-
|
| 294 |
"""
|
| 295 |
|
| 296 |
CITATION_LABEL = "BibTeX citation for EcoLogits Calculator and the EcoLogits library:"
|
|
|
|
| 1 |
HERO_TEXT = """
|
| 2 |
+
<div align="center" class="hero">
|
| 3 |
<a href="https://ecologits.ai/">
|
| 4 |
+
<img style="max-height: 200px" alt="EcoLogits" src="https://raw.githubusercontent.com/genai-impact/ecologits-calculator/main/assets/logo.png">
|
| 5 |
</a>
|
| 6 |
</div>
|
| 7 |
<div align="center">
|
| 8 |
<p style="max-width: 850px; text-align: left">
|
| 9 |
+
<b><a href="https://ecologits.ai/" target="_blank">EcoLogits</a></b> is an <b>open source</b> tool for estimating the <b>energy consumption</b> and <b>environmental footprint</b> when using <b>generative AI models</b>. It is developed by the <b><a href="https://genai-impact.org/">GenAI Impact</a></b> non-profit.
|
| 10 |
+
<br><br>
|
| 11 |
+
This page is the official calculator made for everyone to explore the impact evaluation methodology and raise awareness on sustainable AI.
|
|
|
|
|
|
|
| 12 |
</p>
|
| 13 |
|
| 14 |
</div>
|
| 15 |
<br>
|
| 16 |
"""
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
HOW_TO_TEXT = """
|
| 19 |
Chose a provider, a model and an example of usage (prompts).
|
| 20 |
|
|
|
|
| 68 |
"""
|
| 69 |
|
| 70 |
ABOUT_TEXT = r"""
|
| 71 |
+
### 🎯 Our goal
|
| 72 |
|
| 73 |
**The main goal of the EcoLogits Calculator is to raise awareness on the environmental impacts of LLM inference.**
|
| 74 |
|
|
|
|
| 77 |
At **[GenAI Impact](https://genai-impact.org/) we are dedicated to understanding and mitigating the environmental impacts of generative AI** through rigorous research, innovative tools, and community engagement. Especially, in early 2024 we have launched an new open-source tool called [EcoLogits](https://github.com/genai-impact/ecologits) that tracks the energy consumption and environmental footprint of using generative AI models through APIs.
|
| 78 |
|
| 79 |
|
| 80 |
+
### 🙋 FAQ
|
| 81 |
|
| 82 |
**How we assess the impacts of closed-source models?**
|
| 83 |
|
|
|
|
| 109 |
EcoLogits is focused on estimating the environmental impacts of generative AI (only LLMs for now) used **through API providers (such as OpenAI, Anthropic, Cloud APIs...)** whereas CodeCarbon is more general tool to measure energy consumption and estimate GHG emissions measurement. If you deploy LLMs locally we encourage you to use CodeCarbon to get real numbers of your energy consumption.
|
| 110 |
|
| 111 |
|
| 112 |
+
### 🤗 Contributing
|
| 113 |
|
| 114 |
We are eager to get feedback from the community, don't hesitate to engage the discussion with us on this [GitHub thread](https://github.com/genai-impact/ecologits/discussions/45) or message us on [LinkedIn](https://www.linkedin.com/company/genai-impact/).
|
| 115 |
|
| 116 |
We also welcome any open-source contributions on 🌱 **[EcoLogits](https://github.com/genai-impact/ecologits)** or on 🧮 **EcoLogits Calculator**.
|
| 117 |
|
| 118 |
|
| 119 |
+
### ⚖️ License
|
| 120 |
|
| 121 |
<p xmlns:cc="http://creativecommons.org/ns#" >
|
| 122 |
This work is licensed under
|
| 123 |
<a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">
|
| 124 |
CC BY-SA 4.0
|
| 125 |
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
</p>
|
| 127 |
|
| 128 |
+
### 🙌 Acknowledgement
|
| 129 |
|
| 130 |
We thank [Data For Good](https://dataforgood.fr/) and [Boavizta](https://boavizta.org/en) for supporting the development of this project. Their contributions of tools, best practices, and expertise in environmental impact assessment have been invaluable.
|
| 131 |
|
|
|
|
| 132 |
|
| 133 |
+
### 🤝 Contact
|
|
|
|
| 134 |
|
| 135 |
For general question on the project, please use the [GitHub thread](https://github.com/genai-impact/ecologits/discussions/45).
|
| 136 |
Otherwise use our contact form on [genai-impact.org/contact](https://genai-impact.org/contact/).
|
| 137 |
"""
|
| 138 |
|
| 139 |
SUPPORT_TEXT = r"""
|
| 140 |
+
### How to support us
|
| 141 |
|
| 142 |
At GenAI Impact, our projects are powered by the passion and dedication of our team.
|
| 143 |
+
Since its first release in June 2024, this calculator has been **developed and maintained entirely on a volunteer basis by our members**.
|
| 144 |
+
We aim to keep this tool available as a free and open-source resource for the common good. We need your support to reach this goal, this is how you can help.
|
| 145 |
+
|
| 146 |
+
#### If you have 1 second
|
| 147 |
|
| 148 |
+
3 easy ways to help this project:
|
|
|
|
| 149 |
- Give a ❤️ like to this space
|
| 150 |
+
- Give a ⭐ to the EcoLogits repository on [GitHub](https://github.com/genai-impact/ecologits)
|
| 151 |
- Follow us on [LinkedIn](https://fr.linkedin.com/company/genai-impact)
|
| 152 |
|
| 153 |
+
#### If you have 5 minutes
|
| 154 |
+
|
| 155 |
Share your feedback, ask questions, help other members of the community !
|
| 156 |
|
| 157 |
+
Engage the discussion with us:
|
| 158 |
- Start a new discussion on this space or on this
|
| 159 |
[GitHub thread](https://github.com/genai-impact/ecologits/discussions/45)
|
| 160 |
- Use the contact form on [GenAI Impact website](https://genai-impact.org/contact/)
|
| 161 |
- message us on [LinkedIn](https://www.linkedin.com/company/genai-impact/).
|
| 162 |
|
| 163 |
+
#### If you have more to give
|
| 164 |
+
|
| 165 |
+
###### As an individual
|
| 166 |
|
|
|
|
| 167 |
We welcome any open source contribution ! You can :
|
| 168 |
- Contribute on **[EcoLogits](https://github.com/genai-impact/ecologits)** or on
|
| 169 |
**EcoLogits Calculator**.
|
| 170 |
- Become a an active member of [GenAI Impact ](https://genai-impact.org/contact/) non profit. Get involved in our broader mission !
|
| 171 |
|
| 172 |
|
| 173 |
+
###### As an organization
|
| 174 |
+
|
| 175 |
If EcoLogits Calculator brings value to your organization, customers or communities you can help finance this project.
|
| 176 |
- Become a **sponsor**
|
| 177 |
- Become a **benefactor member** if you are a public sector or non-profit organization or a university.
|
| 178 |
|
| 179 |
+
Contact us on [GenAI Impact](https://genai-impact.org/contact/)
|
|
|
|
| 180 |
"""
|
| 181 |
|
| 182 |
METHODOLOGY_TEXT = r"""
|
| 183 |
+
### 📖 Methodology
|
| 184 |
|
| 185 |
We have developed a methodology to **estimate the energy consumption and environmental impacts for an LLM inference** based on request parameters and hypotheses on the data center location, the hardware used, the model architecture and more.
|
| 186 |
|
| 187 |
In this section we will only cover the principles of the methodology related to the 🧮 **EcoLogits Calculator**. If you wish to learn more on the environmental impacts modeling of an LLM request checkout the 🌱 [EcoLogits documentation page](https://ecologits.ai/methodology/).
|
| 188 |
|
| 189 |
+
#### Modeling impacts of an LLM request
|
| 190 |
|
| 191 |
The environmental impacts of an LLM inference are split into the **usage impacts** $I_{request}^u$ to account for electricity consumption and the **embodied impacts** $I_{request}^e$ that relates to resource extraction, hardware manufacturing and transportation. In general terms it can be expressed as follow:
|
| 192 |
|
|
|
|
| 206 |
* 🌍 **Global Warming Potential** (GWP): Potential impact on global warming in kgCO2eq (commonly known as GHG/carbon emissions).
|
| 207 |
* 🪨 **Abiotic Depletion Potential for Elements** (ADPe): Impact on the depletion of non-living resources such as minerals or metals in kgSbeq.
|
| 208 |
* ⛽️ **Primary Energy** (PE): Total energy consumed from primary sources in MJ.
|
| 209 |
+
* ⛽️ **Water Consumption Footprint** (WCF): Water consumed by data centers and electricity generation power plants.
|
| 210 |
+
|
| 211 |
+
#### Principles, Data and Hypotheses
|
| 212 |
|
|
|
|
| 213 |
We use a **bottom-up methodology** to model impacts, meaning that we will estimate the impacts of low-level physical components to then estimate the impacts at software level (in that case an LLM inference). We also rely on **Life Cycle Approach (LCA) proxies and approach** to model both usage and embodied phases with multi-criteria impacts. If you are interested in this approach we recommend you to read the following [Boavizta](https://boavizta.org/) resources.
|
| 214 |
|
| 215 |
* [Digital & environment: How to evaluate server manufacturing footprint, beyond greenhouse gas emissions?](https://boavizta.org/en/blog/empreinte-de-la-fabrication-d-un-serveur)
|
|
|
|
| 217 |
* [Boavizta API documentation](https://doc.api.boavizta.org/)
|
| 218 |
|
| 219 |
We leverage **open data to estimate the environmental impacts**, here is an exhaustive list of our data providers.
|
| 220 |
+
|
| 221 |
+
* [ML.ENERGY Leaderboard](https://ml.energy/leaderboard/) to estimate GPU energy consumption and latency based on the model architecture and number of output tokens.
|
| 222 |
* [Boavizta API](https://github.com/Boavizta/boaviztapi) to estimate server embodied impacts and base energy consumption.
|
| 223 |
+
* [Our World in Data](https://ourworldindata.org/), [ADEME Base Empreinte®](https://base-empreinte.ademe.fr/) and [World Resource Institute](https://www.wri.org/) for electricity mix impacts per country.
|
| 224 |
|
| 225 |
Finally here are the **main hypotheses** we have made to compute the impacts.
|
| 226 |
|
| 227 |
* ⚠️ **We *"guesstimate"* the model architecture of proprietary LLMs when not disclosed by the provider.**
|
| 228 |
+
* Production setup: quantized models running on data center grade servers and GPUs such as H100.
|
| 229 |
+
* Electricity mixes are yearly averages.
|
| 230 |
* Ignore the following impacts: unused cloud resources, data center building, network and end-user devices... (for now)
|
| 231 |
|
| 232 |
+
### Equivalents
|
| 233 |
|
| 234 |
We have integrated impact equivalents to help people better understand the impacts and have reference points for standard use cases and everyday activities.
|
| 235 |
|
| 236 |
+
#### Request impacts
|
| 237 |
|
| 238 |
These equivalents are computed based on the request impacts only.
|
| 239 |
|
| 240 |
+
##### 🚶♂️➡️ Walking or 🏃♂️➡️ running distance
|
| 241 |
|
| 242 |
We compare the ⚡️ direct energy consumption with the energy consumption of someone 🚶♂️➡️ walking or 🏃♂️➡️ running. From [runningtools.com](https://www.runningtools.com/energyusage.htm) we consider the following energy values per physical activity (for someone weighing 70kg):
|
| 243 |
|
|
|
|
| 246 |
|
| 247 |
We divide the request energy consumption by these values to compute the distance traveled.
|
| 248 |
|
| 249 |
+
##### 🔋 Electric Vehicle distance
|
| 250 |
+
|
| 251 |
We compare the ⚡️ direct energy consumption with the energy consumer by a EV car. From [selectra.info](https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040) or [tesla.com](https://www.tesla.com/fr_fr/support/power-consumption) we consider an average value of energy consumed per kilometer of: $ 0.17\ kWh/km $.
|
| 252 |
|
| 253 |
We divide the request energy consumption by this value to compute the distance driven by an EV.
|
| 254 |
|
| 255 |
+
##### ⏯️ Streaming time
|
| 256 |
|
| 257 |
We compare the 🌍 GHG emissions of the request and of streaming a video. From [impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo), we consider that $ 1\ kgCO2eq $ is equivalent to $ 15.6\ h $ of streaming.
|
| 258 |
|
| 259 |
We multiply that value by the GHG emissions of the request to get an equivalent in hours of video streaming.
|
| 260 |
|
| 261 |
+
#### Scaled impacts
|
| 262 |
|
| 263 |
These equivalents are computed based on the request impacts scaled to a worldwide adoption use case. We imply that the same request is done 1% of the planet everyday for 1 year, and then compute impact equivalents.
|
| 264 |
|
|
|
|
| 266 |
I_{scaled} = I_{request} * [1 \% \ \text{of}\ 8B\ \text{people on earth}] * 365\ \text{days}
|
| 267 |
$$
|
| 268 |
|
| 269 |
+
##### Number of 💨 wind turbines or ☢️ nuclear plants
|
| 270 |
|
| 271 |
We compare the ⚡️ direct energy consumption (scaled) by the energy production of wind turbines and nuclear power plants. From [ecologie.gouv.fr](https://www.ecologie.gouv.fr/eolien-terrestre) we consider that a $ 2\ MW $ wind turbine produces $ 4.2\ GWh $ a year. And from [edf.fr](https://www.edf.fr/groupe-edf/espaces-dedies/jeunes-enseignants/pour-les-jeunes/lenergie-de-a-a-z/produire-de-lelectricite/le-nucleaire-en-chiffres) we learn that a $ 900\ MW $ nuclear power plant produces $ 6\ TWh $ a year.
|
| 272 |
|
| 273 |
We divide the scaled energy consumption by these values to get the number of wind turbines or nuclear power plants needed.
|
| 274 |
|
| 275 |
+
##### Multiplier of 🇮🇪 Ireland electricity consumption
|
| 276 |
|
| 277 |
We compare the ⚡️ direct energy consumption (scaled) by the electricity consumption of Ireland per year. From [wikipedia.org](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) we consider the Ireland electricity consumption to be $ 33\ TWh $ a year for a population of 5M.
|
| 278 |
|
| 279 |
We divide the scaled energy consumption by this value to get the equivalent number of "Ireland countries".
|
| 280 |
|
| 281 |
+
##### Number of ✈️ Paris ↔ New York City flights
|
| 282 |
|
| 283 |
We compare the 🌍 GHG emissions (scaled) of the request and of a return flight Paris ↔ New York City. From [impactco2.fr](https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny) we consider that a return flight Paris → New York City → Paris for one passenger emits $ 1,770\ kgCO2eq $ and we consider an overall average load of 100 passengers per flight.
|
| 284 |
|
| 285 |
We divide the scaled GHG emissions by this value to get the equivalent number of return flights.
|
| 286 |
|
| 287 |
+
##### If you are motivated to help us test and enhance this methodology [contact us](https://genai-impact.org/contact/)! 💪
|
| 288 |
"""
|
| 289 |
|
| 290 |
CITATION_LABEL = "BibTeX citation for EcoLogits Calculator and the EcoLogits library:"
|
src/data/electricity_mix.csv
DELETED
|
@@ -1,4 +0,0 @@
|
|
| 1 |
-
name,unit,source,WOR,EEE,ZWE,ZMB,ZAF,YEM,VNM,VEN,UZB,URY,USA,UKR,TZA,TWN,TTO,TUR,TUN,TKM,TJK,THA,TGO,SYR,SLV,SEN,SVK,SVN,SGP,SWE,SDN,SAU,RUS,SCG,ROU,QAT,PRY,PRT,POL,PAK,PHL,PER,PAN,OMN,NZL,NPL,NOR,NLD,NIC,NGA,NAM,MOZ,MYS,MEX,MLT,MNG,MMR,MKD,MDA,MAR,LBY,LVA,LUX,LTU,LKA,LBN,KAZ,KWT,KOR,PRK,KHM,KGZ,KEN,JPN,JOR,JAM,ITA,ISL,IRN,IRQ,IND,ISR,IRL,IDN,HUN,HTI,HRV,HND,HKG,GTM,GRC,GIB,GHA,GEO,GBR,GAB,FRA,FIN,ETH,ESP,ERI,EGY,EST,ECU,DZA,DOM,DNK,DEU,CZE,CYP,CUB,CRI,COL,CHN,CMR,CHL,CIV,CHE,COG,COD,CAN,BLR,BWA,BRA,BOL,BRN,BEN,BHR,BGR,BEL,BGD,BIH,AZE,AUS,AUT,ARG,AGO,ANT,ARM,ALB,ARE
|
| 2 |
-
adpe,kg éq. Sb,ADEME Base IMPACTS ®,0.0000000737708,0.0000000642317,0.000000109502,0.000000162193,0.0000000862445,0.0000000163908,0.0000000945573,0.000000112811,0.000000103681,0.000000104586,0.0000000985548,0.0000000647907,0.000000132261,0.0000000578088,0.000000064552,0.0000000749765,0.0000000177021,0.000000131822,0.000000152621,0.0000000569593,0.000000134255,0.0000000268396,0.0000000472135,0.0000000470662,0.0000000606109,0.0000000992283,0.0000000198459,0.0000000777062,0.0000000955701,0.0000000134206,0.0000000960312,0.000000132772,0.0000000981761,0.00000001324,0.000000149181,0.0000000341863,0.000000101946,0.0000000842952,0.0000000595304,0.0000000952688,0.0000000790553,0.0000000374073,0.0000000720474,0.000000238273,0.000000127486,0.0000000329318,0.0000000414983,0.0000000621,0.000000128285,0.000000148382,0.000000044938,0.0000000578358,0.000000049475,0.000000176361,0.000000152699,0.000000119873,0.000000110674,0.0000000641089,0.0000000206592,0.000000153757,0.000000105692,0.0000000294596,0.0000000986932,0.0000000182134,0.000000135386,0.0000000141168,0.0000000518017,0.000000117457,0.0000000319202,0.000000181827,0.0000000958533,0.0000000596578,0.0000000147031,0.0000000196047,0.00000005439,0.0000000781905,0.0000000220304,0.0000000404306,0.000000100099,0.0000000610194,0.0000000219257,0.0000000610451,0.0000000644587,0.0000000937057,0.000000153989,0.0000000649373,0.0000000816213,0.0000000803251,0.0000000691645,0.0000000286211,0.000000156003,0.000000137999,0.0000000370973,0.000000113843,0.0000000485798,0.0000000805114,0.000000174161,0.0000000518326,0.0000000512406,0.000000033925,0.0000000990171,0.000000127168,0.0000000216438,0.0000000429285,0.0000000157411,0.0000000878733,0.0000000817565,0.0000000448771,0.0000000299542,0.0000000863908,0.000000122031,0.0000000851552,0.000000146313,0.000000105851,0.0000000949004,0.000000100467,0.000000265575,0.000000174647,0.0000000993179,0.0000000840478,0.0000000866014,0.00000010962,0.0000000969793,0.0000000185641,0.0000000239702,0.0000000135014,0.0000000823611,0.0000000337201,0.0000000394158,0.000000148007,0.000000092567,0.0000000790846,0.000000141124,0.0000000768612,0.000000124074,0.0000000449103,0.0000000854245,0.000000229556,0.0000000141548
|
| 3 |
-
pe,MJ,ADPf / (1-%renewable_energy),9.988,12.873,16.122,1.798,11.732,16.250,11.238,15.163,17.367,107.570,11.358,12.936,9.305,11.439,14.289,16.150,12.902,23.300,19.165,10.414,21.978,16.989,13.012,14.516,11.680,12.146,10.477,11.026,29.629,14.058,13.200,14.242,15.585,11.916,0.020,14.153,13.178,16.175,11.120,8.211,16.364,22.306,24.731,0.396,4.952,8.511,24.696,11.279,468.150,0.206,12.268,11.775,19.374,15.114,14.132,19.120,18.429,11.702,19.116,8.249,10.128,21.043,12.116,12.341,13.260,12.753,10.199,32.793,34.655,15.380,68.996,10.718,13.677,14.799,12.656,0.013,15.022,20.372,20.363,10.023,10.706,11.603,11.784,20.167,18.548,15.762,,14.340,14.487,,10.097,10.425,13.579,28.341,11.289,11.275,36.133,12.090,13.289,10.195,16.334,20.908,16.376,12.412,16.824,16.260,12.517,13.118,17.317,45.996,7.312,14.119,10.807,11.348,14.783,11.782,34.147,0.097,11.987,13.194,19.642,9.031,11.587,15.689,14.337,14.036,14.375,10.776,12.935,21.705,12.831,16.908,11.036,10.049,16.972,,13.380,0.201,19.032
|
| 4 |
-
gwp,kg éq. CO2,ADEME Base IMPACTS ®,0.590478,0.509427,0.842811,0.0141304,1.17562,1.06777,0.555572,0.497373,0.81178,0.296953,0.67978,0.646745,0.475635,0.845351,0.933059,0.706988,0.80722,1.38296,0.0426743,0.646174,0.545455,1.08778,0.473128,1.1195,0.309341,0.498523,0.655825,0.0464664,1.12472,0.913677,0.66131,1.07808,0.664245,0.722125,0.241601,0.571172,1.15075,0.748727,0.761317,0.284364,0.53403,1.41292,0.293397,0.0841323,0.023754,0.544803,0.941626,0.693123,0.357253,0.00880732,0.832206,0.739214,1.31149,1.47192,0.48193,1.24074,1.04213,0.933694,1.35361,0.234273,0.490016,0.154229,0.709185,0.883627,1.128,0.885084,0.599585,0.797361,1.41054,0.156039,0.589603,0.540891,0.781372,1.07345,0.621329,0.0194609,0.930385,1.48728,1.58299,0.901842,0.648118,0.875394,0.541558,1.3858,0.535759,0.692837,0.95888,0.645801,1.13127,0.977477,0.540126,0.132046,0.602137,0.732511,0.0813225,0.322068,0.251299,0.467803,1.13153,0.587775,1.51492,0.627714,1.02318,0.909252,0.633534,0.657374,0.799077,0.978041,1.28325,0.224471,0.214014,1.05738,0.456622,0.574415,0.928583,0.0448568,0.904053,0.0613102,0.238191,0.795697,2.12572,0.278647,0.585131,0.997577,1.19128,0.804567,0.827087,0.256537,0.795168,1.56025,0.726126,1.12326,0.245573,0.476811,0.412014,1.13161,0.252002,0.0207635,1.09088
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/data/throughputs.json
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"models": [
|
| 3 |
+
{
|
| 4 |
+
"provider": "openai",
|
| 5 |
+
"name": "gpt-3.5-turbo",
|
| 6 |
+
"throughput": 144.6
|
| 7 |
+
},
|
| 8 |
+
{
|
| 9 |
+
"provider": "openai",
|
| 10 |
+
"name": "gpt-4",
|
| 11 |
+
"throughput": 33.0
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"provider": "openai",
|
| 15 |
+
"name": "gpt-4-turbo",
|
| 16 |
+
"throughput": 46.5
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"provider": "openai",
|
| 20 |
+
"name": "gpt-4o",
|
| 21 |
+
"throughput": 68.4
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"provider": "openai",
|
| 25 |
+
"name": "gpt-4o-mini",
|
| 26 |
+
"throughput": 59.5
|
| 27 |
+
},
|
| 28 |
+
{
|
| 29 |
+
"provider": "openai",
|
| 30 |
+
"name": "o1",
|
| 31 |
+
"throughput": 442.9
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"provider": "openai",
|
| 35 |
+
"name": "o1-mini",
|
| 36 |
+
"throughput": 173.2
|
| 37 |
+
},
|
| 38 |
+
{
|
| 39 |
+
"provider": "openai",
|
| 40 |
+
"name": "o3-mini",
|
| 41 |
+
"throughput": 597.4
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"provider": "openai",
|
| 45 |
+
"name": "gpt-4.1-nano",
|
| 46 |
+
"throughput": 91.9
|
| 47 |
+
},
|
| 48 |
+
{
|
| 49 |
+
"provider": "openai",
|
| 50 |
+
"name": "gpt-4.1-mini",
|
| 51 |
+
"throughput": 68.7
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"provider": "openai",
|
| 55 |
+
"name": "gpt-4.1",
|
| 56 |
+
"throughput": 61.0
|
| 57 |
+
},
|
| 58 |
+
{
|
| 59 |
+
"provider": "openai",
|
| 60 |
+
"name": "o4-mini",
|
| 61 |
+
"throughput": 64.7
|
| 62 |
+
},
|
| 63 |
+
{
|
| 64 |
+
"provider": "openai",
|
| 65 |
+
"name": "gpt-5-nano",
|
| 66 |
+
"throughput": 82.4
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"provider": "openai",
|
| 70 |
+
"name": "gpt-5-mini",
|
| 71 |
+
"throughput": 47.1
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"provider": "openai",
|
| 75 |
+
"name": "gpt-5",
|
| 76 |
+
"throughput": 41.3
|
| 77 |
+
},
|
| 78 |
+
{
|
| 79 |
+
"provider": "anthropic",
|
| 80 |
+
"name": "claude-3-5-haiku-latest",
|
| 81 |
+
"throughput": 59.6
|
| 82 |
+
},
|
| 83 |
+
{
|
| 84 |
+
"provider": "anthropic",
|
| 85 |
+
"name": "claude-3-5-sonnet-latest",
|
| 86 |
+
"throughput": 52.7
|
| 87 |
+
},
|
| 88 |
+
{
|
| 89 |
+
"provider": "anthropic",
|
| 90 |
+
"name": "claude-3-7-sonnet-latest",
|
| 91 |
+
"throughput": 51.9
|
| 92 |
+
},
|
| 93 |
+
{
|
| 94 |
+
"provider": "anthropic",
|
| 95 |
+
"name": "claude-opus-4-0",
|
| 96 |
+
"throughput": 37.0
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"provider": "anthropic",
|
| 100 |
+
"name": "claude-opus-4-1",
|
| 101 |
+
"throughput": 38.1
|
| 102 |
+
},
|
| 103 |
+
{
|
| 104 |
+
"provider": "anthropic",
|
| 105 |
+
"name": "claude-sonnet-4-0",
|
| 106 |
+
"throughput": 60.2
|
| 107 |
+
},
|
| 108 |
+
{
|
| 109 |
+
"provider": "anthropic",
|
| 110 |
+
"name": "claude-sonnet-4-5",
|
| 111 |
+
"throughput": 61.4
|
| 112 |
+
},
|
| 113 |
+
{
|
| 114 |
+
"provider": "anthropic",
|
| 115 |
+
"name": "claude-haiku-4-5",
|
| 116 |
+
"throughput": 119.8
|
| 117 |
+
},
|
| 118 |
+
{
|
| 119 |
+
"provider": "mistralai",
|
| 120 |
+
"name": "codestral-latest",
|
| 121 |
+
"throughput": 272.8
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"provider": "mistralai",
|
| 125 |
+
"name": "devstral-medium-latest",
|
| 126 |
+
"throughput": 106.7
|
| 127 |
+
},
|
| 128 |
+
{
|
| 129 |
+
"provider": "mistralai",
|
| 130 |
+
"name": "devstral-small-latest",
|
| 131 |
+
"throughput": 187.8
|
| 132 |
+
},
|
| 133 |
+
{
|
| 134 |
+
"provider": "mistralai",
|
| 135 |
+
"name": "magistral-medium-latest",
|
| 136 |
+
"throughput": 106.7
|
| 137 |
+
},
|
| 138 |
+
{
|
| 139 |
+
"provider": "mistralai",
|
| 140 |
+
"name": "magistral-small-latest",
|
| 141 |
+
"throughput": 187.8
|
| 142 |
+
},
|
| 143 |
+
{
|
| 144 |
+
"provider": "mistralai",
|
| 145 |
+
"name": "ministral-3b-latest",
|
| 146 |
+
"throughput": 309.6
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
"provider": "mistralai",
|
| 150 |
+
"name": "ministral-8b-latest",
|
| 151 |
+
"throughput": 213.7
|
| 152 |
+
},
|
| 153 |
+
{
|
| 154 |
+
"provider": "mistralai",
|
| 155 |
+
"name": "mistral-large-latest",
|
| 156 |
+
"throughput": 48.6
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"provider": "mistralai",
|
| 160 |
+
"name": "mistral-medium-latest",
|
| 161 |
+
"throughput": 54.6
|
| 162 |
+
},
|
| 163 |
+
{
|
| 164 |
+
"provider": "mistralai",
|
| 165 |
+
"name": "mistral-small-latest",
|
| 166 |
+
"throughput": 158.0
|
| 167 |
+
},
|
| 168 |
+
{
|
| 169 |
+
"provider": "mistralai",
|
| 170 |
+
"name": "mistral-tiny-latest",
|
| 171 |
+
"throughput": 92.8
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"provider": "mistralai",
|
| 175 |
+
"name": "open-mistral-7b",
|
| 176 |
+
"throughput": 121.5
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"provider": "mistralai",
|
| 180 |
+
"name": "open-mistral-nemo",
|
| 181 |
+
"throughput": 153.2
|
| 182 |
+
},
|
| 183 |
+
{
|
| 184 |
+
"provider": "mistralai",
|
| 185 |
+
"name": "open-mixtral-8x22b",
|
| 186 |
+
"throughput": 85.7
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"provider": "mistralai",
|
| 190 |
+
"name": "open-mixtral-8x7b",
|
| 191 |
+
"throughput": 80
|
| 192 |
+
},
|
| 193 |
+
{
|
| 194 |
+
"provider": "google_genai",
|
| 195 |
+
"name": "gemini-2.0-flash-lite",
|
| 196 |
+
"throughput": 74.1
|
| 197 |
+
},
|
| 198 |
+
{
|
| 199 |
+
"provider": "google_genai",
|
| 200 |
+
"name": "gemini-2.0-flash",
|
| 201 |
+
"throughput": 151.4
|
| 202 |
+
},
|
| 203 |
+
{
|
| 204 |
+
"provider": "google_genai",
|
| 205 |
+
"name": "gemini-2.5-flash-lite",
|
| 206 |
+
"throughput": 74.1
|
| 207 |
+
},
|
| 208 |
+
{
|
| 209 |
+
"provider": "google_genai",
|
| 210 |
+
"name": "gemini-2.5-flash",
|
| 211 |
+
"throughput": 93.2
|
| 212 |
+
},
|
| 213 |
+
{
|
| 214 |
+
"provider": "google_genai",
|
| 215 |
+
"name": "gemini-2.5-pro",
|
| 216 |
+
"throughput": 86.6
|
| 217 |
+
},
|
| 218 |
+
{
|
| 219 |
+
"provider": "cohere",
|
| 220 |
+
"name": "command-a-03-2025",
|
| 221 |
+
"throughput": 77.4
|
| 222 |
+
},
|
| 223 |
+
{
|
| 224 |
+
"provider": "cohere",
|
| 225 |
+
"name": "command-r",
|
| 226 |
+
"throughput": 125.1
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"provider": "cohere",
|
| 230 |
+
"name": "command-r-08-2024",
|
| 231 |
+
"throughput": 67.2
|
| 232 |
+
},
|
| 233 |
+
{
|
| 234 |
+
"provider": "cohere",
|
| 235 |
+
"name": "command-r-plus-08-2024",
|
| 236 |
+
"throughput": 26.9
|
| 237 |
+
},
|
| 238 |
+
{
|
| 239 |
+
"provider": "cohere",
|
| 240 |
+
"name": "command-r7b-12-2024",
|
| 241 |
+
"throughput": 125.1
|
| 242 |
+
}
|
| 243 |
+
]
|
| 244 |
+
}
|
src/electricity_mix.py
CHANGED
|
@@ -1,174 +1,74 @@
|
|
| 1 |
-
from
|
| 2 |
-
import pandas as pd
|
| 3 |
|
| 4 |
-
PATH = "src/data/electricity_mix.csv"
|
| 5 |
|
|
|
|
| 6 |
COUNTRY_CODES = [
|
| 7 |
("🌎 World", "WOR"),
|
| 8 |
-
("🇪🇺 Europe", "EEE"),
|
| 9 |
-
("🇿🇼 Zimbabwe", "ZWE"),
|
| 10 |
-
("🇿🇲 Zambia", "ZMB"),
|
| 11 |
-
("🇿🇦 South Africa", "ZAF"),
|
| 12 |
-
("🇾🇪 Yemen", "YEM"),
|
| 13 |
-
("🇻🇳 Vietnam", "VNM"),
|
| 14 |
-
("🇻🇪 Venezuela", "VEN"),
|
| 15 |
-
("🇺🇿 Uzbekistan", "UZB"),
|
| 16 |
-
("🇺🇾 Uruguay", "URY"),
|
| 17 |
-
("🇺🇸 United States", "USA"),
|
| 18 |
-
("🇺🇦 Ukraine", "UKR"),
|
| 19 |
-
("🇹🇿 Tanzania", "TZA"),
|
| 20 |
-
("🇹🇼 Taiwan", "TWN"),
|
| 21 |
-
("🇹🇹 Trinidad and Tobago", "TTO"),
|
| 22 |
-
("🇹🇷 Turkey", "TUR"),
|
| 23 |
-
("🇹🇳 Tunisia", "TUN"),
|
| 24 |
-
("🇹🇲 Turkmenistan", "TKM"),
|
| 25 |
-
("🇹🇯 Tajikistan", "TJK"),
|
| 26 |
-
("🇹🇭 Thailand", "THA"),
|
| 27 |
-
("🇹🇬 Togo", "TGO"),
|
| 28 |
-
("🇸🇾 Syrian Arab Republic", "SYR"),
|
| 29 |
-
("🇸🇻 El Salvador", "SLV"),
|
| 30 |
-
("🇸🇳 Senegal", "SEN"),
|
| 31 |
-
("🇸🇰 Slovak Republic", "SVK"),
|
| 32 |
-
("🇸🇮 Slovenia", "SVN"),
|
| 33 |
-
("🇸🇬 Singapore", "SGP"),
|
| 34 |
-
("🇸🇪 Sweden", "SWE"),
|
| 35 |
-
("🇸🇩 Sudan", "SDN"),
|
| 36 |
-
("🇸🇦 Saudi Arabia", "SAU"),
|
| 37 |
-
("🇷🇺 Russian Federation", "RUS"),
|
| 38 |
-
("🇷🇸 Serbia and Montenegro", "SCG"),
|
| 39 |
-
("🇷🇴 Romania", "ROU"),
|
| 40 |
-
("🇶🇦 Qatar", "QAT"),
|
| 41 |
-
("🇵🇾 Paraguay", "PRY"),
|
| 42 |
-
("🇵🇹 Portugal", "PRT"),
|
| 43 |
-
("🇵🇱 Poland", "POL"),
|
| 44 |
-
("🇵🇰 Pakistan", "PAK"),
|
| 45 |
-
("🇵🇭 Philippines", "PHL"),
|
| 46 |
-
("🇵🇪 Peru", "PER"),
|
| 47 |
-
("🇵🇦 Panama", "PAN"),
|
| 48 |
-
("🇴🇲 Oman", "OMN"),
|
| 49 |
-
("🇳🇿 New Zealand", "NZL"),
|
| 50 |
-
("🇳🇵 Nepal", "NPL"),
|
| 51 |
-
("🇳🇴 Norway", "NOR"),
|
| 52 |
-
("🇳🇱 Netherlands", "NLD"),
|
| 53 |
-
("🇳🇮 Nicaragua", "NIC"),
|
| 54 |
-
("🇳🇬 Nigeria", "NGA"),
|
| 55 |
-
("🇳🇦 Namibia", "NAM"),
|
| 56 |
-
("🇲🇿 Mozambique", "MOZ"),
|
| 57 |
-
("🇲🇾 Malaysia", "MYS"),
|
| 58 |
-
("🇲🇽 Mexico", "MEX"),
|
| 59 |
-
("🇲🇹 Malta", "MLT"),
|
| 60 |
-
("🇲🇳 Mongolia", "MNG"),
|
| 61 |
-
("🇲🇲 Myanmar", "MMR"),
|
| 62 |
-
("🇲🇰 North Macedonia", "MKD"),
|
| 63 |
-
("🇲🇩 Moldova", "MDA"),
|
| 64 |
-
("🇲🇦 Morocco", "MAR"),
|
| 65 |
-
("🇱🇾 Libya", "LBY"),
|
| 66 |
-
("🇱🇻 Latvia", "LVA"),
|
| 67 |
-
("🇱🇺 Luxembourg", "LUX"),
|
| 68 |
-
("🇱🇹 Lithuania", "LTU"),
|
| 69 |
-
("🇱🇰 Sri Lanka", "LKA"),
|
| 70 |
-
("🇱🇧 Lebanon", "LBN"),
|
| 71 |
-
("🇰🇿 Kazakhstan", "KAZ"),
|
| 72 |
-
("🇰🇼 Kuwait", "KWT"),
|
| 73 |
-
("🇰🇷 South Korea", "KOR"),
|
| 74 |
-
("🇰🇵 North Korea", "PRK"),
|
| 75 |
-
("🇰🇭 Cambodia", "KHM"),
|
| 76 |
-
("🇰🇬 Kyrgyz Republic", "KGZ"),
|
| 77 |
-
("🇰🇪 Kenya", "KEN"),
|
| 78 |
-
("🇯🇵 Japan", "JPN"),
|
| 79 |
-
("🇯🇴 Jordan", "JOR"),
|
| 80 |
-
("🇯🇲 Jamaica", "JAM"),
|
| 81 |
-
("🇮🇹 Italy", "ITA"),
|
| 82 |
-
("🇮🇸 Iceland", "ISL"),
|
| 83 |
-
("🇮🇷 Iran", "IRN"),
|
| 84 |
-
("🇮🇶 Iraq", "IRQ"),
|
| 85 |
-
("🇮🇳 India", "IND"),
|
| 86 |
-
("🇮🇱 Israel", "ISR"),
|
| 87 |
-
("🇮🇪 Ireland", "IRL"),
|
| 88 |
-
("🇮🇩 Indonesia", "IDN"),
|
| 89 |
-
("🇭🇺 Hungary", "HUN"),
|
| 90 |
-
("🇭🇹 Haiti", "HTI"),
|
| 91 |
-
("🇭🇷 Croatia", "HRV"),
|
| 92 |
-
("🇭🇳 Honduras", "HND"),
|
| 93 |
-
("🇭🇰 Hong Kong", "HKG"),
|
| 94 |
-
("🇬🇹 Guatemala", "GTM"),
|
| 95 |
-
("🇬🇷 Greece", "GRC"),
|
| 96 |
-
("🇬🇮 Gibraltar", "GIB"),
|
| 97 |
-
("🇬🇭 Ghana", "GHA"),
|
| 98 |
-
("🇬🇪 Georgia", "GEO"),
|
| 99 |
-
("🇬🇧 United Kingdom", "GBR"),
|
| 100 |
-
("🇬🇦 Gabon", "GAB"),
|
| 101 |
-
("🇫🇷 France", "FRA"),
|
| 102 |
-
("🇫🇮 Finland", "FIN"),
|
| 103 |
-
("🇪🇹 Ethiopia", "ETH"),
|
| 104 |
-
("🇪🇸 Spain", "ESP"),
|
| 105 |
-
("🇪🇷 Eritrea", "ERI"),
|
| 106 |
-
("🇪🇬 Egypt", "EGY"),
|
| 107 |
-
("🇪🇪 Estonia", "EST"),
|
| 108 |
-
("🇪🇨 Ecuador", "ECU"),
|
| 109 |
-
("🇩🇿 Algeria", "DZA"),
|
| 110 |
-
("🇩🇴 Dominican Republic", "DOM"),
|
| 111 |
-
("🇩🇰 Denmark", "DNK"),
|
| 112 |
-
("🇩🇪 Germany", "DEU"),
|
| 113 |
-
("🇨🇿 Czech Republic", "CZE"),
|
| 114 |
-
("🇨🇾 Cyprus", "CYP"),
|
| 115 |
-
("🇨🇺 Cuba", "CUB"),
|
| 116 |
-
("🇨🇷 Costa Rica", "CRI"),
|
| 117 |
-
("🇨🇴 Colombia", "COL"),
|
| 118 |
-
("🇨🇳 China", "CHN"),
|
| 119 |
-
("🇨🇲 Cameroon", "CMR"),
|
| 120 |
-
("🇨🇱 Chile", "CHL"),
|
| 121 |
-
("🇨🇮 Cote d'Ivoire", "CIV"),
|
| 122 |
-
("🇨🇭 Switzerland", "CHE"),
|
| 123 |
-
("🇨🇬 Congo", "COG"),
|
| 124 |
-
("🇨🇩 Democratic Republic of the Congo", "COD"),
|
| 125 |
-
("🇨🇦 Canada", "CAN"),
|
| 126 |
-
("🇧🇾 Belarus", "BLR"),
|
| 127 |
-
("🇧🇼 Botswana", "BWA"),
|
| 128 |
-
("🇧🇷 Brazil", "BRA"),
|
| 129 |
-
("🇧🇴 Bolivia", "BOL"),
|
| 130 |
-
("🇧🇳 Brunei", "BRN"),
|
| 131 |
-
("🇧🇯 Benin", "BEN"),
|
| 132 |
-
("🇧🇭 Bahrain", "BHR"),
|
| 133 |
-
("🇧🇬 Bulgaria", "BGR"),
|
| 134 |
-
("🇧🇪 Belgium", "BEL"),
|
| 135 |
-
("🇧🇩 Bangladesh", "BGD"),
|
| 136 |
-
("🇧🇦 Bosnia and Herzegovina", "BIH"),
|
| 137 |
-
("🇦🇿 Azerbaijan", "AZE"),
|
| 138 |
("🇦🇺 Australia", "AUS"),
|
| 139 |
("🇦🇹 Austria", "AUT"),
|
| 140 |
("🇦🇷 Argentina", "ARG"),
|
| 141 |
-
("
|
| 142 |
-
("
|
| 143 |
-
("
|
| 144 |
-
("
|
| 145 |
-
("
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
]
|
| 147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
-
def find_electricity_mix(code: str):
|
| 150 |
-
# TODO: Maybe more optimal to construct database at the beginning of the app
|
| 151 |
-
# in the same fashion as find_model
|
| 152 |
-
res = []
|
| 153 |
-
with open(PATH) as fd:
|
| 154 |
-
csv = DictReader(fd)
|
| 155 |
-
for row in csv:
|
| 156 |
-
res += [float(row[code])]
|
| 157 |
-
return res
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
def dataframe_electricity_mix(countries: list):
|
| 161 |
-
df = pd.read_csv("src/data/electricity_mix.csv")
|
| 162 |
-
df["name_unit"] = df["name"] + " (" + df["unit"] + ")"
|
| 163 |
-
df = df[["name_unit"] + [x[1] for x in COUNTRY_CODES if x[0] in countries]]
|
| 164 |
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
)
|
| 171 |
|
| 172 |
-
df = df_melted.pivot(columns="name_unit", index="country", values="value")
|
| 173 |
|
| 174 |
-
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
|
|
|
| 2 |
|
|
|
|
| 3 |
|
| 4 |
+
PATH = "src/data/electricity_mix.csv"
|
| 5 |
COUNTRY_CODES = [
|
| 6 |
("🌎 World", "WOR"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
("🇦🇺 Australia", "AUS"),
|
| 8 |
("🇦🇹 Austria", "AUT"),
|
| 9 |
("🇦🇷 Argentina", "ARG"),
|
| 10 |
+
("🇧🇪 Belgium", "BEL"),
|
| 11 |
+
("🇧🇬 Bulgaria", "BGR"),
|
| 12 |
+
("🇧🇷 Brazil", "BRA"),
|
| 13 |
+
("🇨🇦 Canada", "CAN"),
|
| 14 |
+
("🇨🇭 Switzerland", "CHE"),
|
| 15 |
+
("🇨🇱 Chile", "CHL"),
|
| 16 |
+
("🇨🇳 China", "CHN"),
|
| 17 |
+
("🇨🇾 Cyprus", "CYP"),
|
| 18 |
+
("🇨🇿 Czech Republic", "CZE"),
|
| 19 |
+
("🇩🇪 Germany", "DEU"),
|
| 20 |
+
("🇩🇰 Denmark", "DNK"),
|
| 21 |
+
("🇪🇸 Spain", "ESP"),
|
| 22 |
+
("🇪🇪 Estonia", "EST"),
|
| 23 |
+
("🇫🇮 Finland", "FIN"),
|
| 24 |
+
("🇫🇷 France", "FRA"),
|
| 25 |
+
("🇬🇧 United Kingdom", "GBR"),
|
| 26 |
+
("🇬🇷 Greece", "GRC"),
|
| 27 |
+
("🇭🇺 Hungary", "HUN"),
|
| 28 |
+
("🇮🇩 Indonesia", "IDN"),
|
| 29 |
+
("🇮🇳 India", "IND"),
|
| 30 |
+
("🇮🇪 Ireland", "IRL"),
|
| 31 |
+
("🇮🇸 Iceland", "ISL"),
|
| 32 |
+
("🇮🇹 Italy", "ITA"),
|
| 33 |
+
("🇯🇵 Japan", "JPN"),
|
| 34 |
+
("🇰🇷 South Korea", "KOR"),
|
| 35 |
+
("🇱🇹 Lithuania", "LTU"),
|
| 36 |
+
("🇱🇺 Luxembourg", "LUX"),
|
| 37 |
+
("🇱🇻 Latvia", "LVA"),
|
| 38 |
+
("🇲🇽 Mexico", "MEX"),
|
| 39 |
+
("🇲🇹 Malta", "MLT"),
|
| 40 |
+
("🇲🇾 Malaysia", "MYS"),
|
| 41 |
+
("🇳🇱 Netherlands", "NLD"),
|
| 42 |
+
("🇳🇴 Norway", "NOR"),
|
| 43 |
+
("🇳🇿 New Zealand", "NZL"),
|
| 44 |
+
("🇵🇱 Poland", "POL"),
|
| 45 |
+
("🇵🇹 Portugal", "PRT"),
|
| 46 |
+
("🇷🇴 Romania", "ROU"),
|
| 47 |
+
("🇷🇺 Russian Federation", "RUS"),
|
| 48 |
+
("🇸🇰 Slovak Republic", "SVK"),
|
| 49 |
+
("🇸🇮 Slovenia", "SVN"),
|
| 50 |
+
("🇸🇪 Sweden", "SWE"),
|
| 51 |
+
("🇺🇦 Ukraine", "UKR"),
|
| 52 |
+
("🇹🇭 Thailand", "THA"),
|
| 53 |
+
("🇹🇷 Turkey", "TUR"),
|
| 54 |
+
("🇹🇼 Taiwan", "TWN"),
|
| 55 |
+
("🇺🇸 United States", "USA")
|
| 56 |
]
|
| 57 |
|
| 58 |
+
CRITERIA = {
|
| 59 |
+
"gwp": "GHG Emission (kg CO2 eq)",
|
| 60 |
+
"adpe": "Abiotic Resources (kg Sb eq)",
|
| 61 |
+
"pe": "Primary Energy (MJ)",
|
| 62 |
+
"wue": "Water Usage Effectiveness (L/kWh)"
|
| 63 |
+
}
|
| 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
+
def format_country_name(code: str) -> str | None:
|
| 67 |
+
for country_name, country_code in COUNTRY_CODES:
|
| 68 |
+
if country_code == code:
|
| 69 |
+
return country_name
|
| 70 |
+
return None
|
|
|
|
| 71 |
|
|
|
|
| 72 |
|
| 73 |
+
def format_electricity_mix_criterion(criterion: str) -> str | None:
|
| 74 |
+
return CRITERIA.get(criterion)
|
src/expert.py
CHANGED
|
@@ -1,58 +1,52 @@
|
|
|
|
|
| 1 |
import streamlit as st
|
|
|
|
| 2 |
from ecologits.impacts.llm import compute_llm_impacts
|
| 3 |
|
| 4 |
-
from src.
|
|
|
|
| 5 |
from src.impacts import display_impacts
|
| 6 |
-
from src.electricity_mix import
|
| 7 |
-
COUNTRY_CODES,
|
| 8 |
-
find_electricity_mix,
|
| 9 |
-
dataframe_electricity_mix,
|
| 10 |
-
)
|
| 11 |
from src.models import load_models
|
| 12 |
from src.constants import PROMPTS
|
|
|
|
| 13 |
|
| 14 |
import plotly.express as px
|
| 15 |
|
| 16 |
|
| 17 |
-
def reset_model():
|
| 18 |
-
model = "CUSTOM"
|
| 19 |
-
|
| 20 |
-
|
| 21 |
def expert_mode():
|
| 22 |
st.markdown("### 🤓 Expert mode")
|
| 23 |
|
| 24 |
with st.container(border=True):
|
|
|
|
|
|
|
| 25 |
########## Model info ##########
|
| 26 |
|
| 27 |
-
|
| 28 |
|
| 29 |
df = load_models(filter_main=True)
|
| 30 |
|
| 31 |
-
with
|
|
|
|
| 32 |
provider_exp = st.selectbox(
|
| 33 |
label="Provider",
|
| 34 |
-
options=
|
| 35 |
-
index=
|
| 36 |
key=1,
|
| 37 |
)
|
| 38 |
|
| 39 |
-
with
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
model_exp = st.selectbox(
|
| 41 |
label="Model",
|
| 42 |
-
options=
|
| 43 |
-
x
|
| 44 |
-
for x in df["name_clean"].unique()
|
| 45 |
-
if x
|
| 46 |
-
in df[df["provider_clean"] == provider_exp]["name_clean"].unique()
|
| 47 |
-
],
|
| 48 |
key=2,
|
| 49 |
)
|
| 50 |
|
| 51 |
-
with col3:
|
| 52 |
-
output_tokens_exp = st.selectbox(
|
| 53 |
-
label="Example prompt", options=[x[0] for x in PROMPTS], key=3
|
| 54 |
-
)
|
| 55 |
-
|
| 56 |
df_filtered = df[
|
| 57 |
(df["provider_clean"] == provider_exp) & (df["name_clean"] == model_exp)
|
| 58 |
]
|
|
@@ -79,67 +73,111 @@ def expert_mode():
|
|
| 79 |
/ 2
|
| 80 |
)
|
| 81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
########## Model parameters ##########
|
| 83 |
|
| 84 |
-
|
| 85 |
|
| 86 |
-
with
|
| 87 |
-
active_params = st.number_input(
|
| 88 |
-
|
| 89 |
-
|
|
|
|
| 90 |
|
| 91 |
-
with
|
| 92 |
-
|
| 93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
)
|
| 95 |
|
| 96 |
-
with
|
| 97 |
output_tokens = st.number_input(
|
| 98 |
label="Output completion tokens",
|
| 99 |
min_value=0,
|
| 100 |
value=[x[1] for x in PROMPTS if x[0] == output_tokens_exp][0],
|
| 101 |
)
|
| 102 |
|
| 103 |
-
########## Electricity mix ##########
|
| 104 |
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
format="%0.6f",
|
| 116 |
)
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
find_electricity_mix(
|
| 122 |
-
[x[1] for x in COUNTRY_CODES if x[0] == location][0]
|
| 123 |
-
)[0],
|
| 124 |
format="%0.13f",
|
| 125 |
)
|
| 126 |
-
with
|
| 127 |
-
|
| 128 |
-
"
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
format="%0.3f",
|
| 133 |
)
|
| 134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
impacts = compute_llm_impacts(
|
| 136 |
model_active_parameter_count=active_params,
|
| 137 |
model_total_parameter_count=total_params,
|
| 138 |
output_token_count=output_tokens,
|
| 139 |
-
request_latency=
|
| 140 |
-
if_electricity_mix_gwp=
|
| 141 |
-
if_electricity_mix_adpe=
|
| 142 |
-
if_electricity_mix_pe=
|
|
|
|
|
|
|
|
|
|
| 143 |
)
|
| 144 |
|
| 145 |
impacts, usage, embodied = format_impacts(impacts)
|
|
@@ -166,8 +204,8 @@ def expert_mode():
|
|
| 166 |
with col_ghg_comparison:
|
| 167 |
fig_gwp = px.pie(
|
| 168 |
values=[
|
| 169 |
-
|
| 170 |
-
|
| 171 |
],
|
| 172 |
names=["usage", "embodied"],
|
| 173 |
title="GHG emissions",
|
|
@@ -181,8 +219,8 @@ def expert_mode():
|
|
| 181 |
with col_adpe_comparison:
|
| 182 |
fig_adpe = px.pie(
|
| 183 |
values=[
|
| 184 |
-
|
| 185 |
-
|
| 186 |
],
|
| 187 |
names=["usage", "embodied"],
|
| 188 |
title="Abiotic depletion",
|
|
@@ -196,8 +234,8 @@ def expert_mode():
|
|
| 196 |
with col_pe_comparison:
|
| 197 |
fig_pe = px.pie(
|
| 198 |
values=[
|
| 199 |
-
|
| 200 |
-
|
| 201 |
],
|
| 202 |
names=["usage", "embodied"],
|
| 203 |
title="Primary energy",
|
|
@@ -216,24 +254,25 @@ def expert_mode():
|
|
| 216 |
|
| 217 |
countries_to_compare = st.multiselect(
|
| 218 |
label="Countries to compare",
|
| 219 |
-
options=[
|
| 220 |
-
|
|
|
|
| 221 |
)
|
| 222 |
|
| 223 |
try:
|
| 224 |
-
df_comp = dataframe_electricity_mix(countries_to_compare)
|
| 225 |
-
|
| 226 |
impact_type = st.selectbox(
|
| 227 |
label="Select an impact type to compare",
|
| 228 |
-
options=[
|
| 229 |
-
|
|
|
|
| 230 |
)
|
| 231 |
|
| 232 |
-
df_comp.
|
|
|
|
| 233 |
|
| 234 |
fig_2 = px.bar(
|
| 235 |
df_comp,
|
| 236 |
-
x=df_comp.
|
| 237 |
y=impact_type,
|
| 238 |
text=impact_type,
|
| 239 |
color=impact_type,
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
import streamlit as st
|
| 3 |
+
from ecologits.electricity_mix_repository import electricity_mixes
|
| 4 |
from ecologits.impacts.llm import compute_llm_impacts
|
| 5 |
|
| 6 |
+
from src.latency_estimator import latency_estimator
|
| 7 |
+
from src.utils import format_impacts
|
| 8 |
from src.impacts import display_impacts
|
| 9 |
+
from src.electricity_mix import COUNTRY_CODES, format_electricity_mix_criterion, format_country_name
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
from src.models import load_models
|
| 11 |
from src.constants import PROMPTS
|
| 12 |
+
from src.constants import PROMPTS
|
| 13 |
|
| 14 |
import plotly.express as px
|
| 15 |
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
def expert_mode():
|
| 18 |
st.markdown("### 🤓 Expert mode")
|
| 19 |
|
| 20 |
with st.container(border=True):
|
| 21 |
+
st.markdown("###### Configure the model")
|
| 22 |
+
|
| 23 |
########## Model info ##########
|
| 24 |
|
| 25 |
+
provider_col, model_col = st.columns(2)
|
| 26 |
|
| 27 |
df = load_models(filter_main=True)
|
| 28 |
|
| 29 |
+
with provider_col:
|
| 30 |
+
providers_clean = [x for x in df["provider_clean"].unique()]
|
| 31 |
provider_exp = st.selectbox(
|
| 32 |
label="Provider",
|
| 33 |
+
options=providers_clean,
|
| 34 |
+
index=providers_clean.index("OpenAI"),
|
| 35 |
key=1,
|
| 36 |
)
|
| 37 |
|
| 38 |
+
with model_col:
|
| 39 |
+
models_clean = [
|
| 40 |
+
x
|
| 41 |
+
for x in df["name_clean"].unique()
|
| 42 |
+
if x in df[df["provider_clean"] == provider_exp]["name_clean"].unique()
|
| 43 |
+
]
|
| 44 |
model_exp = st.selectbox(
|
| 45 |
label="Model",
|
| 46 |
+
options=models_clean,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
key=2,
|
| 48 |
)
|
| 49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
df_filtered = df[
|
| 51 |
(df["provider_clean"] == provider_exp) & (df["name_clean"] == model_exp)
|
| 52 |
]
|
|
|
|
| 73 |
/ 2
|
| 74 |
)
|
| 75 |
|
| 76 |
+
provider_raw = df_filtered["provider"].values[0]
|
| 77 |
+
model_name_raw = df_filtered["name"].values[0]
|
| 78 |
+
tps_raw = latency_estimator.get_throughput(provider_raw, model_name_raw)
|
| 79 |
+
|
| 80 |
########## Model parameters ##########
|
| 81 |
|
| 82 |
+
active_params_col, total_params_col, throughput_col = st.columns(3)
|
| 83 |
|
| 84 |
+
with active_params_col:
|
| 85 |
+
active_params = st.number_input("Active parameters (B)", 0, None, active_params)
|
| 86 |
+
|
| 87 |
+
with total_params_col:
|
| 88 |
+
total_params = st.number_input("Total parameters (B)", 0, None, total_params)
|
| 89 |
|
| 90 |
+
with throughput_col:
|
| 91 |
+
throughput = st.number_input("Average TPS", 1.0, None, tps_raw)
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
with st.container(border=True):
|
| 95 |
+
st.markdown("###### Configure the prompt")
|
| 96 |
+
|
| 97 |
+
prompt_col, token_col = st.columns(2)
|
| 98 |
+
|
| 99 |
+
with prompt_col:
|
| 100 |
+
output_tokens_exp = st.selectbox(
|
| 101 |
+
label="Example prompt", options=[x[0] for x in PROMPTS], key=3
|
| 102 |
)
|
| 103 |
|
| 104 |
+
with token_col:
|
| 105 |
output_tokens = st.number_input(
|
| 106 |
label="Output completion tokens",
|
| 107 |
min_value=0,
|
| 108 |
value=[x[1] for x in PROMPTS if x[0] == output_tokens_exp][0],
|
| 109 |
)
|
| 110 |
|
|
|
|
| 111 |
|
| 112 |
+
with st.container(border=True):
|
| 113 |
+
st.markdown("###### Configure the data center")
|
| 114 |
+
|
| 115 |
+
dc_pue_col, dc_wue_col, dc_location_col = st.columns(3)
|
| 116 |
+
with dc_pue_col:
|
| 117 |
+
datacenter_pue = st.number_input(
|
| 118 |
+
label="Data center PUE",
|
| 119 |
+
value=1.2,
|
| 120 |
+
min_value=1.0
|
| 121 |
+
)
|
| 122 |
+
with dc_wue_col:
|
| 123 |
+
datacenter_wue = st.number_input(
|
| 124 |
+
label="Data center WUE [L / kWh]",
|
| 125 |
+
value=0.6,
|
| 126 |
+
min_value=0.
|
| 127 |
+
)
|
| 128 |
+
with dc_location_col:
|
| 129 |
+
dc_location = st.selectbox(
|
| 130 |
+
label="Data center location",
|
| 131 |
+
options=[c[1] for c in COUNTRY_CODES],
|
| 132 |
+
format_func=format_country_name,
|
| 133 |
+
index=0
|
| 134 |
+
)
|
| 135 |
|
| 136 |
+
em_gwp_col, em_adpe_col, em_pe_col, em_wue_col = st.columns(4)
|
| 137 |
+
electricity_mix = electricity_mixes.find_electricity_mix(dc_location)
|
| 138 |
+
with em_gwp_col:
|
| 139 |
+
em_gwp = st.number_input(
|
| 140 |
+
label="GHG emissions [kgCO2eq / kWh]",
|
| 141 |
+
value=electricity_mix.gwp,
|
| 142 |
format="%0.6f",
|
| 143 |
)
|
| 144 |
+
with em_adpe_col:
|
| 145 |
+
em_adpe = st.number_input(
|
| 146 |
+
label="Abiotic resources [kgSbeq / kWh]",
|
| 147 |
+
value=electricity_mix.adpe,
|
|
|
|
|
|
|
|
|
|
| 148 |
format="%0.13f",
|
| 149 |
)
|
| 150 |
+
with em_pe_col:
|
| 151 |
+
em_pe = st.number_input(
|
| 152 |
+
label="Primary energy [MJ / kWh]",
|
| 153 |
+
value=electricity_mix.pe,
|
| 154 |
+
format="%0.3f",
|
| 155 |
+
)
|
| 156 |
+
with em_wue_col:
|
| 157 |
+
em_wue = st.number_input(
|
| 158 |
+
label="Water consumption [L / kWh]",
|
| 159 |
+
value=electricity_mix.wue,
|
| 160 |
format="%0.3f",
|
| 161 |
)
|
| 162 |
|
| 163 |
+
estimated_latency = latency_estimator.estimate(
|
| 164 |
+
provider=provider_raw,
|
| 165 |
+
model_name=model_name_raw,
|
| 166 |
+
output_tokens=output_tokens,
|
| 167 |
+
throughput=throughput
|
| 168 |
+
)
|
| 169 |
+
|
| 170 |
impacts = compute_llm_impacts(
|
| 171 |
model_active_parameter_count=active_params,
|
| 172 |
model_total_parameter_count=total_params,
|
| 173 |
output_token_count=output_tokens,
|
| 174 |
+
request_latency=estimated_latency,
|
| 175 |
+
if_electricity_mix_gwp=em_gwp,
|
| 176 |
+
if_electricity_mix_adpe=em_adpe,
|
| 177 |
+
if_electricity_mix_pe=em_pe,
|
| 178 |
+
if_electricity_mix_wue=em_wue,
|
| 179 |
+
datacenter_pue=datacenter_pue,
|
| 180 |
+
datacenter_wue=datacenter_wue
|
| 181 |
)
|
| 182 |
|
| 183 |
impacts, usage, embodied = format_impacts(impacts)
|
|
|
|
| 204 |
with col_ghg_comparison:
|
| 205 |
fig_gwp = px.pie(
|
| 206 |
values=[
|
| 207 |
+
usage.gwp.value if isinstance(usage.gwp.value, float) else usage.gwp.value.mean,
|
| 208 |
+
embodied.gwp.value if isinstance(embodied.gwp.value, float) else embodied.gwp.value.mean,
|
| 209 |
],
|
| 210 |
names=["usage", "embodied"],
|
| 211 |
title="GHG emissions",
|
|
|
|
| 219 |
with col_adpe_comparison:
|
| 220 |
fig_adpe = px.pie(
|
| 221 |
values=[
|
| 222 |
+
usage.adpe.value if isinstance(usage.adpe.value, float) else usage.adpe.value.mean,
|
| 223 |
+
embodied.adpe.value if isinstance(embodied.adpe.value, float) else embodied.adpe.value.mean,
|
| 224 |
],
|
| 225 |
names=["usage", "embodied"],
|
| 226 |
title="Abiotic depletion",
|
|
|
|
| 234 |
with col_pe_comparison:
|
| 235 |
fig_pe = px.pie(
|
| 236 |
values=[
|
| 237 |
+
usage.pe.value if isinstance(usage.pe.value, float) else usage.pe.value.mean,
|
| 238 |
+
embodied.pe.value if isinstance(embodied.pe.value, float) else embodied.pe.value.mean,
|
| 239 |
],
|
| 240 |
names=["usage", "embodied"],
|
| 241 |
title="Primary energy",
|
|
|
|
| 254 |
|
| 255 |
countries_to_compare = st.multiselect(
|
| 256 |
label="Countries to compare",
|
| 257 |
+
options=[c[1] for c in COUNTRY_CODES],
|
| 258 |
+
format_func=format_country_name,
|
| 259 |
+
default=["FRA", "USA", "CHN"],
|
| 260 |
)
|
| 261 |
|
| 262 |
try:
|
|
|
|
|
|
|
| 263 |
impact_type = st.selectbox(
|
| 264 |
label="Select an impact type to compare",
|
| 265 |
+
options=["gwp", "adpe", "pe", "wue"],
|
| 266 |
+
format_func=format_electricity_mix_criterion,
|
| 267 |
+
index=0,
|
| 268 |
)
|
| 269 |
|
| 270 |
+
df_comp = pd.DataFrame([em for em in electricity_mixes.list_electricity_mixes() if em.zone in countries_to_compare])
|
| 271 |
+
df_comp = df_comp.sort_values(by=impact_type, ascending=True)
|
| 272 |
|
| 273 |
fig_2 = px.bar(
|
| 274 |
df_comp,
|
| 275 |
+
x=df_comp.zone.apply(format_country_name),
|
| 276 |
y=impact_type,
|
| 277 |
text=impact_type,
|
| 278 |
color=impact_type,
|
src/impacts.py
CHANGED
|
@@ -10,56 +10,58 @@ from src.utils import (
|
|
| 10 |
EnergyProduction,
|
| 11 |
)
|
| 12 |
|
| 13 |
-
############################################################################################################
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
def get_impacts(model, active_params, total_params, mix_ghg, mix_adpe, mix_pe):
|
| 17 |
-
return 1
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
############################################################################################################
|
| 21 |
-
|
| 22 |
|
| 23 |
def display_impacts(impacts):
|
| 24 |
st.divider()
|
| 25 |
|
| 26 |
-
col1, col_energy,
|
| 27 |
|
| 28 |
with col_energy:
|
| 29 |
-
|
| 30 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>⚡️</p><p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>Energy</p>""", unsafe_allow_html = True)
|
| 31 |
st.markdown(f'<p align="center">Electricity consumption</p>', unsafe_allow_html = True)
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
|
|
|
|
| 37 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>🌍️</p><p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>GHG Emissions</p>""", unsafe_allow_html = True)
|
| 38 |
-
st.markdown(f'<p align="center">Effect on global warming</p>', unsafe_allow_html = True)
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
st.markdown(f'<br>', unsafe_allow_html = True)
|
| 42 |
|
| 43 |
-
col_adpe, col_pe,
|
| 44 |
|
| 45 |
with col_adpe:
|
| 46 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>🪨</p>""", unsafe_allow_html = True)
|
| 47 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>Abiotic Resources</p>""", unsafe_allow_html = True)
|
| 48 |
st.markdown('<p align="center"> Use of metals and minerals</p>', unsafe_allow_html = True)
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
| 51 |
|
| 52 |
with col_pe:
|
| 53 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>⛽️</p>""", unsafe_allow_html = True)
|
| 54 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>Primary Energy</p>""", unsafe_allow_html = True)
|
| 55 |
st.markdown(f'<p align="center">Use of natural energy resources</p>', unsafe_allow_html = True)
|
| 56 |
-
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
-
with
|
| 59 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>🚰</p>""", unsafe_allow_html = True)
|
| 60 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>Water</p>""", unsafe_allow_html = True)
|
| 61 |
-
st.markdown(f'<p align="center">
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
|
| 65 |
|
|
|
|
| 10 |
EnergyProduction,
|
| 11 |
)
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
def display_impacts(impacts):
|
| 15 |
st.divider()
|
| 16 |
|
| 17 |
+
col1, col_energy, col_gwp, col2 = st.columns([1,2,2,1])
|
| 18 |
|
| 19 |
with col_energy:
|
|
|
|
| 20 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>⚡️</p><p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>Energy</p>""", unsafe_allow_html = True)
|
| 21 |
st.markdown(f'<p align="center">Electricity consumption</p>', unsafe_allow_html = True)
|
| 22 |
+
if impacts.ranges:
|
| 23 |
+
range_plot(impacts.energy.magnitude,impacts.energy_min.magnitude, impacts.energy_max.magnitude, impacts.energy.units)
|
| 24 |
+
else:
|
| 25 |
+
st.latex(f'\Large {impacts.energy.magnitude:.3g} \ \large {impacts.energy.units}')
|
| 26 |
|
| 27 |
+
with col_gwp:
|
| 28 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>🌍️</p><p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>GHG Emissions</p>""", unsafe_allow_html = True)
|
| 29 |
+
st.markdown(f'<p align="center">Effect on global warming</p>', unsafe_allow_html = True)
|
| 30 |
+
if impacts.ranges:
|
| 31 |
+
range_plot(impacts.gwp.magnitude,impacts.gwp_min.magnitude, impacts.gwp_max.magnitude, impacts.gwp.units)
|
| 32 |
+
else:
|
| 33 |
+
st.latex(f'\Large {impacts.gwp.magnitude:.3g} \ \large {impacts.gwp.units}')
|
| 34 |
|
| 35 |
st.markdown(f'<br>', unsafe_allow_html = True)
|
| 36 |
|
| 37 |
+
col_adpe, col_pe, col_wcf = st.columns(3)
|
| 38 |
|
| 39 |
with col_adpe:
|
| 40 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>🪨</p>""", unsafe_allow_html = True)
|
| 41 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>Abiotic Resources</p>""", unsafe_allow_html = True)
|
| 42 |
st.markdown('<p align="center"> Use of metals and minerals</p>', unsafe_allow_html = True)
|
| 43 |
+
if impacts.ranges:
|
| 44 |
+
range_plot(impacts.adpe.magnitude, impacts.adpe_min.magnitude, impacts.adpe_max.magnitude, impacts.adpe.units)
|
| 45 |
+
else:
|
| 46 |
+
st.latex(f'\Large {impacts.adpe.magnitude:.3g} \ \large {impacts.adpe.units}')
|
| 47 |
|
| 48 |
with col_pe:
|
| 49 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>⛽️</p>""", unsafe_allow_html = True)
|
| 50 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>Primary Energy</p>""", unsafe_allow_html = True)
|
| 51 |
st.markdown(f'<p align="center">Use of natural energy resources</p>', unsafe_allow_html = True)
|
| 52 |
+
if impacts.ranges:
|
| 53 |
+
range_plot(impacts.pe.magnitude, impacts.pe_min.magnitude, impacts.pe_max.magnitude, impacts.pe.units)
|
| 54 |
+
else:
|
| 55 |
+
st.latex(f'\Large {impacts.pe.magnitude:.3g} \ \large {impacts.pe.units}')
|
| 56 |
|
| 57 |
+
with col_wcf:
|
| 58 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'>🚰</p>""", unsafe_allow_html = True)
|
| 59 |
st.markdown(f"""<p style='font-size:30px;text-align: center;margin-bottom :2px'><strong>Water</p>""", unsafe_allow_html = True)
|
| 60 |
+
st.markdown(f'<p align="center">Water consumption</p>', unsafe_allow_html = True)
|
| 61 |
+
if impacts.ranges:
|
| 62 |
+
range_plot(impacts.wcf.magnitude, impacts.wcf_min.magnitude, impacts.wcf_max.magnitude, impacts.wcf.units)
|
| 63 |
+
else:
|
| 64 |
+
st.latex(f'\Large {impacts.wcf.magnitude:.3g} \ \large {impacts.wcf.units}')
|
| 65 |
|
| 66 |
|
| 67 |
|
src/latency_estimator.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import json
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
_BASE_PATH = Path(__file__).parent / "data" / "throughputs.json"
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class LatencyEstimator:
|
| 10 |
+
__DEFAULT_TPS = 80.0
|
| 11 |
+
|
| 12 |
+
def __init__(self, file_path: str | Path) -> None:
|
| 13 |
+
with open(file_path, "r") as fd:
|
| 14 |
+
data = json.load(fd)
|
| 15 |
+
|
| 16 |
+
self.__throughputs = {}
|
| 17 |
+
for el in data["models"]:
|
| 18 |
+
self.__throughputs[(el["provider"], el["name"])] = el["throughput"]
|
| 19 |
+
|
| 20 |
+
def get_throughput(self, provider: str, model_name: str) -> float:
|
| 21 |
+
return float(self.__throughputs.get((provider, model_name), self.__DEFAULT_TPS))
|
| 22 |
+
|
| 23 |
+
def estimate(self,
|
| 24 |
+
provider: str,
|
| 25 |
+
model_name: str,
|
| 26 |
+
output_tokens: int,
|
| 27 |
+
throughput: float | None = None) -> float:
|
| 28 |
+
if throughput is None:
|
| 29 |
+
throughput = self.__throughputs.get((provider, model_name), self.__DEFAULT_TPS)
|
| 30 |
+
return float(output_tokens / throughput)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
latency_estimator = LatencyEstimator(file_path=_BASE_PATH)
|
src/models.py
CHANGED
|
@@ -1,8 +1,13 @@
|
|
| 1 |
-
import requests
|
| 2 |
import json
|
|
|
|
|
|
|
| 3 |
import pandas as pd
|
| 4 |
-
from src.constants import MODEL_REPOSITORY_URL, MAIN_MODELS
|
| 5 |
import streamlit as st
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
|
| 8 |
def clean_models_data(df, with_filter=True):
|
|
@@ -70,10 +75,68 @@ def clean_models_data(df, with_filter=True):
|
|
| 70 |
]
|
| 71 |
|
| 72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
@st.cache_data
|
| 74 |
-
def load_models(filter_main=True):
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import json
|
| 2 |
+
|
| 3 |
+
import requests
|
| 4 |
import pandas as pd
|
|
|
|
| 5 |
import streamlit as st
|
| 6 |
+
from ecologits.model_repository import models as model_repository, ArchitectureTypes
|
| 7 |
+
from ecologits.status_messages import ModelArchNotReleasedWarning, ModelArchMultimodalWarning
|
| 8 |
+
from ecologits.utils.range_value import RangeValue
|
| 9 |
+
|
| 10 |
+
from src.constants import MODEL_REPOSITORY_URL, MAIN_MODELS
|
| 11 |
|
| 12 |
|
| 13 |
def clean_models_data(df, with_filter=True):
|
|
|
|
| 75 |
]
|
| 76 |
|
| 77 |
|
| 78 |
+
PROVIDERS_FORMAT = {
|
| 79 |
+
"anthropic": "Anthropic",
|
| 80 |
+
"cohere": "Cohere",
|
| 81 |
+
"google_genai": "Google",
|
| 82 |
+
"mistralai": "Mistral AI",
|
| 83 |
+
"openai": "OpenAI",
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
|
| 87 |
@st.cache_data
|
| 88 |
+
def load_models(filter_main=True) -> pd.DataFrame:
|
| 89 |
+
data = []
|
| 90 |
+
for m in model_repository.list_models():
|
| 91 |
+
if filter_main and m.name not in MAIN_MODELS:
|
| 92 |
+
continue # Ignore "not main" models when filter is enabled
|
| 93 |
+
|
| 94 |
+
if m.architecture.type == ArchitectureTypes.DENSE:
|
| 95 |
+
if isinstance(m.architecture.parameters, RangeValue):
|
| 96 |
+
total_parameters = dict(m.architecture.parameters)
|
| 97 |
+
else:
|
| 98 |
+
total_parameters = m.architecture.parameters
|
| 99 |
+
active_parameters = total_parameters
|
| 100 |
+
|
| 101 |
+
elif m.architecture.type == ArchitectureTypes.MOE:
|
| 102 |
+
if isinstance(m.architecture.parameters.total, RangeValue):
|
| 103 |
+
total_parameters = dict(m.architecture.parameters.total)
|
| 104 |
+
else:
|
| 105 |
+
total_parameters = m.architecture.parameters.total
|
| 106 |
+
|
| 107 |
+
if isinstance(m.architecture.parameters.active, RangeValue):
|
| 108 |
+
active_parameters = dict(m.architecture.parameters.active)
|
| 109 |
+
else:
|
| 110 |
+
active_parameters = m.architecture.parameters.active
|
| 111 |
+
|
| 112 |
+
else:
|
| 113 |
+
continue # Ignore model
|
| 114 |
+
|
| 115 |
+
warning_arch = False
|
| 116 |
+
warning_multi_modal = False
|
| 117 |
+
for w in m.warnings:
|
| 118 |
+
if isinstance(w, ModelArchNotReleasedWarning):
|
| 119 |
+
warning_arch = True
|
| 120 |
+
if isinstance(w, ModelArchMultimodalWarning):
|
| 121 |
+
warning_multi_modal = True
|
| 122 |
+
|
| 123 |
+
data.append({
|
| 124 |
+
"provider": m.provider.value,
|
| 125 |
+
"provider_clean": PROVIDERS_FORMAT.get(m.provider.value, m.provider.value),
|
| 126 |
+
"name": m.name,
|
| 127 |
+
"name_clean": clean_model_name(m.name),
|
| 128 |
+
"architecture_type": m.architecture.type.value,
|
| 129 |
+
"total_parameters": total_parameters,
|
| 130 |
+
"active_parameters": active_parameters,
|
| 131 |
+
"warning_arch": warning_arch,
|
| 132 |
+
"warning_multi_modal": warning_multi_modal,
|
| 133 |
+
})
|
| 134 |
+
|
| 135 |
+
return pd.DataFrame(data)
|
| 136 |
+
|
| 137 |
|
| 138 |
+
def clean_model_name(model_name: str) -> str:
|
| 139 |
+
model_name = model_name.replace("latest", "")
|
| 140 |
+
model_name = model_name.replace("-", " ")
|
| 141 |
+
model_name = model_name.replace("_", " ")
|
| 142 |
+
return model_name
|
src/style.css
CHANGED
|
@@ -4,7 +4,7 @@ html, body, [class*="css"] {
|
|
| 4 |
font-family: 'Montserrat', sans-serif;
|
| 5 |
font-size: 18px;
|
| 6 |
font-weight: 500;
|
| 7 |
-
color: #
|
| 8 |
}
|
| 9 |
|
| 10 |
[data-testid="metric-container"] {
|
|
|
|
| 4 |
font-family: 'Montserrat', sans-serif;
|
| 5 |
font-size: 18px;
|
| 6 |
font-weight: 500;
|
| 7 |
+
color: #062522;
|
| 8 |
}
|
| 9 |
|
| 10 |
[data-testid="metric-container"] {
|
src/utils.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
| 1 |
from dataclasses import dataclass
|
| 2 |
from enum import Enum
|
| 3 |
|
| 4 |
-
from ecologits.impacts.modeling import Impacts, Energy, GWP, ADPe, PE
|
| 5 |
|
| 6 |
-
# from ecologits.tracers.utils import llm_impacts
|
| 7 |
from pint import UnitRegistry, Quantity
|
| 8 |
import streamlit as st
|
| 9 |
-
import plotly.express as px
|
| 10 |
import plotly.graph_objects as go
|
| 11 |
|
| 12 |
#####################################################################################
|
|
@@ -15,16 +13,23 @@ import plotly.graph_objects as go
|
|
| 15 |
|
| 16 |
u = UnitRegistry()
|
| 17 |
u.define("Wh = watt_hour")
|
|
|
|
| 18 |
u.define("kWh = kilowatt_hour")
|
| 19 |
u.define("MWh = megawatt_hour")
|
| 20 |
u.define("GWh = gigawatt_hour")
|
| 21 |
u.define("TWh = terawatt_hour")
|
| 22 |
u.define("gCO2eq = gram")
|
|
|
|
| 23 |
u.define("kgCO2eq = kilogram")
|
| 24 |
u.define("tCO2eq = metricton")
|
| 25 |
u.define("kgSbeq = kilogram")
|
|
|
|
|
|
|
|
|
|
| 26 |
u.define("kJ = kilojoule")
|
| 27 |
u.define("MJ = megajoule")
|
|
|
|
|
|
|
| 28 |
u.define("m = meter")
|
| 29 |
u.define("km = kilometer")
|
| 30 |
u.define("s = second")
|
|
@@ -36,17 +41,22 @@ q = u.Quantity
|
|
| 36 |
@dataclass
|
| 37 |
class QImpacts:
|
| 38 |
energy: Quantity
|
| 39 |
-
energy_min : Quantity
|
| 40 |
-
energy_max : Quantity
|
| 41 |
gwp: Quantity
|
| 42 |
-
gwp_min : Quantity
|
| 43 |
-
gwp_max : Quantity
|
| 44 |
adpe: Quantity
|
| 45 |
-
adpe_min : Quantity
|
| 46 |
-
adpe_max : Quantity
|
| 47 |
pe: Quantity
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
|
| 52 |
class PhysicalActivity(str, Enum):
|
|
@@ -108,119 +118,84 @@ AIRPLANE_PARIS_NYC_GWP_EQ = q("177000 kgCO2eq")
|
|
| 108 |
#####################################################################################
|
| 109 |
|
| 110 |
|
| 111 |
-
def format_energy(
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
val_min = val_min.to("Wh")
|
| 119 |
-
val_max = val_max.to("Wh")
|
| 120 |
-
val_mean = val_mean.to("Wh")
|
| 121 |
-
|
| 122 |
-
return val_mean, val_min, val_max
|
| 123 |
|
| 124 |
|
| 125 |
-
def format_gwp(
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
energy_min=energy_min,
|
| 169 |
-
energy_max=energy_max,
|
| 170 |
-
gwp = gwp,
|
| 171 |
-
gwp_min = gwp_min,
|
| 172 |
-
gwp_max = gwp_max,
|
| 173 |
-
adpe = adpe,
|
| 174 |
-
adpe_min = adpe_min,
|
| 175 |
-
adpe_max = adpe_max,
|
| 176 |
-
pe = pe,
|
| 177 |
-
pe_min = pe_min,
|
| 178 |
-
pe_max = pe_max
|
| 179 |
-
), impacts.usage, impacts.embodied
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
def split_impacts_u_e(impacts: Impacts) -> QImpacts:
|
| 183 |
-
return impacts.usage, impacts.embodied
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
def average_range_impacts(x):
|
| 187 |
-
if isinstance(x, float):
|
| 188 |
-
return x
|
| 189 |
-
else:
|
| 190 |
-
return (x.max + x.min) / 2
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
def format_impacts_expert(impacts: Impacts, display_range: bool) -> QImpacts:
|
| 194 |
-
if display_range:
|
| 195 |
-
return (
|
| 196 |
-
QImpacts(
|
| 197 |
-
energy=format_energy(impacts.energy),
|
| 198 |
-
gwp=format_gwp(impacts.gwp),
|
| 199 |
-
adpe=format_adpe(impacts.adpe),
|
| 200 |
-
pe=format_pe(impacts.pe),
|
| 201 |
-
),
|
| 202 |
-
impacts.usage,
|
| 203 |
-
impacts.embodied,
|
| 204 |
-
)
|
| 205 |
|
| 206 |
else:
|
| 207 |
-
energy =
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
impacts.
|
| 222 |
-
impacts.
|
| 223 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
|
| 225 |
|
| 226 |
#####################################################################################
|
|
@@ -280,7 +255,7 @@ def format_energy_eq_electricity_consumption_ireland(energy: Quantity) -> Quanti
|
|
| 280 |
def format_gwp_eq_airplane_paris_nyc(gwp: Quantity) -> Quantity:
|
| 281 |
gwp_eq = gwp * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
|
| 282 |
gwp_eq = gwp_eq.to("kgCO2eq")
|
| 283 |
-
return gwp_eq / AIRPLANE_PARIS_NYC_GWP_EQ
|
| 284 |
|
| 285 |
#####################################################################################
|
| 286 |
### VISUALIZATIONS
|
|
@@ -339,4 +314,4 @@ def range_plot (mean_val, min_val, max_val, unit):
|
|
| 339 |
)
|
| 340 |
|
| 341 |
# Show the plot in Streamlit
|
| 342 |
-
st.plotly_chart(fig, use_container_width=True)
|
|
|
|
| 1 |
from dataclasses import dataclass
|
| 2 |
from enum import Enum
|
| 3 |
|
| 4 |
+
from ecologits.impacts.modeling import Impacts, Energy, GWP, ADPe, PE, WCF, Usage, Embodied
|
| 5 |
|
|
|
|
| 6 |
from pint import UnitRegistry, Quantity
|
| 7 |
import streamlit as st
|
|
|
|
| 8 |
import plotly.graph_objects as go
|
| 9 |
|
| 10 |
#####################################################################################
|
|
|
|
| 13 |
|
| 14 |
u = UnitRegistry()
|
| 15 |
u.define("Wh = watt_hour")
|
| 16 |
+
u.define("mWh = milliwatt_hour")
|
| 17 |
u.define("kWh = kilowatt_hour")
|
| 18 |
u.define("MWh = megawatt_hour")
|
| 19 |
u.define("GWh = gigawatt_hour")
|
| 20 |
u.define("TWh = terawatt_hour")
|
| 21 |
u.define("gCO2eq = gram")
|
| 22 |
+
u.define("mgCO2eq = milligram")
|
| 23 |
u.define("kgCO2eq = kilogram")
|
| 24 |
u.define("tCO2eq = metricton")
|
| 25 |
u.define("kgSbeq = kilogram")
|
| 26 |
+
u.define("gSbeq = gram")
|
| 27 |
+
u.define("mgSbeq = milligram")
|
| 28 |
+
u.define("µgSbeq = microgram")
|
| 29 |
u.define("kJ = kilojoule")
|
| 30 |
u.define("MJ = megajoule")
|
| 31 |
+
u.define("L = liter")
|
| 32 |
+
u.define("mL = milliliter")
|
| 33 |
u.define("m = meter")
|
| 34 |
u.define("km = kilometer")
|
| 35 |
u.define("s = second")
|
|
|
|
| 41 |
@dataclass
|
| 42 |
class QImpacts:
|
| 43 |
energy: Quantity
|
|
|
|
|
|
|
| 44 |
gwp: Quantity
|
|
|
|
|
|
|
| 45 |
adpe: Quantity
|
|
|
|
|
|
|
| 46 |
pe: Quantity
|
| 47 |
+
wcf: Quantity
|
| 48 |
+
ranges: bool = False
|
| 49 |
+
energy_min: Quantity | None = None
|
| 50 |
+
energy_max: Quantity | None = None
|
| 51 |
+
gwp_min: Quantity | None = None
|
| 52 |
+
gwp_max: Quantity | None = None
|
| 53 |
+
adpe_min: Quantity | None = None
|
| 54 |
+
adpe_max: Quantity | None = None
|
| 55 |
+
pe_min: Quantity | None = None
|
| 56 |
+
pe_max: Quantity | None = None
|
| 57 |
+
wcf_min: Quantity | None = None
|
| 58 |
+
wcf_max: Quantity | None = None
|
| 59 |
+
|
| 60 |
|
| 61 |
|
| 62 |
class PhysicalActivity(str, Enum):
|
|
|
|
| 118 |
#####################################################################################
|
| 119 |
|
| 120 |
|
| 121 |
+
def format_energy(energy_value: float, energy_unit = Energy(value=0.).unit) -> Quantity:
|
| 122 |
+
val = q(energy_value, energy_unit)
|
| 123 |
+
if val < q("1 kWh"):
|
| 124 |
+
val = val.to("Wh")
|
| 125 |
+
if val < q("1 Wh"):
|
| 126 |
+
val = val.to("mWh")
|
| 127 |
+
return val
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
|
| 129 |
|
| 130 |
+
def format_gwp(gwp_value: float, gwp_unit = GWP(value=0.).unit) -> Quantity:
|
| 131 |
+
val = q(gwp_value, gwp_unit)
|
| 132 |
+
if val < q("1 kgCO2eq"):
|
| 133 |
+
val = val.to("gCO2eq")
|
| 134 |
+
if val < q("1 gCO2eq"):
|
| 135 |
+
val = val.to("mgCO2eq")
|
| 136 |
+
return val
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
def format_adpe(adpe_value: float, adpe_unit = ADPe(value=0.).unit) -> Quantity:
|
| 140 |
+
val = q(adpe_value, adpe_unit)
|
| 141 |
+
if val < q("1 kgSbeq"):
|
| 142 |
+
val = val.to("gSbeq")
|
| 143 |
+
if val < q("1 gSbeq"):
|
| 144 |
+
val = val.to("mgSbeq")
|
| 145 |
+
if val < q("1 mgSbeq"):
|
| 146 |
+
val = val.to("µgSbeq")
|
| 147 |
+
return val
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
def format_pe(pe_value: float, pe_unit = PE(value=0.).unit) -> Quantity:
|
| 151 |
+
val = q(pe_value, pe_unit)
|
| 152 |
+
if val < q("1 MJ"):
|
| 153 |
+
val = val.to("kJ")
|
| 154 |
+
return val
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def format_wcf(wcf_value: float, wcf_unit = WCF(value=0.).unit) -> Quantity:
|
| 158 |
+
val = q(wcf_value, wcf_unit)
|
| 159 |
+
if val < q("1 L"):
|
| 160 |
+
val = val.to("mL")
|
| 161 |
+
return val
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
def format_impacts(impacts: Impacts) -> tuple[QImpacts, Usage, Embodied]:
|
| 165 |
+
if isinstance(impacts.energy.value, float):
|
| 166 |
+
return QImpacts(
|
| 167 |
+
energy=format_energy(impacts.energy.value),
|
| 168 |
+
gwp=format_gwp(impacts.gwp.value),
|
| 169 |
+
adpe=format_adpe(impacts.adpe.value),
|
| 170 |
+
pe=format_pe(impacts.pe.value),
|
| 171 |
+
wcf=format_wcf(impacts.wcf.value)
|
| 172 |
+
), impacts.usage, impacts.embodied
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
|
| 174 |
else:
|
| 175 |
+
energy = format_energy(impacts.energy.value.mean)
|
| 176 |
+
gwp = format_gwp(impacts.gwp.value.mean)
|
| 177 |
+
adpe = format_adpe(impacts.adpe.value.mean)
|
| 178 |
+
pe = format_pe(impacts.pe.value.mean)
|
| 179 |
+
wcf = format_wcf(impacts.wcf.value.mean)
|
| 180 |
+
|
| 181 |
+
return QImpacts(
|
| 182 |
+
energy=energy,
|
| 183 |
+
energy_min=format_energy(impacts.energy.value.min).to(energy.units),
|
| 184 |
+
energy_max=format_energy(impacts.energy.value.max).to(energy.units),
|
| 185 |
+
gwp=gwp,
|
| 186 |
+
gwp_min=format_gwp(impacts.gwp.value.min).to(gwp.units),
|
| 187 |
+
gwp_max=format_gwp(impacts.gwp.value.max).to(gwp.units),
|
| 188 |
+
adpe=adpe,
|
| 189 |
+
adpe_min=format_adpe(impacts.adpe.value.min).to(adpe.units),
|
| 190 |
+
adpe_max=format_adpe(impacts.adpe.value.max).to(adpe.units),
|
| 191 |
+
pe=pe,
|
| 192 |
+
pe_min=format_pe(impacts.pe.value.min).to(pe.units),
|
| 193 |
+
pe_max=format_pe(impacts.pe.value.max).to(pe.units),
|
| 194 |
+
wcf=wcf,
|
| 195 |
+
wcf_min=format_wcf(impacts.wcf.value.min).to(wcf.units),
|
| 196 |
+
wcf_max=format_wcf(impacts.wcf.value.max).to(wcf.units),
|
| 197 |
+
ranges=True
|
| 198 |
+
), impacts.usage, impacts.embodied
|
| 199 |
|
| 200 |
|
| 201 |
#####################################################################################
|
|
|
|
| 255 |
def format_gwp_eq_airplane_paris_nyc(gwp: Quantity) -> Quantity:
|
| 256 |
gwp_eq = gwp * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
|
| 257 |
gwp_eq = gwp_eq.to("kgCO2eq")
|
| 258 |
+
return gwp_eq / AIRPLANE_PARIS_NYC_GWP_EQ
|
| 259 |
|
| 260 |
#####################################################################################
|
| 261 |
### VISUALIZATIONS
|
|
|
|
| 314 |
)
|
| 315 |
|
| 316 |
# Show the plot in Streamlit
|
| 317 |
+
st.plotly_chart(fig, use_container_width=True)
|
uv.lock
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
version = 1
|
| 2 |
-
revision =
|
| 3 |
requires-python = ">=3.11"
|
| 4 |
resolution-markers = [
|
| 5 |
"python_full_version >= '3.12'",
|
|
@@ -31,20 +31,6 @@ wheels = [
|
|
| 31 |
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
| 32 |
]
|
| 33 |
|
| 34 |
-
[[package]]
|
| 35 |
-
name = "anyio"
|
| 36 |
-
version = "4.9.0"
|
| 37 |
-
source = { registry = "https://pypi.org/simple" }
|
| 38 |
-
dependencies = [
|
| 39 |
-
{ name = "idna" },
|
| 40 |
-
{ name = "sniffio" },
|
| 41 |
-
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
| 42 |
-
]
|
| 43 |
-
sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" }
|
| 44 |
-
wheels = [
|
| 45 |
-
{ url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" },
|
| 46 |
-
]
|
| 47 |
-
|
| 48 |
[[package]]
|
| 49 |
name = "attrs"
|
| 50 |
version = "25.3.0"
|
|
@@ -152,20 +138,13 @@ wheels = [
|
|
| 152 |
|
| 153 |
[[package]]
|
| 154 |
name = "ecologits"
|
| 155 |
-
version = "0.
|
| 156 |
-
source = {
|
| 157 |
dependencies = [
|
| 158 |
-
{ name = "httpx" },
|
| 159 |
{ name = "packaging" },
|
| 160 |
{ name = "pydantic" },
|
| 161 |
-
{ name = "requests" },
|
| 162 |
-
{ name = "tqdm" },
|
| 163 |
{ name = "wrapt" },
|
| 164 |
]
|
| 165 |
-
sdist = { url = "https://files.pythonhosted.org/packages/a4/99/6c7855fecbf28f90a7add8db581b7da700709765d128842303c28133b0a1/ecologits-0.7.3.tar.gz", hash = "sha256:ec6294eb0d0e271effe5f913dd65150da040e438738d960098e783cb1894e277", size = 33335, upload-time = "2025-07-15T17:52:26.27Z" }
|
| 166 |
-
wheels = [
|
| 167 |
-
{ url = "https://files.pythonhosted.org/packages/f5/b1/2459cc5385ff3cb7467cf10b7ec94b54685920563b7030280c665d190d40/ecologits-0.7.3-py3-none-any.whl", hash = "sha256:91c1b91800333dbfd710a4411278d6f71c9c8f0efa3942144f8eb7cb65f19e14", size = 42390, upload-time = "2025-07-15T17:52:24.954Z" },
|
| 168 |
-
]
|
| 169 |
|
| 170 |
[[package]]
|
| 171 |
name = "ecologits-calculator"
|
|
@@ -179,15 +158,23 @@ dependencies = [
|
|
| 179 |
{ name = "tiktoken" },
|
| 180 |
]
|
| 181 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
[package.metadata]
|
| 183 |
requires-dist = [
|
| 184 |
-
{ name = "ecologits",
|
| 185 |
{ name = "pint", specifier = ">=0.24.4" },
|
| 186 |
{ name = "plotly", specifier = ">=6.2.0" },
|
| 187 |
{ name = "streamlit", specifier = ">=1.47.1" },
|
| 188 |
{ name = "tiktoken", specifier = ">=0.9.0" },
|
| 189 |
]
|
| 190 |
|
|
|
|
|
|
|
|
|
|
| 191 |
[[package]]
|
| 192 |
name = "flexcache"
|
| 193 |
version = "0.3"
|
|
@@ -236,43 +223,6 @@ wheels = [
|
|
| 236 |
{ url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" },
|
| 237 |
]
|
| 238 |
|
| 239 |
-
[[package]]
|
| 240 |
-
name = "h11"
|
| 241 |
-
version = "0.16.0"
|
| 242 |
-
source = { registry = "https://pypi.org/simple" }
|
| 243 |
-
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" }
|
| 244 |
-
wheels = [
|
| 245 |
-
{ 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" },
|
| 246 |
-
]
|
| 247 |
-
|
| 248 |
-
[[package]]
|
| 249 |
-
name = "httpcore"
|
| 250 |
-
version = "1.0.9"
|
| 251 |
-
source = { registry = "https://pypi.org/simple" }
|
| 252 |
-
dependencies = [
|
| 253 |
-
{ name = "certifi" },
|
| 254 |
-
{ name = "h11" },
|
| 255 |
-
]
|
| 256 |
-
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" }
|
| 257 |
-
wheels = [
|
| 258 |
-
{ 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" },
|
| 259 |
-
]
|
| 260 |
-
|
| 261 |
-
[[package]]
|
| 262 |
-
name = "httpx"
|
| 263 |
-
version = "0.28.1"
|
| 264 |
-
source = { registry = "https://pypi.org/simple" }
|
| 265 |
-
dependencies = [
|
| 266 |
-
{ name = "anyio" },
|
| 267 |
-
{ name = "certifi" },
|
| 268 |
-
{ name = "httpcore" },
|
| 269 |
-
{ name = "idna" },
|
| 270 |
-
]
|
| 271 |
-
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" }
|
| 272 |
-
wheels = [
|
| 273 |
-
{ 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" },
|
| 274 |
-
]
|
| 275 |
-
|
| 276 |
[[package]]
|
| 277 |
name = "idna"
|
| 278 |
version = "3.10"
|
|
@@ -682,7 +632,7 @@ wheels = [
|
|
| 682 |
|
| 683 |
[[package]]
|
| 684 |
name = "pydantic"
|
| 685 |
-
version = "2.
|
| 686 |
source = { registry = "https://pypi.org/simple" }
|
| 687 |
dependencies = [
|
| 688 |
{ name = "annotated-types" },
|
|
@@ -690,74 +640,98 @@ dependencies = [
|
|
| 690 |
{ name = "typing-extensions" },
|
| 691 |
{ name = "typing-inspection" },
|
| 692 |
]
|
| 693 |
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
| 694 |
wheels = [
|
| 695 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 696 |
]
|
| 697 |
|
| 698 |
[[package]]
|
| 699 |
name = "pydantic-core"
|
| 700 |
-
version = "2.
|
| 701 |
source = { registry = "https://pypi.org/simple" }
|
| 702 |
dependencies = [
|
| 703 |
{ name = "typing-extensions" },
|
| 704 |
]
|
| 705 |
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
| 706 |
wheels = [
|
| 707 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 708 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 709 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 710 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 711 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 712 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 713 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 714 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 715 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 716 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 717 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 718 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 719 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 720 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 721 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 722 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 723 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 724 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 725 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 726 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 727 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 728 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 729 |
-
{ url = "https://files.pythonhosted.org/packages/fe/
|
| 730 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 731 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 732 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 733 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 734 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 735 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 736 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 737 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 738 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 739 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 740 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 741 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 742 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 743 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 744 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 745 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 746 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 747 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 748 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 749 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 750 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 751 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 752 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 753 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 754 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 755 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 756 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 757 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 758 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 759 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 760 |
-
{ url = "https://files.pythonhosted.org/packages/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 761 |
]
|
| 762 |
|
| 763 |
[[package]]
|
|
@@ -1006,15 +980,6 @@ wheels = [
|
|
| 1006 |
{ url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" },
|
| 1007 |
]
|
| 1008 |
|
| 1009 |
-
[[package]]
|
| 1010 |
-
name = "sniffio"
|
| 1011 |
-
version = "1.3.1"
|
| 1012 |
-
source = { registry = "https://pypi.org/simple" }
|
| 1013 |
-
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
|
| 1014 |
-
wheels = [
|
| 1015 |
-
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
|
| 1016 |
-
]
|
| 1017 |
-
|
| 1018 |
[[package]]
|
| 1019 |
name = "streamlit"
|
| 1020 |
version = "1.47.1"
|
|
@@ -1111,18 +1076,6 @@ wheels = [
|
|
| 1111 |
{ url = "https://files.pythonhosted.org/packages/55/a7/535c44c7bea4578e48281d83c615219f3ab19e6abc67625ef637c73987be/tornado-6.5.1-cp39-abi3-win_arm64.whl", hash = "sha256:02420a0eb7bf617257b9935e2b754d1b63897525d8a289c9d65690d580b4dcf7", size = 443596, upload-time = "2025-05-22T18:15:37.433Z" },
|
| 1112 |
]
|
| 1113 |
|
| 1114 |
-
[[package]]
|
| 1115 |
-
name = "tqdm"
|
| 1116 |
-
version = "4.67.1"
|
| 1117 |
-
source = { registry = "https://pypi.org/simple" }
|
| 1118 |
-
dependencies = [
|
| 1119 |
-
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
| 1120 |
-
]
|
| 1121 |
-
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" }
|
| 1122 |
-
wheels = [
|
| 1123 |
-
{ url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" },
|
| 1124 |
-
]
|
| 1125 |
-
|
| 1126 |
[[package]]
|
| 1127 |
name = "typing-extensions"
|
| 1128 |
version = "4.14.1"
|
|
@@ -1134,14 +1087,14 @@ wheels = [
|
|
| 1134 |
|
| 1135 |
[[package]]
|
| 1136 |
name = "typing-inspection"
|
| 1137 |
-
version = "0.4.
|
| 1138 |
source = { registry = "https://pypi.org/simple" }
|
| 1139 |
dependencies = [
|
| 1140 |
{ name = "typing-extensions" },
|
| 1141 |
]
|
| 1142 |
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
| 1143 |
wheels = [
|
| 1144 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1145 |
]
|
| 1146 |
|
| 1147 |
[[package]]
|
|
@@ -1168,6 +1121,15 @@ version = "6.0.0"
|
|
| 1168 |
source = { registry = "https://pypi.org/simple" }
|
| 1169 |
sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" }
|
| 1170 |
wheels = [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1171 |
{ url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" },
|
| 1172 |
{ url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" },
|
| 1173 |
{ url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" },
|
|
@@ -1182,53 +1144,59 @@ wheels = [
|
|
| 1182 |
|
| 1183 |
[[package]]
|
| 1184 |
name = "wrapt"
|
| 1185 |
-
version = "1.17.
|
| 1186 |
source = { registry = "https://pypi.org/simple" }
|
| 1187 |
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
| 1188 |
wheels = [
|
| 1189 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1190 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1191 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1192 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1193 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1194 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1195 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1196 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1197 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1198 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1199 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1200 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1201 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1202 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1203 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1204 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1205 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1206 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1207 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1208 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1209 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1210 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1211 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1212 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1213 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1214 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1215 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1216 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1217 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1218 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1219 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1220 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1221 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1222 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1223 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1224 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1225 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1226 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1227 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1228 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1229 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1230 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1231 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1232 |
-
{ url = "https://files.pythonhosted.org/packages/
|
| 1233 |
-
{ url = "https://files.pythonhosted.org/packages/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1234 |
]
|
|
|
|
| 1 |
version = 1
|
| 2 |
+
revision = 3
|
| 3 |
requires-python = ">=3.11"
|
| 4 |
resolution-markers = [
|
| 5 |
"python_full_version >= '3.12'",
|
|
|
|
| 31 |
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
| 32 |
]
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
[[package]]
|
| 35 |
name = "attrs"
|
| 36 |
version = "25.3.0"
|
|
|
|
| 138 |
|
| 139 |
[[package]]
|
| 140 |
name = "ecologits"
|
| 141 |
+
version = "0.8.2"
|
| 142 |
+
source = { git = "https://github.com/genai-impact/ecologits#81f70cf8b3e81490da226d0fa5bdaf8512e6446d" }
|
| 143 |
dependencies = [
|
|
|
|
| 144 |
{ name = "packaging" },
|
| 145 |
{ name = "pydantic" },
|
|
|
|
|
|
|
| 146 |
{ name = "wrapt" },
|
| 147 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
[[package]]
|
| 150 |
name = "ecologits-calculator"
|
|
|
|
| 158 |
{ name = "tiktoken" },
|
| 159 |
]
|
| 160 |
|
| 161 |
+
[package.dev-dependencies]
|
| 162 |
+
dev = [
|
| 163 |
+
{ name = "watchdog" },
|
| 164 |
+
]
|
| 165 |
+
|
| 166 |
[package.metadata]
|
| 167 |
requires-dist = [
|
| 168 |
+
{ name = "ecologits", git = "https://github.com/genai-impact/ecologits" },
|
| 169 |
{ name = "pint", specifier = ">=0.24.4" },
|
| 170 |
{ name = "plotly", specifier = ">=6.2.0" },
|
| 171 |
{ name = "streamlit", specifier = ">=1.47.1" },
|
| 172 |
{ name = "tiktoken", specifier = ">=0.9.0" },
|
| 173 |
]
|
| 174 |
|
| 175 |
+
[package.metadata.requires-dev]
|
| 176 |
+
dev = [{ name = "watchdog", specifier = ">=6.0.0" }]
|
| 177 |
+
|
| 178 |
[[package]]
|
| 179 |
name = "flexcache"
|
| 180 |
version = "0.3"
|
|
|
|
| 223 |
{ url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" },
|
| 224 |
]
|
| 225 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
[[package]]
|
| 227 |
name = "idna"
|
| 228 |
version = "3.10"
|
|
|
|
| 632 |
|
| 633 |
[[package]]
|
| 634 |
name = "pydantic"
|
| 635 |
+
version = "2.12.0"
|
| 636 |
source = { registry = "https://pypi.org/simple" }
|
| 637 |
dependencies = [
|
| 638 |
{ name = "annotated-types" },
|
|
|
|
| 640 |
{ name = "typing-extensions" },
|
| 641 |
{ name = "typing-inspection" },
|
| 642 |
]
|
| 643 |
+
sdist = { url = "https://files.pythonhosted.org/packages/c3/da/b8a7ee04378a53f6fefefc0c5e05570a3ebfdfa0523a878bcd3b475683ee/pydantic-2.12.0.tar.gz", hash = "sha256:c1a077e6270dbfb37bfd8b498b3981e2bb18f68103720e51fa6c306a5a9af563", size = 814760, upload-time = "2025-10-07T15:58:03.467Z" }
|
| 644 |
wheels = [
|
| 645 |
+
{ url = "https://files.pythonhosted.org/packages/f4/9d/d5c855424e2e5b6b626fbc6ec514d8e655a600377ce283008b115abb7445/pydantic-2.12.0-py3-none-any.whl", hash = "sha256:f6a1da352d42790537e95e83a8bdfb91c7efbae63ffd0b86fa823899e807116f", size = 459730, upload-time = "2025-10-07T15:58:01.576Z" },
|
| 646 |
]
|
| 647 |
|
| 648 |
[[package]]
|
| 649 |
name = "pydantic-core"
|
| 650 |
+
version = "2.41.1"
|
| 651 |
source = { registry = "https://pypi.org/simple" }
|
| 652 |
dependencies = [
|
| 653 |
{ name = "typing-extensions" },
|
| 654 |
]
|
| 655 |
+
sdist = { url = "https://files.pythonhosted.org/packages/7d/14/12b4a0d2b0b10d8e1d9a24ad94e7bbb43335eaf29c0c4e57860e8a30734a/pydantic_core-2.41.1.tar.gz", hash = "sha256:1ad375859a6d8c356b7704ec0f547a58e82ee80bb41baa811ad710e124bc8f2f", size = 454870, upload-time = "2025-10-07T10:50:45.974Z" }
|
| 656 |
wheels = [
|
| 657 |
+
{ url = "https://files.pythonhosted.org/packages/f6/a9/ec440f02e57beabdfd804725ef1e38ac1ba00c49854d298447562e119513/pydantic_core-2.41.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4f276a6134fe1fc1daa692642a3eaa2b7b858599c49a7610816388f5e37566a1", size = 2111456, upload-time = "2025-10-06T21:10:09.824Z" },
|
| 658 |
+
{ url = "https://files.pythonhosted.org/packages/f0/f9/6bc15bacfd8dcfc073a1820a564516d9c12a435a9a332d4cbbfd48828ddd/pydantic_core-2.41.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07588570a805296ece009c59d9a679dc08fab72fb337365afb4f3a14cfbfc176", size = 1915012, upload-time = "2025-10-06T21:10:11.599Z" },
|
| 659 |
+
{ url = "https://files.pythonhosted.org/packages/38/8a/d9edcdcdfe80bade17bed424284427c08bea892aaec11438fa52eaeaf79c/pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28527e4b53400cd60ffbd9812ccb2b5135d042129716d71afd7e45bf42b855c0", size = 1973762, upload-time = "2025-10-06T21:10:13.154Z" },
|
| 660 |
+
{ url = "https://files.pythonhosted.org/packages/d5/b3/ff225c6d49fba4279de04677c1c876fc3dc6562fd0c53e9bfd66f58c51a8/pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46a1c935c9228bad738c8a41de06478770927baedf581d172494ab36a6b96575", size = 2065386, upload-time = "2025-10-06T21:10:14.436Z" },
|
| 661 |
+
{ url = "https://files.pythonhosted.org/packages/47/ba/183e8c0be4321314af3fd1ae6bfc7eafdd7a49bdea5da81c56044a207316/pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:447ddf56e2b7d28d200d3e9eafa936fe40485744b5a824b67039937580b3cb20", size = 2252317, upload-time = "2025-10-06T21:10:15.719Z" },
|
| 662 |
+
{ url = "https://files.pythonhosted.org/packages/57/c5/aab61e94fd02f45c65f1f8c9ec38bb3b33fbf001a1837c74870e97462572/pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63892ead40c1160ac860b5debcc95c95c5a0035e543a8b5a4eac70dd22e995f4", size = 2373405, upload-time = "2025-10-06T21:10:17.017Z" },
|
| 663 |
+
{ url = "https://files.pythonhosted.org/packages/e5/4f/3aaa3bd1ea420a15acc42d7d3ccb3b0bbc5444ae2f9dbc1959f8173e16b8/pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4a9543ca355e6df8fbe9c83e9faab707701e9103ae857ecb40f1c0cf8b0e94d", size = 2073794, upload-time = "2025-10-06T21:10:18.383Z" },
|
| 664 |
+
{ url = "https://files.pythonhosted.org/packages/58/bd/e3975cdebe03ec080ef881648de316c73f2a6be95c14fc4efb2f7bdd0d41/pydantic_core-2.41.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2611bdb694116c31e551ed82e20e39a90bea9b7ad9e54aaf2d045ad621aa7a1", size = 2194430, upload-time = "2025-10-06T21:10:19.638Z" },
|
| 665 |
+
{ url = "https://files.pythonhosted.org/packages/2b/b8/6b7e7217f147d3b3105b57fb1caec3c4f667581affdfaab6d1d277e1f749/pydantic_core-2.41.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fecc130893a9b5f7bfe230be1bb8c61fe66a19db8ab704f808cb25a82aad0bc9", size = 2154611, upload-time = "2025-10-06T21:10:21.28Z" },
|
| 666 |
+
{ url = "https://files.pythonhosted.org/packages/fe/7b/239c2fe76bd8b7eef9ae2140d737368a3c6fea4fd27f8f6b4cde6baa3ce9/pydantic_core-2.41.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:1e2df5f8344c99b6ea5219f00fdc8950b8e6f2c422fbc1cc122ec8641fac85a1", size = 2329809, upload-time = "2025-10-06T21:10:22.678Z" },
|
| 667 |
+
{ url = "https://files.pythonhosted.org/packages/bd/2e/77a821a67ff0786f2f14856d6bd1348992f695ee90136a145d7a445c1ff6/pydantic_core-2.41.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:35291331e9d8ed94c257bab6be1cb3a380b5eee570a2784bffc055e18040a2ea", size = 2327907, upload-time = "2025-10-06T21:10:24.447Z" },
|
| 668 |
+
{ url = "https://files.pythonhosted.org/packages/fd/9a/b54512bb9df7f64c586b369328c30481229b70ca6a5fcbb90b715e15facf/pydantic_core-2.41.1-cp311-cp311-win32.whl", hash = "sha256:2876a095292668d753f1a868c4a57c4ac9f6acbd8edda8debe4218d5848cf42f", size = 1989964, upload-time = "2025-10-06T21:10:25.676Z" },
|
| 669 |
+
{ url = "https://files.pythonhosted.org/packages/9d/72/63c9a4f1a5c950e65dd522d7dd67f167681f9d4f6ece3b80085a0329f08f/pydantic_core-2.41.1-cp311-cp311-win_amd64.whl", hash = "sha256:b92d6c628e9a338846a28dfe3fcdc1a3279388624597898b105e078cdfc59298", size = 2025158, upload-time = "2025-10-06T21:10:27.522Z" },
|
| 670 |
+
{ url = "https://files.pythonhosted.org/packages/d8/16/4e2706184209f61b50c231529257c12eb6bd9eb36e99ea1272e4815d2200/pydantic_core-2.41.1-cp311-cp311-win_arm64.whl", hash = "sha256:7d82ae99409eb69d507a89835488fb657faa03ff9968a9379567b0d2e2e56bc5", size = 1972297, upload-time = "2025-10-06T21:10:28.814Z" },
|
| 671 |
+
{ url = "https://files.pythonhosted.org/packages/ee/bc/5f520319ee1c9e25010412fac4154a72e0a40d0a19eb00281b1f200c0947/pydantic_core-2.41.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:db2f82c0ccbce8f021ad304ce35cbe02aa2f95f215cac388eed542b03b4d5eb4", size = 2099300, upload-time = "2025-10-06T21:10:30.463Z" },
|
| 672 |
+
{ url = "https://files.pythonhosted.org/packages/31/14/010cd64c5c3814fb6064786837ec12604be0dd46df3327cf8474e38abbbd/pydantic_core-2.41.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47694a31c710ced9205d5f1e7e8af3ca57cbb8a503d98cb9e33e27c97a501601", size = 1910179, upload-time = "2025-10-06T21:10:31.782Z" },
|
| 673 |
+
{ url = "https://files.pythonhosted.org/packages/8e/2e/23fc2a8a93efad52df302fdade0a60f471ecc0c7aac889801ac24b4c07d6/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e9decce94daf47baf9e9d392f5f2557e783085f7c5e522011545d9d6858e00", size = 1957225, upload-time = "2025-10-06T21:10:33.11Z" },
|
| 674 |
+
{ url = "https://files.pythonhosted.org/packages/b9/b6/6db08b2725b2432b9390844852e11d320281e5cea8a859c52c68001975fa/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab0adafdf2b89c8b84f847780a119437a0931eca469f7b44d356f2b426dd9741", size = 2053315, upload-time = "2025-10-06T21:10:34.87Z" },
|
| 675 |
+
{ url = "https://files.pythonhosted.org/packages/61/d9/4de44600f2d4514b44f3f3aeeda2e14931214b6b5bf52479339e801ce748/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5da98cc81873f39fd56882e1569c4677940fbc12bce6213fad1ead784192d7c8", size = 2224298, upload-time = "2025-10-06T21:10:36.233Z" },
|
| 676 |
+
{ url = "https://files.pythonhosted.org/packages/7a/ae/dbe51187a7f35fc21b283c5250571a94e36373eb557c1cba9f29a9806dcf/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:209910e88afb01fd0fd403947b809ba8dba0e08a095e1f703294fda0a8fdca51", size = 2351797, upload-time = "2025-10-06T21:10:37.601Z" },
|
| 677 |
+
{ url = "https://files.pythonhosted.org/packages/b5/a7/975585147457c2e9fb951c7c8dab56deeb6aa313f3aa72c2fc0df3f74a49/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365109d1165d78d98e33c5bfd815a9b5d7d070f578caefaabcc5771825b4ecb5", size = 2074921, upload-time = "2025-10-06T21:10:38.927Z" },
|
| 678 |
+
{ url = "https://files.pythonhosted.org/packages/62/37/ea94d1d0c01dec1b7d236c7cec9103baab0021f42500975de3d42522104b/pydantic_core-2.41.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:706abf21e60a2857acdb09502bc853ee5bce732955e7b723b10311114f033115", size = 2187767, upload-time = "2025-10-06T21:10:40.651Z" },
|
| 679 |
+
{ url = "https://files.pythonhosted.org/packages/d3/fe/694cf9fdd3a777a618c3afd210dba7b414cb8a72b1bd29b199c2e5765fee/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bf0bd5417acf7f6a7ec3b53f2109f587be176cb35f9cf016da87e6017437a72d", size = 2136062, upload-time = "2025-10-06T21:10:42.09Z" },
|
| 680 |
+
{ url = "https://files.pythonhosted.org/packages/0f/ae/174aeabd89916fbd2988cc37b81a59e1186e952afd2a7ed92018c22f31ca/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:2e71b1c6ceb9c78424ae9f63a07292fb769fb890a4e7efca5554c47f33a60ea5", size = 2317819, upload-time = "2025-10-06T21:10:43.974Z" },
|
| 681 |
+
{ url = "https://files.pythonhosted.org/packages/65/e8/e9aecafaebf53fc456314f72886068725d6fba66f11b013532dc21259343/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:80745b9770b4a38c25015b517451c817799bfb9d6499b0d13d8227ec941cb513", size = 2312267, upload-time = "2025-10-06T21:10:45.34Z" },
|
| 682 |
+
{ url = "https://files.pythonhosted.org/packages/35/2f/1c2e71d2a052f9bb2f2df5a6a05464a0eb800f9e8d9dd800202fe31219e1/pydantic_core-2.41.1-cp312-cp312-win32.whl", hash = "sha256:83b64d70520e7890453f1aa21d66fda44e7b35f1cfea95adf7b4289a51e2b479", size = 1990927, upload-time = "2025-10-06T21:10:46.738Z" },
|
| 683 |
+
{ url = "https://files.pythonhosted.org/packages/b1/78/562998301ff2588b9c6dcc5cb21f52fa919d6e1decc75a35055feb973594/pydantic_core-2.41.1-cp312-cp312-win_amd64.whl", hash = "sha256:377defd66ee2003748ee93c52bcef2d14fde48fe28a0b156f88c3dbf9bc49a50", size = 2034703, upload-time = "2025-10-06T21:10:48.524Z" },
|
| 684 |
+
{ url = "https://files.pythonhosted.org/packages/b2/53/d95699ce5a5cdb44bb470bd818b848b9beadf51459fd4ea06667e8ede862/pydantic_core-2.41.1-cp312-cp312-win_arm64.whl", hash = "sha256:c95caff279d49c1d6cdfe2996e6c2ad712571d3b9caaa209a404426c326c4bde", size = 1972719, upload-time = "2025-10-06T21:10:50.256Z" },
|
| 685 |
+
{ url = "https://files.pythonhosted.org/packages/27/8a/6d54198536a90a37807d31a156642aae7a8e1263ed9fe6fc6245defe9332/pydantic_core-2.41.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70e790fce5f05204ef4403159857bfcd587779da78627b0babb3654f75361ebf", size = 2105825, upload-time = "2025-10-06T21:10:51.719Z" },
|
| 686 |
+
{ url = "https://files.pythonhosted.org/packages/4f/2e/4784fd7b22ac9c8439db25bf98ffed6853d01e7e560a346e8af821776ccc/pydantic_core-2.41.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9cebf1ca35f10930612d60bd0f78adfacee824c30a880e3534ba02c207cceceb", size = 1910126, upload-time = "2025-10-06T21:10:53.145Z" },
|
| 687 |
+
{ url = "https://files.pythonhosted.org/packages/f3/92/31eb0748059ba5bd0aa708fb4bab9fcb211461ddcf9e90702a6542f22d0d/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:170406a37a5bc82c22c3274616bf6f17cc7df9c4a0a0a50449e559cb755db669", size = 1961472, upload-time = "2025-10-06T21:10:55.754Z" },
|
| 688 |
+
{ url = "https://files.pythonhosted.org/packages/ab/91/946527792275b5c4c7dde4cfa3e81241bf6900e9fee74fb1ba43e0c0f1ab/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:12d4257fc9187a0ccd41b8b327d6a4e57281ab75e11dda66a9148ef2e1fb712f", size = 2063230, upload-time = "2025-10-06T21:10:57.179Z" },
|
| 689 |
+
{ url = "https://files.pythonhosted.org/packages/31/5d/a35c5d7b414e5c0749f1d9f0d159ee2ef4bab313f499692896b918014ee3/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a75a33b4db105dd1c8d57839e17ee12db8d5ad18209e792fa325dbb4baeb00f4", size = 2229469, upload-time = "2025-10-06T21:10:59.409Z" },
|
| 690 |
+
{ url = "https://files.pythonhosted.org/packages/21/4d/8713737c689afa57ecfefe38db78259d4484c97aa494979e6a9d19662584/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08a589f850803a74e0fcb16a72081cafb0d72a3cdda500106942b07e76b7bf62", size = 2347986, upload-time = "2025-10-06T21:11:00.847Z" },
|
| 691 |
+
{ url = "https://files.pythonhosted.org/packages/f6/ec/929f9a3a5ed5cda767081494bacd32f783e707a690ce6eeb5e0730ec4986/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a97939d6ea44763c456bd8a617ceada2c9b96bb5b8ab3dfa0d0827df7619014", size = 2072216, upload-time = "2025-10-06T21:11:02.43Z" },
|
| 692 |
+
{ url = "https://files.pythonhosted.org/packages/26/55/a33f459d4f9cc8786d9db42795dbecc84fa724b290d7d71ddc3d7155d46a/pydantic_core-2.41.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae423c65c556f09569524b80ffd11babff61f33055ef9773d7c9fabc11ed8d", size = 2193047, upload-time = "2025-10-06T21:11:03.787Z" },
|
| 693 |
+
{ url = "https://files.pythonhosted.org/packages/77/af/d5c6959f8b089f2185760a2779079e3c2c411bfc70ea6111f58367851629/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:4dc703015fbf8764d6a8001c327a87f1823b7328d40b47ce6000c65918ad2b4f", size = 2140613, upload-time = "2025-10-06T21:11:05.607Z" },
|
| 694 |
+
{ url = "https://files.pythonhosted.org/packages/58/e5/2c19bd2a14bffe7fabcf00efbfbd3ac430aaec5271b504a938ff019ac7be/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:968e4ffdfd35698a5fe659e5e44c508b53664870a8e61c8f9d24d3d145d30257", size = 2327641, upload-time = "2025-10-06T21:11:07.143Z" },
|
| 695 |
+
{ url = "https://files.pythonhosted.org/packages/93/ef/e0870ccda798c54e6b100aff3c4d49df5458fd64217e860cb9c3b0a403f4/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:fff2b76c8e172d34771cd4d4f0ade08072385310f214f823b5a6ad4006890d32", size = 2318229, upload-time = "2025-10-06T21:11:08.73Z" },
|
| 696 |
+
{ url = "https://files.pythonhosted.org/packages/b1/4b/c3b991d95f5deb24d0bd52e47bcf716098fa1afe0ce2d4bd3125b38566ba/pydantic_core-2.41.1-cp313-cp313-win32.whl", hash = "sha256:a38a5263185407ceb599f2f035faf4589d57e73c7146d64f10577f6449e8171d", size = 1997911, upload-time = "2025-10-06T21:11:10.329Z" },
|
| 697 |
+
{ url = "https://files.pythonhosted.org/packages/a7/ce/5c316fd62e01f8d6be1b7ee6b54273214e871772997dc2c95e204997a055/pydantic_core-2.41.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42ae7fd6760782c975897e1fdc810f483b021b32245b0105d40f6e7a3803e4b", size = 2034301, upload-time = "2025-10-06T21:11:12.113Z" },
|
| 698 |
+
{ url = "https://files.pythonhosted.org/packages/29/41/902640cfd6a6523194123e2c3373c60f19006447f2fb06f76de4e8466c5b/pydantic_core-2.41.1-cp313-cp313-win_arm64.whl", hash = "sha256:ad4111acc63b7384e205c27a2f15e23ac0ee21a9d77ad6f2e9cb516ec90965fb", size = 1977238, upload-time = "2025-10-06T21:11:14.1Z" },
|
| 699 |
+
{ url = "https://files.pythonhosted.org/packages/04/04/28b040e88c1b89d851278478842f0bdf39c7a05da9e850333c6c8cbe7dfa/pydantic_core-2.41.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:440d0df7415b50084a4ba9d870480c16c5f67c0d1d4d5119e3f70925533a0edc", size = 1875626, upload-time = "2025-10-06T21:11:15.69Z" },
|
| 700 |
+
{ url = "https://files.pythonhosted.org/packages/d6/58/b41dd3087505220bb58bc81be8c3e8cbc037f5710cd3c838f44f90bdd704/pydantic_core-2.41.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71eaa38d342099405dae6484216dcf1e8e4b0bebd9b44a4e08c9b43db6a2ab67", size = 2045708, upload-time = "2025-10-06T21:11:17.258Z" },
|
| 701 |
+
{ url = "https://files.pythonhosted.org/packages/d7/b8/760f23754e40bf6c65b94a69b22c394c24058a0ef7e2aa471d2e39219c1a/pydantic_core-2.41.1-cp313-cp313t-win_amd64.whl", hash = "sha256:555ecf7e50f1161d3f693bc49f23c82cf6cdeafc71fa37a06120772a09a38795", size = 1997171, upload-time = "2025-10-06T21:11:18.822Z" },
|
| 702 |
+
{ url = "https://files.pythonhosted.org/packages/41/12/cec246429ddfa2778d2d6301eca5362194dc8749ecb19e621f2f65b5090f/pydantic_core-2.41.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:05226894a26f6f27e1deb735d7308f74ef5fa3a6de3e0135bb66cdcaee88f64b", size = 2107836, upload-time = "2025-10-06T21:11:20.432Z" },
|
| 703 |
+
{ url = "https://files.pythonhosted.org/packages/20/39/baba47f8d8b87081302498e610aefc37142ce6a1cc98b2ab6b931a162562/pydantic_core-2.41.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:85ff7911c6c3e2fd8d3779c50925f6406d770ea58ea6dde9c230d35b52b16b4a", size = 1904449, upload-time = "2025-10-06T21:11:22.185Z" },
|
| 704 |
+
{ url = "https://files.pythonhosted.org/packages/50/32/9a3d87cae2c75a5178334b10358d631bd094b916a00a5993382222dbfd92/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47f1f642a205687d59b52dc1a9a607f45e588f5a2e9eeae05edd80c7a8c47674", size = 1961750, upload-time = "2025-10-06T21:11:24.348Z" },
|
| 705 |
+
{ url = "https://files.pythonhosted.org/packages/27/42/a96c9d793a04cf2a9773bff98003bb154087b94f5530a2ce6063ecfec583/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df11c24e138876ace5ec6043e5cae925e34cf38af1a1b3d63589e8f7b5f5cdc4", size = 2063305, upload-time = "2025-10-06T21:11:26.556Z" },
|
| 706 |
+
{ url = "https://files.pythonhosted.org/packages/3e/8d/028c4b7d157a005b1f52c086e2d4b0067886b213c86220c1153398dbdf8f/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f0bf7f5c8f7bf345c527e8a0d72d6b26eda99c1227b0c34e7e59e181260de31", size = 2228959, upload-time = "2025-10-06T21:11:28.426Z" },
|
| 707 |
+
{ url = "https://files.pythonhosted.org/packages/08/f7/ee64cda8fcc9ca3f4716e6357144f9ee71166775df582a1b6b738bf6da57/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82b887a711d341c2c47352375d73b029418f55b20bd7815446d175a70effa706", size = 2345421, upload-time = "2025-10-06T21:11:30.226Z" },
|
| 708 |
+
{ url = "https://files.pythonhosted.org/packages/13/c0/e8ec05f0f5ee7a3656973ad9cd3bc73204af99f6512c1a4562f6fb4b3f7d/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5f1d5d6bbba484bdf220c72d8ecd0be460f4bd4c5e534a541bb2cd57589fb8b", size = 2065288, upload-time = "2025-10-06T21:11:32.019Z" },
|
| 709 |
+
{ url = "https://files.pythonhosted.org/packages/0a/25/d77a73ff24e2e4fcea64472f5e39b0402d836da9b08b5361a734d0153023/pydantic_core-2.41.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bf1917385ebe0f968dc5c6ab1375886d56992b93ddfe6bf52bff575d03662be", size = 2189759, upload-time = "2025-10-06T21:11:33.753Z" },
|
| 710 |
+
{ url = "https://files.pythonhosted.org/packages/66/45/4a4ebaaae12a740552278d06fe71418c0f2869537a369a89c0e6723b341d/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:4f94f3ab188f44b9a73f7295663f3ecb8f2e2dd03a69c8f2ead50d37785ecb04", size = 2140747, upload-time = "2025-10-06T21:11:35.781Z" },
|
| 711 |
+
{ url = "https://files.pythonhosted.org/packages/da/6d/b727ce1022f143194a36593243ff244ed5a1eb3c9122296bf7e716aa37ba/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:3925446673641d37c30bd84a9d597e49f72eacee8b43322c8999fa17d5ae5bc4", size = 2327416, upload-time = "2025-10-06T21:11:37.75Z" },
|
| 712 |
+
{ url = "https://files.pythonhosted.org/packages/6f/8c/02df9d8506c427787059f87c6c7253435c6895e12472a652d9616ee0fc95/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:49bd51cc27adb980c7b97357ae036ce9b3c4d0bb406e84fbe16fb2d368b602a8", size = 2318138, upload-time = "2025-10-06T21:11:39.463Z" },
|
| 713 |
+
{ url = "https://files.pythonhosted.org/packages/98/67/0cf429a7d6802536941f430e6e3243f6d4b68f41eeea4b242372f1901794/pydantic_core-2.41.1-cp314-cp314-win32.whl", hash = "sha256:a31ca0cd0e4d12ea0df0077df2d487fc3eb9d7f96bbb13c3c5b88dcc21d05159", size = 1998429, upload-time = "2025-10-06T21:11:41.989Z" },
|
| 714 |
+
{ url = "https://files.pythonhosted.org/packages/38/60/742fef93de5d085022d2302a6317a2b34dbfe15258e9396a535c8a100ae7/pydantic_core-2.41.1-cp314-cp314-win_amd64.whl", hash = "sha256:1b5c4374a152e10a22175d7790e644fbd8ff58418890e07e2073ff9d4414efae", size = 2028870, upload-time = "2025-10-06T21:11:43.66Z" },
|
| 715 |
+
{ url = "https://files.pythonhosted.org/packages/31/38/cdd8ccb8555ef7720bd7715899bd6cfbe3c29198332710e1b61b8f5dd8b8/pydantic_core-2.41.1-cp314-cp314-win_arm64.whl", hash = "sha256:4fee76d757639b493eb600fba668f1e17475af34c17dd61db7a47e824d464ca9", size = 1974275, upload-time = "2025-10-06T21:11:45.476Z" },
|
| 716 |
+
{ url = "https://files.pythonhosted.org/packages/e7/7e/8ac10ccb047dc0221aa2530ec3c7c05ab4656d4d4bd984ee85da7f3d5525/pydantic_core-2.41.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f9b9c968cfe5cd576fdd7361f47f27adeb120517e637d1b189eea1c3ece573f4", size = 1875124, upload-time = "2025-10-06T21:11:47.591Z" },
|
| 717 |
+
{ url = "https://files.pythonhosted.org/packages/c3/e4/7d9791efeb9c7d97e7268f8d20e0da24d03438a7fa7163ab58f1073ba968/pydantic_core-2.41.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1ebc7ab67b856384aba09ed74e3e977dded40e693de18a4f197c67d0d4e6d8e", size = 2043075, upload-time = "2025-10-06T21:11:49.542Z" },
|
| 718 |
+
{ url = "https://files.pythonhosted.org/packages/2d/c3/3f6e6b2342ac11ac8cd5cb56e24c7b14afa27c010e82a765ffa5f771884a/pydantic_core-2.41.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8ae0dc57b62a762985bc7fbf636be3412394acc0ddb4ade07fe104230f1b9762", size = 1995341, upload-time = "2025-10-06T21:11:51.497Z" },
|
| 719 |
+
{ url = "https://files.pythonhosted.org/packages/16/89/d0afad37ba25f5801735af1472e650b86baad9fe807a42076508e4824a2a/pydantic_core-2.41.1-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:68f2251559b8efa99041bb63571ec7cdd2d715ba74cc82b3bc9eff824ebc8bf0", size = 2124001, upload-time = "2025-10-07T10:49:54.369Z" },
|
| 720 |
+
{ url = "https://files.pythonhosted.org/packages/8e/c4/08609134b34520568ddebb084d9ed0a2a3f5f52b45739e6e22cb3a7112eb/pydantic_core-2.41.1-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:c7bc140c596097cb53b30546ca257dbe3f19282283190b1b5142928e5d5d3a20", size = 1941841, upload-time = "2025-10-07T10:49:56.248Z" },
|
| 721 |
+
{ url = "https://files.pythonhosted.org/packages/2a/43/94a4877094e5fe19a3f37e7e817772263e2c573c94f1e3fa2b1eee56ef3b/pydantic_core-2.41.1-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2896510fce8f4725ec518f8b9d7f015a00db249d2fd40788f442af303480063d", size = 1961129, upload-time = "2025-10-07T10:49:58.298Z" },
|
| 722 |
+
{ url = "https://files.pythonhosted.org/packages/a2/30/23a224d7e25260eb5f69783a63667453037e07eb91ff0e62dabaadd47128/pydantic_core-2.41.1-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ced20e62cfa0f496ba68fa5d6c7ee71114ea67e2a5da3114d6450d7f4683572a", size = 2148770, upload-time = "2025-10-07T10:49:59.959Z" },
|
| 723 |
+
{ url = "https://files.pythonhosted.org/packages/2b/3e/a51c5f5d37b9288ba30683d6e96f10fa8f1defad1623ff09f1020973b577/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b04fa9ed049461a7398138c604b00550bc89e3e1151d84b81ad6dc93e39c4c06", size = 2115344, upload-time = "2025-10-07T10:50:02.466Z" },
|
| 724 |
+
{ url = "https://files.pythonhosted.org/packages/5a/bd/389504c9e0600ef4502cd5238396b527afe6ef8981a6a15cd1814fc7b434/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:b3b7d9cfbfdc43c80a16638c6dc2768e3956e73031fca64e8e1a3ae744d1faeb", size = 1927994, upload-time = "2025-10-07T10:50:04.379Z" },
|
| 725 |
+
{ url = "https://files.pythonhosted.org/packages/ff/9c/5111c6b128861cb792a4c082677e90dac4f2e090bb2e2fe06aa5b2d39027/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eec83fc6abef04c7f9bec616e2d76ee9a6a4ae2a359b10c21d0f680e24a247ca", size = 1959394, upload-time = "2025-10-07T10:50:06.335Z" },
|
| 726 |
+
{ url = "https://files.pythonhosted.org/packages/14/3f/cfec8b9a0c48ce5d64409ec5e1903cb0b7363da38f14b41de2fcb3712700/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6771a2d9f83c4038dfad5970a3eef215940682b2175e32bcc817bdc639019b28", size = 2147365, upload-time = "2025-10-07T10:50:07.978Z" },
|
| 727 |
+
{ url = "https://files.pythonhosted.org/packages/e6/6c/fa3e45c2b054a1e627a89a364917f12cbe3abc3e91b9004edaae16e7b3c5/pydantic_core-2.41.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:af2385d3f98243fb733862f806c5bb9122e5fba05b373e3af40e3c82d711cef1", size = 2112094, upload-time = "2025-10-07T10:50:25.513Z" },
|
| 728 |
+
{ url = "https://files.pythonhosted.org/packages/e5/17/7eebc38b4658cc8e6902d0befc26388e4c2a5f2e179c561eeb43e1922c7b/pydantic_core-2.41.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:6550617a0c2115be56f90c31a5370261d8ce9dbf051c3ed53b51172dd34da696", size = 1935300, upload-time = "2025-10-07T10:50:27.715Z" },
|
| 729 |
+
{ url = "https://files.pythonhosted.org/packages/2b/00/9fe640194a1717a464ab861d43595c268830f98cb1e2705aa134b3544b70/pydantic_core-2.41.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc17b6ecf4983d298686014c92ebc955a9f9baf9f57dad4065e7906e7bee6222", size = 1970417, upload-time = "2025-10-07T10:50:29.573Z" },
|
| 730 |
+
{ url = "https://files.pythonhosted.org/packages/b2/ad/f4cdfaf483b78ee65362363e73b6b40c48e067078d7b146e8816d5945ad6/pydantic_core-2.41.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:42ae9352cf211f08b04ea110563d6b1e415878eea5b4c70f6bdb17dca3b932d2", size = 2190745, upload-time = "2025-10-07T10:50:31.48Z" },
|
| 731 |
+
{ url = "https://files.pythonhosted.org/packages/cb/c1/18f416d40a10f44e9387497ba449f40fdb1478c61ba05c4b6bdb82300362/pydantic_core-2.41.1-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e82947de92068b0a21681a13dd2102387197092fbe7defcfb8453e0913866506", size = 2150888, upload-time = "2025-10-07T10:50:33.477Z" },
|
| 732 |
+
{ url = "https://files.pythonhosted.org/packages/42/30/134c8a921630d8a88d6f905a562495a6421e959a23c19b0f49b660801d67/pydantic_core-2.41.1-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e244c37d5471c9acdcd282890c6c4c83747b77238bfa19429b8473586c907656", size = 2324489, upload-time = "2025-10-07T10:50:36.48Z" },
|
| 733 |
+
{ url = "https://files.pythonhosted.org/packages/9c/48/a9263aeaebdec81e941198525b43edb3b44f27cfa4cb8005b8d3eb8dec72/pydantic_core-2.41.1-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1e798b4b304a995110d41ec93653e57975620ccb2842ba9420037985e7d7284e", size = 2322763, upload-time = "2025-10-07T10:50:38.751Z" },
|
| 734 |
+
{ url = "https://files.pythonhosted.org/packages/1d/62/755d2bd2593f701c5839fc084e9c2c5e2418f460383ad04e3b5d0befc3ca/pydantic_core-2.41.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f1fc716c0eb1663c59699b024428ad5ec2bcc6b928527b8fe28de6cb89f47efb", size = 2144046, upload-time = "2025-10-07T10:50:40.686Z" },
|
| 735 |
]
|
| 736 |
|
| 737 |
[[package]]
|
|
|
|
| 980 |
{ url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" },
|
| 981 |
]
|
| 982 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 983 |
[[package]]
|
| 984 |
name = "streamlit"
|
| 985 |
version = "1.47.1"
|
|
|
|
| 1076 |
{ url = "https://files.pythonhosted.org/packages/55/a7/535c44c7bea4578e48281d83c615219f3ab19e6abc67625ef637c73987be/tornado-6.5.1-cp39-abi3-win_arm64.whl", hash = "sha256:02420a0eb7bf617257b9935e2b754d1b63897525d8a289c9d65690d580b4dcf7", size = 443596, upload-time = "2025-05-22T18:15:37.433Z" },
|
| 1077 |
]
|
| 1078 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1079 |
[[package]]
|
| 1080 |
name = "typing-extensions"
|
| 1081 |
version = "4.14.1"
|
|
|
|
| 1087 |
|
| 1088 |
[[package]]
|
| 1089 |
name = "typing-inspection"
|
| 1090 |
+
version = "0.4.2"
|
| 1091 |
source = { registry = "https://pypi.org/simple" }
|
| 1092 |
dependencies = [
|
| 1093 |
{ name = "typing-extensions" },
|
| 1094 |
]
|
| 1095 |
+
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
| 1096 |
wheels = [
|
| 1097 |
+
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
|
| 1098 |
]
|
| 1099 |
|
| 1100 |
[[package]]
|
|
|
|
| 1121 |
source = { registry = "https://pypi.org/simple" }
|
| 1122 |
sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" }
|
| 1123 |
wheels = [
|
| 1124 |
+
{ url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" },
|
| 1125 |
+
{ url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" },
|
| 1126 |
+
{ url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" },
|
| 1127 |
+
{ url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" },
|
| 1128 |
+
{ url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" },
|
| 1129 |
+
{ url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" },
|
| 1130 |
+
{ url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" },
|
| 1131 |
+
{ url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" },
|
| 1132 |
+
{ url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" },
|
| 1133 |
{ url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" },
|
| 1134 |
{ url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" },
|
| 1135 |
{ url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" },
|
|
|
|
| 1144 |
|
| 1145 |
[[package]]
|
| 1146 |
name = "wrapt"
|
| 1147 |
+
version = "1.17.3"
|
| 1148 |
source = { registry = "https://pypi.org/simple" }
|
| 1149 |
+
sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" }
|
| 1150 |
wheels = [
|
| 1151 |
+
{ url = "https://files.pythonhosted.org/packages/52/db/00e2a219213856074a213503fdac0511203dceefff26e1daa15250cc01a0/wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7", size = 53482, upload-time = "2025-08-12T05:51:45.79Z" },
|
| 1152 |
+
{ url = "https://files.pythonhosted.org/packages/5e/30/ca3c4a5eba478408572096fe9ce36e6e915994dd26a4e9e98b4f729c06d9/wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85", size = 38674, upload-time = "2025-08-12T05:51:34.629Z" },
|
| 1153 |
+
{ url = "https://files.pythonhosted.org/packages/31/25/3e8cc2c46b5329c5957cec959cb76a10718e1a513309c31399a4dad07eb3/wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f", size = 38959, upload-time = "2025-08-12T05:51:56.074Z" },
|
| 1154 |
+
{ url = "https://files.pythonhosted.org/packages/5d/8f/a32a99fc03e4b37e31b57cb9cefc65050ea08147a8ce12f288616b05ef54/wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311", size = 82376, upload-time = "2025-08-12T05:52:32.134Z" },
|
| 1155 |
+
{ url = "https://files.pythonhosted.org/packages/31/57/4930cb8d9d70d59c27ee1332a318c20291749b4fba31f113c2f8ac49a72e/wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1", size = 83604, upload-time = "2025-08-12T05:52:11.663Z" },
|
| 1156 |
+
{ url = "https://files.pythonhosted.org/packages/a8/f3/1afd48de81d63dd66e01b263a6fbb86e1b5053b419b9b33d13e1f6d0f7d0/wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5", size = 82782, upload-time = "2025-08-12T05:52:12.626Z" },
|
| 1157 |
+
{ url = "https://files.pythonhosted.org/packages/1e/d7/4ad5327612173b144998232f98a85bb24b60c352afb73bc48e3e0d2bdc4e/wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2", size = 82076, upload-time = "2025-08-12T05:52:33.168Z" },
|
| 1158 |
+
{ url = "https://files.pythonhosted.org/packages/bb/59/e0adfc831674a65694f18ea6dc821f9fcb9ec82c2ce7e3d73a88ba2e8718/wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89", size = 36457, upload-time = "2025-08-12T05:53:03.936Z" },
|
| 1159 |
+
{ url = "https://files.pythonhosted.org/packages/83/88/16b7231ba49861b6f75fc309b11012ede4d6b0a9c90969d9e0db8d991aeb/wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77", size = 38745, upload-time = "2025-08-12T05:53:02.885Z" },
|
| 1160 |
+
{ url = "https://files.pythonhosted.org/packages/9a/1e/c4d4f3398ec073012c51d1c8d87f715f56765444e1a4b11e5180577b7e6e/wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a", size = 36806, upload-time = "2025-08-12T05:52:53.368Z" },
|
| 1161 |
+
{ url = "https://files.pythonhosted.org/packages/9f/41/cad1aba93e752f1f9268c77270da3c469883d56e2798e7df6240dcb2287b/wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0", size = 53998, upload-time = "2025-08-12T05:51:47.138Z" },
|
| 1162 |
+
{ url = "https://files.pythonhosted.org/packages/60/f8/096a7cc13097a1869fe44efe68dace40d2a16ecb853141394047f0780b96/wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba", size = 39020, upload-time = "2025-08-12T05:51:35.906Z" },
|
| 1163 |
+
{ url = "https://files.pythonhosted.org/packages/33/df/bdf864b8997aab4febb96a9ae5c124f700a5abd9b5e13d2a3214ec4be705/wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd", size = 39098, upload-time = "2025-08-12T05:51:57.474Z" },
|
| 1164 |
+
{ url = "https://files.pythonhosted.org/packages/9f/81/5d931d78d0eb732b95dc3ddaeeb71c8bb572fb01356e9133916cd729ecdd/wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828", size = 88036, upload-time = "2025-08-12T05:52:34.784Z" },
|
| 1165 |
+
{ url = "https://files.pythonhosted.org/packages/ca/38/2e1785df03b3d72d34fc6252d91d9d12dc27a5c89caef3335a1bbb8908ca/wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9", size = 88156, upload-time = "2025-08-12T05:52:13.599Z" },
|
| 1166 |
+
{ url = "https://files.pythonhosted.org/packages/b3/8b/48cdb60fe0603e34e05cffda0b2a4adab81fd43718e11111a4b0100fd7c1/wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396", size = 87102, upload-time = "2025-08-12T05:52:14.56Z" },
|
| 1167 |
+
{ url = "https://files.pythonhosted.org/packages/3c/51/d81abca783b58f40a154f1b2c56db1d2d9e0d04fa2d4224e357529f57a57/wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc", size = 87732, upload-time = "2025-08-12T05:52:36.165Z" },
|
| 1168 |
+
{ url = "https://files.pythonhosted.org/packages/9e/b1/43b286ca1392a006d5336412d41663eeef1ad57485f3e52c767376ba7e5a/wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe", size = 36705, upload-time = "2025-08-12T05:53:07.123Z" },
|
| 1169 |
+
{ url = "https://files.pythonhosted.org/packages/28/de/49493f962bd3c586ab4b88066e967aa2e0703d6ef2c43aa28cb83bf7b507/wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c", size = 38877, upload-time = "2025-08-12T05:53:05.436Z" },
|
| 1170 |
+
{ url = "https://files.pythonhosted.org/packages/f1/48/0f7102fe9cb1e8a5a77f80d4f0956d62d97034bbe88d33e94699f99d181d/wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6", size = 36885, upload-time = "2025-08-12T05:52:54.367Z" },
|
| 1171 |
+
{ url = "https://files.pythonhosted.org/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", size = 54003, upload-time = "2025-08-12T05:51:48.627Z" },
|
| 1172 |
+
{ url = "https://files.pythonhosted.org/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", size = 39025, upload-time = "2025-08-12T05:51:37.156Z" },
|
| 1173 |
+
{ url = "https://files.pythonhosted.org/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", size = 39108, upload-time = "2025-08-12T05:51:58.425Z" },
|
| 1174 |
+
{ url = "https://files.pythonhosted.org/packages/0c/37/6faf15cfa41bf1f3dba80cd3f5ccc6622dfccb660ab26ed79f0178c7497f/wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277", size = 88072, upload-time = "2025-08-12T05:52:37.53Z" },
|
| 1175 |
+
{ url = "https://files.pythonhosted.org/packages/78/f2/efe19ada4a38e4e15b6dff39c3e3f3f73f5decf901f66e6f72fe79623a06/wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d", size = 88214, upload-time = "2025-08-12T05:52:15.886Z" },
|
| 1176 |
+
{ url = "https://files.pythonhosted.org/packages/40/90/ca86701e9de1622b16e09689fc24b76f69b06bb0150990f6f4e8b0eeb576/wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa", size = 87105, upload-time = "2025-08-12T05:52:17.914Z" },
|
| 1177 |
+
{ url = "https://files.pythonhosted.org/packages/fd/e0/d10bd257c9a3e15cbf5523025252cc14d77468e8ed644aafb2d6f54cb95d/wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050", size = 87766, upload-time = "2025-08-12T05:52:39.243Z" },
|
| 1178 |
+
{ url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" },
|
| 1179 |
+
{ url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" },
|
| 1180 |
+
{ url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" },
|
| 1181 |
+
{ url = "https://files.pythonhosted.org/packages/02/a2/cd864b2a14f20d14f4c496fab97802001560f9f41554eef6df201cd7f76c/wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39", size = 54132, upload-time = "2025-08-12T05:51:49.864Z" },
|
| 1182 |
+
{ url = "https://files.pythonhosted.org/packages/d5/46/d011725b0c89e853dc44cceb738a307cde5d240d023d6d40a82d1b4e1182/wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235", size = 39091, upload-time = "2025-08-12T05:51:38.935Z" },
|
| 1183 |
+
{ url = "https://files.pythonhosted.org/packages/2e/9e/3ad852d77c35aae7ddebdbc3b6d35ec8013af7d7dddad0ad911f3d891dae/wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c", size = 39172, upload-time = "2025-08-12T05:51:59.365Z" },
|
| 1184 |
+
{ url = "https://files.pythonhosted.org/packages/c3/f7/c983d2762bcce2326c317c26a6a1e7016f7eb039c27cdf5c4e30f4160f31/wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b", size = 87163, upload-time = "2025-08-12T05:52:40.965Z" },
|
| 1185 |
+
{ url = "https://files.pythonhosted.org/packages/e4/0f/f673f75d489c7f22d17fe0193e84b41540d962f75fce579cf6873167c29b/wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa", size = 87963, upload-time = "2025-08-12T05:52:20.326Z" },
|
| 1186 |
+
{ url = "https://files.pythonhosted.org/packages/df/61/515ad6caca68995da2fac7a6af97faab8f78ebe3bf4f761e1b77efbc47b5/wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7", size = 86945, upload-time = "2025-08-12T05:52:21.581Z" },
|
| 1187 |
+
{ url = "https://files.pythonhosted.org/packages/d3/bd/4e70162ce398462a467bc09e768bee112f1412e563620adc353de9055d33/wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4", size = 86857, upload-time = "2025-08-12T05:52:43.043Z" },
|
| 1188 |
+
{ url = "https://files.pythonhosted.org/packages/2b/b8/da8560695e9284810b8d3df8a19396a6e40e7518059584a1a394a2b35e0a/wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10", size = 37178, upload-time = "2025-08-12T05:53:12.605Z" },
|
| 1189 |
+
{ url = "https://files.pythonhosted.org/packages/db/c8/b71eeb192c440d67a5a0449aaee2310a1a1e8eca41676046f99ed2487e9f/wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6", size = 39310, upload-time = "2025-08-12T05:53:11.106Z" },
|
| 1190 |
+
{ url = "https://files.pythonhosted.org/packages/45/20/2cda20fd4865fa40f86f6c46ed37a2a8356a7a2fde0773269311f2af56c7/wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58", size = 37266, upload-time = "2025-08-12T05:52:56.531Z" },
|
| 1191 |
+
{ url = "https://files.pythonhosted.org/packages/77/ed/dd5cf21aec36c80443c6f900449260b80e2a65cf963668eaef3b9accce36/wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a", size = 56544, upload-time = "2025-08-12T05:51:51.109Z" },
|
| 1192 |
+
{ url = "https://files.pythonhosted.org/packages/8d/96/450c651cc753877ad100c7949ab4d2e2ecc4d97157e00fa8f45df682456a/wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067", size = 40283, upload-time = "2025-08-12T05:51:39.912Z" },
|
| 1193 |
+
{ url = "https://files.pythonhosted.org/packages/d1/86/2fcad95994d9b572db57632acb6f900695a648c3e063f2cd344b3f5c5a37/wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454", size = 40366, upload-time = "2025-08-12T05:52:00.693Z" },
|
| 1194 |
+
{ url = "https://files.pythonhosted.org/packages/64/0e/f4472f2fdde2d4617975144311f8800ef73677a159be7fe61fa50997d6c0/wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e", size = 108571, upload-time = "2025-08-12T05:52:44.521Z" },
|
| 1195 |
+
{ url = "https://files.pythonhosted.org/packages/cc/01/9b85a99996b0a97c8a17484684f206cbb6ba73c1ce6890ac668bcf3838fb/wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f", size = 113094, upload-time = "2025-08-12T05:52:22.618Z" },
|
| 1196 |
+
{ url = "https://files.pythonhosted.org/packages/25/02/78926c1efddcc7b3aa0bc3d6b33a822f7d898059f7cd9ace8c8318e559ef/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056", size = 110659, upload-time = "2025-08-12T05:52:24.057Z" },
|
| 1197 |
+
{ url = "https://files.pythonhosted.org/packages/dc/ee/c414501ad518ac3e6fe184753632fe5e5ecacdcf0effc23f31c1e4f7bfcf/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804", size = 106946, upload-time = "2025-08-12T05:52:45.976Z" },
|
| 1198 |
+
{ url = "https://files.pythonhosted.org/packages/be/44/a1bd64b723d13bb151d6cc91b986146a1952385e0392a78567e12149c7b4/wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977", size = 38717, upload-time = "2025-08-12T05:53:15.214Z" },
|
| 1199 |
+
{ url = "https://files.pythonhosted.org/packages/79/d9/7cfd5a312760ac4dd8bf0184a6ee9e43c33e47f3dadc303032ce012b8fa3/wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116", size = 41334, upload-time = "2025-08-12T05:53:14.178Z" },
|
| 1200 |
+
{ url = "https://files.pythonhosted.org/packages/46/78/10ad9781128ed2f99dbc474f43283b13fea8ba58723e98844367531c18e9/wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6", size = 38471, upload-time = "2025-08-12T05:52:57.784Z" },
|
| 1201 |
+
{ url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" },
|
| 1202 |
]
|