pain commited on
Commit
b0359f9
1 Parent(s): 87727f0

Upload 6 files

Browse files
Files changed (6) hide show
  1. LICENSE +238 -0
  2. README.md +51 -13
  3. app.py +59 -24
  4. image_generator.py +58 -53
  5. llm_models.py +144 -113
  6. requirements.txt +1 -0
LICENSE ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ACADEMIC PUBLIC LICENSE
2
+ version 1.1
3
+
4
+ Copyright (c) 2024 MOHAMMAD ALBARHAM
5
+
6
+
7
+ Preamble
8
+
9
+ This license contains the terms and conditions of using Arabic Story Generator in
10
+ noncommercial settings: at academic institutions for teaching and research
11
+ use and for personal or educational purposes. You will find that this
12
+ license provides noncommercial users of Arabic Story Generator with rights that are
13
+ similar to the well-known GNU General Public License, yet it retains the
14
+ possibility for Arabic Story Generator authors to financially support the development by
15
+ selling commercial licenses. In fact, if you intend to use Arabic Story Generator in a
16
+ "for-profit" environment, where research is conducted to develop or enhance
17
+ a product, is used in a commercial service offering, or when an entity uses
18
+ Arabic Story Generator to participate in government-funded, EU-funded, military or similar
19
+ research projects, then you need to obtain a commercial license (OMNEST).
20
+ In that case, or if you are unsure, please contact the Author or visit
21
+ www.omnest.com to inquire about commercial licenses.
22
+
23
+ What are the rights given to noncommercial users? Similarly to GPL, you
24
+ have the right to use the software, to distribute copies, to receive source
25
+ code, to change the software and distribute your modifications or the
26
+ modified software. Also similarly to the GPL, if you distribute verbatim or
27
+ modified copies of this software, they must be distributed under this
28
+ license.
29
+
30
+ By modeling the GPL, this license guarantees that you're safe when using
31
+ Arabic Story Generator in your work, for teaching or research. This license guarantees
32
+ that Arabic Story Generator will remain available free of charge for nonprofit use. You
33
+ can modify Arabic Story Generator to your purposes, and you can also share your modifications.
34
+ Even in the unlikely case of the authors abandoning Arabic Story Generator entirely, this
35
+ license permits anyone to continue developing it from the last release, and
36
+ to create further releases under this license.
37
+
38
+ We believe that the combination of noncommercial open-source and commercial
39
+ licensing will be beneficial for the whole user community, because income from
40
+ commercial licenses will enable faster development and a higher level of
41
+ software quality, while further enjoying the informal, open communication
42
+ and collaboration channels of open source development.
43
+
44
+ The precise terms and conditions for using, copying, distribution and
45
+ modification follow.
46
+
47
+
48
+ ACADEMIC PUBLIC LICENSE
49
+
50
+ TERMS AND CONDITIONS FOR USE, COPYING, DISTRIBUTION AND MODIFICATION
51
+
52
+ 0. Definitions
53
+
54
+ "Program" means a copy of Arabic Story Generator, which is said to be distributed under
55
+ this Academic Public License.
56
+
57
+ "Work based on the Program" means either the Program or any derivative work
58
+ under copyright law: that is to say, a work containing the Program or a
59
+ portion of it, either verbatim or with modifications and/or translated into
60
+ another language. (Hereinafter, translation is included without limitation
61
+ in the term "modification".)
62
+
63
+ "Using the Program" means any act of creating executables that contain or
64
+ directly use libraries that are part of the Program, running any of the
65
+ tools that are part of the Program, or creating works based on the Program.
66
+
67
+ Each licensee is addressed as "you".
68
+
69
+ 1. Permission is hereby granted to use the Program free of charge for
70
+ noncommercial purposes, including teaching and academic research at
71
+ universities, colleges and other educational institutions and personal
72
+ non-profit purposes. For using the Program for commercial purposes,
73
+ including but not restricted to consulting activities, design of commercial
74
+ hardware or software networking products, and joint research with a
75
+ commercial entity, government-funded, EU-funded, military or similar
76
+ research projects, you have to contact the Author or visit www.omnest.com
77
+ for an appropriate license. Permission is also granted to use the Program
78
+ for a reasonably limited period of time for the purpose of evaluating its
79
+ usefulness for a particular purpose.
80
+
81
+ 2. You may copy and distribute verbatim copies of the Program's
82
+ source code as you receive it, in any medium, provided that you
83
+ conspicuously and appropriately publish on each copy an appropriate
84
+ copyright notice and disclaimer of warranty; keep intact all the
85
+ notices that refer to this License and to the absence of any warranty;
86
+ and give any other recipients of the Program a copy of this License
87
+ along with the Program.
88
+
89
+ 3. You may modify your copy or copies of the Program or any portion
90
+ of it, thus forming a work based on the Program, and copy and
91
+ distribute such modifications or work under the terms of Section 2
92
+ above, provided that you also meet all of these conditions:
93
+
94
+ a) You must cause the modified files to carry prominent notices
95
+ stating that you changed the files and the date of any change.
96
+
97
+ b) You must cause any work that you distribute or publish, that in
98
+ whole or in part contains or is derived from the Program or any
99
+ part thereof, to be licensed as a whole at no charge to all third
100
+ parties under the terms of this License.
101
+
102
+ These requirements apply to the modified work as a whole. If
103
+ identifiable sections of that work are not derived from the Program,
104
+ and can be reasonably considered independent and separate works in
105
+ themselves, then this License, and its terms, do not apply to those
106
+ sections when you distribute them as separate works. But when you
107
+ distribute the same sections as part of a whole which is a work based
108
+ on the Program, the distribution of the whole must be on the terms of
109
+ this License, whose regulations for other licensees extend to the
110
+ entire whole, and thus to each and every part regardless of who wrote it.
111
+ (If the same, independent sections are distributed as part of a package
112
+ that is otherwise reliant on, or is based on the Program, then the
113
+ distribution of the whole package, including but not restricted to the
114
+ independent section, must be on the unmodified terms of this License,
115
+ regadless of who the author of the included sections was.)
116
+
117
+ Thus, it is not the intent of this section to claim rights or contest
118
+ your rights to work written entirely by you; rather, the intent is to
119
+ exercise the right to control the distribution of derivative or
120
+ collective works based or reliant on the Program.
121
+
122
+ In addition, mere aggregation of another work not based on the Program
123
+ with the Program (or with a work based on the Program) on a volume of
124
+ storage or distribution medium does not bring the other work under
125
+ the scope of this License.
126
+
127
+ 4. You may copy and distribute the Program (or a work based on it,
128
+ under Section 3) in object code or executable form under the terms of
129
+ Sections 2 and 3 above provided that you also do one of the following:
130
+
131
+ a) Accompany it with the complete corresponding machine-readable
132
+ source code, which must be distributed under the terms of Sections
133
+ 2 and 3 above on a medium customarily used for software interchange; or,
134
+
135
+ b) Accompany it with a written offer, valid for at least three
136
+ years, to give any third party, for a charge no more than your
137
+ cost of physically performing source distribution, a complete
138
+ machine-readable copy of the corresponding source code, to be
139
+ distributed under the terms of Sections 2 and 3 above on a medium
140
+ customarily used for software interchange; or,
141
+
142
+ c) Accompany it with the information you received as to the offer
143
+ to distribute corresponding source code. (This alternative is
144
+ allowed only for noncommercial distribution and only if you received
145
+ the program in object code or executable form with such an offer,
146
+ in accord with Subsection b) above.)
147
+
148
+ The source code for a work means the preferred form of the work for
149
+ making modifications to it. For an executable work, complete source
150
+ code means all the source code for all modules it contains, plus any
151
+ associated interface definition files, plus the scripts used to
152
+ control compilation and installation of the executable. However, as a
153
+ special exception, the source code distributed need not include
154
+ anything that is normally distributed (in either source or binary
155
+ form) with the major components (compiler, kernel, and so on) of the
156
+ operating system on which the executable runs, unless that component
157
+ itself accompanies the executable.
158
+
159
+ If distribution of executable or object code is made by offering
160
+ access to copy from a designated place, then offering equivalent
161
+ access to copy the source code from the same place counts as
162
+ distribution of the source code, even though third parties are not
163
+ compelled to copy the source along with the object code.
164
+
165
+ 5. You may not copy, modify, sublicense, or distribute the Program
166
+ except as expressly provided under this License. Any attempt
167
+ otherwise to copy, modify, sublicense or distribute the Program is
168
+ void, and will automatically terminate your rights under this License.
169
+ However, parties who have received copies, or rights, from you under
170
+ this License will not have their licenses terminated so long as such
171
+ parties remain in full compliance.
172
+
173
+ 6. You are not required to accept this License, since you have not
174
+ signed it. Nothing else grants you permission to modify or distribute
175
+ the Program or its derivative works; law prohibits these actions
176
+ if you do not accept this License. Therefore, by modifying or distributing
177
+ the Program (or any work based on the Program), you indicate your
178
+ acceptance of this License and all its terms and conditions for copying,
179
+ distributing or modifying the Program or works based on it, to do so.
180
+
181
+ 7. Each time you redistribute the Program (or any work based on the
182
+ Program), the recipient automatically receives a license from the
183
+ original licensor to copy, distribute or modify the Program subject to
184
+ these terms and conditions. You may not impose any further
185
+ restrictions on the recipients' exercise of the rights granted herein.
186
+ You are not responsible for enforcing compliance by third parties to
187
+ this License.
188
+
189
+ 8. If, as a consequence of a court judgment or allegation of patent
190
+ infringement or for any other reason (not limited to patent issues),
191
+ conditions are imposed on you (whether by court order, agreement or
192
+ otherwise) that contradict the conditions of this License, they do not
193
+ excuse you from the conditions of this License. If you cannot
194
+ distribute so as to satisfy simultaneously your obligations under this
195
+ License and any other pertinent obligations, then as a consequence you
196
+ may not distribute the Program at all. For example, if a patent
197
+ license would not permit royalty-free redistribution of the Program by
198
+ all those who receive copies directly or indirectly through you, then
199
+ the only way you could satisfy both it and this License would be to
200
+ refrain entirely from distribution of the Program.
201
+
202
+ If any portion of this section is held invalid or unenforceable under
203
+ any particular circumstance, the balance of the section is intended to
204
+ apply and the section as a whole is intended to apply in other
205
+ circumstances.
206
+
207
+ 9. If the distribution and/or use of the Program are restricted in
208
+ certain countries either by patents or by copyrighted interfaces, the
209
+ original copyright holder who places the Program under this License
210
+ may add an explicit geographical distribution limitation excluding
211
+ those countries, so that distribution is permitted only in or among
212
+ countries not thus excluded. In such case, this License incorporates
213
+ the limitation as if written in the body of this License.
214
+
215
+ NO WARRANTY
216
+
217
+ 10. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
218
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
219
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
220
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
221
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
222
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
223
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
224
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
225
+ REPAIR OR CORRECTION.
226
+
227
+ 11. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED ON IN WRITING
228
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
229
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
230
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
231
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM INCLUDING BUT NOT LIMITED
232
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
233
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
234
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
235
+ POSSIBILITY OF SUCH DAMAGES.
236
+
237
+ END OF TERMS AND CONDITIONS
238
+
README.md CHANGED
@@ -1,13 +1,51 @@
1
- ---
2
- title: Arabic Story Generator
3
- emoji: 🦀
4
- colorFrom: purple
5
- colorTo: blue
6
- sdk: gradio
7
- sdk_version: 4.32.2
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Gradio Application
2
+
3
+ <img src="image_logo.png" style="width:50%; height:auto;">
4
+
5
+
6
+ This is a Gradio application that allows you to generate an Arabic story using generative AI models.
7
+
8
+ ## Installation
9
+
10
+ 1. Clone this repository:
11
+
12
+ ```shell
13
+ git clone https://github.com/mohammad-albarham/Arabic_story_generator.git
14
+ ```
15
+
16
+ 2. Install the required dependencies:
17
+
18
+ ```shell
19
+ pip install -r requirements.txt
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ 0. Add the keys for OPEN AI API model and stability AI API in [models.py](https://github.com/mohammad-albarham/Arabic_story_generator/blob/3702d6cad85fe38ff5944d7f99f43a37d7dec151/llm_models.py#L16) and [image_generator.py](https://github.com/mohammad-albarham/Arabic_story_generator/blob/3702d6cad85fe38ff5944d7f99f43a37d7dec151/image_generator.py#L22)
25
+ 1. Run the application:
26
+
27
+ ```shell
28
+ gradio app.py
29
+ ```
30
+
31
+ 2. Open your web browser and navigate to [http://localhost:7860](http://localhost:7860).
32
+
33
+ 3. Add your a description and the needed number of pages and click on generate story.
34
+
35
+ ## Contributing
36
+
37
+ Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request.
38
+
39
+ ### Instrcutions for the contribution:
40
+
41
+ 1. Please install black formatter as follows:
42
+ `pip install black`
43
+ 2. Make sure to format all python files you want to change using this command on the terminal:
44
+ `black .`
45
+
46
+ You can see this tutorial for more information about the formatter: [tutorial](https://www.freecodecamp.org/news/auto-format-your-python-code-with-black/)
47
+
48
+
49
+ ## License
50
+
51
+ [ACADEMIC PUBLIC LICENSE](https://github.com/mohammad-albarham/Arabic_story_generator/tree/main?tab=License-1-ov-file)
app.py CHANGED
@@ -3,7 +3,7 @@ from llm_models import get_text_image_pairs
3
  import time
4
  from tqdm import tqdm
5
 
6
- title_markdown = ("""
7
  <div style="display: flex; justify-content: center; align-items: center; text-align: center; direction: rtl;">
8
  <img src="https://s11.ax1x.com/2023/12/28/piqvDMV.png" alt="MoE-LLaVA🚀" style="max-width: 120px; height: auto; margin-right: 20px;">
9
  <div style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
@@ -12,15 +12,19 @@ title_markdown = ("""
12
  <h2 style="margin: 0; font-size: 1.5em;">صانع القصص بالذكاء الاصطناعي التوليدي</h2>
13
  </div>
14
  </div>
15
- """)
 
16
 
17
- def get_text_images_values(k, input_prompt):
18
 
19
  pages = int(k)
 
 
 
20
 
21
- segments_list, images_names = get_text_image_pairs(pages,input_prompt)
22
  return segments_list, images_names
23
 
 
24
  css = """
25
  .gradio-container {direction: rtl}
26
  .gradio-container-4-18-0 .prose h1 {direction: rtl};
@@ -31,30 +35,61 @@ with gr.Blocks(css=css) as demo:
31
 
32
  gr.Markdown(title_markdown)
33
 
34
- prompt = gr.Textbox(label="معلومات بسيطة عن القصة",
35
- info="أدخل بعض المعلومات عن القصة، مثلاً: خالد صبي في الرابعة من عمره، ويحب أن يصبح طياراً في المستقبل",
36
- placeholder="خالد صبي في الرابعة من عمره، ويحب أن يصبح طياراً في المستقبل",
37
- text_align="right",
38
- rtl=True,
39
- elem_classes="rtl-textbox",
40
- elem_id="rtl-textbox")
41
-
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
  with gr.Row():
44
-
45
 
46
- max_textboxes = 10 # Define the max number of textboxed, so we will add the max number of textboxes and images to the layout
47
 
48
  def variable_outputs(k, segments_list):
49
  k = int(k)
50
- return [gr.Textbox(label= f"الصفحة رقم {i+1}", value=item, text_align="right", visible=True) for i, item in enumerate(segments_list)] + [gr.Textbox(visible=False, text_align="right", rtl=True)]*(max_textboxes-k)
51
-
52
- def variable_outputs_image(k,images_names):
 
 
 
 
 
 
 
 
 
 
53
  k = int(k)
54
- return [gr.Image(value=item, scale=1, visible=True) for item in images_names] + [gr.Image(scale=1,visible=False)]*(max_textboxes-k)
55
-
 
 
56
  with gr.Column():
57
- s = gr.Slider(1, max_textboxes, value=1, step=1, info="أقصى عدد صفحات يمكن توليده هو 10 صفحات",label="كم عدد صفحات القصة التي تريدها؟")
 
 
 
 
 
 
 
58
  textboxes = []
59
  imageboxes = []
60
  for i in tqdm(range(max_textboxes)):
@@ -64,15 +99,15 @@ with gr.Blocks(css=css) as demo:
64
  imageboxes.append(i_t)
65
  textboxes.append(t)
66
 
67
- segment_list = gr.JSON(value=[],visible=False)
68
  images_list = gr.JSON(value=[], visible=False)
69
 
70
  submit = gr.Button(value="أنشئ القصة الآن")
71
 
72
  submit.click(
73
  fn=get_text_images_values,
74
- inputs=[s,prompt],
75
- outputs=[segment_list, images_list]
76
  ).then(
77
  fn=variable_outputs,
78
  inputs=[s, segment_list],
@@ -83,4 +118,4 @@ with gr.Blocks(css=css) as demo:
83
  outputs=imageboxes,
84
  )
85
 
86
- demo.launch()
 
3
  import time
4
  from tqdm import tqdm
5
 
6
+ title_markdown = """
7
  <div style="display: flex; justify-content: center; align-items: center; text-align: center; direction: rtl;">
8
  <img src="https://s11.ax1x.com/2023/12/28/piqvDMV.png" alt="MoE-LLaVA🚀" style="max-width: 120px; height: auto; margin-right: 20px;">
9
  <div style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
 
12
  <h2 style="margin: 0; font-size: 1.5em;">صانع القصص بالذكاء الاصطناعي التوليدي</h2>
13
  </div>
14
  </div>
15
+ """
16
+
17
 
18
+ def get_text_images_values(k, input_prompt, api_key_openai, api_key_stability_ai):
19
 
20
  pages = int(k)
21
+ segments_list, images_names = get_text_image_pairs(
22
+ pages, input_prompt, api_key_openai, api_key_stability_ai
23
+ )
24
 
 
25
  return segments_list, images_names
26
 
27
+
28
  css = """
29
  .gradio-container {direction: rtl}
30
  .gradio-container-4-18-0 .prose h1 {direction: rtl};
 
35
 
36
  gr.Markdown(title_markdown)
37
 
38
+ with gr.Row():
39
+ api_key_openai = gr.Textbox(
40
+ label="Open AI API Key",
41
+ placeholder="أدخل مفتاح API الخاص بك هنا",
42
+ type="password",
43
+ )
44
+ api_key_stability_ai = gr.Textbox(
45
+ label="Stability AI API Key",
46
+ placeholder="أدخل مفتاح API الخاص بك هنا",
47
+ type="password",
48
+ )
49
+
50
+ prompt = gr.Textbox(
51
+ label="معلومات بسيطة عن القصة",
52
+ info="أدخل بعض المعلومات عن القصة، مثلاً: خالد صبي في الرابعة من عمره، ويحب أن يصبح طياراً في المستقبل",
53
+ placeholder="خالد صبي في الرابعة من عمره، ويحب أن يصبح طياراً في المستقبل",
54
+ text_align="right",
55
+ rtl=True,
56
+ elem_classes="rtl-textbox",
57
+ elem_id="rtl-textbox",
58
+ )
59
 
60
  with gr.Row():
 
61
 
62
+ max_textboxes = 10 # Define the max number of textboxed, so we will add the max number of textboxes and images to the layout
63
 
64
  def variable_outputs(k, segments_list):
65
  k = int(k)
66
+ return [
67
+ gr.Textbox(
68
+ label=f"الصفحة رقم {i+1}",
69
+ value=item,
70
+ text_align="right",
71
+ visible=True,
72
+ )
73
+ for i, item in enumerate(segments_list)
74
+ ] + [gr.Textbox(visible=False, text_align="right", rtl=True)] * (
75
+ max_textboxes - k
76
+ )
77
+
78
+ def variable_outputs_image(k, images_names):
79
  k = int(k)
80
+ return [
81
+ gr.Image(value=item, scale=1, visible=True) for item in images_names
82
+ ] + [gr.Image(scale=1, visible=False)] * (max_textboxes - k)
83
+
84
  with gr.Column():
85
+ s = gr.Slider(
86
+ 1,
87
+ max_textboxes,
88
+ value=1,
89
+ step=1,
90
+ info="أقصى عدد صفحات يمكن توليده هو 10 صفحات",
91
+ label="كم عدد صفحات القصة التي تريدها؟",
92
+ )
93
  textboxes = []
94
  imageboxes = []
95
  for i in tqdm(range(max_textboxes)):
 
99
  imageboxes.append(i_t)
100
  textboxes.append(t)
101
 
102
+ segment_list = gr.JSON(value=[], visible=False)
103
  images_list = gr.JSON(value=[], visible=False)
104
 
105
  submit = gr.Button(value="أنشئ القصة الآن")
106
 
107
  submit.click(
108
  fn=get_text_images_values,
109
+ inputs=[s, prompt, api_key_openai, api_key_stability_ai],
110
+ outputs=[segment_list, images_list],
111
  ).then(
112
  fn=variable_outputs,
113
  inputs=[s, segment_list],
 
118
  outputs=imageboxes,
119
  )
120
 
121
+ demo.launch()
image_generator.py CHANGED
@@ -5,68 +5,73 @@ from PIL import Image
5
  from stability_sdk import client
6
  import stability_sdk.interfaces.gooseai.generation.generation_pb2 as generation
7
  import uuid
8
-
9
-
10
 
11
  # Our Host URL should not be prepended with "https" nor should it have a trailing slash.
12
- os.environ['STABILITY_HOST'] = 'grpc.stability.ai:443'
13
-
14
- # Sign up for an account at the following link to get an API Key.
15
- # https://platform.stability.ai/
16
-
17
- # Click on the following link once you have created an account to be taken to your API Key.
18
- # https://platform.stability.ai/account/keys
19
 
20
- # Paste your API Key below.
21
 
22
- os.environ['STABILITY_KEY'] = 'key_here'
23
 
 
 
 
 
24
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- # Set up our connection to the API.
27
- stability_api = client.StabilityInference(
28
- key=os.environ['STABILITY_KEY'], # API Key reference.
29
- verbose=True, # Print debug messages.
30
- engine="stable-diffusion-xl-1024-v1-0", # Set the engine to use for generation.
31
- # Check out the following link for a list of available engines: https://platform.stability.ai/docs/features/api-parameters#engine
32
- )
 
 
 
 
 
 
 
 
 
 
33
 
34
- def get_image(prompt):
35
- # Set up our initial generation parameters.
36
- answers = stability_api.generate(
37
- prompt=prompt, # The prompt we want to generate an image from.
38
- seed=4253978046, # If a seed is provided, the resulting generated image will be deterministic.
39
- # What this means is that as long as all generation parameters remain the same, you can always recall the same image simply by generating it again.
40
- # Note: This isn't quite the case for Clip Guided generations, which we'll tackle in a future example notebook.
41
- steps=30, # Amount of inference steps performed on image generation. Defaults to 30.
42
- cfg_scale=8.0, # Influences how strongly your generation is guided to match your prompt.
43
- # Setting this value higher increases the strength in which it tries to match your prompt.
44
- # Defaults to 7.0 if not specified.
45
- width=512, # Generation width, defaults to 512 if not included.
46
- height=512, # Generation height, defaults to 512 if not included.
47
- samples=1, # Number of images to generate, defaults to 1 if not included.
48
- sampler=generation.SAMPLER_K_DPMPP_2M # Choose which sampler we want to denoise our generation with.
49
- # Defaults to k_dpmpp_2m if not specified. Clip Guidance only supports ancestral samplers.
50
- # (Available Samplers: ddim, plms, k_euler, k_euler_ancestral, k_heun, k_dpm_2, k_dpm_2_ancestral, k_dpmpp_2s_ancestral, k_lms, k_dpmpp_2m, k_dpmpp_sde)
51
- )
52
 
53
- # print("Finish the prompt")
54
- # Set up our warning to print to the console if the adult content classifier is tripped.
55
- # If adult content classifier is not tripped, save generated images.
56
- for resp in answers:
57
- for artifact in resp.artifacts:
58
- # if artifact.finish_reason == generation.FILTER:
59
- # print(artifact.finish_reason)
60
- # print("Warning")
61
- # warnings.warn(
62
- # "Your request activated the API's safety filters and could not be processed."
63
- # "Please modify the prompt and try again.")
64
-
65
- if artifact.type == generation.ARTIFACT_IMAGE:
66
- img = Image.open(io.BytesIO(artifact.binary))
67
- unique_filename = str(uuid.uuid4())
68
 
69
- img.save(str(unique_filename)+ ".png") # Save our generated images with their seed number as the filename.
 
 
70
 
71
- return unique_filename + ".png"
72
 
 
 
 
 
 
 
5
  from stability_sdk import client
6
  import stability_sdk.interfaces.gooseai.generation.generation_pb2 as generation
7
  import uuid
8
+ import gradio as gr
 
9
 
10
  # Our Host URL should not be prepended with "https" nor should it have a trailing slash.
11
+ os.environ["STABILITY_HOST"] = "grpc.stability.ai:443"
 
 
 
 
 
 
12
 
 
13
 
14
+ def get_image(prompt, api_key_stability_ai):
15
 
16
+ # Sign up for an account at the following link to get an API Key.
17
+ # https://platform.stability.ai/
18
+ # Click on the following link once you have created an account to be taken to your API Key.
19
+ # https://platform.stability.ai/account/keys
20
 
21
+ # Set up our connection to the API.
22
+ if api_key_stability_ai == "":
23
+ raise gr.Error("Please add your Stability AI API key ")
24
+ else:
25
+ try:
26
+ stability_api = client.StabilityInference(
27
+ key=api_key_stability_ai, # API Key reference.
28
+ verbose=True, # Print debug messages.
29
+ engine="stable-diffusion-xl-1024-v1-0", # Set the engine to use for generation.
30
+ # Check out the following link for a list of available engines: https://platform.stability.ai/docs/features/api-parameters#engine
31
+ )
32
 
33
+ # Set up our initial generation parameters.
34
+ answers = stability_api.generate(
35
+ prompt=prompt, # The prompt we want to generate an image from.
36
+ seed=4253978046, # If a seed is provided, the resulting generated image will be deterministic.
37
+ # What this means is that as long as all generation parameters remain the same, you can always recall the same image simply by generating it again.
38
+ # Note: This isn't quite the case for Clip Guided generations, which we'll tackle in a future example notebook.
39
+ steps=30, # Amount of inference steps performed on image generation. Defaults to 30.
40
+ cfg_scale=8.0, # Influences how strongly your generation is guided to match your prompt.
41
+ # Setting this value higher increases the strength in which it tries to match your prompt.
42
+ # Defaults to 7.0 if not specified.
43
+ width=512, # Generation width, defaults to 512 if not included.
44
+ height=512, # Generation height, defaults to 512 if not included.
45
+ samples=1, # Number of images to generate, defaults to 1 if not included.
46
+ sampler=generation.SAMPLER_K_DPMPP_2M, # Choose which sampler we want to denoise our generation with.
47
+ # Defaults to k_dpmpp_2m if not specified. Clip Guidance only supports ancestral samplers.
48
+ # (Available Samplers: ddim, plms, k_euler, k_euler_ancestral, k_heun, k_dpm_2, k_dpm_2_ancestral, k_dpmpp_2s_ancestral, k_lms, k_dpmpp_2m, k_dpmpp_sde)
49
+ )
50
 
51
+ # print("Finish the prompt")
52
+ # Set up our warning to print to the console if the adult content classifier is tripped.
53
+ # If adult content classifier is not tripped, save generated images.
54
+ for resp in answers:
55
+ for artifact in resp.artifacts:
56
+ # if artifact.finish_reason == generation.FILTER:
57
+ # print(artifact.finish_reason)
58
+ # print("Warning")
59
+ # warnings.warn(
60
+ # "Your request activated the API's safety filters and could not be processed."
61
+ # "Please modify the prompt and try again.")
 
 
 
 
 
 
 
62
 
63
+ if artifact.type == generation.ARTIFACT_IMAGE:
64
+ img = Image.open(io.BytesIO(artifact.binary))
65
+ unique_filename = str(uuid.uuid4())
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ img.save(
68
+ str(unique_filename) + ".png"
69
+ ) # Save our generated images with their seed number as the filename.
70
 
71
+ return unique_filename + ".png"
72
 
73
+ except Exception as error:
74
+ print(str(error))
75
+ raise gr.Error(
76
+ "An error occurred while generating the image. Please try again."
77
+ )
llm_models.py CHANGED
@@ -3,126 +3,157 @@ from openai import OpenAI
3
  from pydantic import BaseModel
4
  from typing import List
5
  from image_generator import get_image
 
 
6
 
7
  class StepByStepAIResponse(BaseModel):
8
  title: str
9
  story_segments: List[str]
10
  image_prompts: List[str]
11
 
 
12
  class GetTranslation(BaseModel):
13
  translated_text: List[str]
14
 
15
 
16
- client = OpenAI(api_key="key_here")
17
-
18
-
19
- def generate_story(k, prompt):
20
- """ Generate a story with k segments and initial prompt"""
21
-
22
- response = client.chat.completions.create(
23
- model="gpt-4-turbo-preview",
24
- messages=[
25
- {
26
- "role": "system",
27
- "content": f"""
28
- Your expertise lies in weaving captivating narratives for children, complemented by images that vividly bring each tale to life. Embark on a creative endeavor to construct a story segmented into {k} distinct chapters, each a cornerstone of an enchanting journey for a young audience.
29
- The input prompt will be on Arabic, but the output must be in English.
30
-
31
- **Task Overview**:
32
-
33
- 1. **Story Development**:
34
- - Craft a narrative divided into {k} parts, with a strict 50-word limit for each.
35
- - Start with an engaging introduction that lays the foundation for the adventure.
36
- - Ensure each part naturally progresses from the previous, crafting a fluid story that escalates to an exhilarating climax.
37
- - Wrap up the narrative with a gratifying conclusion that ties all story threads together.
38
- - Keep character continuity intact across the story, with consistent presence from beginning to end.
39
- - You must describe the characters in details in every image prompt.
40
- - Use language and themes that are child-friendly, imbued with wonder, and easy to visualize.
41
- - The story will talk about {prompt}
42
-
43
- 2. **Image Generation Instructions for Image Models**:
44
- - For every story part, create a comprehensive prompt for generating an image that encapsulates the scene's essence. Each prompt should:
45
- - Offer a detailed description of the scene, characters, and critical elements, providing enough specificity for the image model to create a consistent and coherent visual.
46
- - Request the images be in an anime style to ensure visual consistency throughout.
47
- - Given the image model's isolated processing, reintroduce characters, settings, and pivotal details in each prompt to maintain narrative and visual continuity.
48
- - Focus on visual storytelling components that enhance the story segments, steering clear of direct text inclusion in the images.
49
-
50
- **Key Points**:
51
- - Due to the image model's lack of recall, stress the need for self-contained prompts that reintroduce crucial elements each time. This strategy guarantees that, although generated independently, each image mirrors a continuous and cohesive visual story.
52
-
53
- Through your skill in melding textual and visual storytelling, you will breathe life into this magical tale, offering young readers a journey to remember through both prose and illustration.
54
-
55
- """
56
- },
57
- ],
58
- functions=[
59
- {
60
- "name": "get_story_segments_and_image_prompts",
61
- "description": "Get user answer in series of segment and image prompts",
62
- "parameters": StepByStepAIResponse.model_json_schema(),
63
- }
64
- ],
65
- function_call={"name": "get_story_segments_and_image_prompts"}, # Corrected to match the defined function name
66
- temperature=1,
67
- max_tokens=1000,
68
- top_p=1,
69
- frequency_penalty=0,
70
- presence_penalty=0
71
- )
72
-
73
- output = json.loads(response.choices[0].message.function_call.arguments)
74
-
75
- sbs = StepByStepAIResponse(**output)
76
-
77
- return sbs
78
-
79
- def get_Arabic_translation(story_segments):
80
-
81
- response = client.chat.completions.create(
82
- model="gpt-4-turbo-preview",
83
- messages=[
84
- {
85
- "role": "system",
86
- "content":
87
-
88
- f"""
89
- You are an expert translator of text from English to Arabic.
90
-
91
- On the following, you can find the input text that you need to translate to Arabic:
92
- {story_segments}
93
-
94
- Translate it from English to Arabic.
95
-
96
- """
97
- },
98
- ],
99
- functions=[
100
- {
101
- "name": "translate_text_from_english_to_arabic",
102
- "description": "Translate the text from English to Arabic.",
103
- "parameters": GetTranslation.model_json_schema(),
104
- }
105
- ],
106
- function_call={"name": "translate_text_from_english_to_arabic"}, # Corrected to match the defined function name
107
- temperature=1,
108
- max_tokens=1000,
109
- top_p=1,
110
- frequency_penalty=0,
111
- presence_penalty=0
112
- )
113
-
114
- output = json.loads(response.choices[0].message.function_call.arguments)
115
-
116
- sbs = GetTranslation(**output)
117
-
118
- return sbs
119
-
120
- def get_text_image_pairs(k, prompt):
121
-
122
- describtion = generate_story(k, prompt)
123
-
124
- segements_translation = get_Arabic_translation(describtion.story_segments)
125
-
126
- images_names = [get_image(itm) for itm in describtion.image_prompts]
127
-
128
- return (segements_translation.translated_text, images_names)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  from pydantic import BaseModel
4
  from typing import List
5
  from image_generator import get_image
6
+ import gradio as gr
7
+
8
 
9
  class StepByStepAIResponse(BaseModel):
10
  title: str
11
  story_segments: List[str]
12
  image_prompts: List[str]
13
 
14
+
15
  class GetTranslation(BaseModel):
16
  translated_text: List[str]
17
 
18
 
19
+ def generate_story(k, prompt, api_key):
20
+ """Generate a story with k segments and initial prompt"""
21
+
22
+ if api_key == "":
23
+ raise gr.Error("Please add your OpenAI API key ")
24
+
25
+ else:
26
+ try:
27
+ client = OpenAI(api_key=api_key)
28
+
29
+ response = client.chat.completions.create(
30
+ model="gpt-4-turbo-preview",
31
+ messages=[
32
+ {
33
+ "role": "system",
34
+ "content": f"""
35
+ Your expertise lies in weaving captivating narratives for children, complemented by images that vividly bring each tale to life. Embark on a creative endeavor to construct a story segmented into {k} distinct chapters, each a cornerstone of an enchanting journey for a young audience.
36
+ The input prompt will be on Arabic, but the output must be in English.
37
+
38
+ **Task Overview**:
39
+
40
+ 1. **Story Development**:
41
+ - Craft a narrative divided into {k} parts, with a strict 50-word limit for each.
42
+ - Start with an engaging introduction that lays the foundation for the adventure.
43
+ - Ensure each part naturally progresses from the previous, crafting a fluid story that escalates to an exhilarating climax.
44
+ - Wrap up the narrative with a gratifying conclusion that ties all story threads together.
45
+ - Keep character continuity intact across the story, with consistent presence from beginning to end.
46
+ - You must describe the characters in details in every image prompt.
47
+ - Use language and themes that are child-friendly, imbued with wonder, and easy to visualize.
48
+ - The story will talk about {prompt}
49
+
50
+ 2. **Image Generation Instructions for Image Models**:
51
+ - For every story part, create a comprehensive prompt for generating an image that encapsulates the scene's essence. Each prompt should:
52
+ - Offer a detailed description of the scene, characters, and critical elements, providing enough specificity for the image model to create a consistent and coherent visual.
53
+ - Request the images be in an anime style to ensure visual consistency throughout.
54
+ - Given the image model's isolated processing, reintroduce characters, settings, and pivotal details in each prompt to maintain narrative and visual continuity.
55
+ - Focus on visual storytelling components that enhance the story segments, steering clear of direct text inclusion in the images.
56
+
57
+ **Key Points**:
58
+ - Due to the image model's lack of recall, stress the need for self-contained prompts that reintroduce crucial elements each time. This strategy guarantees that, although generated independently, each image mirrors a continuous and cohesive visual story.
59
+
60
+ Through your skill in melding textual and visual storytelling, you will breathe life into this magical tale, offering young readers a journey to remember through both prose and illustration.
61
+
62
+ """,
63
+ },
64
+ ],
65
+ functions=[
66
+ {
67
+ "name": "get_story_segments_and_image_prompts",
68
+ "description": "Get user answer in series of segment and image prompts",
69
+ "parameters": StepByStepAIResponse.model_json_schema(),
70
+ }
71
+ ],
72
+ function_call={
73
+ "name": "get_story_segments_and_image_prompts"
74
+ }, # Corrected to match the defined function name
75
+ temperature=1,
76
+ max_tokens=1000,
77
+ top_p=1,
78
+ frequency_penalty=0,
79
+ presence_penalty=0,
80
+ )
81
+
82
+ output = json.loads(response.choices[0].message.function_call.arguments)
83
+
84
+ sbs = StepByStepAIResponse(**output)
85
+
86
+ return sbs
87
+
88
+ except Exception as error:
89
+ print(str(error))
90
+ raise gr.Error(
91
+ "An error occurred while generating the story. Please try again."
92
+ )
93
+
94
+
95
+ def get_Arabic_translation(story_segments, api_key):
96
+
97
+ if api_key == "":
98
+ raise gr.Error("Please add your OpenAI API key ")
99
+
100
+ else:
101
+ try:
102
+ client = OpenAI(api_key=api_key)
103
+ response = client.chat.completions.create(
104
+ model="gpt-4-turbo-preview",
105
+ messages=[
106
+ {
107
+ "role": "system",
108
+ "content": f"""
109
+ You are an expert translator of text from English to Arabic.
110
+
111
+ On the following, you can find the input text that you need to translate to Arabic:
112
+ {story_segments}
113
+
114
+ Translate it from English to Arabic.
115
+
116
+ """,
117
+ },
118
+ ],
119
+ functions=[
120
+ {
121
+ "name": "translate_text_from_english_to_arabic",
122
+ "description": "Translate the text from English to Arabic.",
123
+ "parameters": GetTranslation.model_json_schema(),
124
+ }
125
+ ],
126
+ function_call={
127
+ "name": "translate_text_from_english_to_arabic"
128
+ }, # Corrected to match the defined function name
129
+ temperature=1,
130
+ max_tokens=1000,
131
+ top_p=1,
132
+ frequency_penalty=0,
133
+ presence_penalty=0,
134
+ )
135
+ output = json.loads(response.choices[0].message.function_call.arguments)
136
+
137
+ sbs = GetTranslation(**output)
138
+
139
+ return sbs
140
+ except Exception as error:
141
+ print(str(error))
142
+ raise gr.Error(
143
+ "An error occurred while translating the text. Please try again."
144
+ )
145
+
146
+
147
+ def get_text_image_pairs(k, prompt, api_key_openai, api_key_stability_ai):
148
+
149
+ describtion = generate_story(k, prompt, api_key_openai)
150
+
151
+ segements_translation = get_Arabic_translation(
152
+ describtion.story_segments, api_key_openai
153
+ )
154
+
155
+ images_names = [
156
+ get_image(itm, api_key_stability_ai) for itm in describtion.image_prompts
157
+ ]
158
+
159
+ return (segements_translation.translated_text, images_names)
requirements.txt CHANGED
@@ -4,3 +4,4 @@ openai==1.12.0
4
  pydantic==2.6.1
5
  rich==13.7.0
6
  stability-sdk==0.8.5
 
 
4
  pydantic==2.6.1
5
  rich==13.7.0
6
  stability-sdk==0.8.5
7
+ black==24.4.2