2017-06-20 62 views
0

我有一个包含dict的python文件形式的应用程序配置文件,我正在运行AWS lambda函数从S3获取此conf文件,更改其中的三个变量,然后将副本推回到S3。有没有简单的方法来做到这一点?一位同事说要尝试Jinja模板,但这似乎仅限于HTML文件?从另一个python文件编辑python文件的参数

由于

蟒配置文件的一个例子是下面。我需要改变 “阿尔法” 和 “循环” 变量

import zutil 
 

 
alpha = 2.13 
 
cycles = 100 
 

 

 
def my_transform(x, y, z): 
 
    v = [x, y, z] 
 
    v = zutil.rotate_vector(v, alpha, 0.0) 
 
    return {'v1': v[0], 'v2': v[1], 'v3': v[2]} 
 

 
parameters = { 
 
    # units for dimensional quantities 
 
    'units': 'SI', 
 
    # reference state 
 
    'reference': 'IC_1', 
 
    'time marching': { 
 
     'unsteady': { 
 
      'total time': 1.0, 
 
      'time step': 1.0, 
 
      'order': 'second', 
 
     }, 
 
     'scheme': { 
 
      'name': 'lu-sgs', 
 
      'stage': 1, 
 
      #'name' : 'runge kutta', 
 
      #'stage': 5, 
 
     }, 
 
     'lu-sgs': { 
 
      'Number Of SGS Cycles': 8, 
 
      'Min CFL': 0.1, 
 
      'Max CFL': 5.0, 
 
      'Include Backward Sweep': True, 
 
      'Include Relaxation': True, 
 
      'Jacobian Update Frequency': 1, 
 
      'Jacobian Epsilon': 1.0e-08, 
 
      'CFL growth': 1.05, 
 
      'Use Rusanov Flux For Jacobian': 'true', 
 
      'Finite Difference Jacobian': 'false', 
 
     }, 
 

 
     'multigrid': 10, 
 
     'cfl': 2.5, 
 
     'cfl transport': 2.5 * 0.5, 
 
     'ramp': {'initial': 1.0, 'growth': 1.1}, 
 
     'cycles': cycles, 
 
    }, 
 

 
    'equations': 'RANS', 
 

 
    'RANS': { 
 
     'order': 'euler_second', 
 
     'limiter': 'vanalbada', 
 
     'precondition': 'true', 
 
     'turbulence': { 
 
        'model': 'sst', 
 
     }, 
 
    }, 
 

 
    'material': 'air', 
 
    'air': { 
 
     'gamma': 1.4, 
 
     'gas constant': 287.0, 
 
     'Sutherlands const': 110.4, 
 
     'Prandtl No': 0.72, 
 
     'Turbulent Prandtl No': 0.9, 
 
    }, 
 
    'IC_1': { 
 
     'temperature': 310.928, 
 
     'pressure': 101325.0, 
 
     'alpha': alpha, # User defined variable used for post processing 
 
     'V': { 
 
      'vector': zutil.vector_from_angle(alpha, 0.0), 
 
      'Mach': 0.85, 
 
     }, 
 
     'Reynolds No': 5.0e6, 
 
     'Reference Length': 275.8, 
 
     'turbulence intensity': 1.e-4, 
 
     'eddy viscosity ratio': 0.1, 
 
    }, 
 
    'BC_1': { 
 
     'ref': 7, 
 
     'type': 'symmetry', 
 
    }, 
 
    'BC_2': { 
 
     'ref': 3, 
 
     'type': 'wall', 
 
     'kind': 'noslip', 
 
    }, 
 
    'BC_3': { 
 
     'ref': 9, 
 
     'type': 'farfield', 
 
     'condition': 'IC_1', 
 
     'kind': 'riemann', 
 
    }, 
 
    'write output': { 
 
     'format': 'vtk', 
 
        'surface variables': ['V', 'p', 'T', 'rho', 'walldist', 'yplus', 'mach', 'cp', 'eddy', 'pressureforce', 'frictionforce'], 
 
        'volume variables': ['V', 'p', 'T', 'rho', 'walldist', 'mach', 'cp', 'eddy'], 
 
        'frequency': 500, 
 
    }, 
 
    'report': { 
 
     'frequency': 10, 
 
     'forces': { 
 
      'FR_1': { 
 
       'name': 'wall', 
 
       'zone': [9, 10, 11, 12, 13], 
 
       'transform': my_transform, 
 
       'reference area': 594720.0 * 0.5, # half model area # half model area # half model area 
 
      }, 
 
     }, 
 
    }, 
 
}

