2017-06-20 6 views
0

Ich habe eine Konfigurationsdatei für eine Anwendung in Form einer Python-Datei mit einem dict und ich führe eine AWS Lambda-Funktion, um diese Conf-Datei von S3 zu bekommen, Ändere drei Variablen darin und schiebe dann eine Kopie zurück nach S3. Gibt es einen einfachen Weg, dies zu tun? Ein Mitarbeiter sagte, er solle Jinja Templating ausprobieren, aber das scheint nur auf HTML-Dateien beschränkt zu sein.Bearbeiten von Parametern in einer Python-Datei aus einer anderen Python-Datei

Dank

Ein Beispiel für die Datei Python Config ist unten. Ich brauche das "Alpha" und "Zyklen" Variablen

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 ist eine Vorlagenbibliothek und es ist sicherlich nicht nur auf HTML beschränkt. Aber ich bin mir nicht sicher, warum Sie eine Vorlage in erster Linie benötigen, wenn alles, was Sie lesen, reines Python-Diktat aus einer Python-Datei ist. Obwohl es für mich eine seltsame Art ist, mit confs umzugehen. Warum versuchen Sie nicht, eine conf-Datei in YAML oder JSON zu haben und auf diese Weise einfach zu lesen, zu manipulieren und zurück zu S3 zu schreiben. [Hier] (http://docs.aws.amazon.com/lambda/latest/dg/with-s3.html) ist ein Tutorial, um mit AWS lambda auf Dateien von/nach S3 zuzugreifen. – SRC

+0

@SRC, Die Anwendung läuft die Python-Datei als das Format der Konfig, ich werde ein Beispiel in das OP werfen. Ich nehme an, ich könnte das .py lesen, das dict in eine JSON-Datei schreiben, diese verarbeiten und dann in eine andere Python-Datei zurückgeben. Was das Lesen von S3 angeht, habe ich das schon funktioniert. – Lewiky

+1

Obwohl dies eine schreckliche und schlechte Lösung ist, empfehle ich dringend, dass Sie Ihren Code/Ihre Architektur überprüfen, damit Sie diese Lösung nicht verwenden müssen, aber wenn Sie eine Zeichenfolge (oder eine Datei mit wenigen Zeilen) haben und diese ausführen möchten Ein Python-Code kann dann mit [eval] (https://docs.python.org/3/library/functions.html#eval) oder [exec] (https://docs.python.org/3/library/ functions.html # exec) – SRC

Antwort

1

Jinja2 kann es sicherlich ändern tun. aber wenn es sich lohnt Frage zu tun, ist eine andere

ich ändern Sie die Dateien ein wenig zu machen darstellbaren von 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 
      }, 
     }, 
},      
} 

Hier ist, wie es zu machen jinja2 verwenden. Angenommen, der Pfad_1 ist der Pfad Ihrer Konfigurationsdatei. path_2 ist der Weg der neuen Config-Datei

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

Danke für den Rat, nahm es und erweiterte wie in meiner Antwort ich gepostet. – Lewiky

0

ich eine Lösung gefunden, ist es nicht schön ist und wie SRC erwähnt, ist es eine schlechte Lösung, die nicht in etwas Reales verwendet werden sollte, aber es funktioniert.

Ich nahm Rat von milo und konvertiert meine Referenz control.py Datei in eine Vorlage Jinja wie hier gezeigt:

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])

Dann geändert ich Funktion meine Lambda, diese Vorlage zu erhalten, führe es aus, was die jetzt gerenderte Steuerdatei nach stdio druckt, wo ich in der Lambda-Funktion das stdio für meine exec-Funktion umgeleitet habe, wo ich es abfangen und in ein S3-Objekt streamen kann, das dann zurück nach S3 geschoben wird.

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()

die Idee der Umleitung des stdio here

gefunden

ich durch die stdin an die Lambda-Funktion als Parameter an die jinja Vorlage passieren verlängern werde.

Verwandte Themen