Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tut] Creating an Advent Calendar App in Python with AI Image Creation

#1
Creating an Advent Calendar App in Python with AI Image Creation

<div>
<div class="kk-star-ratings kksr-auto kksr-align-left kksr-valign-top" data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;960956&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;top&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;2&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;5&quot;,&quot;greet&quot;:&quot;Rate this post&quot;,&quot;legend&quot;:&quot;5\/5 - (2 votes)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;width&quot;:&quot;142.5&quot;,&quot;_legend&quot;:&quot;{score}\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>
<div class="kksr-stars">
<div class="kksr-stars-inactive">
<div class="kksr-star" data-star="1" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" data-star="2" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" data-star="3" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" data-star="4" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" data-star="5" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
</p></div>
<div class="kksr-stars-active" style="width: 142.5px;">
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
<div class="kksr-star" style="padding-right: 5px">
<div class="kksr-icon" style="width: 24px; height: 24px;"></div>
</p></div>
</p></div>
</div>
<div class="kksr-legend" style="font-size: 19.2px;"> 5/5 – (2 votes) </div>
</div>
<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="731" height="731" src="https://blog.finxter.com/wp-content/uploads/2022/12/image-115.png" alt="" class="wp-image-961010" srcset="https://blog.finxter.com/wp-content/uploads/2022/12/image-115.png 731w, https://blog.finxter.com/wp-content/uplo...00x300.png 300w, https://blog.finxter.com/wp-content/uplo...50x150.png 150w" sizes="(max-width: 731px) 100vw, 731px" /><figcaption class="wp-element-caption"><em><strong>Example</strong>: AI-Generated Image</em></figcaption></figure>
</div>
<p>This blog describes a fun mini Python project using <strong>AI image creation</strong> for creating artwork for an advent calendar implemented using <a href="https://blog.finxter.com/how-to-install-pygame-on-pycharm/" data-type="post" data-id="35078" target="_blank" rel="noreferrer noopener">PyGame</a>.</p>
<h2>Context</h2>
<p>It’s December 1st, and my daughter has just opened the first door on her physical advent calendar, counting down the days of the festival of general consumerism that some people call Christmas. Out pops a small chocolate with a festive robin embossed onto it.</p>
<p>I don’t really recall when the chocolate treat became ubiquitous. Back in my childhood days, advent calendar doors just opened to reveal an image.</p>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" loading="lazy" width="1024" height="504" src="https://blog.finxter.com/wp-content/uploads/2022/12/image-116-1024x504.png" alt="" class="wp-image-961017" srcset="https://blog.finxter.com/wp-content/uploads/2022/12/image-116-1024x504.png 1024w, https://blog.finxter.com/wp-content/uplo...00x148.png 300w, https://blog.finxter.com/wp-content/uplo...68x378.png 768w, https://blog.finxter.com/wp-content/uplo...ge-116.png 1460w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption"><em><strong>Example</strong>: AI-Generated Image</em></figcaption></figure>
</div>
<p>This article describes a mini project to generate a virtual old-school Advent calendar using royalty-free bespoke images generated from Python using a third-party AI service through an API.</p>
<p>All code and some AI-generated image samples are available on <a rel="noreferrer noopener" href="https://github.com/finxter/ai-painted-advent-calendar" data-type="URL" data-id="https://github.com/finxter/ai-painted-advent-calendar" target="_blank">GitHub</a>.</p>
<h2>Painting the Images</h2>
<p>There are now many AI engines for creating images from a text description. This project uses <em>deepai. </em>Creating an image with the <em>deepai </em>API is pretty simple. They provide code samples for several languages on their site.</p>
<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" loading="lazy" width="730" height="730" src="https://blog.finxter.com/wp-content/uploads/2022/12/image-117.png" alt="" class="wp-image-961021" srcset="https://blog.finxter.com/wp-content/uploads/2022/12/image-117.png 730w, https://blog.finxter.com/wp-content/uplo...00x300.png 300w, https://blog.finxter.com/wp-content/uplo...50x150.png 150w" sizes="(max-width: 730px) 100vw, 730px" /></figure>
</div>
<p>I further selected the engine for producing art in the impressionism style but you can choose from a range of other styles at <a href="https://api.deepai.org" target="_blank" rel="noreferrer noopener">https://api.deepai.org</a>.</p>
<p>The <strong><code>aipaint</code> </strong>function below uses the <code><a rel="noreferrer noopener" href="https://blog.finxter.com/python-requests-library/" data-type="post" data-id="37796" target="_blank">requests</a></code> library <code>post</code> method to send a description string e.g. <code>"Christmas presents under tree"</code> to the API endpoint <a href="https://api.deepai.org/api/impressionism-painting-generator">https://api.deepai.org/api/impressionism-painting-generator</a> with an API key included in the header. </p>
<p>Note that the AI artist style forms parts of the end-point URL.</p>
<p>An API key is used to control access to the API service. The quickstart <strong><code>api-key</code></strong> below is only good for about 10 free requests. You can pay $5 for a new API key and 100 more request calls if you so wish.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def aipaint(description): r = requests.post( "https://api.deepai.org/api/impressionism-painting-generator", data={ 'text': description, }, headers={'api-key': 'quickstart-QUdJIGlzIGNvbWluZy4uLi4K'} ) ret = r.json() return ret
</pre>
<p>The <strong><code>aipaint()</code> </strong>function will return a JSON object, including an element called <strong><code>output_url</code> </strong>from which the image can be viewed. </p>
<p>The following is an example AI painting created, in the impressionist style, for the description <code>"Christmas presents under tree"</code>:</p>
<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" loading="lazy" width="325" height="321" src="https://blog.finxter.com/wp-content/uploads/2022/12/image-111.png" alt="" class="wp-image-960978" srcset="https://blog.finxter.com/wp-content/uploads/2022/12/image-111.png 325w, https://blog.finxter.com/wp-content/uplo...00x296.png 300w" sizes="(max-width: 325px) 100vw, 325px" /></figure>
</div>
<p>The <strong><code>output_url</code> </strong>will look something like this <code>https://api.deepai.org/job-view-file/eb654821-f89c-4065-9302-a702ad942971/outputs/output.jpg</code></p>
<p>Be warned when you read this – the above URL will no longer exist. The created image is only hosted by <em>deepai </em>for a few hours, so our advent calendar code will need to download to a local folder.  </p>
<p>To download the image we can use <strong><code>urlretrieve</code>:</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">painting=aipaint(description) urllib.request.urlretrieve(painting['output_url'], filename)</pre>
<h2>Caching 25 Images</h2>
<p>The original hope was to create images on the fly as an advent door is opened, but as there is a cost for each API request and up to 30 seconds is required for each image to be generated by the AI engine and downloaded, an alternative approach was adopted in writing a <strong><code>prepaint.py</code></strong> script to create and download 25 images.</p>
<p><strong><code>prepaint.py</code></strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import urllib.request
import config
import requests
import urllib.request
from os.path import exists def aipaint(description): r = requests.post( "https://api.deepai.org/api/impressionism-painting-generator", data={ 'text': description, }, headers={'api-key': 'quickstart-QUdJIGlzIGNvbWluZy4uLi4K'} ) ret = r.json() return ret count=1 while count&lt;=25: # pop off the first image description description=config.descriptions.pop(0) # push it back on at end (this ensures we cycle through descriptions and never run out ) # obviously best if there are 25 descriptions though config.descriptions.append(description) filename='./images/image'+ (f"{count:02d}") +".jpg" if(exists(filename)): print(filename + " already exists") else: print("Painting: "+description) try: painting=aipaint(description) if(len(painting)&lt;2): if(painting['status']): print("You've probably run out of deepai (free) credits.") print("Status returned "+painting['status']) else: print("Storing as "+filename) urllib.request.urlretrieve(painting['output_url'], filename) print("Paint now dried on "+filename) except Exception as ex: print("Paint "+filename+" failed") print(ex) count+=1 print("Paintings complete and paint has dried!")
print("Now run main.py to access the Advent calendar")</pre>
<p><strong><code>config.descriptions</code></strong> is a list of Christmas image descriptions. </p>
<p>Ideally, there should be 25 descriptions, but we treat the array as a circular queue so that every time we pop an item off the front, we push back at the end of the queue. </p>
<p>This just ensures we can generate 25 images even without 25 descriptions. My experimentation suggests you will not get the same image back from two requests with the same image description anyway!</p>
<p>Images are cached in an images folder with 25 filenames <strong><code>image01.jpg</code></strong> through <strong><code>image25.jpg</code></strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">filename='./images/image'+ (f"{count:02d}") +".jpg"</pre>
<p>The script first checks whether an image already exists – if yes we just loop through to the next image.</p>
<p>With the code in <a href="https://github.com/finxter/ai-painted-advent-calendar" data-type="URL" data-id="https://github.com/finxter/ai-painted-advent-calendar" target="_blank" rel="noreferrer noopener">GitHub</a> I’ve included 25 images. If you want to generate your own just delete some or all from the images folder and edit the descriptions in <strong><code>config.py</code></strong>.</p>
<p>If you don’t yet want to purchase <em>deepai </em>credits – I recommend you just delete a few to experiment.</p>
<p>Sample output from the prepaint.py script</p>
<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" loading="lazy" width="567" height="327" src="https://blog.finxter.com/wp-content/uploads/2022/12/image-112.png" alt="" class="wp-image-960984" srcset="https://blog.finxter.com/wp-content/uploads/2022/12/image-112.png 567w, https://blog.finxter.com/wp-content/uplo...00x173.png 300w" sizes="(max-width: 567px) 100vw, 567px" /></figure>
</div>
<h2>The Advent app</h2>
<p>I chose to use the PyGame library to produce the virtual Advent app. </p>
<p>Running<strong> <code>main.py</code></strong> launches a window with a grid of 25 doors. </p>
<p>Red doors indicate available doors to open based on the current date of the month. When a red labeled door is opened, a festive image is displayed along with a short promotion text that can be customized in <strong><code>config.py</code></strong></p>
<div class="is-layout-flex wp-container-3 wp-block-columns">
<div class="is-layout-flow wp-block-column">
<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" loading="lazy" width="503" height="534" src="https://blog.finxter.com/wp-content/uploads/2022/12/image-113.png" alt="" class="wp-image-960988" srcset="https://blog.finxter.com/wp-content/uploads/2022/12/image-113.png 503w, https://blog.finxter.com/wp-content/uplo...83x300.png 283w" sizes="(max-width: 503px) 100vw, 503px" /></figure>
</div>
</div>
<div class="is-layout-flow wp-block-column">
<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" loading="lazy" width="506" height="537" src="https://blog.finxter.com/wp-content/uploads/2022/12/image-114.png" alt="" class="wp-image-960990" srcset="https://blog.finxter.com/wp-content/uploads/2022/12/image-114.png 506w, https://blog.finxter.com/wp-content/uplo...83x300.png 283w" sizes="(max-width: 506px) 100vw, 506px" /></figure>
</div>
</div>
</div>
<p>A click on the image re-displays the grid of calendar doors.&nbsp;</p>
<p>A click on the lower portion of the screen opens a browser with the configured URL.</p>
<p>The PyGame script itself is fairly straightforward. Just one interesting snippet to highlight: To arrange the doors in a ‘random’ order. An array of the numbers 1 to 25 is created (constants <strong>HEIGHT</strong> and <strong>WIDTH</strong> are both defined as 5 in <strong><code>config.py</code></strong>). </p>
<p>This array is shuffled using <strong><code><a rel="noreferrer noopener" href="https://blog.finxter.com/how-to-shuffle-two-arrays-in-unison-in-python/" data-type="post" data-id="671520" target="_blank">random.shuffle</a></code></strong>. By pre-setting the random seed to a set figure (here 1 was chosen), the same random shuffle is produced every time the <strong><code>main.py</code></strong> is run.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">doormap=list(range(1,HEIGHT*WIDTH+1))
random.seed(1)
random.shuffle(doormap)</pre>
<h2>Appendix – Full Code</h2>
<p>Here are the two code files:</p>
<p><code><strong>config.py</strong></code>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">HEIGHT = 5
WIDTH = 5 descriptions=["Christmas presents under tree", "Santas Elf", "Santa in sleigh flying over a town delivering gifts on christmas eve", "candy cane on an christmas tree", "a festive robin redbreast", "a snowman with carrot nose and presents", "fairy on top of a christmas tree", "children playing with christmas presents", "christmas lunch", "christmas carol singers", "christmas bells in a christmas tree", "rudolph the red nosed reindeer", "Santa in sleigh", "two snowmen with presents", "snowy village scene", "christmas decoration", "christmas bells", "christmas snowflake", "christmas pudding with custard", "christmas feast with turkey", "father christmas laughing", "christmas baby in a manger", "christmas mulled wine", "children enjoying playing with a new toy train", ] gifts=[('8 python cheat sheets','https://blog.finxter.com/python-cheat-sheets/'),
('the finxter academy','https://academy.finxter.com/'),
('the finxter app','https://app.finxter.com/learn/computer/science/'),
('the finxster freelancer course','https://finxter.gumroad.com/l/python-freelancer/'),
('The Ultimate Guide to Start Learning Python','https://blog.finxter.com/start-learning-python/'),
('Coffee Break Numpy book','https://www.amazon.com/gp/product/B07WHB8FWC/ref=as_li_tl?ie=UTF8&amp;tag=finxter-20&amp;camp=1789&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=B07WHB8FWC&amp;linkId=447a5019492081d1b2892d9470bb29fc'),
('Leaving the Rat Race with Python book','https://www.amazon.com/Leaving-Rat-Race-Python-Developing-ebook/dp/B08G1XLDNB/ref=sr_1_5?qid=1670149592&amp;refinements=p_27%3AChristian+Mayer&amp;s=digital-text&amp;sr=1-5&amp;text=Christian+Mayer'),
('Coffee break Python book','https://www.amazon.com/Coffee-Break-Python-Kickstart-Understanding-ebook/dp/B07GSTJPFD/ref=sr_1_4?qid=1670149592&amp;refinements=p_27%3AChristian+Mayer&amp;s=digital-text&amp;sr=1-4&amp;text=Christian+Mayer'),
('Coffee Break Python Slicing','https://www.amazon.com/Coffee-Break-Python-Slicing-Workouts-ebook/dp/B07KSHLLG5/ref=sr_1_8?qid=1670149592&amp;refinements=p_27%3AChristian+Mayer&amp;s=digital-text&amp;sr=1-8&amp;text=Christian+Mayer'),
('Coffee Break Pandas','https://www.amazon.com/Coffee-Break-Pandas-Puzzles-Superpower-ebook/dp/B08NG8QHW7/ref=sr_1_9?qid=1670149592&amp;refinements=p_27%3AChristian+Mayer&amp;s=digital-text&amp;sr=1-9&amp;text=Christian+Mayer'),
('',''),</pre>
<p><code><strong>main.py</strong></code>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pygame
import sys
import time
import random
import datetime
import webbrowser
import config HEIGHT = config.HEIGHT
WIDTH = config.WIDTH
LINEHEIGHT = 30
CLICKABLEHEIGHT = 150
FONT = 'verdana' # Colors
BLACK = (0, 0, 0)
GRAY = (200, 200, 200)
WHITE = (255, 255, 255)
RED = (200, 0, 0) # use a seeded random shuffle on numbers 1 to 25 # specify seed to always generate the same random sequence of door labels for our 5x5 grid
doormap=list(range(1,HEIGHT*WIDTH+1))
random.seed(1) random.shuffle(doormap) #get current time
d = datetime.datetime.now()
#get the day of month
datemax=int(d.strftime("%d")) #lambda function to convert eg 1 to 1st, 2 to 2nd
ordinal = lambda n: "%d%s" % (n,"tsnrhtdd"[(n//10%10!=1)*(n%10&lt;4)*n%10::4]) # Create game
pygame.init()
size = width, height = 500, 500
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Finxter Advent Calendar') #font_name = 'calibr'#pygame.font.get_default_font()
bigfont = pygame.font.SysFont(FONT, 20)
hugefont = pygame.font.SysFont(FONT, 40) # Compute board size
BOARD_PADDING = 10
board_width = width - (BOARD_PADDING * 2)
board_height = height - (BOARD_PADDING * 2)
cell_size = int(min(board_width / WIDTH, board_height / HEIGHT))
halfcell_size=cell_size/2+10
board_origin = (BOARD_PADDING, BOARD_PADDING) # utility function to add text to screen
def addText(text, position, color): giftText = bigfont.render(text, True, color) giftRect = giftText.get_rect() giftRect.center = position screen.blit(giftText, giftRect) # start from the main grid when dooropen>0 it indicate the door/image to display
dooropen=0 while True: # Check if game quit for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() screen.fill(BLACK) if dooropen: # paint the correct image onto the screen filename='images/image'+ (f"{dooropen:02d}") +".jpg" image = pygame.image.load(filename) rect = image.get_rect() screen.blit(image, rect) # going to create a semi transparent clickable area which can link to a URL # the URL 'gifts' are stored in the imported config giftlabel,gifturl = config.gifts[dooropen%len(config.gifts)] s = pygame.Surface((width,CLICKABLEHEIGHT)) s.set_alpha(200) s.fill(GRAY) screen.blit(s, (0,height-CLICKABLEHEIGHT)) clickable = pygame.Rect(0,height-CLICKABLEHEIGHT,width,CLICKABLEHEIGHT) # add text to the clickable area if(dooropen==25): addText("It's Christmas!", ((width / 2), 4*cell_size+LINEHEIGHT), RED) else: addText("On the "+ ordinal(25-dooropen) +" night before xmas", ((width / 2), 4*cell_size), WHITE) addText("Finxter brought unto me:", ((width / 2), 4*cell_size+LINEHEIGHT), WHITE) addText(giftlabel, ((width / 2), 4*cell_size+(2*LINEHEIGHT)), RED) # open URL in browser if clickable area clicked # otherwise close the door by setting dooropen to 0 click, _, _ = pygame.mouse.get_pressed() if click == 1: mouse = pygame.mouse.get_pos() if clickable.collidepoint(mouse) : time.sleep(0.2) webbrowser.open(gifturl, new=dooropen, autoraise=True) else: dooropen = 0 time.sleep(0.2) pygame.display.flip() continue # Draw board cells = [] for i in range(HEIGHT): row = [] for j in range(WIDTH): # Draw rectangle for cell rect = pygame.Rect( board_origin[0] + j * cell_size, board_origin[1] + i * cell_size, cell_size, cell_size ) pygame.draw.rect(screen, GRAY, rect) pygame.draw.rect(screen, WHITE, rect, 3) doornumber=doormap[(j*HEIGHT)+i] label = hugefont.render(str(doornumber), True, RED if doornumber&lt;=datemax else WHITE) labelRect = label.get_rect() labelRect.center = (j * cell_size+halfcell_size, i * cell_size+halfcell_size) screen.blit(label, labelRect) row.append(rect) cells.append(row) left, _, right = pygame.mouse.get_pressed() if left: mouse = pygame.mouse.get_pos() for i in range(HEIGHT): for j in range(WIDTH): if cells[i][j].collidepoint(mouse) and dooropen==0: dooropen=doormap[(j*HEIGHT)+i] # did they attempt to open a door ahead of current date # dont allow that! if dooropen>datemax: dooropen=0 time.sleep(0.2) pygame.display.flip()</pre>
<p><code><strong>prepaint.py</strong></code>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import urllib.request
import config
import requests
from os.path import exists def aipaint(description): r = requests.post( "https://api.deepai.org/api/impressionism-painting-generator", data={ 'text': description, }, headers={'api-key': 'quickstart-QUdJIGlzIGNvbWluZy4uLi4K'} ) ret = r.json() return ret count=1 while count&lt;=25: # pop off the first image description description=config.descriptions.pop(0) # push it back on at end (this ensures we cycle through descriptions and never run out ) # obviously best is there are 25 descriptions though config.descriptions.append(description) filename='./images/image'+ (f"{count:02d}") +".jpg" if(exists(filename)): print(filename+" already exists") else: print("Painting: "+description) try: painting=aipaint(description) if(len(painting)&lt;2): if(painting['status']): print("You've probably run out of deepai (free) credits.") print("Status returned "+painting['status']) else: print("Storing as "+filename) urllib.request.urlretrieve(painting['output_url'], filename) print("Paint now dried on "+filename) except Exception as ex: print("Paint "+filename+" failed") print(ex) count+=1 print("Paintings complete and paint has dried!")
print("Now run main.py to access the Advent calendar")</pre>
</div>


https://www.sickgaming.net/blog/2022/12/...-creation/
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016