Skip to content

Commit 167e462

Browse files
author
Nijat Khanbabayev
committed
Merge branch 'main' into nk/auto_deps_auto_callable_model
2 parents d180f35 + 839a0d9 commit 167e462

File tree

24 files changed

+2242
-98
lines changed

24 files changed

+2242
-98
lines changed

.copier-answers.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Changes here will be overwritten by Copier
2-
_commit: b74d698
2+
_commit: 3160d4c
33
_src_path: https://github.com/python-project-templates/base.git
44
add_docs: false
55
add_extension: python

.github/workflows/build.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
run: make coverage
5454

5555
- name: Upload test results (Python)
56-
uses: actions/upload-artifact@v6
56+
uses: actions/upload-artifact@v7
5757
with:
5858
name: py-test-results-${{ matrix.os }}-${{ matrix.python-version }}-
5959
path: junit.xml
@@ -74,7 +74,7 @@ jobs:
7474
- name: Twine check
7575
run: make dist
7676

77-
- uses: actions/upload-artifact@v6
77+
- uses: actions/upload-artifact@v7
7878
with:
7979
name: dist-${{matrix.os}}
8080
path: dist

.gitignore

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ __pycache__/
1111
*.exp
1212
*.lib
1313

14+
# Rust
15+
target
16+
1417
# Distribution / packaging
1518
.Python
1619
build/
@@ -55,26 +58,12 @@ junit.xml
5558
.hypothesis/
5659
.pytest_cache/
5760

58-
# Translations
59-
*.mo
60-
*.pot
61-
62-
# Django stuff:
61+
# Django
6362
*.log
6463
local_settings.py
6564
db.sqlite3
6665
db.sqlite3-journal
6766

68-
# Flask stuff:
69-
instance/
70-
.webassets-cache
71-
72-
# Scrapy stuff:
73-
.scrapy
74-
75-
# PyBuilder
76-
target/
77-
7867
# IPython
7968
profile_default/
8069
ipython_config.py
@@ -85,15 +74,12 @@ ipython_config.py
8574
# pipenv
8675
Pipfile.lock
8776

88-
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
89-
__pypackages__/
90-
91-
# Celery stuff
77+
# Celery
9278
celerybeat-schedule
9379
celerybeat.pid
9480

95-
# SageMath parsed files
96-
*.sage.py
81+
# Airspeed Velocity
82+
.asv
9783

