Pierre Chapuis commited on
Commit
e7e651d
·
unverified ·
1 Parent(s): d086be7

update client and use high-level interface

Browse files
Files changed (4) hide show
  1. pyproject.toml +1 -1
  2. requirements.lock +3 -3
  3. requirements.txt +1 -1
  4. src/app.py +21 -19
pyproject.toml CHANGED
@@ -12,7 +12,7 @@ dependencies = [
12
  "pillow>=10.4.0",
13
  "gradio-imageslider>=0.0.20",
14
  "pillow-heif>=0.18.0",
15
- "finegrain @ git+ssh://[email protected]/finegrain-ai/finegrain-python@570e3deb369e9e7b0f9d16809f6fa29ff2f60f61#subdirectory=finegrain",
16
  ]
17
  readme = "README.md"
18
  requires-python = ">= 3.12, <3.13"
 
12
  "pillow>=10.4.0",
13
  "gradio-imageslider>=0.0.20",
14
  "pillow-heif>=0.18.0",
15
+ "finegrain @ git+ssh://[email protected]/finegrain-ai/finegrain-python@7f397f68d6a1bf7d5a567500dfdaf02ed462649d#subdirectory=finegrain",
16
  ]
17
  readme = "README.md"
18
  requires-python = ">= 3.12, <3.13"
requirements.lock CHANGED
@@ -37,9 +37,9 @@ fastapi==0.115.11
37
  # via gradio
38
  ffmpy==0.5.0
39
  # via gradio
40
- filelock==3.17.0
41
  # via huggingface-hub
42
- finegrain @ git+ssh://[email protected]/finegrain-ai/finegrain-python@570e3deb369e9e7b0f9d16809f6fa29ff2f60f61#subdirectory=finegrain
43
  # via eraser
44
  fonttools==4.56.0
45
  # via matplotlib
@@ -141,7 +141,7 @@ requests==2.32.3
141
  # via huggingface-hub
142
  rich==13.9.4
143
  # via typer
144
- ruff==0.9.10
145
  # via gradio
146
  semantic-version==2.10.0
147
  # via gradio
 
37
  # via gradio
38
  ffmpy==0.5.0
39
  # via gradio
40
+ filelock==3.18.0
41
  # via huggingface-hub
42
+ finegrain @ git+ssh://[email protected]/finegrain-ai/finegrain-python@7f397f68d6a1bf7d5a567500dfdaf02ed462649d#subdirectory=finegrain
43
  # via eraser
44
  fonttools==4.56.0
45
  # via matplotlib
 
141
  # via huggingface-hub
142
  rich==13.9.4
143
  # via typer
144
+ ruff==0.11.0
145
  # via gradio
146
  semantic-version==2.10.0
147
  # via gradio
requirements.txt CHANGED
@@ -3,4 +3,4 @@ gradio_imageslider>=0.0.20
3
  environs>=11.0.0
4
  pillow>=10.4.0
5
  pillow-heif>=0.18.0
6
- git+https://github.com/finegrain-ai/finegrain-python@570e3deb369e9e7b0f9d16809f6fa29ff2f60f61#subdirectory=finegrain
 
3
  environs>=11.0.0
4
  pillow>=10.4.0
5
  pillow-heif>=0.18.0
6
+ git+https://github.com/finegrain-ai/finegrain-python@7f397f68d6a1bf7d5a567500dfdaf02ed462649d#subdirectory=finegrain
src/app.py CHANGED
@@ -6,10 +6,11 @@ from typing import Any
6
  import gradio as gr
7
  import pillow_heif
8
  from environs import Env
9
- from finegrain import EditorAPIContext
10
  from gradio_image_annotation import image_annotator
11
  from gradio_imageslider import ImageSlider
12
  from PIL import Image
 
13
 
14
  pillow_heif.register_heif_opener()
15
  pillow_heif.register_avif_opener()
@@ -41,6 +42,12 @@ def _ctx() -> EditorAPIContext:
41
  return ctx
42
 
