Skip to content

Commit

Permalink
Merge pull request #625 from graphistry/dev/fix-new-types
Browse files Browse the repository at this point in the history
Dev/fix new types
  • Loading branch information
lmeyerov authored Dec 29, 2024
2 parents c18d72a + 43c6553 commit e2ee9f4
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 33 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Development]

## [0.35.4 - 2024-12-28]

### Fixes

* `Plottable._render` now typed as `RenderModesConcrete`
* Remote GFQL - Handle `output_type is None`

## [0.35.3 - 2024-12-24]

### Docs
Expand Down
25 changes: 4 additions & 21 deletions graphistry/Plottable.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Plottable(object):
_point_x : Optional[str]
_point_y : Optional[str]
_height : int
_render : bool
_render : RenderModesConcrete
_url_params : dict
_name : Optional[str]
_description : Optional[str]
Expand Down Expand Up @@ -497,26 +497,9 @@ def settings(self,
url_params: Dict[str, Any] = {},
render: Optional[Union[bool, RenderModes]] = None
) -> 'Plottable':
"""Specify iframe height and add URL parameter dictionary.
The library takes care of URI component encoding for the dictionary.
:param height: Height in pixels.
:type height: int
:param url_params: Dictionary of querystring parameters to append to the URL.
:type url_params: dict
:param render: Set default render mode from RenderModes types, where True/None is "auto" and False is "url"
:type render: Optional[Union[bool, RenderModes]]
"""

res = self.copy()
res._height = height or self._height
res._url_params = dict(self._url_params, **url_params)
res._render = self._render if render is None else render
return res
if 1 + 1:
raise RuntimeError('should not happen')
return self

def to_cudf(self) -> 'Plottable':
if 1 + 1:
Expand Down
4 changes: 2 additions & 2 deletions graphistry/PlotterBase.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from graphistry.Plottable import Plottable, RenderModes
from graphistry.Plottable import Plottable, RenderModes, RenderModesConcrete
from typing import Any, Callable, Dict, List, Optional, Union
from graphistry.render.resolve_render_mode import resolve_render_mode
import copy, hashlib, numpy as np, pandas as pd, pyarrow as pa, sys, uuid
Expand Down Expand Up @@ -155,7 +155,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
self._point_y : Optional[str] = None
# Settings
self._height : int = 500
self._render : bool = True
self._render : RenderModesConcrete = resolve_render_mode(self, True)
self._url_params : dict = {'info': 'true'}
self._privacy : Optional[Privacy] = None
# Metadata
Expand Down
2 changes: 1 addition & 1 deletion graphistry/compute/python_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def task(g: Plottable) -> Dict[str, Any]:
"engine": engine,
**({"run_label": run_label} if run_label else {}),
**({'format': format} if format != 'json' else {}),
**({'output_type': output_type} if output_type != 'json' else {})
**({'output_type': output_type} if output_type is not None and output_type != 'json' else {})
}

url = f"{self.base_url_server()}/api/v2/datasets/{dataset_id}/python"
Expand Down
23 changes: 15 additions & 8 deletions graphistry/render/resolve_render_mode.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
from functools import lru_cache
from typing import Optional, Union

from graphistry.Plottable import RENDER_MODE_CONCRETE_VALUES, Plottable, RenderModes, RenderModesConcrete
from graphistry.util import in_databricks, in_ipython


def resolve_render_mode(
self: Plottable,
render: Optional[Union[bool, RenderModes]],
) -> RenderModesConcrete:

# cascade
if render is None:
render = self._render
@lru_cache(10)
def resolve_cascaded(render: Union[bool, RenderModes]):

