acecalisto3 commited on
Commit
8ca88cc
·
verified ·
1 Parent(s): afe9aee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +136 -69
app.py CHANGED
@@ -1,5 +1,5 @@
1
  import threading
2
- import time
3
  import gradio as gr
4
  import logging
5
  import json
@@ -10,17 +10,20 @@ import os
10
  from pathlib import Path
11
  from typing import Dict, List, Tuple, Optional, Any, Union
12
  from dataclasses import dataclass, field
13
- from enum import Enum
 
 
14
  from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
15
  from sentence_transformers import SentenceTransformer
16
  import faiss
17
  import numpy as np
18
  from PIL import Image
19
 
20
- # Configure logging
21
  logging.basicConfig(
22
  level=logging.INFO,
23
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
 
24
  handlers=[
25
  logging.StreamHandler(),
26
  logging.FileHandler('gradio_builder.log')
@@ -28,16 +31,16 @@ logging.basicConfig(
28
  )
29
  logger = logging.getLogger(__name__)
30
 
31
- # Constants
32
  DEFAULT_PORT = 7860
33
  MODEL_CACHE_DIR = Path("model_cache")
34
  TEMPLATE_DIR = Path("templates")
35
  TEMP_DIR = Path("temp")
36
  DATABASE_PATH = Path("code_database.json")
37
 
38
- # Ensure directories exist
39
  for directory in [MODEL_CACHE_DIR, TEMPLATE_DIR, TEMP_DIR]:
40
- directory.mkdir(exist_ok=True, parents=True)
41
 
42
  @dataclass
43
  class Template:
@@ -45,38 +48,51 @@ class Template:
45
  description: str
46
  components: List[str] = field(default_factory=list)
47
 
 
 
 
 
 
 
48
  class TemplateManager:
49
  def __init__(self, template_dir: Path):
50
  self.template_dir = template_dir
51
  self.templates: Dict[str, Template] = {}
 
52
 
53
- def load_templates(self):
 
 
 
54
  for file_path in self.template_dir.glob("*.json"):
55
  try:
56
  with open(file_path, 'r') as f:
57
  template_data = json.load(f)
58
- template = Template(**template_data)
59
- self.templates[template_data['description']] = template
60
- except json.JSONDecodeError as e:
61
- logger.error(f"Error loading template from {file_path}: {e}")
62
- except KeyError as e:
63
- logger.error(f"Missing key in template file {file_path}: {e}")
64
 
65
  def save_template(self, name: str, template: Template) -> bool:
 
 
 
66
  file_path = self.template_dir / f"{name}.json"
67
  try:
68
  with open(file_path, 'w') as f:
69
  json.dump(dataclasses.asdict(template), f, indent=2)
70
  return True
71
  except Exception as e:
72
- logger.error(f"Error saving template to {file_path}: {e}")
73
  return False
74
 
75
  def get_template(self, name: str) -> Optional[str]:
 
 
 
76
  return self.templates.get(name, {}).get('code', "")
77
 
78
  class RAGSystem:
79
- def __init__(self, model_name: str = "gpt2", device: str = "cuda" if torch.cuda.is_available() else "cpu", embedding_model="all-mpnet-base-v2"):
80
  self.device = device
81
  self.embedding_model = None
82
  self.code_embeddings = None
@@ -89,127 +105,157 @@ class RAGSystem:
89
  self.model = AutoModelForCausalLM.from_pretrained(model_name, cache_dir=MODEL_CACHE_DIR).to(device)
90
  self.pipe = pipeline("text-generation", model=self.model, tokenizer=self.tokenizer, device=self.device)
91
  self.embedding_model = SentenceTransformer(embedding_model)
92
- self.load_database()
93
- logger.info("RAG system initialized successfully.")
94
  except Exception as e:
95
- logger.error(f"Error loading language model or embedding model: {e}. Falling back to placeholder generation.")
96
 
97
- def load_database(self):
 
 
 
98
  if DATABASE_PATH.exists():
99
  try:
100
  with open(DATABASE_PATH, 'r', encoding='utf-8') as f:
101
  self.database = json.load(f)
102
  self.code_embeddings = np.array(self.database['embeddings'])
103
- logger.info("Loaded code database from file.")
104
  self._build_index()
105
  except (json.JSONDecodeError, KeyError) as e:
106
- logger.error(f"Error loading code database: {e}. Creating new database.")
107
  self.database = {'codes': [], 'embeddings': []}
108
  self.code_embeddings = np.array([])
109
  self._build_index()
110
  else:
111
- logger.info("Code database does not exist. Creating new database.")
112
  self.database = {'codes': [], 'embeddings': []}
113
  self.code_embeddings = np.array([])
114
  self._build_index()
115
 
116
  if self.embedding_model and len(self.database['codes']) != len(self.database['embeddings']):
117
- logger.warning("Mismatch between number of codes and embeddings, rebuilding embeddings.")
118
  self.rebuild_embeddings()
119
  elif self.embedding_model is None:
120
- logger.warning ("Embeddings are not supported in this context.")
121
 
122
  def _build_index(self):
 
 
 
123
  if len(self.code_embeddings) > 0 and self.embedding_model:
124
- self.index = faiss.IndexFlatL2(self.code_embeddings.shape[1]) # L2 distance
125
  self.index.add(self.code_embeddings)
126
 
127
  def add_to_database(self, code: str):
 
 
 
128
  try:
129
  if self.embedding_model is None:
130
- raise ValueError("Embedding model not loaded.")
131
  embedding = self.embedding_model.encode(code)
132
  self.database['codes'].append(code)
133
  self.database['embeddings'].append(embedding.tolist())
134
  self.code_embeddings = np.vstack((self.code_embeddings, embedding)) if len(self.code_embeddings) > 0 else np.array([embedding])
135
  self.index.add(np.array([embedding]))
136
- self.save_database()
137
- logger.info(f"Added code snippet to database. Total size: {len(self.database['codes'])}.")
138
  except Exception as e:
139
- logger.error(f"Error adding to database: {e}")
140
 
141
- def save_database(self):
 
 
 
142
  try:
143
  with open(DATABASE_PATH, 'w', encoding='utf-8') as f:
144
  json.dump(self.database, f, indent=2)
145
- logger.info(f"Saved database to {DATABASE_PATH}.")
146
  except Exception as e:
147
- logger.error(f"Error saving database: {e}")
148
 
149
  def rebuild_embeddings(self):
 
 
 
150
  try:
151
  if self.embedding_model is None:
152
- raise ValueError("Embedding model not loaded.")
153
  embeddings = self.embedding_model.encode(self.database['codes'])
154
  self.code_embeddings = embeddings
155
  self.database['embeddings'] = embeddings.tolist()
156
  self._build_index()
157
- self.save_database()
158
- logger.info("Rebuilt and saved embeddings to the database.")
159
  except Exception as e:
160
- logger.error(f"Error rebuilding embeddings: {e}")
161
 
162
  def retrieve_similar_code(self, description: str, top_k: int = 3) -> List[str]:
 
 
 
163
  if self.embedding_model is None or self.index is None:
164
- logger.warning("Embedding model or index not available. Cannot retrieve similar code.")
165
  return []
166
  try:
167
  embedding = self.embedding_model.encode(description)
168
  D, I = self.index.search(np.array([embedding]), top_k)
169
- logger.info(f"Retrieved {top_k} similar code snippets for description: {description}.")
170
  return [self.database['codes'][i] for i in I[0]]
171
  except Exception as e:
172
- logger.error(f"Error retrieving similar code: {e}")
173
  return []
174
 
175
  def generate_code(self, description: str, template_code: str) -> str:
 
 
 
176
  retrieved_codes = self.retrieve_similar_code(description)
177
  prompt = f"Description: {description} Retrieved Code Snippets: {''.join([f'```python {code} ```' for code in retrieved_codes])} Template: ```python {template_code} ``` Generated Code: ```python "
178
  if self.pipe:
179
  try:
180
  generated_text = self.pipe(prompt, max_length=500, num_return_sequences=1)[0]['generated_text']
181
  generated_code = generated_text.split("Generated Code:")[1].strip().split('```')[0]
182
- logger.info("Code generated successfully.")
183
  return generated_code
184
  except Exception as e:
185
- logger.error(f"Error generating code with language model: {e}. Returning template code.")
186
  return template_code
187
  else:
188
- logger.warning("Text generation pipeline is not available. Returning placeholder code.")
189
  return f"# Placeholder code generation. Description: {description} {template_code}"
190
 
191
  class GradioInterface:
192
  def __init__(self):
193
  self.template_manager = TemplateManager(TEMPLATE_DIR)
194
- self.template_manager.load_templates()
195
  self.rag_system = RAGSystem()
 
196
 
197
  def _extract_components(self, code: str) -> List[str]:
 
 
 
198
  components = []
199
- function_matches = re.findall(r'def (\w+)\(', code) # added parenthesis for more accuracy
200
  components.extend(function_matches)
201
- class_matches = re.findall(r'class (\w+)\:', code) # added colon for more accuracy
202
  components.extend(class_matches)
203
- logger.info(f"Extracted components: {components}")
204
  return components
205
 
206
  def _get_template_choices(self) -> List[str]:
 
 
 
207
  return list(self.template_manager.templates.keys())
208
 
209
- def launch(self, **kwargs):
 
 
 
210
  with gr.Blocks() as interface:
211
  gr.Markdown("## Code Generation Interface")
212
- description_input = gr.Textbox(label="Description", placeholder="Enter a description for the code you want to generate.")
213
  code_output = gr.Textbox(label="Generated Code", interactive=False)
214
  generate_button = gr.Button("Generate Code")
215
  template_choice = gr.Dropdown(label="Select Template", choices=self._get_template_choices(), value=None)
@@ -217,29 +263,35 @@ class GradioInterface:
217
  status_output = gr.Textbox(label="Status", interactive=False)
218
 
219
  def generate_code_wrapper(description, template_choice):
 
 
 
220
  try:
221
  template_code = self.template_manager.get_template(template_choice) if template_choice else ""
222
- generated_code = self.rag_system.generate_code(description, template_code)
223
- return generated_code, "Code generated successfully."
224
  except Exception as e:
225
- return "", f"Error generating code: {e}"
226
 
227
  def save_template_wrapper(code, name, description):
 
 
 
228
  try:
229
  if not name:
230
- return code, "Template name cannot be empty."
231
  if not code:
232
- return code, "Code cannot be empty."
233
 
234
  components = self._extract_components(code)
235
  template = Template(code=code, description=name, components=components)
236
  if self.template_manager.save_template(name, template):
237
  self.rag_system.add_to_database(code)
238
- return code, f"Template '{name}' saved successfully."
239
  else:
240
- return code, "Failed to save template."
241
  except Exception as e:
242
- return code, f"Error saving template: {e}"
243
 
244
  generate_button.click(
245
  fn=generate_code_wrapper,
@@ -253,23 +305,38 @@ class GradioInterface:
253
  outputs=[code_output, status_output]
254
  )
255
 
256
- logger.info("Launching Gradio interface.")
257
- interface.launch(**kwargs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
 
259
  def main():
260
- logger.info("=== Application Startup ===")
 
 
 
261
  try:
262
  interface = GradioInterface()
263
- interface.launch(
264
- server_port=DEFAULT_PORT,
265
- share=False,
266
- debug=True
267
- )
268
  except Exception as e:
269
- logger.error(f"Application error: {e}")
270
  raise
271
- finally:
272
- logger.info("=== Application Shutdown ===")
273
 
274
- if __name__ == "__main__":
275
  main()
 
1
  import threading
2
+ from datetime import datetime
3
  import gradio as gr
4
  import logging
5
  import json
 
10
  from pathlib import Path
11
  from typing import Dict, List, Tuple, Optional, Any, Union
12
  from dataclasses import dataclass, field
13
+ from enum import Enum # We're bringing in the big guns with Enum!
14
+
15
+ # Our magical models and transformers
16
  from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
17
  from sentence_transformers import SentenceTransformer
18
  import faiss
19
  import numpy as np
20
  from PIL import Image
21
 
22
+ # A touch of style for our logging
23
  logging.basicConfig(
24
  level=logging.INFO,
25
+ format='%(as_time)s - %(levelname)s - %(name)s - %(message)s',
26
+ datefmt='%Y-%m-%d %H:%M:%S',
27
  handlers=[
28
  logging.StreamHandler(),
29
  logging.FileHandler('gradio_builder.log')
 
31
  )
32
  logger = logging.getLogger(__name__)
33
 
34
+ # Constants with a touch of mystery
35
  DEFAULT_PORT = 7860
36
  MODEL_CACHE_DIR = Path("model_cache")
37
  TEMPLATE_DIR = Path("templates")
38
  TEMP_DIR = Path("temp")
39
  DATABASE_PATH = Path("code_database.json")
40
 
41
+ # Ensure our directories exist, like a well-organized wizard
42
  for directory in [MODEL_CACHE_DIR, TEMPLATE_DIR, TEMP_DIR]:
43
+ directory.mkdir(parents=True, exist_ok=True)
44
 
45
  @dataclass
46
  class Template:
 
48
  description: str
49
  components: List[str] = field(default_factory=list)
50
 
51
+ def __post_init__(self):
52
+ """
53
+ Init like a boss with some post-initialization magic.
54
+ """
55
+ self.components = self._extract_components()
56
+
57
  class TemplateManager:
58
  def __init__(self, template_dir: Path):
59
  self.template_dir = template_dir
60
  self.templates: Dict[str, Template] = {}
61
+ self._load_templates()
62
 
63
+ def _load_templates(self):
64
+ """
65
+ Load templates with grace and elegance.
66
+ """
67
  for file_path in self.template_dir.glob("*.json"):
68
  try:
69
  with open(file_path, 'r') as f:
70
  template_data = json.load(f)
71
+ self.templates[template_data['description']] = Template(**template_data)
72
+ except (json.JSONDecodeError, KeyError) as e:
73
+ logger.error(f"Oh no! An error loading template from {file_path}: {e}")
 
 
 
74
 
75
  def save_template(self, name: str, template: Template) -> bool:
76
+ """
77
+ Save a template with care and precision.
78
+ """
79
  file_path = self.template_dir / f"{name}.json"
80
  try:
81
  with open(file_path, 'w') as f:
82
  json.dump(dataclasses.asdict(template), f, indent=2)
83
  return True
84
  except Exception as e:
85
+ logger.error(f"An unfortunate error saving template to {file_path}: {e}")
86
  return False
87
 
88
  def get_template(self, name: str) -> Optional[str]:
89
+ """
90
+ Retrieve a template with finesse.
91
+ """
92
  return self.templates.get(name, {}).get('code', "")
93
 
94
  class RAGSystem:
95
+ def __init__(self, model_name: str = "gpt3-incredible", device: str = "cuda" if torch.cuda.is_available() else "cpu", embedding_model="all-knowing-embedder"):
96
  self.device = device
97
  self.embedding_model = None
98
  self.code_embeddings = None
 
105
  self.model = AutoModelForCausalLM.from_pretrained(model_name, cache_dir=MODEL_CACHE_DIR).to(device)
106
  self.pipe = pipeline("text-generation", model=self.model, tokenizer=self.tokenizer, device=self.device)
107
  self.embedding_model = SentenceTransformer(embedding_model)
108
+ self._load_database()
109
+ logger.info("RAG system initialized with incredible power!")
110
  except Exception as e:
111
+ logger.error(f"A dark force prevented loading the language model or embedding model: {e}. The placeholder generation shall be used.")
112
 
113
+ def _load_database(self):
114
+ """
115
+ Load the code database with ancient knowledge.
116
+ """
117
  if DATABASE_PATH.exists():
118
  try:
119
  with open(DATABASE_PATH, 'r', encoding='utf-8') as f:
120
  self.database = json.load(f)
121
  self.code_embeddings = np.array(self.database['embeddings'])
122
+ logger.info("Ancient code database has been loaded.")
123
  self._build_index()
124
  except (json.JSONDecodeError, KeyError) as e:
125
+ logger.error(f"A curse has been cast upon the code database: {e}. A new database shall be created.")
126
  self.database = {'codes': [], 'embeddings': []}
127
  self.code_embeddings = np.array([])
128
  self._build_index()
129
  else:
130
+ logger.info("No code database has been found. A new one shall be created.")
131
  self.database = {'codes': [], 'embeddings': []}
132
  self.code_embeddings = np.array([])
133
  self._build_index()
134
 
135
  if self.embedding_model and len(self.database['codes']) != len(self.database['embeddings']):
136
+ logger.warning("A mysterious mismatch between codes and embeddings has occurred. The embeddings shall be rebuilt.")
137
  self.rebuild_embeddings()
138
  elif self.embedding_model is None:
139
+ logger.warning("Embeddings are not supported in this realm. Proceed with caution.")
140
 
141
  def _build_index(self):
142
+ """
143
+ Construct an index with magical efficiency.
144
+ """
145
  if len(self.code_embeddings) > 0 and self.embedding_model:
146
+ self.index = faiss.IndexFlatL2(self.code_embeddings.shape[1]) # L2 distance, the measure of true similarity
147
  self.index.add(self.code_embeddings)
148
 
149
  def add_to_database(self, code: str):
150
+ """
151
+ Add a code snippet to the database with care.
152
+ """
153
  try:
154
  if self.embedding_model is None:
155
+ raise ValueError("The embedding model has not been summoned.")
156
  embedding = self.embedding_model.encode(code)
157
  self.database['codes'].append(code)
158
  self.database['embeddings'].append(embedding.tolist())
159
  self.code_embeddings = np.vstack((self.code_embeddings, embedding)) if len(self.code_embeddings) > 0 else np.array([embedding])
160
  self.index.add(np.array([embedding]))
161
+ self._save_database()
162
+ logger.info(f"A new code snippet has been added to the ancient database. Total size: {len(self.database['codes'])}.")
163
  except Exception as e:
164
+ logger.error(f"A dark force prevented adding to the database: {e}")
165
 
166
+ def _save_database(self):
167
+ """
168
+ Save the database with eternal preservation.
169
+ """
170
  try:
171
  with open(DATABASE_PATH, 'w', encoding='utf-8') as f:
172
  json.dump(self.database, f, indent=2)
173
+ logger.info(f"The ancient database has been saved to {DATABASE_PATH}.")
174
  except Exception as e:
175
+ logger.error(f"A curse has been cast upon saving the database: {e}")
176
 
177
  def rebuild_embeddings(self):
178
+ """
179
+ Rebuild embeddings with renewed power.
180
+ """
181
  try:
182
  if self.embedding_model is None:
183
+ raise ValueError("The embedding model has not been summoned.")
184
  embeddings = self.embedding_model.encode(self.database['codes'])
185
  self.code_embeddings = embeddings
186
  self.database['embeddings'] = embeddings.tolist()
187
  self._build_index()
188
+ self._save_database()
189
+ logger.info("The embeddings have been rebuilt and saved with enhanced power.")
190
  except Exception as e:
191
+ logger.error(f"A dark force prevented rebuilding the embeddings: {e}")
192
 
193
  def retrieve_similar_code(self, description: str, top_k: int = 3) -> List[str]:
194
+ """
195
+ Retrieve similar code with uncanny accuracy.
196
+ """
197
  if self.embedding_model is None or self.index is None:
198
+ logger.warning("The embedding model or index is missing. Similar code retrieval is beyond our reach.")
199
  return []
200
  try:
201
  embedding = self.embedding_model.encode(description)
202
  D, I = self.index.search(np.array([embedding]), top_k)
203
+ logger.info(f"{top_k} similar code snippets have been retrieved for the description: {description}. Prepare to be amazed!")
204
  return [self.database['codes'][i] for i in I[0]]
205
  except Exception as e:
206
+ logger.error(f"A dark force prevented retrieving similar code: {e}. The retrieval shall be attempted again.")
207
  return []
208
 
209
  def generate_code(self, description: str, template_code: str) -> str:
210
+ """
211
+ Generate code with incredible creativity.
212
+ """
213
  retrieved_codes = self.retrieve_similar_code(description)
214
  prompt = f"Description: {description} Retrieved Code Snippets: {''.join([f'```python {code} ```' for code in retrieved_codes])} Template: ```python {template_code} ``` Generated Code: ```python "
215
  if self.pipe:
216
  try:
217
  generated_text = self.pipe(prompt, max_length=500, num_return_sequences=1)[0]['generated_text']
218
  generated_code = generated_text.split("Generated Code:")[1].strip().split('```')[0]
219
+ logger.info("Incredible code has been generated!")
220
  return generated_code
221
  except Exception as e:
222
+ logger.error(f"A dark force prevented code generation with the language model: {e}. The template code shall be returned.")
223
  return template_code
224
  else:
225
+ logger.warning("The text generation pipeline is beyond our reach. A placeholder code shall be returned.")
226
  return f"# Placeholder code generation. Description: {description} {template_code}"
227
 
228
  class GradioInterface:
229
  def __init__(self):
230
  self.template_manager = TemplateManager(TEMPLATE_DIR)
 
231
  self.rag_system = RAGSystem()
232
+ self.interface = self._build_interface()
233
 
234
  def _extract_components(self, code: str) -> List[str]:
235
+ """
236
+ Extract components with precision and clarity.
237
+ """
238
  components = []
239
+ function_matches = re.findall(r'def (\w+)\(', code) # Parenthesis, the key to accuracy
240
  components.extend(function_matches)
241
+ class_matches = re.findall(r'class (\w+)\:', code) # Colon, the revealer of classes
242
  components.extend(class_matches)
243
+ logger.info(f"Components have been extracted: {components}")
244
  return components
245
 
246
  def _get_template_choices(self) -> List[str]:
247
+ """
248
+ Present template choices with elegance.
249
+ """
250
  return list(self.template_manager.templates.keys())
251
 
252
+ def _build_interface(self) -> gr.Blocks:
253
+ """
254
+ Construct the Gradio interface with style and functionality.
255
+ """
256
  with gr.Blocks() as interface:
257
  gr.Markdown("## Code Generation Interface")
258
+ description_input = gr.Textbox(label="Description", placeholder="Enter a description for the code you wish to bring to life.")
259
  code_output = gr.Textbox(label="Generated Code", interactive=False)
260
  generate_button = gr.Button("Generate Code")
261
  template_choice = gr.Dropdown(label="Select Template", choices=self._get_template_choices(), value=None)
 
263
  status_output = gr.Textbox(label="Status", interactive=False)
264
 
265
  def generate_code_wrapper(description, template_choice):
266
+ """
267
+ Generate code with a simple button click.
268
+ """
269
  try:
270
  template_code = self.template_manager.get_template(template_choice) if template_choice else ""
271
+ generated_code, status = self.rag_system.generate_code(description, template_code)
272
+ return generated_code, status
273
  except Exception as e:
274
+ return "", f"A dark force prevented code generation: {e}"
275
 
276
  def save_template_wrapper(code, name, description):
277
+ """
278
+ Save a template with ease and security.
279
+ """
280
  try:
281
  if not name:
282
+ return code, "A template name must be provided to seal its destiny."
283
  if not code:
284
+ return code, "Code cannot be empty. It must be filled with potential."
285
 
286
  components = self._extract_components(code)
287
  template = Template(code=code, description=name, components=components)
288
  if self.template_manager.save_template(name, template):
289
  self.rag_system.add_to_database(code)
290
+ return code, f"Template '{name}' has been saved for eternity."
291
  else:
292
+ return code, "A mysterious force prevented saving the template."
293
  except Exception as e:
294
+ return code, f"An error occurred while saving the template: {e}"
295
 
296
  generate_button.click(
297
  fn=generate_code_wrapper,
 
305
  outputs=[code_output, status_output]
306
  )
307
 
308
+ logger.info("The Gradio interface is ready to be unveiled.")
309
+ return interface
310
+
311
+ def launch(self, **kwargs):
312
+ """
313
+ Launch the Gradio interface with a flourish.
314
+ """
315
+ logger.info("=== Application Startup ===")
316
+ try:
317
+ self.interface.launch(
318
+ server_port=DEFAULT_PORT,
319
+ share=False,
320
+ debug=True,
321
+ **kwargs
322
+ )
323
+ except Exception as e:
324
+ logger.error(f"An unexpected error has occurred: {e}. The application shall be shut down.")
325
+ raise
326
+ finally:
327
+ logger.info("=== Application Shutdown ===")
328
 
329
  def main():
330
+ """
331
+ The main function, where the magic begins.
332
+ """
333
+ logger.info("=== Application Initiation ===")
334
  try:
335
  interface = GradioInterface()
336
+ interface.launch()
 
 
 
 
337
  except Exception as e:
338
+ logger.error(f"A critical error has occurred: {e}. The application shall be terminated.")
339
  raise
 
 
340
 
341
+ if __name__ == '__main__':
342
  main()