+0

Jinja是一个模板库,它当然不仅限于HTML。但我不确定为什么你需要首先有一个模板,如果你只是从python文件中读取纯python字典。尽管对我来说,它看起来是一种处理confs的奇怪方式。你为什么不尝试使用YAML或JSON来创建一个conf文件,这样就很容易读取,操作和写回到S3。 [Here](http://docs.aws.amazon.com/lambda/latest/dg/with-s3.html)是一个使用AWS lambda从/到S3访问文件的教程。 – SRC

+0

@SRC,运行的应用程序需要Python文件作为配置的格式,我会向OP中举例说明。我想我可以读取.py,将字典转换为JSON文件,处理该文件,然后将其转储回另一个python文件。至于写给S3的阅读,我已经有了这个工作。 – Lewiky

+1

虽然这是一个糟糕的解决方案,但我强烈建议您检查一下代码/体系结构,这样您就不需要使用此解决方案,但是如果您有一个字符串(或包含少量行的文件)并且想要将其作为一个Python代码,然后你可以使用[eval](https://docs.python.org/3/library/functions.html#eval)或[exec](https://docs.python.org/3/library/ functions.html #exec) – SRC

回答

1

Jinja2的肯定能做到这一点。但如果它是值得做的是另外一个问题

我修改你的文件一点点,使其渲染由Jinja2的

import zutil 

alpha = {{ alpha | default(2.13) }} 
cycles = {{ cycles | default(100)}} 

def my_transform(x,y,z): 
    v = [x,y,z] 
    v = zutil.rotate_vector(v,alpha,0.0) 
    return {'v1' : v[0], 'v2' : v[1], 'v3' : v[2]} 

parameters = { 

# units for dimensional quantities 
'units' : 'SI', 

# reference state 
'reference' : 'IC_1', 

'time marching' : { 
        'unsteady' : { 
           'total time' : 1.0, 
           'time step' : 1.0, 
           'order' : 'second', 
           }, 
        'scheme' : { 
          'name' : 'lu-sgs', 
           'stage': 1, 
           #'name' : 'runge kutta', 
           #'stage': 5, 
           }, 
        'lu-sgs' : { 
           'Number Of SGS Cycles' : 8, 
           'Min CFL' : 0.1, 
           'Max CFL' : 5.0, 
           'Include Backward Sweep' : True, 
           'Include Relaxation' : True, 
           'Jacobian Update Frequency' : 1, 
           'Jacobian Epsilon' : 1.0e-08, 
           'CFL growth' : 1.05, 
           'Use Rusanov Flux For Jacobian' : 'true', 
           'Finite Difference Jacobian' : 'false', 
           }, 

        'multigrid' : 10, 
        'cfl': 2.5, 
        'cfl transport' : 2.5*0.5, 
        'ramp': { 'initial': 1.0, 'growth': 1.1 }, 
        'cycles' : cycles, 
        }, 

'equations' : 'RANS', 

'RANS' : { 
       'order' : 'euler_second', 
       'limiter' : 'vanalbada', 
       'precondition' : 'true',           
       'turbulence' : { 
           'model' : 'sst', 
           }, 
       }, 

'material' : 'air', 
'air' : { 
     'gamma' : 1.4, 
     'gas constant' : 287.0, 
     'Sutherlands const': 110.4, 
     'Prandtl No' : 0.72, 
     'Turbulent Prandtl No' : 0.9, 
     }, 
'IC_1' : { 
      'temperature':310.928, 
      'pressure':101325.0, 
      'alpha': alpha, # User defined variable used for post processing 
      'V': { 
       'vector' : zutil.vector_from_angle(alpha,0.0), 
       'Mach' : 0.85, 
       }, 
      'Reynolds No' : 5.0e6, 
      'Reference Length' : 275.8, 
      'turbulence intensity':1.e-4, 
      'eddy viscosity ratio':0.1, 
      }, 
'BC_1' : { 
      'ref' : 7, 
      'type' : 'symmetry', 
     }, 
'BC_2' : { 
      'ref' : 3, 
      'type' : 'wall', 
      'kind' : 'noslip', 
     }, 
'BC_3' : { 
      'ref' : 9, 
      'type' : 'farfield', 
      'condition' : 'IC_1', 
      'kind' : 'riemann', 
     }, 
'write output' : { 
        'format' : 'vtk', 
        'surface variables': ['V','p','T','rho','walldist','yplus','mach','cp','eddy','pressureforce','frictionforce'], 
        'volume variables': ['V','p','T','rho','walldist','mach','cp','eddy'], 
        'frequency' : 500, 
       },  
'report' : { 
      'frequency' : 10, 
     'forces' : { 
      'FR_1' : { 
       'name' : 'wall', 
       'zone' : [9,10,11,12,13], 
       'transform' : my_transform, 
       'reference area' : 594720.0*0.5, # half model area # half model area # half model area 
      }, 
     }, 
},      
} 

下面是如何使用Jinja2的渲染它。假设path_1是你的配置文件的路径。 PATH_2是新的配置文件的路径

from jinja2 import Environment, FileSystemLoader 

new_config_contex = {'alpha':3, 'cycles': 200} 
path, template_filename = os.path.split(path_1) 
env = Environment(loader=FileSystemLoader(path)) 
new_conf_file_content=env.get_template(template_filename).render(new_config_contex) 
with open(path_2, "wb") as f: 
    f.write(new_conf_file_content) 
+0

感谢您的建议,接受并延伸出我的回复,我张贴。 – Lewiky

0

我找到了解决办法,这不是漂亮和SRC所提到的,这是一个坏的解决方案,不应该在任何实际使用,但它的工作原理。

我从蜀黍了意见和转换我的参考control.py文件到神社模板如下所示:

import jinja2 
 
from sys import argv 
 

 
pyConf = """ 
 
import zutil 
 

 
alpha = {{alpha}} 
 
cycles = {{cycles}} 
 

 
def my_transform(x,y,z): 
 
    v = [x,y,z] 
 
    v = zutil.rotate_vector(v,alpha,0.0) 
 
    return {'v1' : v[0], 'v2' : v[1], 'v3' : v[2]} 
 

 
parameters = { 
 

 
# units for dimensional quantities 
 
'units' : 'SI', 
 

 
# reference state 
 
'reference' : 'IC_1', 
 

 
'time marching' : { 
 
        'unsteady' : { 
 
           'total time' : 1.0, 
 
           'time step' : 1.0, 
 
           'order' : 'second', 
 
           }, 
 
        'scheme' : { 
 
          'name' : 'lu-sgs', 
 
           'stage': 1, 
 
           #'name' : 'runge kutta', 
 
           #'stage': 5, 
 
           }, 
 
        'lu-sgs' : { 
 
           'Number Of SGS Cycles' : 8, 
 
           'Min CFL' : 0.1, 
 
           'Max CFL' : 5.0, 
 
           'Include Backward Sweep' : True, 
 
           'Include Relaxation' : True, 
 
           'Jacobian Update Frequency' : 1, 
 
           'Jacobian Epsilon' : 1.0e-08, 
 
           'CFL growth' : 1.05, 
 
           'Use Rusanov Flux For Jacobian' : 'true', 
 
           'Finite Difference Jacobian' : 'false', 
 
           }, 
 

 
        'multigrid' : 10, 
 
        'cfl': 2.5, 
 
        'cfl transport' : 2.5*0.5, 
 
        'ramp': { 'initial': 1.0, 'growth': 1.1 }, 
 
        'cycles' : cycles, 
 
        }, 
 

 
'equations' : 'RANS', 
 

 
'RANS' : { 
 
       'order' : 'euler_second', 
 
       'limiter' : 'vanalbada', 
 
       'precondition' : 'true', 
 
       'turbulence' : { 
 
           'model' : 'sst', 
 
           }, 
 
       }, 
 

 
'material' : 'air', 
 
'air' : { 
 
     'gamma' : 1.4, 
 
     'gas constant' : 287.0, 
 
     'Sutherlands const': 110.4, 
 
     'Prandtl No' : 0.72, 
 
     'Turbulent Prandtl No' : 0.9, 
 
     }, 
 
'IC_1' : { 
 
      'temperature':310.928, 
 
      'pressure':101325.0, 
 
      'alpha': alpha, # User defined variable used for post processing 
 
      'V': { 
 
       'vector' : zutil.vector_from_angle(alpha,0.0), 
 
       'Mach' : 0.85, 
 
       }, 
 
      'Reynolds No' : 5.0e6, 
 
      'Reference Length' : 275.8, 
 
      'turbulence intensity':1.e-4, 
 
      'eddy viscosity ratio':0.1, 
 
      }, 
 
'BC_1' : { 
 
      'ref' : 7, 
 
      'type' : 'symmetry', 
 
     }, 
 
'BC_2' : { 
 
      'ref' : 3, 
 
      'type' : 'wall', 
 
      'kind' : 'noslip', 
 
     }, 
 
'BC_3' : { 
 
      'ref' : 9, 
 
      'type' : 'farfield', 
 
      'condition' : 'IC_1', 
 
      'kind' : 'riemann', 
 
     }, 
 
'write output' : { 
 
        'format' : 'vtk', 
 
        'surface variables': ['V','p','T','rho','walldist','yplus','mach','cp','eddy','pressureforce','frictionforce'], 
 
        'volume variables': ['V','p','T','rho','walldist','mach','cp','eddy'], 
 
        'frequency' : 500, 
 
       }, 
 
'report' : { 
 
      'frequency' : 10, 
 
     'forces' : { 
 
      'FR_1' : { 
 
       'name' : 'wall', 
 
       'zone' : [9,10,11,12,13], 
 
       'transform' : my_transform, 
 
       'reference area' : 594720.0*0.5, # half model area # half model area # half model area 
 
      }, 
 
     }, 
 
}, 
 
} 
 
""" 
 
template = jinja2.Template(pyConf) 
 
print template.render(alpha = argv[1], cycles = argv[2])

然后我修改了我的lambda函数,让这个模板,执行它,它将现在呈现的控制文件打印到stdio中,在lambda函数中,我已将stdio重定向到了我的exec函数,在那里我可以捕获它并将其流式传输到S3对象中,然后再将它们推回到S3。

import boto3 
 
import jinja2 
 
import sys 
 
import StringIO 
 
import contextlib 
 

 
@contextlib.contextmanager 
 
def stdoutIO(stdout=None): 
 
    old = sys.stdout 
 
    if stdout is None: 
 
     stdout = StringIO.StringIO() 
 
    sys.stdout = stdout 
 
    yield stdout 
 
    sys.stdout = old 
 

 
s3 = boto3.resource('s3') 
 

 
def main(json_input, context): 
 
    client = boto3.client('s3') 
 
    body = client.get_object(Bucket = "cfdworkflow2", Key='Control/control.py').get('Body').read() 
 
    c_body = convertBody(body) 
 
    s3.Object('cfdworkflow2', 'Control/parsedControl.py').put(Body=c_body) 
 

 
def convertBody(body): 
 
    sys.argv = ['','3','100'] 
 
    with stdoutIO() as s: 
 
     exec(body) 
 
    return s.getvalue()

发现重定向标准输入输出here

为了延长我会通过标准输入到lambda函数作为参数传递到神社模板的想法。

相关问题