Skip to content

Commit 48276c7

Browse files
authored
Merge pull request #4 from bcdev/yogesh-fix-issues
Fix tiny issues and add new features
2 parents 9d57453 + 31c9d19 commit 48276c7

File tree

14 files changed

+1285
-36
lines changed

14 files changed

+1285
-36
lines changed

CHANGES.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## Version 0.0.3 (in development)
2+
3+
* **Bug fix** - `ExternalPythonOperator` does not need Airflow in external environment now.
4+
5+
* Jupyter Lab can now be started in any conda/mamba environment via Gaiaflow.
6+
7+
* Added user workflow diagram in the `Overview` page of the documentation.
8+
9+
* Added a new subcommand `gaiaflow dev update-deps --help` to update
10+
dependencies on the fly in Airflow containers for workflow tasks.
11+
12+
13+
114
## Version 0.0.2
215

316
* **Chore**: Update `pyproject.toml` to include `README.md` and necessary links.

docs/index.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,64 @@ Quick rule of thumb:
215215
- Use `prod_local` for testing end-to-end workflows on production-like settngs.
216216
- Use `prod` for production pipelines in the real cluster.
217217

218+
## User workflow:
219+
A typical user workflow could look like this:
220+
221+
```mermaid
222+
flowchart TD
223+
A1[Start]--> A
224+
A{Prerequisites installed except template?}-->|Yes| D{Which OS?}
225+
A -->|No| STOP[Stop]
226+
227+
D -->|Windows WSL2| E1[Install template via conda/mamba/miniforge prompt<br/>then create env in WSL2 CLI + install gaiaflow]
228+
D -->|Linux| E2[Install template + create env<br/>then install gaiaflow]
229+
E1 --> M
230+
E2 --> M
231+
232+
M[Start services in Dev Mode<br/>`gaiaflow start dev -p .`] --> N[Experiment in JupyterLab if needed]
233+
234+
N --> P[Refactor to production code<br/>inside Python package and logging experiements to MLFlow and artifacts to S3 MinIO if needed]
235+
P --> Q[Write tests in tests/ folder]
236+
Q --> R[Create workflows with create_task mode=dev in Airflow]
237+
R --> S[Run & monitor DAG in Airflow]
238+
S --> T[Track experiments in MLflow & outputs in MinIO]
239+
T --> V{Workflow ran successfully in dev mode?}
240+
V --> |Yes| V1{Test your package in docker mode?}
241+
242+
V1 --> |Yes| V2[Change create_task mode to dev_docker and run gaiaflow dev dockerize -p .]
243+
244+
V2 --> V3{Docker mode ran successfully?}
245+
V3 --> |Yes| V4{Move to production?}
246+
247+
V4 --> |Yes| X1[Start Prod-Local infra<br/>`gaiaflow prod-local start -p .`]
248+
249+
V --> |No| V5[Fix bugs]
250+
V1 --> |No| STOP[Stop]
251+
V3 --> |No| V6[Fix bugs]
252+
V4 --> |No| STOP[Stop]
253+
254+
V5 --> R
255+
V6 --> V3
256+
257+
X1 --> X2[Build Docker image<br/>`gaiaflow prod-local dockerize -p .`]
258+
X2 --> X3[Configure secrets if needed]
259+
X3 --> Y{Prod-Local Success?}
260+
Y2 --> Y
261+
Y -->|Yes| Y1[Set create_task mode to prod - Local services are not needed anymore]
262+
Y1 --> Z[Deploy to Production Cluster ]
263+
264+
Y -->|No| Y2[Fix the bugs]
265+
266+
class A,D,U,Y,V,V1,V3,V4 decision;
267+
class E1,F1,G1,H1 windows;
268+
class E2,G2,H2 linux;
269+
class Z prod;
270+
class STOP,STOP2 stop;
271+
272+
classDef decision fill:#FFDD99,stroke:#E67E22,stroke-width:2px;
273+
classDef windows fill:#AED6F1,stroke:#2874A6,stroke-width:2px;
274+
classDef linux fill:#ABEBC6,stroke:#1E8449,stroke-width:2px;
275+
classDef prod fill:#D7BDE2,stroke:#7D3C98,stroke-width:2px;
276+
classDef stop fill:#F5B7B1,stroke:#922B21,stroke-width:2px;
277+
278+
```

docs/start.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ This means now you have successfully installed Docker.
207207

208208
### Gaiaflow Installation
209209

210+
In Windows, install `gaiaflow` using WSL2 terminal in a new mamba/conda environment.
211+
210212
You can install Gaiaflow directly via pip:
211213

212214
`pip install gaiaflow`

mkdocs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,14 @@ markdown_extensions:
7676
- pymdownx.emoji:
7777
emoji_index: !!python/name:material.extensions.emoji.twemoji
7878
emoji_generator: !!python/name:material.extensions.emoji.to_svg
79+
- pymdownx.superfences:
80+
custom_fences:
81+
- name: mermaid
82+
class: mermaid
83+
format: !!python/name:pymdownx.superfences.fence_code_format
7984

8085
extra:
86+
mermaid: true
8187
social:
8288
- icon: fontawesome/brands/github
8389
link: https://github.com/bcdev/gaiaflow

pixi.lock

