Commit 9b8820e43d7c164f7cef3372224d6b9d6975ecef

Authored by Miguel Barão
1 parent a7d6b9e1
Exists in dev

move run_script to questions.py

it was only used there.
aprendizations/questions.py
@@ -11,11 +11,11 @@ import logging @@ -11,11 +11,11 @@ import logging
11 from os import path 11 from os import path
12 import random 12 import random
13 import re 13 import re
14 -from typing import Any, Dict, NewType 14 +from typing import Any, Dict, List, NewType
15 import uuid 15 import uuid
16 16
17 -# this project  
18 -from aprendizations.tools import run_script 17 +# third party libraries
  18 +import yaml
19 19
20 # setup logger for this module 20 # setup logger for this module
21 logger = logging.getLogger(__name__) 21 logger = logging.getLogger(__name__)
@@ -33,8 +33,9 @@ class QuestionException(Exception): @@ -33,8 +33,9 @@ class QuestionException(Exception):
33 # ============================================================================ 33 # ============================================================================
34 class Question(dict): 34 class Question(dict):
35 ''' 35 '''
36 - Classes derived from this base class are meant to instantiate questions  
37 - for each student. 36 + Base class for all question types
  37 +
  38 + Classes derived from this base class can instantiate questions.
38 Instances can shuffle options or automatically generate questions. 39 Instances can shuffle options or automatically generate questions.
39 ''' 40 '''
40 41
@@ -695,3 +696,44 @@ class QFactory(): @@ -695,3 +696,44 @@ class QFactory():
695 question = question_from(qdict) # returns a Question instance 696 question = question_from(qdict) # returns a Question instance
696 question.gen() 697 question.gen()
697 return question 698 return question
  699 +
  700 +# -----------------------------------------------------------------------------
  701 +async def run_script(script: str,
  702 + args: List[str],
  703 + stdin: str = '',
  704 + timeout: int = 5) -> Any:
  705 +
  706 + # normalize args
  707 + script = path.expanduser(script)
  708 + input_bytes = stdin.encode('utf-8')
  709 + args = [str(a) for a in args]
  710 +
  711 + try:
  712 + p = await asyncio.create_subprocess_exec(
  713 + script, *args,
  714 + stdin=asyncio.subprocess.PIPE,
  715 + stdout=asyncio.subprocess.PIPE,
  716 + stderr=asyncio.subprocess.DEVNULL,
  717 + )
  718 + except FileNotFoundError:
  719 + logger.error(f'Can not execute script "{script}": not found.')
  720 + except PermissionError:
  721 + logger.error(f'Can not execute script "{script}": wrong permissions.')
  722 + except OSError:
  723 + logger.error(f'Can not execute script "{script}": unknown reason.')
  724 + else:
  725 + try:
  726 + stdout, _ = await asyncio.wait_for(p.communicate(input_bytes), timeout)
  727 + except asyncio.TimeoutError:
  728 + logger.warning(f'Timeout {timeout}s exceeded running "{script}".')
  729 + return
  730 +
  731 + if p.returncode != 0:
  732 + logger.error(f'Return code {p.returncode} running "{script}".')
  733 + else:
  734 + try:
  735 + output = yaml.safe_load(stdout.decode('utf-8', 'ignore'))
  736 + except yaml.YAMLError:
  737 + logger.error(f'Error parsing yaml output of "{script}"')
  738 + else:
  739 + return output
aprendizations/tools.py
@@ -212,42 +212,42 @@ def load_yaml(filename: str, default: Any = None) -> Any: @@ -212,42 +212,42 @@ def load_yaml(filename: str, default: Any = None) -> Any:
212 # ---------------------------------------------------------------------------- 212 # ----------------------------------------------------------------------------
213 # Same as above, but asynchronous 213 # Same as above, but asynchronous
214 # ---------------------------------------------------------------------------- 214 # ----------------------------------------------------------------------------
215 -async def run_script(script: str,  
216 - args: List[str] = [],  
217 - stdin: str = '',  
218 - timeout: int = 2) -> Any:  
219 -  
220 - # normalize args  
221 - script = path.expanduser(script)  
222 - input_bytes = stdin.encode('utf-8')  
223 - args = [str(a) for a in args]  
224 -  
225 - try:  
226 - p = await asyncio.create_subprocess_exec(  
227 - script, *args,  
228 - stdin=asyncio.subprocess.PIPE,  
229 - stdout=asyncio.subprocess.PIPE,  
230 - stderr=asyncio.subprocess.DEVNULL,  
231 - )  
232 - except FileNotFoundError:  
233 - logger.error(f'Can not execute script "{script}": not found.')  
234 - except PermissionError:  
235 - logger.error(f'Can not execute script "{script}": wrong permissions.')  
236 - except OSError:  
237 - logger.error(f'Can not execute script "{script}": unknown reason.')  
238 - else:  
239 - try:  
240 - stdout, _ = await asyncio.wait_for(p.communicate(input_bytes), timeout)  
241 - except asyncio.TimeoutError:  
242 - logger.warning(f'Timeout {timeout}s exceeded running "{script}".')  
243 - return  
244 -  
245 - if p.returncode != 0:  
246 - logger.error(f'Return code {p.returncode} running "{script}".')  
247 - else:  
248 - try:  
249 - output = yaml.safe_load(stdout.decode('utf-8', 'ignore'))  
250 - except Exception:  
251 - logger.error(f'Error parsing yaml output of "{script}"')  
252 - else:  
253 - return output 215 +# async def run_script(script: str,
  216 +# args: List[str] = [],
  217 +# stdin: str = '',
  218 +# timeout: int = 5) -> Any:
  219 +#
  220 +# # normalize args
  221 +# script = path.expanduser(script)
  222 +# input_bytes = stdin.encode('utf-8')
  223 +# args = [str(a) for a in args]
  224 +#
  225 +# try:
  226 +# p = await asyncio.create_subprocess_exec(
  227 +# script, *args,
  228 +# stdin=asyncio.subprocess.PIPE,
  229 +# stdout=asyncio.subprocess.PIPE,
  230 +# stderr=asyncio.subprocess.DEVNULL,
  231 +# )
  232 +# except FileNotFoundError:
  233 +# logger.error(f'Can not execute script "{script}": not found.')
  234 +# except PermissionError:
  235 +# logger.error(f'Can not execute script "{script}": wrong permissions.')
  236 +# except OSError:
  237 +# logger.error(f'Can not execute script "{script}": unknown reason.')
  238 +# else:
  239 +# try:
  240 +# stdout, _ = await asyncio.wait_for(p.communicate(input_bytes), timeout)
  241 +# except asyncio.TimeoutError:
  242 +# logger.warning(f'Timeout {timeout}s exceeded running "{script}".')
  243 +# return
  244 +#
  245 +# if p.returncode != 0:
  246 +# logger.error(f'Return code {p.returncode} running "{script}".')
  247 +# else:
  248 +# try:
  249 +# output = yaml.safe_load(stdout.decode('utf-8', 'ignore'))
  250 +# except Exception:
  251 +# logger.error(f'Error parsing yaml output of "{script}"')
  252 +# else:
  253 +# return output