43
 
 
 
 
 
 
 
44
  def resize(image: Image.Image, shortest_side: int = 768) -> Image.Image:
45
  if image.width <= shortest_side and image.height <= shortest_side:
46
  return image
@@ -53,36 +60,31 @@ def resize(image: Image.Image, shortest_side: int = 768) -> Image.Image:
53
  class ProcessParams:
54
  image: Image.Image
55
  prompt: str | None = None
56
- bbox: tuple[int, int, int, int] | None = None
57
 
58
 
59
  async def _process(ctx: EditorAPIContext, params: ProcessParams) -> Image.Image:
60
  with io.BytesIO() as f:
61
  params.image.save(f, format="JPEG")
62
- response = await ctx.request("POST", "state/upload", files={"file": f})
63
- st_input = response.json()["state"]
64
 
65
  if params.bbox:
66
- segment_input_st = st_input
67
- segment_params = {"bbox": list(params.bbox)}
68
  else:
69
  assert params.prompt
70
- segment_input_st = await ctx.ensure_skill(
71
- f"infer-bbox/{st_input}",
72
- {"product_name": params.prompt},
73
- )
74
- segment_params = {}
75
 
76
- st_mask = await ctx.ensure_skill(f"segment/{segment_input_st}", segment_params)
77
- st_erased = await ctx.ensure_skill(f"erase/{st_input}/{st_mask}", {"mode": "free"})
 
 
 
 
78
 
79
- response = await ctx.request(
80
- "GET",
81
- f"state/image/{st_erased}",
82
- params={"format": "JPEG", "resolution": "DISPLAY"},
83
- )
84
  f = io.BytesIO()
85
- f.write(response.content)
86
  f.seek(0)
87
  return Image.open(f)
88
 
 
6
  import gradio as gr
7
  import pillow_heif
8
  from environs import Env
9
+ from finegrain import BoundingBox, EditorAPIContext, EraseResultWithImage, ErrorResult
10
  from gradio_image_annotation import image_annotator
11
  from gradio_imageslider import ImageSlider
12
  from PIL import Image
13
+ from typing_extensions import TypeIs
14
 
15
  pillow_heif.register_heif_opener()
16
  pillow_heif.register_avif_opener()
 
42
  return ctx
43
 
44
 
45
+ def is_error(result: Any) -> TypeIs[ErrorResult]:
46
+ if isinstance(result, ErrorResult):
47
+ raise RuntimeError(result.error)
48
+ return False
49
+
50
+
51
  def resize(image: Image.Image, shortest_side: int = 768) -> Image.Image:
52
  if image.width <= shortest_side and image.height <= shortest_side:
53
  return image
 
60
  class ProcessParams:
61
  image: Image.Image
62
  prompt: str | None = None
63
+ bbox: BoundingBox | None = None
64
 
65
 
66
  async def _process(ctx: EditorAPIContext, params: ProcessParams) -> Image.Image:
67
  with io.BytesIO() as f:
68
  params.image.save(f, format="JPEG")
69
+ st_input = await ctx.call_async.upload_image(f)
 
70
 
71
  if params.bbox:
72
+ segment_input_st, segment_bbox = st_input, params.bbox
 
73
  else:
74
  assert params.prompt
75
+ bbox_r = await ctx.call_async.infer_bbox(st_input, params.prompt)
76
+ assert not is_error(bbox_r)
77
+ segment_input_st, segment_bbox = bbox_r.state_id, None
 
 
78
 
79
+ mask_r = await ctx.call_async.segment(segment_input_st, bbox=segment_bbox)
80
+ assert not is_error(mask_r)
81
+
82
+ erased_r = await ctx.call_async.erase(st_input, mask_r.state_id, mode="express", with_image=True)
83
+ assert not is_error(erased_r)
84
+ assert isinstance(erased_r, EraseResultWithImage)
85
 
 
 
 
 
 
86
  f = io.BytesIO()
87
+ f.write(erased_r.image)
88
  f.seek(0)
89
  return Image.open(f)
90