Lines changed: 1020 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "gaiaflow"
33
requires-python = ">= 3.11"
4-
version = "0.0.2"
4+
version = "0.0.3.dev0"
55
description = "Local-first MLOps infrastructure python tool that simplifies the process of building, testing, and deploying ML workflows."
66
authors = [{name = "Yogesh Kumar Baljeet Singh", email = "[email protected]"}]
77
dependencies = [
@@ -16,6 +16,7 @@ dependencies = [
1616
"apache-airflow-providers-fab>=2.3.1,<3",
1717
"apache-airflow-providers-docker>=4.4.2,<5",
1818
"mlflow>=3.2.0,<4",
19+
"jupyter>=1.1.1,<2",
1920
]
2021
readme= "README.md"
2122

@@ -78,6 +79,8 @@ mkdocs-material = ">=9.6.17,<10"
7879
mkdocstrings = ">=0.30.0,<0.31"
7980
mkdocstrings-python = ">=1.17.0,<2"
8081
pytest-cov = ">=6.2.1,<7"
82+
jupyter = ">=1.1.1,<2"
83+
pymdown-extensions = ">=10.16.1,<11"
8184

8285
[project.scripts]
8386
gaiaflow = "gaiaflow.cli.cli:app"

src/docker_stuff/airflow/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ RUN micromamba --version
1919
USER airflow
2020
COPY environment.yml .
2121

22-
RUN micromamba env create -f environment.yml -n default_user_env
22+
RUN micromamba env create -f environment.yml -n default_user_env && rm environment.yml
2323
RUN micromamba env list
2424

2525
RUN micromamba shell init -s bash

src/gaiaflow/cli/commands/mlops.py

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,16 @@ def start(
5252
jupyter_port: int = typer.Option(
5353
8895, "--jupyter-port", "-j", help="Port for JupyterLab"
5454
),
55-
delete_volume: bool = typer.Option(
56-
False, "--delete-volume", "-v", help="Delete volumes on shutdown"
57-
),
5855
docker_build: bool = typer.Option(
5956
False, "--docker-build", "-b", help="Force Docker image build"
6057
),
58+
user_env_name: str = typer.Option(
59+
None, "--env", "-e", help="Provide conda/mamba environment name for "
60+
"Jupyter Lab to run. If not set, it will use the name from your environment.yml file."
61+
),
62+
env_tool: "str" = typer.Option(
63+
"mamba", "--env-tool", "-t", help="Which tool to use for running your Jupyter lab. Options: mamba, conda",
64+
),
6165
):
6266
imports = load_imports()
6367
typer.echo(f"Selected Gaiaflow services: {service}")
@@ -84,8 +88,9 @@ def start(
8488
service=s,
8589
cache=cache,
8690
jupyter_port=jupyter_port,
87-
delete_volume=delete_volume,
8891
docker_build=docker_build,
92+
user_env_name=user_env_name,
93+
env_tool=env_tool,
8994
)
9095
else:
9196
typer.echo("Running start with all services")
@@ -97,8 +102,9 @@ def start(
97102
service=Service.all,
98103
cache=cache,
99104
jupyter_port=jupyter_port,
100-
delete_volume=delete_volume,
101105
docker_build=docker_build,
106+
user_env_name=user_env_name,
107+
env_tool=env_tool,
102108
)
103109

104110

@@ -265,8 +271,31 @@ def dockerize(
265271
image_name=image_name
266272
)
267273

274+
@app.command(help="Update the dependencies for the Airflow tasks. This command "
275+
"synchronizes the running container environments with the project's"
276+
"`environment.yml`. Make sure you have updated "
277+
"`environment.yml` before running"
278+
"this, as the container environments are updated based on "
279+
"its contents.")
280+
def update_deps(
281+
project_path: Path = typer.Option(..., "--path", "-p", help="Path to your project"),
282+
):
283+
imports = load_imports()
284+
gaiaflow_path, user_project_path = imports.create_gaiaflow_context_path(
285+
project_path
286+
)
287+
gaiaflow_path_exists = imports.gaiaflow_path_exists_in_state(gaiaflow_path, True)
288+
if not gaiaflow_path_exists:
289+
imports.save_project_state(user_project_path, gaiaflow_path)
290+
else:
291+
typer.echo(
292+
f"Gaiaflow project already exists at {gaiaflow_path}. Skipping "
293+
f"saving to the state"
294+
)
268295

269-
270-
# TODO: To let the user update the current infra with new local packages or
271-
# mounts as they want it.
272-
# def update():
296+
typer.echo("Running update_deps")
297+
imports.MlopsManager.run(
298+
gaiaflow_path=gaiaflow_path,
299+
user_project_path=user_project_path,
300+
action=imports.ExtendedAction.UPDATE_DEPS,
301+
)

src/gaiaflow/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class ExtendedAction:
1919
DOCKERIZE = Action("dockerize")
2020
CREATE_CONFIG = Action("create_config")
2121
CREATE_SECRET = Action("create_secret")
22+
UPDATE_DEPS = Action("update_deps")
2223

2324

2425
GAIAFLOW_CONFIG_DIR = Path.home() / ".gaiaflow"

src/gaiaflow/core/operators.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def create_task(self):
125125
from gaiaflow.core.runner import run
126126

127127
args, kwargs = self.resolve_args_kwargs()
128-
kwargs["params"] = self.params
128+
kwargs["params"] = dict(self.params)
129129
op_kwargs = {"func_path": self.func_path, "args": args, "kwargs": kwargs}
130130

131131
return ExternalPythonOperator(
@@ -135,6 +135,8 @@ def create_task(self):
135135
op_kwargs=op_kwargs,
136136
do_xcom_push=True,
137137
retries=self.retries,
138+
expect_airflow=False,
139+
expect_pendulum=False,
138140
)
139141

140142

0 commit comments

Comments
 (0)