first commit
This commit is contained in:
+10
@@ -0,0 +1,10 @@
|
||||
# Python-generated files
|
||||
__pycache__/
|
||||
*.py[oc]
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
||||
# Virtual environments
|
||||
.venv
|
||||
@@ -0,0 +1 @@
|
||||
3.14
|
||||
@@ -0,0 +1,54 @@
|
||||
import polars as pl
|
||||
from sqlalchemy import text
|
||||
|
||||
from log import *
|
||||
|
||||
|
||||
def create_clickhouse_table(
|
||||
df: pl.DataFrame,
|
||||
table_name: str,
|
||||
clickhouse_engine
|
||||
):
|
||||
type_mapping = {
|
||||
pl.Int8: "Nullable(Int8)",
|
||||
pl.Int16: "Nullable(Int16)",
|
||||
pl.Int32: "Nullable(Int32)",
|
||||
pl.Int64: "Nullable(Int64)",
|
||||
pl.UInt8: "Nullable(UInt8)",
|
||||
pl.UInt16: "Nullable(UInt16)",
|
||||
pl.UInt32: "Nullable(UInt32)",
|
||||
pl.UInt64: "Nullable(UInt64)",
|
||||
pl.Float32: "Nullable(Float32)",
|
||||
pl.Float64: "Nullable(Float64)",
|
||||
pl.Boolean: "Nullable(Bool)",
|
||||
pl.String: "Nullable(String)",
|
||||
pl.Date: "Nullable(Date)",
|
||||
pl.Datetime: "Nullable(DateTime)",
|
||||
}
|
||||
|
||||
columns = []
|
||||
|
||||
for col_name, dtype in df.schema.items():
|
||||
|
||||
clickhouse_type = type_mapping.get(
|
||||
dtype,
|
||||
"Nullable(String)"
|
||||
)
|
||||
|
||||
columns.append(
|
||||
f"`{col_name}` {clickhouse_type}"
|
||||
)
|
||||
|
||||
create_sql = f"""
|
||||
CREATE TABLE IF NOT EXISTS {table_name}
|
||||
(
|
||||
{', '.join(columns)}
|
||||
)
|
||||
ENGINE = MergeTree()
|
||||
ORDER BY tuple()
|
||||
"""
|
||||
|
||||
with clickhouse_engine.begin() as conn:
|
||||
conn.execute(text(create_sql))
|
||||
|
||||
log.info(f"Table ready: {table_name}")
|
||||
@@ -0,0 +1,31 @@
|
||||
from db_con.connection import *
|
||||
|
||||
from log import *
|
||||
|
||||
|
||||
def truncate_table(client, table_name: str) -> None:
|
||||
"""
|
||||
Truncate a ClickHouse table.
|
||||
"""
|
||||
query = f"TRUNCATE TABLE {table_name}"
|
||||
|
||||
print(f"Truncating table: {table_name}")
|
||||
client.command(query)
|
||||
|
||||
log.info(f"Table {table_name} truncated successfully.")
|
||||
|
||||
|
||||
|
||||
def delete_rows(client, table_name: str, condition: str) -> None:
|
||||
"""
|
||||
Delete rows from a ClickHouse table based on a condition.
|
||||
"""
|
||||
query = f"""
|
||||
ALTER TABLE {table_name}
|
||||
DELETE WHERE {condition}
|
||||
"""
|
||||
|
||||
print(f"Deleting rows from {table_name} where {condition}")
|
||||
client.command(query)
|
||||
|
||||
log.info("Delete command submitted successfully.")
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
# SQL Server
|
||||
MSSQL_SERVER=43.242.212.54,21443
|
||||
MSSQL_DB=OneApp_KelloggsMT
|
||||
MSSQL_USER=ankit_malik
|
||||
MSSQL_PASS=M4l!k#Ank1t001
|
||||
|
||||
# ClickHouse
|
||||
CH_HOST=172.188.12.194
|
||||
CH_PORT=8123
|
||||
CH_USER=default
|
||||
CH_PASS=dipanshu_k
|
||||
CH_DB=kelloggs
|
||||
@@ -0,0 +1,86 @@
|
||||
from dotenv import load_dotenv
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.engine import URL, Engine
|
||||
import os
|
||||
import clickhouse_connect
|
||||
|
||||
from log import *
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# SQL Server
|
||||
MSSQL_SERVER = os.getenv("MSSQL_SERVER")
|
||||
MSSQL_DB = os.getenv("MSSQL_DB")
|
||||
MSSQL_USER = os.getenv("MSSQL_USER")
|
||||
MSSQL_PASS = os.getenv("MSSQL_PASS")
|
||||
|
||||
# ClickHouse
|
||||
CH_HOST = os.getenv("CH_HOST")
|
||||
CH_PORT = int(os.getenv("CH_PORT", "8123"))
|
||||
CH_USER = os.getenv("CH_USER")
|
||||
CH_PASS = os.getenv("CH_PASS")
|
||||
CH_DB = os.getenv("CH_DB")
|
||||
|
||||
|
||||
def build_sql_server_engine() -> Engine:
|
||||
odbc_dsn = (
|
||||
f"DRIVER={{ODBC Driver 18 for SQL Server}};"
|
||||
f"SERVER={MSSQL_SERVER};"
|
||||
f"DATABASE={MSSQL_DB};"
|
||||
f"UID={MSSQL_USER};"
|
||||
f"PWD={MSSQL_PASS};"
|
||||
"TrustServerCertificate=yes;"
|
||||
)
|
||||
|
||||
sql_url = URL.create(
|
||||
drivername="mssql+pyodbc",
|
||||
query={"odbc_connect": odbc_dsn},
|
||||
)
|
||||
|
||||
engine = create_engine(
|
||||
sql_url,
|
||||
pool_size=3,
|
||||
max_overflow=2,
|
||||
pool_pre_ping=True,
|
||||
connect_args={
|
||||
"fast_executemany": True,
|
||||
},
|
||||
)
|
||||
|
||||
with engine.connect() as conn:
|
||||
log.info(conn.execute(text("SELECT 1")))
|
||||
|
||||
return engine
|
||||
|
||||
|
||||
def build_clickhouse_engine() -> Engine:
|
||||
clickhouse_url = URL.create(
|
||||
drivername="clickhouse+http",
|
||||
username=CH_USER,
|
||||
password=CH_PASS,
|
||||
host=CH_HOST,
|
||||
port=CH_PORT,
|
||||
database=CH_DB,
|
||||
)
|
||||
|
||||
engine = create_engine(
|
||||
clickhouse_url,
|
||||
pool_pre_ping=True,
|
||||
)
|
||||
|
||||
with engine.connect() as conn:
|
||||
log.info( conn.execute(text("SELECT 1")))
|
||||
|
||||
return engine
|
||||
|
||||
|
||||
|
||||
|
||||
def get_clickhouse_client():
|
||||
return clickhouse_connect.get_client(
|
||||
host=CH_HOST,
|
||||
port=CH_PORT,
|
||||
username=CH_USER,
|
||||
password="CH_PASS",
|
||||
database=CH_DB
|
||||
)
|
||||
+876
@@ -0,0 +1,876 @@
|
||||
import os
|
||||
import pyarrow
|
||||
import sys
|
||||
import logging
|
||||
from datetime import date, timedelta
|
||||
import polars as pl
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.engine import Engine, URL
|
||||
import clickhouse_connect
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from log import log
|
||||
from clickhouse_task.create_table import create_clickhouse_table , check
|
||||
from db_con.connection import *
|
||||
from mids import *
|
||||
|
||||
|
||||
|
||||
#PROJECT_ID = 40148
|
||||
p=40148
|
||||
|
||||
|
||||
|
||||
|
||||
def fetch_SOS_OneApp(engine: Engine, mids: list[int]) -> pl.DataFrame:
|
||||
|
||||
|
||||
|
||||
if not mids:
|
||||
log.warning("No MIDs — nothing to fetch.")
|
||||
return pl.DataFrame()
|
||||
|
||||
mid_list = ",".join(str(mid) for mid in mids)
|
||||
|
||||
sql = f""" SELECT
|
||||
MID,
|
||||
EmpId AS employee_id,
|
||||
StoreId AS store_id,
|
||||
VisitDate AS visit_date,
|
||||
StoreTypeid AS storetype_id,
|
||||
ChannelId AS channel_id,
|
||||
SOSDefinitionName,
|
||||
SOSHeaderDeatils,
|
||||
SOSHeaderName,
|
||||
SOSHeaderID,
|
||||
SOSChildDeatils,
|
||||
SOSChildName,
|
||||
SOSChildID,
|
||||
SOSHeaderFacing,
|
||||
ChildTotalFacing,
|
||||
ChildSelfFacing,
|
||||
SOSTarget
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
sm.CountryName,
|
||||
sc.MID,
|
||||
sm.RegionName,
|
||||
sm.StateName,
|
||||
sm.CityName,
|
||||
Em.SupervisorName,
|
||||
Em.EmpId,
|
||||
Em.EmpName AS EmployeeName,
|
||||
Em.DesignationName AS Designation,
|
||||
sm.StoreId,
|
||||
CAST(sc.VisitDate AS DATE) AS VisitDate,
|
||||
sm.StoreCode,
|
||||
sm.StoreName,
|
||||
sm.Address,
|
||||
sm.StoreTypeid,
|
||||
sm.ChannelId,
|
||||
sm.ChainName,
|
||||
|
||||
MSD.SOSDefinitionName,
|
||||
|
||||
CASE
|
||||
WHEN ISNULL(TS.SOSHeaderTable,'')='Master_Category' THEN 'Category'
|
||||
WHEN ISNULL(TS.SOSHeaderTable,'')='Master_SubCategory' THEN 'SubCategory'
|
||||
WHEN ISNULL(TS.SOSHeaderTable,'')='Master_Brand' THEN 'Brand'
|
||||
WHEN ISNULL(TS.SOSHeaderTable,'')='Master_SubBrand' THEN 'SubBrand'
|
||||
END AS SOSHeaderDeatils,
|
||||
|
||||
TS.SOSHeaderName,
|
||||
TS.SOSHeaderValue AS SOSHeaderID,
|
||||
|
||||
CASE
|
||||
WHEN ISNULL(TSC.SOSChildTable,'')='Master_Category' THEN 'Category'
|
||||
WHEN ISNULL(TSC.SOSChildTable,'')='Master_SubCategory' THEN 'SubCategory'
|
||||
WHEN ISNULL(TSC.SOSChildTable,'')='Master_Brand' THEN 'Brand'
|
||||
WHEN ISNULL(TSC.SOSChildTable,'')='Master_SubBrand' THEN 'SubBrand'
|
||||
END AS SOSChildDeatils,
|
||||
|
||||
TSC.SOSChildName,
|
||||
TSC.SOSChildValue AS SOSChildID,
|
||||
TSC.ChildTotalFacing,
|
||||
TS.SOSHeaderFacing,
|
||||
TSC.ChildSelfFacing,
|
||||
|
||||
(
|
||||
SELECT TOP 1 SOSTarget
|
||||
FROM OneApp_KelloggsMT.dbo.Mapping_StoreShareOfShelfTarget a
|
||||
WHERE a.SOSDefinitionId = MSD.SOSDefinitionId
|
||||
AND a.StoreId = sm.StoreId
|
||||
AND a.FromDate <= sc.VisitDate
|
||||
AND a.ToDate >= sc.VisitDate
|
||||
) AS SOSTarget
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.T_ShareOfShelfHeader TS
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.T_StoreCoverage SC
|
||||
ON TS.MID = SC.MID
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_StoreDetail SM
|
||||
ON SC.StoreId = SM.StoreId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Employee_Detail EM
|
||||
ON SC.EmpId = EM.EmpId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.T_ShareOfShelfChild TSC
|
||||
ON TS.SOSId = TSC.SOSId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_ShareOfShelfDefinition MSD
|
||||
ON MSD.SOSDefinitionId = TSC.SOSDefinitionId
|
||||
|
||||
WHERE EM.EmpName NOT LIKE 'test%'
|
||||
AND SC.MID IN ({mid_list})
|
||||
) A
|
||||
"""
|
||||
|
||||
log.info(f"Fetching data for {len(mids):,} MIDs")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(f"Fetched {len(df):,} rows from SQL Server")
|
||||
|
||||
return df
|
||||
|
||||
|
||||
def fetch_OQaD(engine: Engine, mids: list[int]) -> pl.DataFrame:
|
||||
|
||||
if not mids:
|
||||
log.warning("No MIDs — nothing to fetch.")
|
||||
return pl.DataFrame()
|
||||
|
||||
mid_list = ",".join(map(str, mids))
|
||||
|
||||
sql = f"""
|
||||
WITH MID_TABLE_COV1 AS
|
||||
(
|
||||
SELECT DISTINCT
|
||||
EmpId,
|
||||
CAST(VisitDate AS DATE) AS VisitDate
|
||||
FROM OneApp_KelloggsMT.dbo.T_StoreCoverage
|
||||
WHERE MID IN ({mid_list})
|
||||
),
|
||||
|
||||
QUIZ AS
|
||||
(
|
||||
SELECT DISTINCT
|
||||
E.EmpId,
|
||||
CAST(DQ.VisitDate AS DATE) AS VisitDate,
|
||||
DQ.QuestionId,
|
||||
DQ.AnswerId,
|
||||
QC.QuestionCategoryId,
|
||||
QC.QuestionCategory
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.T_OQAD DQ
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Employee_Detail E
|
||||
ON DQ.EmpId = E.EmpId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_OQAD_Question QU
|
||||
ON DQ.QuestionId = QU.QuestionId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_OQAD_Category QC
|
||||
ON QU.QuestionCategoryId = QC.QuestionCategoryId
|
||||
|
||||
WHERE E.EmpName NOT LIKE 'test%'
|
||||
AND E.EmpName NOT LIKE '%TEST%'
|
||||
AND E.RightId = 6
|
||||
AND (
|
||||
E.ResignDate IS NULL
|
||||
OR E.ResignDate >= DQ.VisitDate
|
||||
)
|
||||
AND EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM MID_TABLE_COV1 A
|
||||
WHERE A.EmpId = DQ.EmpId
|
||||
AND A.VisitDate = CAST(DQ.VisitDate AS DATE)
|
||||
)
|
||||
)
|
||||
|
||||
SELECT
|
||||
Q.EmpId AS employee_id,
|
||||
0 AS process_id,
|
||||
Q.VisitDate AS visit_date,
|
||||
Q.QuestionCategoryId AS question_category_id,
|
||||
Q.QuestionCategory AS question_category,
|
||||
QM.QuestionId AS question_id,
|
||||
QM.Question AS question,
|
||||
|
||||
ISNULL(QA.AnswerId,0) AS answer_id,
|
||||
ISNULL(QA.Answer,'') AS answer,
|
||||
|
||||
CASE
|
||||
WHEN QA.AnswerId IS NULL THEN 'Not Answer'
|
||||
WHEN QA.RightAnswer = 1 THEN 'Y'
|
||||
WHEN QA.RightAnswer IS NULL THEN 'Not Answer'
|
||||
ELSE 'N'
|
||||
END AS correct_answer
|
||||
|
||||
FROM QUIZ Q
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_OQAD_Question QM
|
||||
ON Q.QuestionId = QM.QuestionId
|
||||
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.Master_OQAD_Answer QA
|
||||
ON Q.AnswerId = QA.AnswerId
|
||||
"""
|
||||
|
||||
log.info(f"Fetching OQaD data for {len(mids):,} MIDs")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(f"Fetched {len(df):,} rows")
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def fetch_Survey(engine: Engine, mids: list[int]) -> pl.DataFrame:
|
||||
if not mids:
|
||||
log.warning("No MIDs — nothing to fetch.")
|
||||
return pl.DataFrame()
|
||||
|
||||
mid_list = ",".join(map(str, mids))
|
||||
|
||||
sql = f"""
|
||||
WITH QUIZ AS
|
||||
(
|
||||
SELECT
|
||||
SC.MID,
|
||||
SC.StoreId,
|
||||
EM.EmpId,
|
||||
EM.SupervisorId,
|
||||
CAST(SC.VisitDate AS DATE) AS VisitDate,
|
||||
|
||||
DQ.QuestionId,
|
||||
QU.Question,
|
||||
DQ.Answer,
|
||||
|
||||
QC.CategoryId,
|
||||
QC.Category,
|
||||
|
||||
MSS.SubCategoryId,
|
||||
MSS.SubCategory
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.T_SURVEY DQ
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.T_StoreCoverage SC
|
||||
ON DQ.MID = SC.MID
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_SurveyQuestion QU
|
||||
ON DQ.QuestionId = QU.QuestionId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_SurveySubCategory MSS
|
||||
ON QU.SubCategoryId = MSS.SubCategoryId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_SurveyCategory QC
|
||||
ON MSS.CategoryId = QC.CategoryId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Employee_Detail EM
|
||||
ON SC.EmpId = EM.EmpId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_Survey MS
|
||||
ON DQ.SurveyId = MS.SurveyId
|
||||
AND QU.SurveyId = MS.SurveyId
|
||||
|
||||
WHERE EM.EmpName NOT LIKE 'test%'
|
||||
AND SC.MID IN ({mid_list})
|
||||
)
|
||||
|
||||
SELECT
|
||||
Q.MID,
|
||||
Q.SupervisorId,
|
||||
Q.EmpId,
|
||||
SM.StoreId,
|
||||
Q.VisitDate,
|
||||
|
||||
SM.StoreTypeId,
|
||||
SM.ChainId,
|
||||
|
||||
Q.CategoryId,
|
||||
Q.Category,
|
||||
|
||||
Q.SubCategoryId,
|
||||
Q.SubCategory,
|
||||
|
||||
Q.QuestionId,
|
||||
Q.Question,
|
||||
Q.Answer
|
||||
|
||||
FROM QUIZ Q
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_StoreDetail SM
|
||||
ON Q.StoreId = SM.StoreId
|
||||
"""
|
||||
|
||||
log.info(f"Fetching Survey data for {len(mids):,} MIDs")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(f"Fetched {len(df):,} Survey rows")
|
||||
|
||||
return df
|
||||
|
||||
|
||||
def fetch_additional_visibility(
|
||||
engine: Engine,
|
||||
mids: list[int]
|
||||
) -> pl.DataFrame:
|
||||
|
||||
if not mids:
|
||||
log.warning("No MIDs — nothing to fetch.")
|
||||
return pl.DataFrame()
|
||||
|
||||
mid_list = ",".join(map(str, mids))
|
||||
|
||||
sql = f"""
|
||||
SELECT
|
||||
TS.MID,
|
||||
|
||||
EM.EmpId AS emp_id,
|
||||
|
||||
SM.StoreId AS store_id,
|
||||
SM.StoreTypeId AS storetype_id,
|
||||
SM.ChannelId AS channel_id,
|
||||
SM.ChainId AS chain_id,
|
||||
|
||||
CASE
|
||||
WHEN SM.CameraAllow = 1 THEN 'Y'
|
||||
ELSE 'N'
|
||||
END AS camera_allowed,
|
||||
|
||||
CAST(SC.VisitDate AS DATE) AS visit_date,
|
||||
|
||||
CASE
|
||||
WHEN TS.Present = 0 THEN 'N'
|
||||
ELSE 'Y'
|
||||
END AS is_present,
|
||||
|
||||
ISNULL(MB.BrandId, 0) AS brand_id,
|
||||
ISNULL(MD.DisplayId, 0) AS display_id,
|
||||
|
||||
ISNULL(TS.Remark, '') AS remarks,
|
||||
|
||||
CASE
|
||||
WHEN ISNULL(TS.ImageUrl, '') = '' THEN ''
|
||||
ELSE CONCAT(
|
||||
'https://kimt1.parinaam.in/Upload/VisibilityImages/',
|
||||
TS.ImageUrl
|
||||
)
|
||||
END AS image_url
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.T_AdditionalVisibility TS
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.T_StoreCoverage SC
|
||||
ON TS.MID = SC.MID
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_StoreDetail SM
|
||||
ON SC.StoreId = SM.StoreId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Employee_Detail EM
|
||||
ON SC.EmpId = EM.EmpId
|
||||
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.Master_Brand MB
|
||||
ON TS.BrandId = MB.BrandId
|
||||
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.Master_Display MD
|
||||
ON TS.DisplayId = MD.DisplayId
|
||||
|
||||
WHERE EM.EmpName NOT LIKE 'test%'
|
||||
AND TS.Present = 1
|
||||
AND SC.MID IN ({mid_list})
|
||||
"""
|
||||
|
||||
log.info(
|
||||
f"Fetching Additional Visibility data for {len(mids):,} MIDs"
|
||||
)
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"Fetched {len(df):,} Additional Visibility rows"
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
def fetch_Coverage(engine: Engine, mids: list[int]) -> pl.DataFrame:
|
||||
|
||||
|
||||
|
||||
if not mids:
|
||||
log.warning("No MIDs — nothing to fetch.")
|
||||
return pl.DataFrame()
|
||||
|
||||
mid_list = ",".join(str(mid) for mid in mids)
|
||||
|
||||
sql = f"""
|
||||
SELECT
|
||||
{p} AS project_id,
|
||||
JP.MID,
|
||||
sm.StoreId AS store_id,
|
||||
JP.EmpId AS employee_id,
|
||||
CONVERT(date, JP.VisitDate) AS visit_date,
|
||||
JP.InTime AS in_time,
|
||||
JP.OutTime AS out_time,
|
||||
CASE
|
||||
WHEN JP.OutTime IS NULL OR JP.InTime IS NULL THEN NULL
|
||||
WHEN JP.OutTime < JP.InTime THEN 0
|
||||
ELSE DATEDIFF(SECOND, JP.InTime, JP.OutTime) / 60
|
||||
END AS duration_minutes,
|
||||
CASE
|
||||
WHEN (
|
||||
SELECT TOP 1 EmpId
|
||||
FROM OneApp_KelloggsMT.dbo.T_StoreCoverage SC
|
||||
WHERE SC.EmpId = JP.EmpId
|
||||
AND SC.StoreId = JP.StoreId
|
||||
AND SC.VisitDate = JP.VisitDate
|
||||
AND SC.ReasonId IN (0,1,3,9,10,19,20)
|
||||
) > 0
|
||||
THEN 'Y' ELSE 'N'
|
||||
END AS is_covered,
|
||||
CASE JP.Deviation
|
||||
WHEN 0 THEN 'Planned'
|
||||
WHEN 1 THEN 'Adhoc'
|
||||
WHEN 2 THEN 'Beat Plan'
|
||||
WHEN 3 THEN 'Non Merchandised'
|
||||
WHEN 4 THEN 'Add New Store'
|
||||
WHEN 5 THEN 'Non Program'
|
||||
ELSE ''
|
||||
END AS coverage_type,
|
||||
sm.StoreTypeId AS storetype_id,
|
||||
Em.SupervisorId AS supervisor_id,
|
||||
ISNULL(JP.ReasonId, 0) AS reason_id,
|
||||
sm.CameraAllow AS camera_allow,
|
||||
CAST(
|
||||
CASE
|
||||
WHEN sm.Latitude IS NULL OR sm.Latitude = 0 THEN 0
|
||||
WHEN sm.Longitude IS NULL OR sm.Longitude = 0 THEN 0
|
||||
WHEN JP.Latitude IS NULL OR JP.Latitude = 0 THEN 0
|
||||
WHEN JP.Longitude IS NULL OR JP.Longitude = 0 THEN 0
|
||||
ELSE SQRT(
|
||||
POWER(69.1 * (JP.Latitude - sm.Latitude), 2) +
|
||||
POWER(69.1 * (sm.Longitude - JP.Longitude)
|
||||
* COS(JP.Latitude / 57.3), 2)
|
||||
) * 1000
|
||||
END AS FLOAT
|
||||
) AS distance_meters,
|
||||
GETDATE() AS update_date,
|
||||
'ETL-SQLAlchemy' AS update_by
|
||||
FROM OneApp_KelloggsMT.dbo.T_StoreCoverage JP WITH (NOLOCK)
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_StoreDetail sm
|
||||
ON JP.StoreId = sm.StoreId
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Employee_Detail Em
|
||||
ON JP.EmpId = Em.EmpId
|
||||
WHERE JP.MID IN ({mid_list})
|
||||
AND Em.UserName NOT LIKE 'test%'
|
||||
"""
|
||||
|
||||
log.info(f"Fetching coverage data for {len(mids):,} MIDs")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(f"Fetched {len(df):,} rows from SQL Server")
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
def fetch_stock_details(
|
||||
engine: Engine,
|
||||
mids: list[int]
|
||||
) -> pl.DataFrame:
|
||||
|
||||
if not mids:
|
||||
log.warning("No MIDs — nothing to fetch.")
|
||||
return pl.DataFrame()
|
||||
|
||||
mid_list = ",".join(map(str, mids))
|
||||
|
||||
sql = f"""
|
||||
SELECT
|
||||
SC.MID,
|
||||
|
||||
EM.SupervisorId AS supervisor_id,
|
||||
EM.EmpId AS employee_id,
|
||||
|
||||
SM.StoreId AS store_id,
|
||||
|
||||
CAST(SC.VisitDate AS DATE) AS visitdate,
|
||||
|
||||
SC.StoreTypeId,
|
||||
SM.StoreCategoryId,
|
||||
|
||||
VP.ProductId AS product_id,
|
||||
|
||||
TS.MSL,
|
||||
MP.MBQ,
|
||||
|
||||
ISNULL(TS.OpeningStock, 0)
|
||||
+ ISNULL(TS.MidDayStock, 0) AS stock_qty,
|
||||
|
||||
0 AS damagedstock,
|
||||
0 AS loststock,
|
||||
0 AS expirystock,
|
||||
|
||||
CASE
|
||||
WHEN ISNULL(TS.OpeningStock, 0)
|
||||
+ ISNULL(TS.MidDayStock, 0) >= 1
|
||||
THEN 'Y'
|
||||
ELSE 'N'
|
||||
END AS skuavailability,
|
||||
|
||||
'Parinaam' AS stocktype
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.T_Stock TS
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.T_StoreCoverage SC
|
||||
ON TS.MID = SC.MID
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_StoreDetail SM
|
||||
ON SC.StoreId = SM.StoreId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Employee_Detail EM
|
||||
ON SC.EmpId = EM.EmpId
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Product VP
|
||||
ON TS.ProductId = VP.ProductId
|
||||
|
||||
INNER JOIN
|
||||
(
|
||||
SELECT
|
||||
MBQ,
|
||||
ProductId,
|
||||
StateId,
|
||||
ChainId,
|
||||
StoreTypeId,
|
||||
StoreCategoryId,
|
||||
StoreClassId
|
||||
FROM OneApp_KelloggsMT.dbo.Mapping_ProductAssortment
|
||||
WHERE FromDate <= CAST(GETDATE() AS DATE)
|
||||
AND ToDate >= CAST(GETDATE() AS DATE)
|
||||
) MP
|
||||
ON MP.StateId = SM.StateId
|
||||
AND MP.ChainId = SM.ChainId
|
||||
AND MP.StoreTypeId = SM.StoreTypeId
|
||||
AND MP.StoreCategoryId = SM.StoreCategoryId
|
||||
AND MP.StoreClassId = SM.StoreClassId
|
||||
AND MP.ProductId = TS.ProductId
|
||||
|
||||
WHERE EM.EmpName NOT LIKE 'test%'
|
||||
AND SC.MID IN ({mid_list})
|
||||
"""
|
||||
|
||||
log.info(
|
||||
f"Fetching Stock Details data for {len(mids):,} MIDs"
|
||||
)
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"Fetched {len(df):,} Stock Details rows"
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def fetch_Attendance(
|
||||
engine: Engine,
|
||||
end_date: date | None = None,
|
||||
days_back: int = 15
|
||||
) -> pl.DataFrame:
|
||||
"""
|
||||
Fetch attendance source data.
|
||||
|
||||
Default:
|
||||
end_date = yesterday
|
||||
start_date = yesterday - 15 days
|
||||
"""
|
||||
|
||||
if end_date is None:
|
||||
end_date = date.today() - timedelta(days=1)
|
||||
|
||||
start_date = end_date - timedelta(days=days_back)
|
||||
|
||||
sql = f"""
|
||||
SELECT
|
||||
JP.EmpId AS employee_id,
|
||||
JP.StoreId AS store_id,
|
||||
CAST(JP.VisitDate AS DATE) AS visit_date,
|
||||
|
||||
EM.ManagerId AS supervisor_id,
|
||||
EM.JoinDate AS date_of_join,
|
||||
EM.ResignDate AS date_of_resign,
|
||||
EM.LegacyCode,
|
||||
|
||||
SC.ReasonId,
|
||||
SC.InTime,
|
||||
SC.OutTime,
|
||||
|
||||
MPU.PositionId,
|
||||
MP.PositionCode
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.Mapping_JourneyPlan JP
|
||||
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.AspNetUsers EM
|
||||
ON JP.EmpId = EM.Id
|
||||
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.T_StoreCoverage SC
|
||||
ON JP.EmpId = SC.EmpId
|
||||
AND JP.StoreId = SC.StoreId
|
||||
AND JP.VisitDate = SC.VisitDate
|
||||
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.Mapping_PositionUser MPU
|
||||
ON JP.EmpId = MPU.EmpId
|
||||
AND JP.VisitDate BETWEEN MPU.FromDate AND MPU.ToDate
|
||||
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.Master_Position MP
|
||||
ON MPU.PositionId = MP.PositionId
|
||||
|
||||
WHERE JP.VisitDate BETWEEN '{start_date}'
|
||||
AND '{end_date}'
|
||||
AND EM.RightId = 6
|
||||
AND EM.EmployeeName NOT LIKE '%test%'
|
||||
"""
|
||||
|
||||
log.info(
|
||||
f"Fetching Attendance data from {start_date} to {end_date}"
|
||||
)
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"Fetched {len(df):,} attendance rows "
|
||||
f"for {df['employee_id'].n_unique():,} employees"
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
def fetch_login(engine: Engine , mids: list[int]) -> pl.DataFrame:
|
||||
|
||||
sql = """
|
||||
WITH login_data AS
|
||||
(
|
||||
SELECT
|
||||
UD.EmpId,
|
||||
CAST(UD.LoginDate AS DATE) AS LoginDate,
|
||||
CONVERT(VARCHAR(8), UD.InTime, 108) AS LoginTime,
|
||||
|
||||
ROW_NUMBER() OVER
|
||||
(
|
||||
PARTITION BY
|
||||
UD.EmpId,
|
||||
CAST(UD.LoginDate AS DATE)
|
||||
ORDER BY UD.LoginDate
|
||||
) AS rn
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.T_DeviceLogin UD
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Employee_Detail EM
|
||||
ON UD.EmpId = EM.EmpId
|
||||
|
||||
WHERE CAST(UD.LoginDate AS DATE) =
|
||||
CAST(DATEADD(DAY,-1,GETDATE()) AS DATE)
|
||||
|
||||
AND EM.RightId = 6
|
||||
AND EM.EmpName NOT LIKE '%test%'
|
||||
AND (
|
||||
EM.ResignDate IS NULL
|
||||
OR CAST(EM.ResignDate AS DATE) >=
|
||||
CAST(DATEADD(DAY,-1,GETDATE()) AS DATE)
|
||||
)
|
||||
)
|
||||
|
||||
SELECT
|
||||
LD.EmpId AS employee_id,
|
||||
LD.LoginDate AS login_date,
|
||||
LD.LoginTime AS login_time,
|
||||
|
||||
(
|
||||
SELECT MIN(CONVERT(VARCHAR(8), SC.InTime, 108))
|
||||
FROM OneApp_KelloggsMT.dbo.T_StoreCoverage SC
|
||||
WHERE SC.IsDel = 0
|
||||
AND SC.EmpId = LD.EmpId
|
||||
AND CAST(SC.VisitDate AS DATE) = LD.LoginDate
|
||||
) AS first_store_in_time,
|
||||
|
||||
(
|
||||
SELECT MAX(CONVERT(VARCHAR(8), SC.OutTime, 108))
|
||||
FROM OneApp_KelloggsMT.dbo.T_StoreCoverage SC
|
||||
WHERE SC.IsDel = 0
|
||||
AND SC.EmpId = LD.EmpId
|
||||
AND CAST(SC.VisitDate AS DATE) = LD.LoginDate
|
||||
) AS last_store_out_time,
|
||||
|
||||
CONCAT('40148','_',CAST(LD.EmpId AS VARCHAR(50))) AS unique_id
|
||||
|
||||
FROM login_data LD
|
||||
WHERE LD.rn = 1
|
||||
"""
|
||||
|
||||
|
||||
log.info("Fetching Login data for yesterday")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(f"Fetched {len(df):,} Login rows")
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
def fetch_Promotion(engine: Engine, mids: list[int]) -> pl.DataFrame:
|
||||
|
||||
|
||||
|
||||
if not mids:
|
||||
log.warning("No MIDs — nothing to fetch.")
|
||||
return pl.DataFrame()
|
||||
|
||||
mid_list = ",".join(str(mid) for mid in mids)
|
||||
|
||||
sql = f"""
|
||||
SELECT
|
||||
sc.MID AS mid,
|
||||
{p} AS project_id,
|
||||
sc.StoreId AS store_id,
|
||||
Em.EmpId AS employee_id,
|
||||
CONVERT(date, sc.VisitDate) AS visit_date,
|
||||
Em.SupervisorId AS supervisor_id,
|
||||
sm.ChannelId AS channel_id,
|
||||
sm.ChainId AS chain_id,
|
||||
sm.StoreTypeId AS storetype_id,
|
||||
msd.PromoDefinitionId AS promo_definition_id,
|
||||
msd.PromoDefinitionName AS promo_definition_name,
|
||||
|
||||
-- Resolve which dimension level the promo targets
|
||||
-- (Category / SubCategory / Brand / SubBrand)
|
||||
CASE
|
||||
WHEN ISNULL(ts.PromoTable,'') = 'Master_Category' THEN 'Category'
|
||||
WHEN ISNULL(ts.PromoTable,'') = 'Master_SubCategory' THEN 'SubCategory'
|
||||
WHEN ISNULL(ts.PromoTable,'') = 'Master_Brand' THEN 'Brand'
|
||||
WHEN ISNULL(ts.PromoTable,'') = 'Master_SubBrand' THEN 'SubBrand'
|
||||
ELSE ''
|
||||
END AS promotion_details,
|
||||
|
||||
ts.PromoValue AS promotion_details_id,
|
||||
|
||||
-- Resolve the actual name of that dimension item
|
||||
-- SQL Server evaluates exactly ONE of these subqueries per row
|
||||
CASE
|
||||
WHEN ISNULL(ts.PromoTable,'') = 'Master_Category'
|
||||
THEN (SELECT a.CategoryName
|
||||
FROM OneApp_KelloggsMT.dbo.Master_Category a
|
||||
WHERE a.CategoryId = ts.PromoValue)
|
||||
WHEN ISNULL(ts.PromoTable,'') = 'Master_SubCategory'
|
||||
THEN (SELECT a.SubCategoryName
|
||||
FROM OneApp_KelloggsMT.dbo.Master_SubCategory a
|
||||
WHERE a.SubCategoryId = ts.PromoValue)
|
||||
WHEN ISNULL(ts.PromoTable,'') = 'Master_Brand'
|
||||
THEN (SELECT a.BrandName
|
||||
FROM OneApp_KelloggsMT.dbo.Master_Brand a
|
||||
WHERE a.BrandId = ts.PromoValue)
|
||||
WHEN ISNULL(ts.PromoTable,'') = 'Master_SubBrand'
|
||||
THEN (SELECT a.SubBrandName
|
||||
FROM OneApp_KelloggsMT.dbo.Master_SubBrand a
|
||||
WHERE a.SubBrandId = ts.PromoValue)
|
||||
END AS promo_value_name,
|
||||
|
||||
-- Present flag: 0 → 'N', anything else → 'Y'
|
||||
CASE WHEN ts.Present = 0 THEN 'N' ELSE 'Y' END AS is_present,
|
||||
|
||||
-- Reason only populated when promo is ABSENT
|
||||
CASE
|
||||
WHEN ts.Present = 1 THEN ''
|
||||
ELSE ISNULL(mnp.PromoReason, '')
|
||||
END AS reason,
|
||||
|
||||
ISNULL(mpq.PromoQuestionName, '') AS question,
|
||||
ISNULL(tpq.PromoAnswerName, '') AS answer,
|
||||
|
||||
-- Image URLs — empty string when no image
|
||||
CASE
|
||||
WHEN ISNULL(SHI.PromoImage1,'') = '' THEN ''
|
||||
ELSE 'https://kimt1.parinaam.in/Upload/PromotionImages/'
|
||||
+ SHI.PromoImage1
|
||||
END AS image1,
|
||||
CASE
|
||||
WHEN ISNULL(SHI.PromoImage2,'') = '' THEN ''
|
||||
ELSE 'https://kimt1.parinaam.in/Upload/PromotionImages/'
|
||||
+ SHI.PromoImage2
|
||||
END AS image2,
|
||||
|
||||
GETDATE() AS update_date,
|
||||
'ETL-SQLAlchemy' AS update_by
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.T_Promotion ts
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.T_StoreCoverage sc
|
||||
ON ts.mid = sc.mid
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_StoreDetail sm
|
||||
ON sc.StoreId = sm.StoreId
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.vw_Employee_Detail Em
|
||||
ON sc.EmpId = Em.EmpId
|
||||
INNER JOIN OneApp_KelloggsMT.dbo.Master_PromotionDefinition msd
|
||||
ON msd.PromoDefinitionId = ts.PromoDefinitionId
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.T_PromotionImages SHI
|
||||
ON ts.PId = SHI.PId
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.Master_PromotionReason mnp
|
||||
ON ts.PromoReasonId = mnp.PromoReasonId
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.t_promotionquestion tpq
|
||||
ON ts.PId = tpq.PId
|
||||
LEFT JOIN OneApp_KelloggsMT.dbo.Master_PromotionQuestion mpq
|
||||
ON tpq.PromoQuestionId = mpq.PromoQuestionId
|
||||
|
||||
WHERE Em.EmpName NOT LIKE 'test%'
|
||||
AND sc.MID IN ({mid_list})
|
||||
"""
|
||||
|
||||
log.info(f"Fetching Coverage data for {len(mids):,} MIDs")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(f"Fetched {len(df):,} rows from SQL Server")
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
import logging
|
||||
|
||||
# Create logs folder if it doesn't exist
|
||||
Path("logs").mkdir(exist_ok=True)
|
||||
|
||||
# Daily log file
|
||||
log_file = Path("logs") / f"etl_{datetime.now():%Y%m%d}.log"
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s | %(levelname)-8s | %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
handlers=[
|
||||
logging.StreamHandler(),
|
||||
logging.FileHandler(log_file, encoding="utf-8"),
|
||||
],
|
||||
)
|
||||
|
||||
# Export logger
|
||||
log = logging.getLogger("etl")
|
||||
@@ -0,0 +1,120 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.11"
|
||||
# dependencies = [
|
||||
# "polars>=0.20.0",
|
||||
# "sqlalchemy>=2.0.0",
|
||||
# "pyodbc>=5.0.0",
|
||||
# "pyyaml>=6.0.3",
|
||||
# "clickhouse-connect>=0.7.0",
|
||||
# "clickhouse-sqlalchemy>=0.3.2",
|
||||
# "python-dotenv>=1.0.0",
|
||||
# "pyarrow>=18.0.0"
|
||||
# ]
|
||||
# ///
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import yaml
|
||||
import pyarrow
|
||||
import sys
|
||||
import logging
|
||||
from datetime import date, timedelta
|
||||
import polars as pl
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.engine import Engine, URL
|
||||
import clickhouse_connect
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from log import log
|
||||
from clickhouse_task.create_table import create_clickhouse_table , check
|
||||
from db_con.connection import *
|
||||
from mids import *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
log.info("Hello from data-move Python data pipeline !")
|
||||
check()
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
run_date = datetime.strptime(sys.argv[1], "%Y-%m-%d").date()
|
||||
else:
|
||||
run_date = date.today() - timedelta(days=1)
|
||||
|
||||
print(run_date)
|
||||
print(type(run_date))
|
||||
# connecting with both db servers sql-server
|
||||
|
||||
|
||||
log.info("connecting with both db servers sql-serveras well as clickhouse DB")
|
||||
|
||||
sql_engine = build_sql_server_engine()
|
||||
clickhouse_engine = build_clickhouse_engine()
|
||||
client=get_clickhouse_client()
|
||||
|
||||
log.info("Both databases connected successfully")
|
||||
|
||||
mids=collect_mids(sql_engine , run_date)
|
||||
|
||||
|
||||
# fetching polar df from sql-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
with open("tables.yml", "r") as file:
|
||||
config = yaml.safe_load(file)
|
||||
|
||||
for table in config["tables"]:
|
||||
|
||||
table_name=table["name"],
|
||||
table_type=table["type"],
|
||||
operation=table["operation"]
|
||||
|
||||
log.info(table_name, operation)
|
||||
fn=f"fetch_{table_name}"
|
||||
|
||||
if table_type =="FACT" :
|
||||
|
||||
if table_name == "Attendance" :
|
||||
df = globals()[fn](sql_engine, run_date)
|
||||
|
||||
else:
|
||||
df = globals()[fn](sql_engine, mids)
|
||||
|
||||
|
||||
|
||||
|
||||
else:
|
||||
|
||||
df = globals()[fn](sql_engine)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#fetch table details
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,362 @@
|
||||
import os
|
||||
import pyarrow
|
||||
import sys
|
||||
import logging
|
||||
from datetime import date, timedelta
|
||||
import polars as pl
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.engine import Engine, URL
|
||||
import clickhouse_connect
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from log import log
|
||||
from clickhouse_task.create_table import create_clickhouse_table , check
|
||||
from db_con.connection import *
|
||||
from mids import *
|
||||
|
||||
|
||||
|
||||
#PROJECT_ID = 40148
|
||||
p=40148
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def fetch_Store_master(engine: Engine) -> pl.DataFrame:
|
||||
sql = """
|
||||
SELECT
|
||||
RegionId AS region_id,
|
||||
RegionName AS region,
|
||||
StateId AS state_id,
|
||||
StateName AS state,
|
||||
CityId AS city_id,
|
||||
CityName AS city,
|
||||
CityCode AS cpm_city_id,
|
||||
|
||||
ChannelId AS channel_id,
|
||||
ChannelName AS channel,
|
||||
|
||||
DistributorId AS distributor_id,
|
||||
Distributor AS distributor_name,
|
||||
|
||||
ChainId AS keyaccount_id,
|
||||
ChainName AS keyaccount,
|
||||
|
||||
StoreUniqueCode AS insight_store_id,
|
||||
StoreCode AS client_store_code,
|
||||
|
||||
Latitude AS latitude,
|
||||
Longitude AS longitude,
|
||||
|
||||
StoreCategoryId AS store_category_id,
|
||||
StoreCategory AS store_category,
|
||||
|
||||
StoreTypeId AS store_type_id,
|
||||
StoreType AS store_type,
|
||||
|
||||
StoreClassId AS store_classification_id,
|
||||
StoreClass AS store_classification,
|
||||
|
||||
StLayerFourId,
|
||||
|
||||
StoreId AS store_id,
|
||||
StoreName AS store_name,
|
||||
Address AS address
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.vw_storedetail
|
||||
"""
|
||||
|
||||
log.info("Fetching Store Master data")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"Fetched {len(df):,} stores"
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
def fetch_sku_master(engine: Engine) -> pl.DataFrame:
|
||||
|
||||
sql = """
|
||||
SELECT
|
||||
CM.CategoryId AS category_id,
|
||||
CM.CategoryCode AS category_code,
|
||||
CM.CategoryName AS category_name,
|
||||
|
||||
SCA.SubCategoryId AS sub_category_id,
|
||||
SCA.SubCategoryCode AS sub_category_code,
|
||||
SCA.SubCategoryName AS sub_category_name,
|
||||
|
||||
BR.BrandId AS brand_id,
|
||||
BR.BrandCode AS brand_code,
|
||||
BR.BrandName AS brand_name,
|
||||
|
||||
SB.SubBrandId AS sub_brand_id,
|
||||
SB.SubBrandCode AS sub_brand_code,
|
||||
SB.SubBrandName AS sub_brand_name,
|
||||
|
||||
P.ProductId AS product_id,
|
||||
P.ProductName AS product_name,
|
||||
P.ProductCode AS product_code,
|
||||
|
||||
P.MRP AS mrp,
|
||||
|
||||
FL.FlavourId AS flavour_id,
|
||||
FL.Flavour AS flavour,
|
||||
|
||||
P.Grammage AS grammage,
|
||||
P.ProductSequence AS product_sequence,
|
||||
P.CaseSize AS case_size,
|
||||
|
||||
MC.Company AS company_name,
|
||||
MC.IsCompetitor AS is_competitor,
|
||||
|
||||
P.PTR AS ptr
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.Master_Product P
|
||||
|
||||
RIGHT JOIN OneApp_KelloggsMT.dbo.Master_Flavour FL
|
||||
ON P.FlavourId = FL.FlavourId
|
||||
|
||||
RIGHT JOIN OneApp_KelloggsMT.dbo.Master_SubBrand SB
|
||||
ON P.SubBrandId = SB.SubBrandId
|
||||
|
||||
RIGHT JOIN OneApp_KelloggsMT.dbo.Master_Brand BR
|
||||
ON SB.BrandId = BR.BrandId
|
||||
|
||||
RIGHT JOIN OneApp_KelloggsMT.dbo.Master_SubCategory SCA
|
||||
ON BR.SubCategoryId = SCA.SubCategoryId
|
||||
|
||||
RIGHT JOIN OneApp_KelloggsMT.dbo.Master_Category CM
|
||||
ON SCA.CategoryId = CM.CategoryId
|
||||
|
||||
RIGHT JOIN OneApp_KelloggsMT.dbo.Master_Company MC
|
||||
ON MC.CompanyId = BR.CompanyId
|
||||
"""
|
||||
|
||||
log.info("Fetching SKU Master data")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"Fetched {len(df):,} SKU Master rows"
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
def fetch_display_master(engine: Engine) -> pl.DataFrame:
|
||||
"""
|
||||
Fetch Display Master data.
|
||||
Source: Master_Display
|
||||
Target: display_master
|
||||
"""
|
||||
|
||||
sql = """
|
||||
SELECT
|
||||
DisplayId AS display_id,
|
||||
DisplayCode AS display_code,
|
||||
DisplayName AS display_name,
|
||||
DisplayRefImage AS display_ref_url
|
||||
FROM OneApp_KelloggsMT.dbo.Master_Display
|
||||
"""
|
||||
|
||||
log.info("Fetching Display Master data")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"Fetched {len(df):,} Display Master records"
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
import polars as pl
|
||||
from sqlalchemy.engine import Engine
|
||||
from loguru import logger as log
|
||||
|
||||
|
||||
def fetch_employee_master(engine: Engine) -> pl.DataFrame:
|
||||
"""
|
||||
Fetch Employee Master data.
|
||||
Source: vw_Employee_Detail + Mapping_PositionUser + Master_Position
|
||||
Target: Employee_Master
|
||||
"""
|
||||
|
||||
sql = """
|
||||
SELECT
|
||||
RegionId AS region_id,
|
||||
RegionName AS region,
|
||||
|
||||
StateId AS state_id,
|
||||
StateName AS state,
|
||||
|
||||
CityId AS city_id,
|
||||
CityName AS city,
|
||||
|
||||
A.EmpId AS employee_id,
|
||||
EmpName AS employee_name,
|
||||
Gender AS gender,
|
||||
|
||||
A.DesignationId AS designation_id,
|
||||
DesignationName AS designation,
|
||||
|
||||
SupervisorId AS manager_id,
|
||||
SupervisorName AS manager_name,
|
||||
|
||||
JoinDate AS employee_joining_date,
|
||||
ResignDate AS employee_resign_date,
|
||||
|
||||
C.PositionCode AS position_code,
|
||||
|
||||
EmpCode AS employee_legacy_code,
|
||||
|
||||
RIGHTNAME AS employee_role,
|
||||
|
||||
CASE
|
||||
WHEN RIGHTNAME IN ('Client', 'Client HO')
|
||||
THEN 'NON CPM'
|
||||
ELSE 'CPM'
|
||||
END AS employee_type
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.vw_Employee_Detail A
|
||||
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT DISTINCT
|
||||
PositionId,
|
||||
EmpId
|
||||
FROM OneApp_KelloggsMT.dbo.Mapping_PositionUser
|
||||
WHERE DATEDIFF(DAY, FromDate, GETDATE()) >= 0
|
||||
AND DATEDIFF(DAY, ToDate, GETDATE()) <= 0
|
||||
) B
|
||||
ON A.EmpId = B.EmpId
|
||||
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT
|
||||
PositionId,
|
||||
PositionCode
|
||||
FROM OneApp_KelloggsMT.dbo.Master_Position
|
||||
) C
|
||||
ON B.PositionId = C.PositionId
|
||||
"""
|
||||
|
||||
log.info("Fetching Employee Master data")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"Fetched {len(df):,} Employee Master records"
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def fetch_employee_master(engine: Engine) -> pl.DataFrame:
|
||||
"""
|
||||
Fetch Employee Master data.
|
||||
Source: vw_Employee_Detail + Mapping_PositionUser + Master_Position
|
||||
Target: Employee_Master
|
||||
"""
|
||||
|
||||
sql = """
|
||||
SELECT
|
||||
RegionId AS region_id,
|
||||
RegionName AS region,
|
||||
|
||||
StateId AS state_id,
|
||||
StateName AS state,
|
||||
|
||||
CityId AS city_id,
|
||||
CityName AS city,
|
||||
|
||||
A.EmpId AS employee_id,
|
||||
EmpName AS employee_name,
|
||||
Gender AS gender,
|
||||
|
||||
A.DesignationId AS designation_id,
|
||||
DesignationName AS designation,
|
||||
|
||||
SupervisorId AS manager_id,
|
||||
SupervisorName AS manager_name,
|
||||
|
||||
JoinDate AS employee_joining_date,
|
||||
ResignDate AS employee_resign_date,
|
||||
|
||||
C.PositionCode AS position_code,
|
||||
|
||||
EmpCode AS employee_legacy_code,
|
||||
|
||||
RIGHTNAME AS employee_role,
|
||||
|
||||
CASE
|
||||
WHEN RIGHTNAME IN ('Client', 'Client HO')
|
||||
THEN 'NON CPM'
|
||||
ELSE 'CPM'
|
||||
END AS employee_type
|
||||
|
||||
FROM OneApp_KelloggsMT.dbo.vw_Employee_Detail A
|
||||
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT DISTINCT
|
||||
PositionId,
|
||||
EmpId
|
||||
FROM OneApp_KelloggsMT.dbo.Mapping_PositionUser
|
||||
WHERE DATEDIFF(DAY, FromDate, GETDATE()) >= 0
|
||||
AND DATEDIFF(DAY, ToDate, GETDATE()) <= 0
|
||||
) B
|
||||
ON A.EmpId = B.EmpId
|
||||
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT
|
||||
PositionId,
|
||||
PositionCode
|
||||
FROM OneApp_KelloggsMT.dbo.Master_Position
|
||||
) C
|
||||
ON B.PositionId = C.PositionId
|
||||
"""
|
||||
|
||||
log.info("Fetching Employee Master data")
|
||||
|
||||
df = pl.read_database(
|
||||
query=sql,
|
||||
connection=engine
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"Fetched {len(df):,} Employee Master records"
|
||||
)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import os
|
||||
import pyarrow
|
||||
import sys
|
||||
import logging
|
||||
from datetime import date, timedelta
|
||||
import polars as pl
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.engine import Engine, URL
|
||||
import clickhouse_connect
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from log import log
|
||||
from clickhouse_task.create_table import create_clickhouse_table , check
|
||||
from db_con.connection import *
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def collect_mids(engine: Engine, target_date: date) -> list[int]:
|
||||
|
||||
sql = text("""
|
||||
SELECT MID FROM OneApp_KelloggsMT.dbo.T_StoreCoverage
|
||||
WHERE CONVERT(date, CreateDate) = :target_date
|
||||
UNION
|
||||
SELECT MID FROM OneApp_KelloggsMT.dbo.T_StoreCoverage
|
||||
WHERE CONVERT(date, UpdateDate) = :target_date
|
||||
""")
|
||||
log.info(f"Collecting MIDs for: {target_date}")
|
||||
with engine.connect() as conn:
|
||||
result = conn.execute(sql, {"target_date": target_date})
|
||||
mids = [row[0] for row in result.fetchall()]
|
||||
log.info(f"Found {len(mids):,} MIDs")
|
||||
return mids
|
||||
@@ -0,0 +1,10 @@
|
||||
[project]
|
||||
name = "data-move"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.14"
|
||||
dependencies = [
|
||||
"clickhouse-sqlalchemy>=0.3.2",
|
||||
"pyyaml>=6.0.3",
|
||||
]
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
tables:
|
||||
- name: SOS_OneApp
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: OQaD
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: Survey
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: additional_visibility
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: Coverage
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: Login
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: Stock_Details
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: Attendance
|
||||
type: FACT
|
||||
operation: DELETE+INSERT
|
||||
|
||||
- name: Store_Master
|
||||
type: DIMENSION
|
||||
operation: DELETE+INSERT
|
||||
|
||||
- name: SKU_Master
|
||||
type: DIMENSION
|
||||
operation: DELETE+INSERT
|
||||
|
||||
- name: display_master
|
||||
type: DIMENSION
|
||||
operation: DELETE+INSERT
|
||||
|
||||
- name: Employee_Master
|
||||
type: DIMENSION
|
||||
operation: DELETE+INSERT
|
||||
|
||||
- name: Journey_Plan
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: coverage_remarks
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: mapping_storevisibility
|
||||
type: BRIDGE
|
||||
operation: INSERT
|
||||
|
||||
- name: Master_VisibilityReason
|
||||
type: DIMENSION
|
||||
operation: INSERT
|
||||
|
||||
- name: Master_VisibilityDefinition
|
||||
type: DIMENSION
|
||||
operation: INSERT
|
||||
|
||||
- name: Web Logins
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: Promotion
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: PaidVisibility
|
||||
type: FACT
|
||||
operation: INSERT
|
||||
|
||||
- name: Master_Salesterritorylayer
|
||||
type: DIMENSION
|
||||
operation: INSERT
|
||||
@@ -0,0 +1,351 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.14"
|
||||
|
||||
[[package]]
|
||||
name = "asynch"
|
||||
version = "0.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "ciso8601" },
|
||||
{ name = "leb128" },
|
||||
{ name = "lz4" },
|
||||
{ name = "pytz" },
|
||||
{ name = "tzlocal" },
|
||||
{ name = "zstd" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0b/ce/f11ee2cafa6010d295db3ddee089f14cfc5fa9b8a19d0a21356c18a49267/asynch-0.3.1.tar.gz", hash = "sha256:d8bb3c1793a74a2e9d44cc7e8406ead3cf3818c11ecd6d8405b702b23148c584", size = 59825, upload-time = "2025-11-11T15:20:22.975Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/b0/9547aeadb577cb0c590162661b31110f7c3c02c1b23653a1b33222c7ff70/asynch-0.3.1-py3-none-any.whl", hash = "sha256:32b30a4409b70514077f7bf8ef713a248158fe5e63504c2769a4c7f772828412", size = 76502, upload-time = "2025-11-11T15:20:21.46Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2026.5.20"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f3/ce/ee2ecad540810a79593028e88299baeae54d346cc7a0d94b6199988b89b1/certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d", size = 135422, upload-time = "2026-05-20T11:46:50.073Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897", size = 134134, upload-time = "2026-05-20T11:46:48.578Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.4.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ciso8601"
|
||||
version = "2.3.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c1/8a/075724aea06c98626109bfd670c27c248c87b9ba33e637f069bf46e8c4c3/ciso8601-2.3.3.tar.gz", hash = "sha256:db5d78d9fb0de8686fbad1c1c2d168ed52efb6e8bf8774ae26226e5034a46dae", size = 31909, upload-time = "2025-08-20T16:31:33.51Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/3a/54ad0ae2257870076b4990545a8f16221470fecea0aa7a4e1f39506db8c5/ciso8601-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82db4047d74d8b1d129e7a8da578518729912c3bd19cb71541b147e41f426381", size = 16115, upload-time = "2025-08-20T16:30:54.971Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/fb/9fe767d44520691e2b706769466852fbdeb44a82dc294c2766bce1049d22/ciso8601-2.3.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:a553f3fc03a2ed5ca6f5716de0b314fa166461df01b45d8b36043ccac3a5e79f", size = 24214, upload-time = "2025-08-20T16:30:56.359Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/ac/984fd3948f372c46c436a2b48da43f4fb7bc6f156a6f4bc858adaab79d42/ciso8601-2.3.3-cp314-cp314-macosx_11_0_x86_64.whl", hash = "sha256:ff59c26083b7bef6df4f0d96e4b649b484806d3d7bcc2de14ad43147c3aafb04", size = 15929, upload-time = "2025-08-20T16:30:58.352Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/3a/5572917d4e0bec2c1ef0eda8652f9dc8d1850d29d3eef9e5e82ffe5d6791/ciso8601-2.3.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:99a1fa5a730790431d0bfcd1f3a6387f60cddc6853d8dcc5c2e140cd4d67a928", size = 41578, upload-time = "2025-08-20T16:30:59.351Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/cf/07321ce5cf099b98de0c02cd4bab4818610da69743003e94c8fb6e8a59cb/ciso8601-2.3.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c35265c1b0bd2ac30ed29b49818dd38b0d1dfda43086af605d8b91722727dec0", size = 42085, upload-time = "2025-08-20T16:31:00.338Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/c7/3c521d6779ee433d9596eb3fcded79549bbe371843f25e62006c04f74dc9/ciso8601-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aa9df2f84ab25454f14df92b2dd4f9aae03dbfa581565a716b3e89b8e2110c03", size = 41313, upload-time = "2025-08-20T16:31:01.313Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/93/efd40db0d6b512be1cbe4e7e750882c2e88f580e17f35b3e9cc9c23004b5/ciso8601-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:32e06a35eb251cfc4bbe01a858c598da0a160e4ad7f42ff52477157ceaf48061", size = 41443, upload-time = "2025-08-20T16:31:02.357Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/8e/515f9404faa39af8df5e2b899cafbca5dbe7cd2ffe5cc124ef393ffdaf1c/ciso8601-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:7657ba9730dc1340d73b9e61eca14f341c41dd308128c808b8b084d2b85bc03e", size = 17977, upload-time = "2025-08-20T16:31:03.429Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clickhouse-driver"
|
||||
version = "0.2.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pytz" },
|
||||
{ name = "tzlocal" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/46/9e/d8e40b29b6269a84552441a553fc64dff28f2d7e2d92e81c6be84fe12b4c/clickhouse_driver-0.2.10.tar.gz", hash = "sha256:925fc6ecda1e5314e3f03bcb493955c068b070cdba221fb8ce27329ee8a7f71b", size = 409448, upload-time = "2025-11-10T22:49:58.764Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/9f/513e661a80b0db9b6be5ce525d6cc86339c04dfc8d75f577b775e5ac5cf1/clickhouse_driver-0.2.10-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:19dd1de015d98dd1559d14ef05de2b6a0560c98b77ef160b3b99632a87fc8212", size = 211779, upload-time = "2025-11-10T22:48:36.873Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/6e/842610028ca39c826865402d46b7d7f499a9a249de219edfce889c0e025d/clickhouse_driver-0.2.10-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b6f35a9ee7f7a8ce3483764c3bc2d23c8be1c5ce3aef537b1a3cebe59fdb0c4d", size = 205709, upload-time = "2025-11-10T22:48:38.404Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/94/ddbcda962f7ca36cbcf7ded105f68f99b261dc29b9c28ca2eaec70382f66/clickhouse_driver-0.2.10-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:888ab59b2cccda24680cfbaeb723fd8922c6148b9a43ad4cf067fef55959f19f", size = 1032732, upload-time = "2025-11-10T22:48:40.047Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/1d/9d378af127ca1d35b734c965a9ec26318253f07d2a7eaa4a5643210fe327/clickhouse_driver-0.2.10-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fbf5d692ee4df241e82d200a195dc2ddbe7fbf490ebd185fbd9da32478245399", size = 1085199, upload-time = "2025-11-10T22:48:41.784Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/38/d65aedbe40e08a085fe3c2fcdcfcc0cec084d2e838e653c1ed4408771d9a/clickhouse_driver-0.2.10-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2f1d42ffcdc5b77346403e7ac49639a48c2fb58767a3e55657bd40e36290e9f0", size = 1089153, upload-time = "2025-11-10T22:48:43.283Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/e3/e60fbcd5ec1458da9fe313984527e9ce5f95636c178bd2d08d6257c42c30/clickhouse_driver-0.2.10-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74b36dfb79311bcf1ba6edde926908a46778a5e9db6302f126a799550f1fb807", size = 1023508, upload-time = "2025-11-10T22:48:44.83Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/80/345be27d8011bcbd2fd3437d15b0e387369e2a8a8b73a7704af25bb6e90b/clickhouse_driver-0.2.10-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8c49d4b6619ce9237817185a41db6645f1557f7a77f2a822029ded1041179d55", size = 995994, upload-time = "2025-11-10T22:48:46.35Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/76/de011c4460a2b80e517c9a5f1b80a9fe3937e2987989e9776a79dc0a1e99/clickhouse_driver-0.2.10-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:503bbcbfedd65840489dadf3d0a2ac391888828b8f82579e6ec08efb1f362659", size = 1043865, upload-time = "2025-11-10T22:48:47.924Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/f4/264b6bb95488eebd79565372c8fbe397df2aac1478224629ebdc229eab00/clickhouse_driver-0.2.10-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:64aa403194bf4d3bdbecc2f8412ca85f4b9a35ed8dc228f23061a9889ce18dc4", size = 1038468, upload-time = "2025-11-10T22:48:50.706Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/95/01b3cc32ba060132ce9183f7af9059995fed2ded8d41865e86193f17ce30/clickhouse_driver-0.2.10-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20b16b066760cfcc6a8a5342e91585a84ba22152f83421030edd3582b6e420e3", size = 998721, upload-time = "2025-11-10T22:48:52.924Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/d4/21e3203f8d22ad32224b0623ad2772103bb3a05ce367d6b27e78e118ea2f/clickhouse_driver-0.2.10-cp314-cp314-win32.whl", hash = "sha256:5ac6eed651dd6320a50338ff331fea93d20ed13dec27c7c7bfab71f8db3c76bb", size = 192639, upload-time = "2025-11-10T22:48:54.729Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/6b/1e87eb25614c0477fdadd5cf0b49675bc91cfcae95a10cbb83e3a688b01b/clickhouse_driver-0.2.10-cp314-cp314-win_amd64.whl", hash = "sha256:9f17746188833162e06e6af595e6a41c2ed09c7714b96860217c696fdb7689cf", size = 206586, upload-time = "2025-11-10T22:48:56.002Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clickhouse-sqlalchemy"
|
||||
version = "0.3.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "asynch" },
|
||||
{ name = "clickhouse-driver" },
|
||||
{ name = "requests" },
|
||||
{ name = "sqlalchemy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2d/b9/801073bb20edd4efc5e7240ea318b755867fb0d62acb374daafc35419b39/clickhouse-sqlalchemy-0.3.2.tar.gz", hash = "sha256:267f3a9a1d0d186eb99a41895a684922d31125cea21702cd7dc73af1ccdd10e7", size = 45206, upload-time = "2024-06-12T12:08:58.044Z" }
|
||||
|
||||
[[package]]
|
||||
name = "data-move"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "clickhouse-sqlalchemy" },
|
||||
{ name = "pyyaml" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "clickhouse-sqlalchemy", specifier = ">=0.3.2" },
|
||||
{ name = "pyyaml", specifier = ">=6.0.3" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "greenlet"
|
||||
version = "3.5.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6d/6e/802acd792aebb2256fbbee8cacf2727faaeb6f240ac11008f09eae4414bc/greenlet-3.5.1.tar.gz", hash = "sha256:5a56aeb7d5d9cc4b3a735efb5095bd4b4f6f0e4f93e5ca876d0e2315137b7829", size = 197356, upload-time = "2026-05-20T15:05:03.917Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/cb/c62454606daf5640369c94d8a9dd540599b1bfc090e2d2180cb77f4038d2/greenlet-3.5.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d8ab31c9de8651a2facdd5c5bb0011f2380dd1a7af78ce2adf4b56095294fc07", size = 285579, upload-time = "2026-05-20T13:08:56.396Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/71/c4270398c2eba968a6071af1dfbdcaeee6ec1c24bc8b435b8cc452700da6/greenlet-3.5.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e300185139abc337ade480c327183adf42a875ac7181bfe66d7d4efea31fbea", size = 651106, upload-time = "2026-05-20T14:00:09.448Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/ab/71e34b78a44ec271fb5f550c17bc46d301ddc5953890d935f270b0dcdb5a/greenlet-3.5.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7ffdb990dcaa0234cf9845aead5df2e3c3a8b6507d409274dd87e0d5ab05ffc2", size = 663478, upload-time = "2026-05-20T14:05:45.88Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/96/4efd6fa5c62c85426a0c19077a586258ebc3a2a146ff2493e4312a697a22/greenlet-3.5.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f82b3597e9d83b63408affed0b48fd0f54935edac4302237b9a837be0dae33c", size = 660800, upload-time = "2026-05-20T13:14:29.129Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/e0/6c71401a25cac7000261304e866a2f2cc04dc74810d40e2f118aa4799495/greenlet-3.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c0141e37414c10164e702b8fb1473304221ad98f71600850c6ef7ff4880feba0", size = 1617518, upload-time = "2026-05-20T14:02:28.662Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/26/c5c06643e8c0af9e7bf18e16cb51d0ab7625155f0392e1c9015d66d556cd/greenlet-3.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:50ae25a67bea74ea41fb14b960bc532df73eb713417b2d61892dced82fe8d3bc", size = 1681593, upload-time = "2026-05-20T13:14:39.417Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/bd/e11a108317485075e68af9d23039619b86b28130c3b50d227d42edece64b/greenlet-3.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:8a17c42330e261299766b75ac1ea32caa437a9453c8f65d16a13140db378ecd3", size = 239800, upload-time = "2026-05-20T13:09:30.128Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/f8/8e8e8417b7bf28639a5a56356ef934d0375e1d0c70a57e04d7701e870ffe/greenlet-3.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:7b5f5fae05b8ac6d176a61b60c394a8cbdc2b5b91b81793066e68745cf165e54", size = 236862, upload-time = "2026-05-20T13:09:10.498Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/12/41bf27fde4d3605d3773ae57751eda182b8be2f5398011c041173b1d9534/greenlet-3.5.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:ea8da1e900d758d078810d4255d8c6aa572181896a31ec79d779eb79c3adc9ad", size = 293637, upload-time = "2026-05-20T13:12:35.529Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/44/ba14b23e9757707050c2f397d305bbcae62e5d7cad122f8b6baec5ae4a1f/greenlet-3.5.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a19570c52a21420dcbc94e661994bc325c0b5b11304540fed514586da5dc8f2e", size = 650840, upload-time = "2026-05-20T14:00:11.079Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/37/5ddc2b686a6844f91abecef43411842426da2e1573f60b49ecf2547f4ae1/greenlet-3.5.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3d955c89b75eeca4723d7cc14135f393cd47c32e2a6cb4a8e4c6e760a26b0986", size = 656416, upload-time = "2026-05-20T14:05:47.118Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/f0/d17510297c35a2992712f0bf84de3779749999f7d3d63aa1f09db7c62dbe/greenlet-3.5.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2daaaebd1a5aa88c49045b6baf9310b3263796bd88db713edf37cf53e7bb4e", size = 654397, upload-time = "2026-05-20T13:14:30.696Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/eb/147387705bb89092645b012586e7273cb5ed3c90ef7eaf3a69173eaf0209/greenlet-3.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3bfbd69cc349e43bf3a8ae1c85548ff0718efc887615c2db16c3833d7b0b072d", size = 1614469, upload-time = "2026-05-20T14:02:30.192Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/4e/37ee0da7732b7aa9896f17e15579a9df34b9fcb9dd494f0adfa749af6623/greenlet-3.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4378720dd888136c27215a0214d32a4d37c3852765d45bc37aad0623423cfd78", size = 1675115, upload-time = "2026-05-20T13:14:40.972Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/f3/97dfcf4a6eb5077f8a672234216fb5923eb89f2cab7081cb10b2cf75b605/greenlet-3.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:45718441607f9325d948db98cbc691276059316d0358c188c246da4e1d4d23d2", size = 245246, upload-time = "2026-05-20T13:12:22.646Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/73/d7f72e34b582f694f4a9b248162db7b09cc458a259ba8f0c0bfa1a34ea7d/greenlet-3.5.1-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:2baee5ca02031757ffe8cc3d69f0cc0aec7065ce362622da74f32d3bcab1c541", size = 285575, upload-time = "2026-05-20T13:12:07.043Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/59/fa9c6e87dc8ad27a95dabe2f29f372b733d05a8a67470f6c901ed9975655/greenlet-3.5.1-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b1ec3274918a81d3ea778b9e75b56b72b33f300edb6cf7f3a7fe1dae56683de", size = 656428, upload-time = "2026-05-20T14:00:12.556Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/f9/e753408871eaa61dfe35e619cfc67512b036fde99893685d50eea9e07146/greenlet-3.5.1-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:111e2390ffffc47d5840b01711dd7fac07d4c09283d0283e7f3264b14e284c64", size = 667064, upload-time = "2026-05-20T14:05:48.662Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/27/5565b5b40389f1c7753003a07e21892fda8660926787036d5bc0308b8113/greenlet-3.5.1-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e630136e905fe5ff43e86945ae41220b6d1470956a39220e708110ac48d01ea5", size = 665697, upload-time = "2026-05-20T13:14:32.943Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/82/e7de4178c0c2d1c9a5a3be3cc0b33e46a85b3ee4a77c071bf7ad8600e079/greenlet-3.5.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:975eac34b44a7077ca4d421348455b94f0f518246a7f14bc6d2fdcfe5b584368", size = 1621256, upload-time = "2026-05-20T14:02:31.91Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/10/f2dddcf7dacac17dfc68691809589adad06135eb28930429cf58a6467a2f/greenlet-3.5.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:9ab3c3a0b2ae6198e67c898dad5215a49f9ae0d0081b3c3ec59f333e39eeca26", size = 1685956, upload-time = "2026-05-20T13:14:42.55Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/17/4a232b32133230ada52f70e9d7f5b65b0caef8772f01849bd8d149e7e4ca/greenlet-3.5.1-cp315-cp315-win_amd64.whl", hash = "sha256:cbfc69be86e10dcfef5b1e6269d1d6926552aa89ee39e1de3353360c1b6989ab", size = 239802, upload-time = "2026-05-20T13:13:15.481Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/ae/4e623a7e6d4d2a5f4cb8e4c82de4169fc637942caae68d6e676b8a128ac5/greenlet-3.5.1-cp315-cp315-win_arm64.whl", hash = "sha256:92fd6d44ac5e5a887c8a5dc4a8ba0ba908527c31c12f78c6bc7dcfe8aab279f6", size = 236853, upload-time = "2026-05-20T13:15:37.301Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/57/816d9cff29119da3505b3d6a5e14a8af89006ac36f47f891ff293ee05af1/greenlet-3.5.1-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:a6fdf2433a5441ef9a95464f7c3e674775da1c8c1177fff311cee1acad4626ed", size = 293877, upload-time = "2026-05-20T13:10:19.078Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/a1/59b0a7c7d140ff1a75626680b9a9899b79a9176cab298b394968fb023295/greenlet-3.5.1-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7546556f0d649f99f6a361098a55f761181bb2ea12ff150bb16d26092ad88244", size = 655333, upload-time = "2026-05-20T14:00:14.758Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/1b/5efe127597625042218939d01855109f352779050768b670b52edcc16a6c/greenlet-3.5.1-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5ee3ea898009fa898f85f9982255d35278c477bebe185beca249cab42d4526c", size = 659443, upload-time = "2026-05-20T14:05:50.159Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/6d/c404246ea4d22d097a7426d0efb5b781bd7eb67715f09e79001bd552ab18/greenlet-3.5.1-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5c81f74d204d3edd136ebfd50dce53acbb776995d721a0fe801626cfc93b8cd", size = 658356, upload-time = "2026-05-20T13:14:35.091Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/02/f8ee37fb6d2219329f350af241c27fcf12df57e723d11f6fc6d3bacdadaa/greenlet-3.5.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:2c18ef16bf6d4dd410e4dd52996888ea1497be26892fe5bbc73580aba4287b8e", size = 1619216, upload-time = "2026-05-20T14:02:33.403Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/c5/3dc9475ace2c7a3680da12372cddd7f1ac874eb410a1ac48d3e9dab83782/greenlet-3.5.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:17d86354f0ae6b61bf9be5148d0dd34e06c3cb7c602c671f79f29ac3b150e659", size = 1678427, upload-time = "2026-05-20T13:14:43.71Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/4e/750c15c317a41ffb36f0bf40b933e3d744a7dede61889f74443ea69690cf/greenlet-3.5.1-cp315-cp315t-win_amd64.whl", hash = "sha256:e7516cf6ae6b8a582c2770a0caed47b8a48373ed732c33d69a72913ae6ac923e", size = 245225, upload-time = "2026-05-20T13:13:59.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/fd/d3baea2eeb7b617efd47e87ca06e2ec2c6118d303aa9e918e0ce16eadc10/greenlet-3.5.1-cp315-cp315t-win_arm64.whl", hash = "sha256:5028648bf2253ec4745add746129d3904121fa7fe871a76bed23c5720573ce0a", size = 239590, upload-time = "2026-05-20T13:13:37.382Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.18"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leb128"
|
||||
version = "1.0.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a4/3c/ef6fe994b4b45d84187fea994f124173d587f4f8ab0641693ef269e80f56/leb128-1.0.9.tar.gz", hash = "sha256:8f8b0e2216ba8a318e2897360d9a34d88e2c968656fcb7c7bbb1aef31010f1c6", size = 26710, upload-time = "2026-01-09T08:29:39.261Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/f6/62cd379fe8527c6d685013ebed11c85fd4fced125bde9b3c80ebd5759850/leb128-1.0.9-py2.py3-none-any.whl", hash = "sha256:fef16ef20aca33dfdd2f4841d8004ec4acb7ed8545b63a7bc1183292c9a3e594", size = 3700, upload-time = "2026-01-09T08:29:37.446Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lz4"
|
||||
version = "4.4.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/57/51/f1b86d93029f418033dddf9b9f79c8d2641e7454080478ee2aab5123173e/lz4-4.4.5.tar.gz", hash = "sha256:5f0b9e53c1e82e88c10d7c180069363980136b9d7a8306c4dca4f760d60c39f0", size = 172886, upload-time = "2025-11-03T13:02:36.061Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/63/9c/70bdbdb9f54053a308b200b4678afd13efd0eafb6ddcbb7f00077213c2e5/lz4-4.4.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c216b6d5275fc060c6280936bb3bb0e0be6126afb08abccde27eed23dead135f", size = 207586, upload-time = "2025-11-03T13:02:18.263Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/cb/bfead8f437741ce51e14b3c7d404e3a1f6b409c440bad9b8f3945d4c40a7/lz4-4.4.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c8e71b14938082ebaf78144f3b3917ac715f72d14c076f384a4c062df96f9df6", size = 207161, upload-time = "2025-11-03T13:02:19.286Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/18/b192b2ce465dfbeabc4fc957ece7a1d34aded0d95a588862f1c8a86ac448/lz4-4.4.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b5e6abca8df9f9bdc5c3085f33ff32cdc86ed04c65e0355506d46a5ac19b6e9", size = 1292415, upload-time = "2025-11-03T13:02:20.829Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/79/a4e91872ab60f5e89bfad3e996ea7dc74a30f27253faf95865771225ccba/lz4-4.4.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3b84a42da86e8ad8537aabef062e7f661f4a877d1c74d65606c49d835d36d668", size = 1279920, upload-time = "2025-11-03T13:02:22.013Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/01/d52c7b11eaa286d49dae619c0eec4aabc0bf3cda7a7467eb77c62c4471f3/lz4-4.4.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bba042ec5a61fa77c7e380351a61cb768277801240249841defd2ff0a10742f", size = 1368661, upload-time = "2025-11-03T13:02:23.208Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/da/137ddeea14c2cb86864838277b2607d09f8253f152156a07f84e11768a28/lz4-4.4.5-cp314-cp314-win32.whl", hash = "sha256:bd85d118316b53ed73956435bee1997bd06cc66dd2fa74073e3b1322bd520a67", size = 90139, upload-time = "2025-11-03T13:02:24.301Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/2c/8332080fd293f8337779a440b3a143f85e374311705d243439a3349b81ad/lz4-4.4.5-cp314-cp314-win_amd64.whl", hash = "sha256:92159782a4502858a21e0079d77cdcaade23e8a5d252ddf46b0652604300d7be", size = 101497, upload-time = "2025-11-03T13:02:25.187Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/28/2635a8141c9a4f4bc23f5135a92bbcf48d928d8ca094088c962df1879d64/lz4-4.4.5-cp314-cp314-win_arm64.whl", hash = "sha256:d994b87abaa7a88ceb7a37c90f547b8284ff9da694e6afcfaa8568d739faf3f7", size = 93812, upload-time = "2025-11-03T13:02:26.133Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2025.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.34.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "charset-normalizer" },
|
||||
{ name = "idna" },
|
||||
{ name = "urllib3" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
version = "2.0.50"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/57/da/6fbf010c8ebb347679d0d100b22fe9ba5e13fd04046c5df7280d2f0bf706/sqlalchemy-2.0.50.tar.gz", hash = "sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9", size = 9907424, upload-time = "2026-05-24T19:20:04.018Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/df/32/10ac51b4be7cdecd7e93d069251c86dfbf70b7adbd7c67b48ccea6c49e1c/sqlalchemy-2.0.50-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0", size = 2158519, upload-time = "2026-05-24T19:27:56.472Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/76/e703d2f7681d7d66c4c891af3f07c7ccf4c76ad7f18351de035b5eda007a/sqlalchemy-2.0.50-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb", size = 3282063, upload-time = "2026-05-24T20:09:38.57Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/26/ef168b184a25701f9995e8fb7e503fafd7a99c1c77cda1bc1a26ea2ed486/sqlalchemy-2.0.50-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e", size = 3287069, upload-time = "2026-05-24T20:17:21.942Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/15/765acc2bc693bccc43ca4a95d5b69750da8aaf6db1b5c616536e087f8920/sqlalchemy-2.0.50-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d", size = 3230453, upload-time = "2026-05-24T20:09:40.398Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/61/08e03c3adbf5db0087a0b6816746fec8f3032fb2f7fc899a9bb9b2a48ce4/sqlalchemy-2.0.50-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f", size = 3252413, upload-time = "2026-05-24T20:17:24.067Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/0c/370a1f2db38436c615e10134c8a37de3688e74084792380695f3f5083860/sqlalchemy-2.0.50-cp314-cp314-win32.whl", hash = "sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8", size = 2120063, upload-time = "2026-05-24T19:50:11.08Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/a0/fe92bb9817863bc13ba093bda931979a26cc2ca69f8e8f26d07add3d7c6f/sqlalchemy-2.0.50-cp314-cp314-win_amd64.whl", hash = "sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39", size = 2145830, upload-time = "2026-05-24T19:50:12.452Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/ff/e5640a98a0b2f491eb8fde10fb6c773621a2e44340de231fafcc9370f4a9/sqlalchemy-2.0.50-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70", size = 2178435, upload-time = "2026-05-24T19:42:58.889Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/85/337116e186f1236375b5fb70c21cfac98e8e8ab0d3a47be838dc47a59e08/sqlalchemy-2.0.50-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086", size = 3566059, upload-time = "2026-05-24T20:01:20.848Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/34/bb0e190e161c3c2c24314a65add57218be14a4a9486886b7f5047c1ff7c8/sqlalchemy-2.0.50-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52", size = 3535366, upload-time = "2026-05-24T20:03:56.768Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/5a/a7f759f97e4fd499c5d4e4488c760d5a7fbecf3028b465a04274fcd52384/sqlalchemy-2.0.50-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a", size = 3474879, upload-time = "2026-05-24T20:01:23.058Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/d9/2907ea38eb60687d297bf9c39e5ee58053c87b57fe8a9cae97090cecbf10/sqlalchemy-2.0.50-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d", size = 3486117, upload-time = "2026-05-24T20:03:59.052Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/e3/5aa06f167559f8c0bdae487e297d23ba548150ab016a3418265d617a4985/sqlalchemy-2.0.50-cp314-cp314t-win32.whl", hash = "sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e", size = 2150823, upload-time = "2026-05-24T20:08:58.644Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/9b/112fb8f977582d7489d036e409e3723948bcf5320b3ac465f3c481bbe8f9/sqlalchemy-2.0.50-cp314-cp314t-win_amd64.whl", hash = "sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51", size = 2185794, upload-time = "2026-05-24T20:09:00.319Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/10/f7220e9b784d295d241c86ed99aeb537f92afcd469a64861f2717e9bb077/sqlalchemy-2.0.50-py3-none-any.whl", hash = "sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9", size = 1943861, upload-time = "2026-05-24T19:59:01.119Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.15.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2026.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzlocal"
|
||||
version = "5.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "tzdata", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8b/2e/c14812d3d4d9cd1773c6be938f89e5735a1f11a9f184ac3639b93cef35d5/tzlocal-5.3.1.tar.gz", hash = "sha256:cceffc7edecefea1f595541dbd6e990cb1ea3d19bf01b2809f362a03dd7921fd", size = 30761, upload-time = "2025-03-05T21:17:41.549Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl", hash = "sha256:eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d", size = 18026, upload-time = "2025-03-05T21:17:39.857Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "1.5.7.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/49/62/b9c075ad664e7c4cbb3d8d2be7c246506abe1bc7f778eb58d260ef9538c8/zstd-1.5.7.3.tar.gz", hash = "sha256:403e5205f4ac04b92e6b0cda654be2f51de268228a0db0067bc087faacf2f495", size = 672559, upload-time = "2026-01-08T16:24:43.361Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/d9/854b2643b677d22c914e352691cc46fea875867863fb453814fabaa9cc38/zstd-1.5.7.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:5412c86c34cbaf6906433ef3f2c96c407f208782f06cd3e5f01f066788adb3b8", size = 268245, upload-time = "2026-01-08T16:43:39.347Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/b7/97f8c206efd27df3dc7ebe2bf2d69193a67d5de024726b15c2b79ddace30/zstd-1.5.7.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f94246befb1e473211a298c96e5768f3c63eaad814ac14d160d79ae9858e1d03", size = 230992, upload-time = "2026-01-08T16:43:37.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/d9/e2771b6144f3b2a26daaf6bb40c233ef887fce03627e7825e11a674ced65/zstd-1.5.7.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:31050e17a1a546fb82c90eee8ee3c30d22b9d0594b5937e69d38b7a5084af2a2", size = 2162418, upload-time = "2026-01-08T18:09:00.35Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/a5/871ac984f6b8bad512104747e55eb3b65bd89342715e030522e9cbe3b1c7/zstd-1.5.7.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ba8ec5dfd48c86d19f880713246f85d09ee06e8cd17141956258650878000d6", size = 2202154, upload-time = "2026-01-08T18:08:57.748Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/5d/828157d6fe7f72d5c5473231a575e98e4e2c861d65a8acdd0e7200588ff6/zstd-1.5.7.3-cp314-cp314-manylinux_2_14_i686.whl", hash = "sha256:3005540ba406157f3e205c998709ab5f8e68b390c658c7c238eb8986092089d5", size = 300205, upload-time = "2026-01-08T16:29:58.595Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/71/09617dcd1d3be40fc43f210f6d99c2011861db9c8e1a444a571e1022716e/zstd-1.5.7.3-cp314-cp314-manylinux_2_14_x86_64.whl", hash = "sha256:3934b54a3b7df039fcd4cf7b0f0a38c86ce44d26321255ffc3fac73d6cdcc59d", size = 304148, upload-time = "2026-01-08T16:41:47.079Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/c2/6abdab0a1b0b1326bd53fa187568630d78a01bd3734e035360869d80a52b/zstd-1.5.7.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e9230cd3e9153e2bed16f332558f8f3f7d869f4d15e8fa3f9c360bfa163a8b4a", size = 2096739, upload-time = "2026-01-08T18:09:03.943Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/7b/3867d0279bab7d0a69fdc06403e4d23f7e6a8f54530ef6626bcf09a19d62/zstd-1.5.7.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5bffba70af539f14f9df5367b1add9119f14d5e35b658aef7b765417ea461e0e", size = 2125551, upload-time = "2026-01-08T18:09:02.133Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/f3/75566c4d29ab144ac4e1c915e4f58ce239cbe5ae4f8376fb56edf4114866/zstd-1.5.7.3-cp314-cp314-win32.whl", hash = "sha256:a006e70c88ab67bb56989e11d820adc7601a6a7ad5558b3c6c690b19a1dadc5b", size = 153519, upload-time = "2026-01-08T17:20:15.507Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/22/6c42f636f92e74cda4acfeab0e64dd4a3db3a07d5f5723ae885b8155c85a/zstd-1.5.7.3-cp314-cp314-win_amd64.whl", hash = "sha256:cb4957c330c7b94b0546c7b9529723b49e865608683b9503a251fe793da9d4db", size = 171454, upload-time = "2026-01-08T17:20:17.124Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/71/ff79a965e040d90de1cabb842ef22ef4475ef37cae81be3646cbb9c7a9b4/zstd-1.5.7.3-cp314-cp314-win_arm64.whl", hash = "sha256:a785426081ab7cafe4522876ac771d701766deea9a6d8352e87744da00e6637f", size = 163084, upload-time = "2026-01-08T16:37:52.448Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/46/56453790f9b7859e5593b767361adb2662318c55c3e4af0fffa1d389a2a5/zstd-1.5.7.3-cp314-cp314t-manylinux_2_14_i686.whl", hash = "sha256:b52ef154793be0399befd742328ec6f5dff95154248d6d18dd65851cf22a1a5f", size = 300364, upload-time = "2026-01-10T11:12:15.545Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/9e/501836085c9c6672effc0bc11d0383b439d414edd033958209bb93c68ac3/zstd-1.5.7.3-cp314-cp314t-manylinux_2_14_x86_64.whl", hash = "sha256:8024a8ba9156b1b2e64e69d147df5ddedeaed107f9da02a3428fd7baf3e5b920", size = 304338, upload-time = "2026-01-10T11:12:03.378Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/ee/b71a41ae810b429b909b4d68c9bd6decc4bca1407cac8d157b9470a654e2/zstd-1.5.7.3-cp315-cp315-manylinux_2_14_i686.whl", hash = "sha256:31ac7fbacca4759aad4b6abc13bbc05e68788e9e85a968255f7624b3b8db31df", size = 300146, upload-time = "2026-01-08T16:56:10.452Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/24/3925528355ededa372951f10e85bec9870e3f4d325b04cfb6d9707ba7dec/zstd-1.5.7.3-cp315-cp315-manylinux_2_14_x86_64.whl", hash = "sha256:d03b2927c5843ded4d1319836a33a9c21675d2f86f916a2f234a060d4c67d87c", size = 304202, upload-time = "2026-01-08T16:35:34.94Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/37/2ed92c824e2f8ecff1a5f699677277a4d46ce9d527800aadf5f867455ccd/zstd-1.5.7.3-cp315-cp315t-manylinux_2_14_i686.whl", hash = "sha256:5dfbf2564eb574fc1f45613ecf28036a82533c3dd70e7bb1c9854168c638da7a", size = 300404, upload-time = "2026-01-08T16:24:41.593Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/77/a152dde083129c3eee60c3bc83963b8c747112afe375b3d6d4a96fa15427/zstd-1.5.7.3-cp315-cp315t-manylinux_2_14_x86_64.whl", hash = "sha256:7f2f5776b902f41daf7b63e75a9384b0d7c855f824f14dabefc67814b8fa5611", size = 304333, upload-time = "2026-01-08T16:25:49.196Z" },
|
||||
]
|
||||
Reference in New Issue
Block a user