DKOps 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dkops-0.1.0/LICENSE +21 -0
- dkops-0.1.0/PKG-INFO +406 -0
- dkops-0.1.0/README.md +366 -0
- dkops-0.1.0/pyproject.toml +100 -0
- dkops-0.1.0/setup.cfg +4 -0
- dkops-0.1.0/src/DKOps/__init__.py +0 -0
- dkops-0.1.0/src/DKOps/environment_config.py +385 -0
- dkops-0.1.0/src/DKOps/launcher.py +368 -0
- dkops-0.1.0/src/DKOps/logger_config.py +299 -0
- dkops-0.1.0/src/DKOps/table_governance/__init__.py +34 -0
- dkops-0.1.0/src/DKOps/table_governance/contracts/__init__.py +0 -0
- dkops-0.1.0/src/DKOps/table_governance/contracts/loader.py +669 -0
- dkops-0.1.0/src/DKOps/table_governance/contracts/validator.py +269 -0
- dkops-0.1.0/src/DKOps/table_governance/migrations/__init__.py +0 -0
- dkops-0.1.0/src/DKOps/table_governance/migrations/safe_migrator.py +270 -0
- dkops-0.1.0/src/DKOps/table_governance/readers/__init__.py +3 -0
- dkops-0.1.0/src/DKOps/table_governance/readers/table_reader.py +297 -0
- dkops-0.1.0/src/DKOps/table_governance/writers/__init__.py +15 -0
- dkops-0.1.0/src/DKOps/table_governance/writers/append_writer.py +42 -0
- dkops-0.1.0/src/DKOps/table_governance/writers/base_writer.py +384 -0
- dkops-0.1.0/src/DKOps/table_governance/writers/create_writer.py +91 -0
- dkops-0.1.0/src/DKOps/table_governance/writers/delete_writer.py +111 -0
- dkops-0.1.0/src/DKOps/table_governance/writers/partition_writer.py +75 -0
- dkops-0.1.0/src/DKOps/table_governance/writers/table_writer.py +162 -0
- dkops-0.1.0/src/DKOps/table_governance/writers/upsert_writer.py +110 -0
- dkops-0.1.0/src/DKOps.egg-info/PKG-INFO +406 -0
- dkops-0.1.0/src/DKOps.egg-info/SOURCES.txt +33 -0
- dkops-0.1.0/src/DKOps.egg-info/dependency_links.txt +1 -0
- dkops-0.1.0/src/DKOps.egg-info/requires.txt +16 -0
- dkops-0.1.0/src/DKOps.egg-info/top_level.txt +1 -0
- dkops-0.1.0/tests/test_contracts.py +280 -0
- dkops-0.1.0/tests/test_luncher.py +283 -0
- dkops-0.1.0/tests/test_safe_migrator.py +282 -0
- dkops-0.1.0/tests/test_table_reader.py +368 -0
- dkops-0.1.0/tests/test_table_writer.py +382 -0
dkops-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Roberto Sanchez Figueroa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
dkops-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: DKOps
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Lakehouse automation framework for DataOps, DevOps, QA, and Medallion architecture on Databricks
|
|
5
|
+
Author-email: Roberto <brrsanchezfi@unal.edu.co>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/brrsanchezfi/DKOps
|
|
8
|
+
Project-URL: Documentation, https://github.com/brrsanchezfi/DKOps
|
|
9
|
+
Project-URL: Repository, https://github.com/brrsanchezfi/DKOps
|
|
10
|
+
Keywords: databricks,spark,delta,lakehouse,dataops,medallion
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Database
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: loguru>=0.7.0
|
|
27
|
+
Provides-Extra: local
|
|
28
|
+
Requires-Dist: pyspark==3.5.3; extra == "local"
|
|
29
|
+
Requires-Dist: delta-spark==3.2.0; extra == "local"
|
|
30
|
+
Provides-Extra: databricks-connect
|
|
31
|
+
Requires-Dist: databricks-connect<16.0,>=14.0; extra == "databricks-connect"
|
|
32
|
+
Requires-Dist: zstandard>=0.21.0; extra == "databricks-connect"
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
36
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
37
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
38
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
<div align="center">
|
|
42
|
+
|
|
43
|
+
# DKOps
|
|
44
|
+
|
|
45
|
+
**Framework de gobierno de tablas Delta y orquestación de pipelines Spark para entornos híbridos local ↔ Databricks.**
|
|
46
|
+
|
|
47
|
+
[](https://www.python.org/)
|
|
48
|
+
[](https://spark.apache.org/)
|
|
49
|
+
[](https://delta.io/)
|
|
50
|
+
[](LICENSE)
|
|
51
|
+
[](#-contribuir)
|
|
52
|
+
|
|
53
|
+
*El mismo código corre en tu PC y en Databricks — sin cambios.*
|
|
54
|
+
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## ¿Qué es DKOps?
|
|
60
|
+
|
|
61
|
+
DKOps es un framework Python que **profesionaliza la construcción de pipelines de datos** sobre Spark + Delta Lake. Resuelve los problemas que aparecen cuando un equipo crece más allá de "scripts sueltos":
|
|
62
|
+
|
|
63
|
+
- **Contratos de tabla** — el schema, los permisos, el particionado y los metadatos viven en JSON versionado, no enterrados en código.
|
|
64
|
+
- **`TableWriter`** — API unificada: `overwrite`, `append`, `upsert`, `overwrite_partition`, `delete`. Un solo objeto, sin ruido.
|
|
65
|
+
- **merge_schema** — declara `"merge_schema": true` en el contrato y Delta añade columnas nuevas automáticamente al hacer append, sin recrear la tabla.
|
|
66
|
+
- **Enmascaramiento de columnas** — declara `"mask": "security.fn"` en una columna y el framework aplica `ALTER TABLE … SET MASK` post-escritura en Unity Catalog.
|
|
67
|
+
- **Migraciones seguras** — `SafeMigrator` compara contrato vs estado real y genera un plan de cambios sin pérdida de datos.
|
|
68
|
+
- **Runtime-agnóstico** — el mismo pipeline corre en local PC (Spark + Delta) y en Databricks (Connect o cluster nativo). El framework detecta el entorno y se adapta.
|
|
69
|
+
- **Configuración por entorno** — placeholders `{catalog.bronze}`, `{path.silver}` se resuelven contra `dev`/`prod` desde un único `config.json`.
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from DKOps.launcher import Launcher
|
|
73
|
+
from DKOps.table_governance import load_contract, TableWriter
|
|
74
|
+
|
|
75
|
+
launcher = Launcher("config/config.json")
|
|
76
|
+
contract = load_contract("tables/fact_ventas.json")
|
|
77
|
+
|
|
78
|
+
TableWriter(contract).overwrite(df) # full load
|
|
79
|
+
TableWriter(contract).upsert(df_nuevo, keys=["venta_id"]) # SCD1
|
|
80
|
+
TableWriter(contract).append(df_evolucionado) # schema evolution automática
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Tabla de contenidos
|
|
86
|
+
|
|
87
|
+
- [Arquitectura](#-arquitectura)
|
|
88
|
+
- [Instalación](#-instalación)
|
|
89
|
+
- [Requisitos](#requisitos)
|
|
90
|
+
- [Entorno local PC (`.venv-local`)](#entorno-local-pc-venv-local)
|
|
91
|
+
- [Entorno Databricks Connect (`.venv-databricks`)](#entorno-databricks-connect-venv-databricks)
|
|
92
|
+
- [Configuración](#-configuración)
|
|
93
|
+
- [Quickstart](#-quickstart)
|
|
94
|
+
- [Demos](#-demos)
|
|
95
|
+
- [Build](#-build)
|
|
96
|
+
- [Estado del proyecto](#-estado-del-proyecto)
|
|
97
|
+
- [Contribuir](#-contribuir)
|
|
98
|
+
- [Licencia](#-licencia)
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 🏗️ Arquitectura
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
DKOps/
|
|
106
|
+
├── launcher.py # punto de entrada — detecta runtime y crea SparkSession
|
|
107
|
+
├── environment_config.py # resuelve catalogs/paths/secrets según workspace activo
|
|
108
|
+
├── logger_config.py # logging estructurado (loguru) con contexto
|
|
109
|
+
└── table_governance/
|
|
110
|
+
├── contracts/
|
|
111
|
+
│ ├── loader.py # carga JSON → TableContract tipado (merge_schema, mask)
|
|
112
|
+
│ └── validator.py # valida DataFrame contra contrato (tipos, nulls)
|
|
113
|
+
├── writers/
|
|
114
|
+
│ ├── table_writer.py # ★ fachada pública: overwrite/append/upsert/delete
|
|
115
|
+
│ ├── base_writer.py # bridge local PC ↔ Databricks + merge_schema + masks
|
|
116
|
+
│ ├── create_writer.py # CREATE OR REPLACE TABLE
|
|
117
|
+
│ ├── append_writer.py # INSERT INTO
|
|
118
|
+
│ ├── upsert_writer.py # MERGE INTO (SCD1)
|
|
119
|
+
│ ├── partition_writer.py # overwrite de partición específica
|
|
120
|
+
│ └── delete_writer.py # DELETE WHERE
|
|
121
|
+
└── migrations/
|
|
122
|
+
└── safe_migrator.py # compara contrato vs tabla real → plan de migración
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Filosofía:** pasar `spark` y `env` a cada componente es ruido. El `Launcher` se auto-registra como singleton del proceso; los writers, loaders y migrator obtienen lo que necesitan vía `Launcher.current()`. La API queda mínima: `TableWriter(contract).overwrite(df)`.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 📦 Instalación
|
|
130
|
+
|
|
131
|
+
### Requisitos
|
|
132
|
+
|
|
133
|
+
- **Python 3.10+** (3.11 recomendado)
|
|
134
|
+
- **Java 11 o 17** (requerido por Spark)
|
|
135
|
+
- **Git**
|
|
136
|
+
|
|
137
|
+
DKOps se distribuye con `pyproject.toml`. Recomendamos dos virtual environments separados — uno para correr localmente con Spark, otro para Databricks Connect — porque tienen dependencias incompatibles entre sí (PySpark vanilla vs `databricks-connect`).
|
|
138
|
+
|
|
139
|
+
### Entorno local PC (`.venv-local`)
|
|
140
|
+
|
|
141
|
+
Para desarrollo y tests en tu máquina con Spark + Delta Lake configurados desde cero.
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# 1. Clonar el repo
|
|
145
|
+
git clone https://github.com/brrsanchezfi/BigDataFrameworkSpark.git
|
|
146
|
+
cd <NOMBRE_REPO>
|
|
147
|
+
|
|
148
|
+
# 2. Crear el venv local
|
|
149
|
+
python3 -m venv .venv-local
|
|
150
|
+
source .venv-local/bin/activate # Linux/Mac/WSL
|
|
151
|
+
# .venv-local\Scripts\activate # Windows PowerShell
|
|
152
|
+
|
|
153
|
+
# 3. Instalar el framework + dependencias locales
|
|
154
|
+
pip install --upgrade pip
|
|
155
|
+
pip install -e ".[local]"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Esto instala:
|
|
159
|
+
- `pyspark` 3.5.x (con Delta Lake configurado vía JARs en runtime)
|
|
160
|
+
- `loguru` para logging estructurado
|
|
161
|
+
- `pytest` para tests
|
|
162
|
+
- DKOps en modo editable (`-e`) — los cambios al código se reflejan al instante
|
|
163
|
+
|
|
164
|
+
**Verificación:**
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
python -c "from DKOps.launcher import Launcher; print('OK')"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Entorno Databricks Connect (`.venv-databricks`)
|
|
171
|
+
|
|
172
|
+
Para conectarte desde tu máquina a un cluster Databricks remoto. **No mezcles este venv con el local** — las versiones de PySpark son incompatibles.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# 1. Crear el venv (asegúrate de NO tener el local activo)
|
|
176
|
+
deactivate 2>/dev/null
|
|
177
|
+
python3 -m venv .venv-databricks
|
|
178
|
+
source .venv-databricks/bin/activate
|
|
179
|
+
|
|
180
|
+
# 2. Instalar el framework + extras de Databricks
|
|
181
|
+
pip install --upgrade pip
|
|
182
|
+
pip install -e ".[databricks]"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Esto instala:
|
|
186
|
+
- `databricks-connect` (versión que coincida con el runtime de tu cluster)
|
|
187
|
+
- `databricks-sdk`
|
|
188
|
+
- `loguru`, `pytest`
|
|
189
|
+
- DKOps en modo editable
|
|
190
|
+
|
|
191
|
+
**Configurar credenciales** (PAT o OAuth):
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Opción A: Personal Access Token (rápido para desarrollo)
|
|
195
|
+
export DATABRICKS_HOST="https://<workspace>.azuredatabricks.net"
|
|
196
|
+
export DATABRICKS_TOKEN="<tu-pat>"
|
|
197
|
+
|
|
198
|
+
# Opción B: OAuth via Databricks CLI (recomendado para uso prolongado)
|
|
199
|
+
databricks auth login
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Luego edita tu `config.json`:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"EXECUTION_ENVIRONMENT": "databricks",
|
|
207
|
+
"CLUSTER_ID": "<tu-cluster-id>"
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Verificación:**
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
python -c "from databricks.connect import DatabricksSession; \
|
|
215
|
+
DatabricksSession.builder.getOrCreate().sql('SELECT 1').show()"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Cuál venv activar
|
|
219
|
+
|
|
220
|
+
| Estás haciendo... | Activa |
|
|
221
|
+
|---|---|
|
|
222
|
+
| Desarrollo del framework, tests unitarios, demos en local | `.venv-local` |
|
|
223
|
+
| Ejecutar contra un cluster Databricks remoto desde la PC | `.venv-databricks` |
|
|
224
|
+
| Notebook dentro del workspace Databricks | Ninguno — usa el del cluster |
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## ⚙️ Configuración
|
|
229
|
+
|
|
230
|
+
DKOps lee un `config.json` que define:
|
|
231
|
+
- El runtime (`local` o `databricks`).
|
|
232
|
+
- Los **environments** del proyecto (`dev`, `prod`) con sus catálogos, paths y secrets scopes.
|
|
233
|
+
- Configuración de logging.
|
|
234
|
+
|
|
235
|
+
Estructura mínima:
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"EXECUTION_ENVIRONMENT": "local",
|
|
240
|
+
"SPARK_APP_NAME": "miPipeline",
|
|
241
|
+
"SPARK_WAREHOUSE_DIR": "/tmp/spark-warehouse",
|
|
242
|
+
"DELTA_VERSION": "3.2.0",
|
|
243
|
+
|
|
244
|
+
"environments": {
|
|
245
|
+
"<workspace_id>": {
|
|
246
|
+
"env": "dev",
|
|
247
|
+
"env_short": "d",
|
|
248
|
+
"catalogs": {
|
|
249
|
+
"bronze": "bronze_dev",
|
|
250
|
+
"silver": "silver_dev",
|
|
251
|
+
"gold": "gold_dev"
|
|
252
|
+
},
|
|
253
|
+
"paths": {
|
|
254
|
+
"bronze": "abfss://bronze@<storage>.dfs.core.windows.net",
|
|
255
|
+
"silver": "abfss://silver@<storage>.dfs.core.windows.net"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
DKOps busca el config en este orden:
|
|
263
|
+
1. Argumento explícito: `Launcher("ruta/config.json")`
|
|
264
|
+
2. Variable de entorno: `PATH_CONFIG_LAUNCHER=ruta/config.json`
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## 🚀 Quickstart
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
from DKOps.launcher import Launcher
|
|
272
|
+
from DKOps.table_governance import load_contract, TableWriter
|
|
273
|
+
|
|
274
|
+
# 1. Inicializa el Launcher (auto-detecta runtime, crea SparkSession)
|
|
275
|
+
launcher = Launcher("config/config.json")
|
|
276
|
+
|
|
277
|
+
# 2. Carga un contrato JSON — los placeholders {catalog.silver} se resuelven solos
|
|
278
|
+
contract = load_contract("tables/fact_ventas.json")
|
|
279
|
+
|
|
280
|
+
# 3. Construye tu DataFrame (de un source, una transformación, lo que sea)
|
|
281
|
+
df = launcher.spark.read.parquet("source/ventas.parquet")
|
|
282
|
+
|
|
283
|
+
# 4. Escribe — full load inicial
|
|
284
|
+
TableWriter(contract).overwrite(df)
|
|
285
|
+
|
|
286
|
+
# 5. Día siguiente — solo añadir lo nuevo
|
|
287
|
+
TableWriter(contract).upsert(df_delta, keys=["venta_id", "fecha"])
|
|
288
|
+
|
|
289
|
+
# 6. Schema evolution — el contrato tiene merge_schema: true
|
|
290
|
+
df_nuevo_campo = df_delta.withColumn("canal", lit("web"))
|
|
291
|
+
TableWriter(contract).append(df_nuevo_campo) # Delta añade la columna automáticamente
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Para ejemplos completos con varias capas y tests, ver la carpeta [`demos/`](demos/).
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## 📚 Demos
|
|
299
|
+
|
|
300
|
+
Cada demo es **independiente y autocontenido**, pensado como referencia de uso.
|
|
301
|
+
|
|
302
|
+
| Demo | Tema | Qué demuestra |
|
|
303
|
+
|---|---|---|
|
|
304
|
+
| [`demos/demo_1`](demos/demo_1) | Contratos y writers gobernados | Bootstrap, append, upsert, partition overwrite, delete y migración con `SafeMigrator`. Dominio: aeronáutica. |
|
|
305
|
+
| [`demos/demo_2`](demos/demo_2) | Transformaciones testeables y Data Quality | Pipeline bronze → silver → gold con funciones puras de transformación, tests `pytest` y motor de DQ declarativo. Dominio: manufactura de aseo. |
|
|
306
|
+
| [`demos/demo_3`](demos/demo_3) | merge_schema y enmascaramiento | Schema evolution con `merge_schema: true` y column masking con `mask` en contratos. Dominio: e-commerce. |
|
|
307
|
+
|
|
308
|
+
Para correr un demo:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
source .venv-local/bin/activate
|
|
312
|
+
cd demos/demo_1
|
|
313
|
+
python pipeline_aeronautica.py
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## 🔨 Build
|
|
319
|
+
|
|
320
|
+
DKOps usa `pyproject.toml` (PEP 517/621). Para construir el wheel distribuible:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
source .venv-local/bin/activate
|
|
324
|
+
pip install --upgrade build
|
|
325
|
+
python -m build
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Esto genera en `dist/`:
|
|
329
|
+
- `dkops-X.Y.Z-py3-none-any.whl` — wheel para instalar en Databricks o cualquier entorno
|
|
330
|
+
- `dkops-X.Y.Z.tar.gz` — sdist
|
|
331
|
+
|
|
332
|
+
**Subir a Databricks** como librería del cluster:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
databricks libraries install --cluster-id <id> --whl dist/dkops-X.Y.Z-py3-none-any.whl
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Versionado:** DKOps sigue [Semantic Versioning](https://semver.org/). La versión vive en `pyproject.toml`.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## 📊 Estado del proyecto
|
|
343
|
+
|
|
344
|
+
| Componente | Estado |
|
|
345
|
+
|---|---|
|
|
346
|
+
| `Launcher` (multi-runtime) | ✅ Estable |
|
|
347
|
+
| Contratos + `ContractLoader` | ✅ Estable |
|
|
348
|
+
| `TableWriter` (fachada unificada) | ✅ Estable |
|
|
349
|
+
| Writers individuales (`Create`, `Append`, `Upsert`, `Partition`, `Delete`) | ✅ Estables |
|
|
350
|
+
| `merge_schema` (schema evolution) | ✅ Disponible |
|
|
351
|
+
| Enmascaramiento de columnas (`mask`) | ✅ Disponible (Databricks / Unity Catalog) |
|
|
352
|
+
| `SafeMigrator` (esquema seguro) | ✅ Estable |
|
|
353
|
+
| Demos (1, 2, 3) | ✅ Disponibles |
|
|
354
|
+
| Tests del framework (36 tests) | ✅ Disponibles |
|
|
355
|
+
| Documentación de API | 🚧 En desarrollo |
|
|
356
|
+
| Soporte SCD2 | 📋 Backlog |
|
|
357
|
+
| Módulo de Data Quality nativo | 📋 Backlog (existe prototipo en `demo_2`) |
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
<div align="center">
|
|
362
|
+
|
|
363
|
+
## 🤝 Contribuir
|
|
364
|
+
|
|
365
|
+
**¿Te interesa lo que estamos construyendo? Las contribuciones son bienvenidas y muy apreciadas.**
|
|
366
|
+
|
|
367
|
+
[](https://github.com/brrsanchezfi/BigDataFrameworkSpark/issues)
|
|
368
|
+
[](https://github.com/brrsanchezfi/BigDataFrameworkSpark/pulls)
|
|
369
|
+
[](https://github.com/brrsanchezfi/BigDataFrameworkSpark/commits)
|
|
370
|
+
|
|
371
|
+
</div>
|
|
372
|
+
|
|
373
|
+
Áreas donde nos vendría especialmente bien ayuda:
|
|
374
|
+
|
|
375
|
+
- 🧪 **Más tests** — la suite cubre contratos, writers y migrator; faltan tests de integración y cobertura de casos extremos.
|
|
376
|
+
- 📖 **Documentación** — guías de uso, referencia de API, casos reales.
|
|
377
|
+
- 🎨 **Más demos** — dominios distintos, patrones distintos.
|
|
378
|
+
- 🐛 **Reportar bugs** — abre un issue con un caso reproducible.
|
|
379
|
+
- 💡 **Discutir ideas** — el módulo de Data Quality, soporte SCD2, integración con Great Expectations son temas abiertos.
|
|
380
|
+
|
|
381
|
+
### Cómo contribuir
|
|
382
|
+
|
|
383
|
+
1. **Haz fork** del repo y crea una rama: `git checkout -b feature/mi-mejora`
|
|
384
|
+
2. Activa el venv local: `source .venv-local/bin/activate`
|
|
385
|
+
3. Haz tus cambios siguiendo el estilo del código existente.
|
|
386
|
+
4. Si añades funcionalidad, **añade un test o un demo** que la demuestre.
|
|
387
|
+
5. Verifica que los demos siguen pasando: `cd demos/demo_2 && pytest`
|
|
388
|
+
6. Abre un Pull Request describiendo el cambio y por qué es útil.
|
|
389
|
+
|
|
390
|
+
¿Primera vez contribuyendo a un proyecto open source? Consulta [esta guía de GitHub](https://docs.github.com/es/get-started/quickstart/contributing-to-projects).
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## 📄 Licencia
|
|
395
|
+
|
|
396
|
+
DKOps se distribuye bajo licencia MIT. Ver [`LICENSE`](LICENSE) para los términos completos.
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
<div align="center">
|
|
401
|
+
|
|
402
|
+
**Hecho con ☕ y ❤️ por el equipo de Data Engineering.**
|
|
403
|
+
|
|
404
|
+
Si DKOps te resulta útil, considera darle una ⭐ al repo — ayuda a que otros lo encuentren.
|
|
405
|
+
|
|
406
|
+
</div>
|