# => RenderMode
if isinstance(render, bool):
Expand All @@ -33,3 +28,15 @@ def resolve_render_mode(
return "browser"
except Exception:
return "url"


def resolve_render_mode(
self: Plottable,
render: Optional[Union[bool, RenderModes]],
) -> RenderModesConcrete:

# cascade
if render is None:
render = self._render

return resolve_cascaded(render)
9 changes: 8 additions & 1 deletion graphistry/tests/render/test_resolve_render_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from unittest.mock import Mock

import graphistry.render
from graphistry.render.resolve_render_mode import resolve_render_mode
from graphistry.render.resolve_render_mode import resolve_cascaded, resolve_render_mode
from graphistry.tests.common import NoAuthTestCase
from graphistry.tests.test_compute import CGFull
from graphistry.tests.test_plotter import Fake_Response
Expand All @@ -24,12 +24,14 @@ def abc_g() -> CGFull:
's', 'd'))

def test_resolve_concrete(abc_g):
resolve_cascaded.cache_clear()

# concrete
for mode in ['g', 'url', 'browser', 'ipython', 'databricks']:
assert resolve_render_mode(abc_g, mode) == mode

def test_resolve_sniffed(abc_g):
resolve_cascaded.cache_clear()

# bool
assert resolve_render_mode(abc_g, True) in ['url', 'ipython', 'databricks', 'browser']
Expand All @@ -39,6 +41,7 @@ def test_resolve_sniffed(abc_g):
assert resolve_render_mode(abc_g, None) in ['url', 'ipython', 'databricks', 'browser']

def test_resolve_cascade(abc_g):
resolve_cascaded.cache_clear()

assert resolve_render_mode(abc_g.settings(render='g'), None) == 'g'
assert resolve_render_mode(abc_g.settings(render='g'), 'url') == 'url'
Expand All @@ -50,6 +53,7 @@ def test_resolve_cascade(abc_g):
class TestIPython(NoAuthTestCase):

def test_no_ipython(self, mock_in_ipython):
resolve_cascaded.cache_clear()
mock_in_ipython.return_value = False

mode_render_true = resolve_render_mode(abc_g, True)
Expand All @@ -62,6 +66,7 @@ def test_no_ipython(self, mock_in_ipython):
self.assertEqual(mode_render_ipython, 'ipython')

def test_ipython(self, mock_in_ipython):
resolve_cascaded.cache_clear()
mock_in_ipython.return_value = True

mode_render_true = resolve_render_mode(abc_g, True)
Expand All @@ -78,6 +83,7 @@ def test_ipython(self, mock_in_ipython):
class TestDatabricks(NoAuthTestCase):

def test_no_databricks(self, mock_in_databricks):
resolve_cascaded.cache_clear()
mock_in_databricks.return_value = False

mode_render_true = resolve_render_mode(abc_g, True)
Expand All @@ -90,6 +96,7 @@ def test_no_databricks(self, mock_in_databricks):
self.assertEqual(mode_render_ipython, 'databricks')

def test_ipython(self, mock_in_databricks):
resolve_cascaded.cache_clear()
mock_in_databricks.return_value = True

mode_render_true = resolve_render_mode(abc_g, True)
Expand Down
3 changes: 3 additions & 0 deletions graphistry/tests/test_ipython.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import graphistry, IPython
from common import NoAuthTestCase
from mock import patch
from graphistry.render.resolve_render_mode import resolve_cascaded
from graphistry.tests.test_plotter import Fake_Response, triangleEdges


Expand All @@ -10,6 +11,7 @@ class TestPlotterReturnValue(NoAuthTestCase):

@patch("graphistry.render.resolve_render_mode.in_ipython")
def test_no_ipython(self, mock_in_ipython, mock_post, mock_open):
resolve_cascaded.cache_clear()
mock_in_ipython.return_value = False
url = graphistry.bind(source="src", destination="dst").plot(triangleEdges, render="browser")
self.assertIn("fakedatasetname", url)
Expand All @@ -19,6 +21,7 @@ def test_no_ipython(self, mock_in_ipython, mock_post, mock_open):

@patch("graphistry.render.resolve_render_mode.in_ipython")
def test_ipython(self, mock_in_ipython, mock_post, mock_open):
resolve_cascaded.cache_clear()
mock_in_ipython.return_value = True

# The setUpClass in NoAuthTestCase only run once, so, reset the _is_authenticated to True here
Expand Down

0 comments on commit e2ee9f4

Please sign in to comment.