9884
# Environments
9985
.env
@@ -141,14 +127,12 @@ js/node_modules
141127
js/test-results
142128
js/playwright-report
143129
js/*.tgz
144-
ccflow/extension
145130

146131
# Jupyter
147132
.ipynb_checkpoints
148133
.autoversion
149134
Untitled*.ipynb
150-
!ccflow/extension/ccflow.json
151-
!ccflow/extension/install.json
135+
ccflow/extension
152136
ccflow/nbextension
153137
ccflow/labextension
154138

@@ -158,8 +142,11 @@ ccflow/labextension
158142
# Rust
159143
target
160144

145+
# Hydra
146+
outputs/
147+
multirun/
148+
161149
# Examples
162-
outputs
163150
raw.html
164151
extracted.csv
165152
etl.db

Makefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,15 @@ format: fix
4646
################
4747
# Other Checks #
4848
################
49-
.PHONY: check-manifest checks check
49+
.PHONY: check-dist check-types checks check
5050

51-
check-manifest: ## check python sdist manifest with check-manifest
52-
check-manifest -v
51+
check-dist: ## check python sdist and wheel with check-dist
52+
check-dist -v
5353

54-
checks: check-manifest
54+
check-types: ## check python types with ty
55+
ty check --python $$(which python)
56+
57+
checks: check-dist
5558

5659
# Alias
5760
check: checks

ccflow/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.8.0"
1+
__version__ = "0.8.1"
22

33
# Import exttypes early so modules that import `from ccflow import PyObjectPath` during
44
# initialization find it (avoids circular import issues with functions that import utilities

ccflow/base.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def __new__(self, name: str, bases: Tuple[type], namespaces: Dict[str, Any], **k
150150

151151

152152
class BaseModel(PydanticBaseModel, _RegistryMixin, metaclass=_SerializeAsAnyMeta):
153-
"""BaseModel is a base class for all pydantic models within the cubist flow framework.
153+
"""BaseModel is a base class for all pydantic models within the ccflow framework.
154154
155155
This gives us a way to add functionality to the framework, including
156156
- Type of object is part of serialization/deserialization
@@ -241,6 +241,34 @@ def get_widget(
241241
# Can't use self.model_dump_json or self.model_dump because they don't expose the fallback argument
242242
return JSON(self.__pydantic_serializer__.to_python(self, **kwargs), **(widget_kwargs or {}))
243243

244+
def __panel__(self):
245+
"""Return a Panel viewable for this model.
246+
247+
Requires ccflow UI dependencies (panel, panel_material_ui).
248+
"""
249+
try:
250+
from ccflow.ui.model import ModelViewer
251+
except ImportError:
252+
raise ImportError(
253+
"panel and other optional dependencies must be installed to use ModelViewer. Pip install ccflow[full] to install all optional dependencies."
254+
) from None
255+
256+
return ModelViewer(model=self)
257+
258+
def get_panel(self):
259+
"""Get a Panel pane for this model.
260+
261+
Requires panel to be installed.
262+
"""
263+
try:
264+
import panel as pn
265+
except ImportError:
266+
raise ImportError(
267+
"panel and other optional dependencies must be installed to use get_panel(). Pip install ccflow[full] to install all optional dependencies."
268+
) from None
269+
270+
return pn.panel(self)
271+
244272
@model_validator(mode="wrap")
245273
def _base_model_validator(cls, v, handler, info):
246274
if isinstance(v, str):
@@ -400,6 +428,15 @@ def models(self) -> MappingProxyType:
400428
"""Return an immutable pointer to the models dictionary."""
401429
return MappingProxyType(self._models)
402430

431+
def __panel__(self):
432+
"""Return a Panel viewable for this registry.
433+
434+
Requires ccflow UI dependencies (panel, panel_material_ui).
435+
"""
436+
from ccflow.ui.registry import ModelRegistryViewer
437+
438+
return ModelRegistryViewer(self)
439+
403440
@classmethod
404441
def root(cls) -> Self:
405442
"""Return a static instance of the root registry."""

ccflow/context.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""This module defines re-usable contexts for the "Callable Model" framework defined in flow.callable.py."""
22

3-
import warnings
43
from datetime import date, datetime
54
from typing import Any, Generic, Hashable, Optional, Sequence, Set, TypeVar
65

@@ -11,9 +10,6 @@
1110
from .exttypes import Frequency
1211
from .validators import normalize_date, normalize_datetime
1312

14-
warnings.simplefilter("always", DeprecationWarning)
15-
16-
1713
__all__ = (
1814
"FlowContext",
1915
"NullContext",

ccflow/exttypes/narwhals.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ def validate_from_any(value: Any):
5959
if source_args and source_args[0] and source_args[0] is not Any:
6060
backend = source_args[0].__module__.split(".", 1)[0]
6161

62+
if "backend" in value:
63+
if backend is None:
64+
# backend in source args takes precedence
65+
backend = value["backend"]
66+
67+
value = value["data"]
68+
6269
try:
6370
try:
6471
value = nw.from_dict(value, backend=backend)
@@ -89,7 +96,10 @@ def validate_from_any(value: Any):
8996

9097
def serialize(value: Any):
9198
if isinstance(value, nw.DataFrame):
92-
return value.to_dict(as_series=False)
99+
return {
100+
"data": value.to_dict(as_series=False),
101+
"backend": value.implementation.value,
102+
}
93103
else:
94104
raise ValueError("Cannot serialize a LazyFrame to JSON. Please use the collect() method to convert it to a DataFrame first.")
95105

ccflow/tests/evaluators/util.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import logging
2-
from datetime import date, datetime
2+
from datetime import date, datetime, timezone
33
from typing import Any, ClassVar, List, Optional
44

55
import pandas as pd
@@ -36,7 +36,7 @@ class MyDateCallable(CallableModel):
3636

3737
@Flow.call(volatile=True, validate_result=False)
3838
def current_time(self, context: DateContext):
39-
out = datetime.utcnow()
39+
out = datetime.now(timezone.utc)
4040
log.info("Current datetime: %s", out)
4141
return out
4242

ccflow/tests/result/test_narwhals.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import narwhals.stable.v1 as nw
44
import polars as pl
55
import pytest
6+
from polars.testing import assert_frame_equal
67

78
from ccflow.exttypes.narwhals import (
89
DataFrameT,
@@ -90,3 +91,10 @@ class MyNarwhalsResult(NarwhalsDataFrameResult):
9091
df = pl.DataFrame(data)
9192
result = MyNarwhalsResult(df=df)
9293
assert result.df.schema["d"] == nw.Float64()
94+
95+
96+
def test_serialization(data):
97+
df = pl.DataFrame(data)
98+
result = NarwhalsDataFrameResult(df=df)
99+
result2 = NarwhalsDataFrameResult.model_validate_json(result.model_dump_json())
100+
assert_frame_equal(result.df.to_native(), result2.df.to_native())

0 commit comments

Comments
 (0)