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 from os import path
12 12 import random
13 13 import re
14   -from typing import Any, Dict, NewType
  14 +from typing import Any, Dict, List, NewType
15 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 20 # setup logger for this module
21 21 logger = logging.getLogger(__name__)
... ... @@ -33,8 +33,9 @@ class QuestionException(Exception):
33 33 # ============================================================================
34 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 39 Instances can shuffle options or automatically generate questions.
39 40 '''
40 41  
... ... @@ -695,3 +696,44 @@ class QFactory():
695 696 question = question_from(qdict) # returns a Question instance
696 697 question.gen()
697 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 212 # ----------------------------------------------------------------------------
213 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
... ...