Fix api extension duplicating
diff --git a/extensions/api/script.py b/extensions/api/script.py
index 1774c345fc..bd7c19002a 100644
--- a/extensions/api/script.py
+++ b/extensions/api/script.py
@@ -1,8 +1,9 @@
+import json
 from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
 from threading import Thread
+
 from modules import shared
-from modules.text_generation import generate_reply, encode
-import json
+from modules.text_generation import encode, generate_reply
 
 params = {
     'port': 5000,
@@ -87,5 +88,5 @@ def run_server():
         print(f'Starting KoboldAI compatible api at http://{server_addr[0]}:{server_addr[1]}/api')
     server.serve_forever()
 
-def ui():
+def setup():
     Thread(target=run_server, daemon=True).start()
diff --git a/modules/extensions.py b/modules/extensions.py
index dbc938404b..c55dc97882 100644
--- a/modules/extensions.py
+++ b/modules/extensions.py
@@ -7,6 +7,7 @@
 
 state = {}
 available_extensions = []
+setup_called = False
 
 def load_extensions():
     global state
@@ -39,6 +40,8 @@ def apply_extensions(text, typ):
     return text
 
 def create_extensions_block():
+    global setup_called
+
     # Updating the default values
     for extension, name in iterator():
         if hasattr(extension, 'params'):
@@ -47,8 +50,19 @@ def create_extensions_block():
                 if _id in shared.settings:
                     extension.params[param] = shared.settings[_id]
 
+    should_display_ui = False
+
+    # Running setup function
+    if not setup_called:
+        for extension, name in iterator():
+            if hasattr(extension, "setup"):
+                extension.setup()
+            if hasattr(extension, "ui"):
+                should_display_ui = True
+        setup_called = True
+
     # Creating the extension ui elements
-    if len(state) > 0:
+    if should_display_ui:
         with gr.Box(elem_id="extensions"):
             gr.Markdown("Extensions")
             for extension, name in iterator():

Prevent server in `api` extension run multiple times, causing "Port already taken" error. 

I added new `setup()` method to extensions to run once when app is ready to initialize extensions when app is first loaded.
It also helps against empty "Extensions" block, when no actual ui is present.
