akhaliq HF Staff commited on
Commit
625f193
·
verified ·
1 Parent(s): 2b23def

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. app.py +153 -0
  2. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ """
3
+ Built with anycoder
4
+ """
5
+ import gradio as gr
6
+ from daggr import GradioNode, FnNode, InferenceNode, Graph
7
+
8
+ # --- Helper to parse resolution strings ---
9
+ def parse_resolution_string(res_str):
10
+ """
11
+ Extracts the width and height from the resolution string.
12
+ Example: "1024x1024 ( 1:1 )" -> (1024, 1024)
13
+ """
14
+ if not res_str:
15
+ return None, None
16
+
17
+ # Split by 'x' to get width and height parts
18
+ parts = res_str.split('x')
19
+ if len(parts) >= 2:
20
+ try:
21
+ w = int(parts[0].strip())
22
+ h = int(parts[1].split('(')[0].strip())
23
+ return w, h
24
+ except ValueError:
25
+ pass
26
+ return None, None
27
+
28
+ # --- Helper to map resolution category to string ---
29
+ def map_resolution_cat(res_cat_value):
30
+ """
31
+ Maps the numeric category (e.g., '1024') to the full resolution string
32
+ (e.g., '1024x1024 ( 1:1 )').
33
+ """
34
+ # This mapping corresponds to the order in the Z-Image API documentation
35
+ # 0: '720x720 ( 1:1 )', 1: '896x512 ( 16:9 )', ...
36
+ # We construct the mapping based on the default list provided in the docs.
37
+
38
+ # The API docs list specific strings. We map the numeric key to these strings.
39
+ # Note: The API documentation for /update_res_choices returns a list of strings.
40
+ # We must match the input 'res_cat_value' (int/str) to the correct index.
41
+
42
+ # The documentation lists the output as a list of strings.
43
+ # We will map the index to the string.
44
+
45
+ # Let's define the resolution strings based on the documentation provided
46
+ # to ensure consistency.
47
+ resolution_map = {
48
+ '0': '720x720 ( 1:1 )',
49
+ '1': '896x512 ( 16:9 )',
50
+ '2': '512x896 ( 9:16 )',
51
+ '3': '832x544 ( 3:2 )',
52
+ '4': '544x832 ( 2:3 )',
53
+ '5': '800x576 ( 4:3 )',
54
+ '6': '576x800 ( 3:4 )',
55
+ '7': '1024x1024 ( 1:1 )',
56
+ '8': '1152x896 ( 9:7 )',
57
+ '9': '896x1152 ( 7:9 )',
58
+ '10': '1152x864 ( 4:3 )',
59
+ '11': '864x1152 ( 3:4 )',
60
+ '12': '1248x832 ( 3:2 )',
61
+ '13': '832x1248 ( 2:3 )',
62
+ '14': '1280x720 ( 16:9 )',
63
+ '15': '720x1280 ( 9:16 )',
64
+ '16': '1344x576 ( 21:9 )',
65
+ '17': '576x1344 ( 9:21 )',
66
+ '18': '1280x1280 ( 1:1 )',
67
+ '19': '1440x1120 ( 9:7 )',
68
+ '20': '1120x1440 ( 7:9 )',
69
+ '21': '1472x1104 ( 4:3 )',
70
+ '22': '1104x1472 ( 3:4 )',
71
+ '23': '1536x1024 ( 3:2 )',
72
+ '24': '1024x1536 ( 2:3 )',
73
+ '25': '1536x864 ( 16:9 )',
74
+ '26': '864x1536 ( 9:16 )',
75
+ '27': '1680x720 ( 21:9 )',
76
+ '28': '720x1680 ( 9:21 )',
77
+ }
78
+
79
+ # Handle if input is int or string
80
+ key = str(res_cat_value)
81
+ return resolution_map.get(key, '1024x1024 ( 1:1 )')
82
+
83
+ # --- Node 1: Resolution Updater ---
84
+ # Updates the resolution dropdown state before generation
85
+ update_resolution_node = GradioNode(
86
+ space_or_url="Tongyi-MAI/Z-Image",
87
+ api_name="/update_res_choices",
88
+ inputs={
89
+ "res_cat_value": gr.Textbox(label="Resolution Category Value", value="1024"),
90
+ },
91
+ outputs={
92
+ "updated_resolution": gr.Textbox(label="Updated Resolution String"),
93
+ },
94
+ postprocess=lambda original, target: target.get("updated_resolution", "1024x1024 ( 1:1 )"),
95
+ )
96
+
97
+ # --- Node 2: Image Generator ---
98
+ # Generates the image based on the resolved resolution
99
+ generate_image_node = GradioNode(
100
+ space_or_url="Tongyi-MAI/Z-Image",
101
+ api_name="/generate",
102
+ inputs={
103
+ "prompt": gr.Textbox(label="Prompt", placeholder="Describe your image...", value="Hello!!"),
104
+ "negative_prompt": gr.Textbox(label="Negative Prompt", placeholder="Blurry, low quality...", value="Hello!!"),
105
+ "resolution": gr.Textbox(label="Resolution", value="1024x1024 ( 1:1 )"),
106
+ "seed": gr.Number(label="Seed", value=42),
107
+ "num_inference_steps": gr.Number(label="Inference Steps", value=30, precision=0),
108
+ "guidance_scale": gr.Number(label="Guidance Scale (CFG)", value=4),
109
+ "cfg_normalization": gr.Checkbox(label="CFG Normalization", value=False),
110
+ "random_seed": gr.Checkbox(label="Random Seed", value=True),
111
+ "gallery_images": gr.Gallery(label="Gallery Images", visible=False),
112
+ },
113
+ outputs={
114
+ "images": gr.Gallery(label="Generated Images"),
115
+ "seed_used": gr.Textbox(label="Seed Used"),
116
+ "seed_number": gr.Number(label="Seed"),
117
+ },
118
+ )
119
+
120
+ # --- Node 3: Image Preview (FnNode) ---
121
+ # Extracts the first image from the gallery for preview
122
+ preview_node = FnNode(
123
+ fn=lambda images: images[0] if images and len(images) > 0 else None,
124
+ inputs={"images": gr.Gallery(label="Images")},
125
+ outputs={"preview": gr.Image(label="Preview")},
126
+ )
127
+
128
+ # --- Node 4: Metadata Logger (FnNode) ---
129
+ # Logs metadata about the generation
130
+ log_metadata_node = FnNode(
131
+ fn=lambda prompt, seed, res: f"Prompt: {prompt}\nSeed: {seed}\nResolution: {res}",
132
+ inputs={
133
+ "prompt": gr.Textbox(label="Prompt"),
134
+ "seed": gr.Number(label="Seed"),
135
+ "res": gr.Textbox(label="Resolution"),
136
+ },
137
+ outputs={"log": gr.Textbox(label="Generation Log", interactive=False)},
138
+ )
139
+
140
+ # --- Build the Graph ---
141
+ graph = Graph(
142
+ name="Z-Image Workflow",
143
+ nodes=[
144
+ update_resolution_node,
145
+ generate_image_node,
146
+ preview_node,
147
+ log_metadata_node
148
+ ]
149
+ )
150
+
151
+ # --- Launch ---
152
+ if __name__ == "__main__":
153
+ graph.launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ daggr
2
+ gradio