2017-07-10 2 views
2

ich eine mehrzeilige Zeichenfolge haben:yaml.dump Zugabe unerwünschte Zeilenumbrüche in mehrzeiligen Strings

>>> import credstash 
>>> d = credstash.getSecret('alex_test_key', region='ap-southeast-2') 

Um die Rohdaten zu sehen (erste 162 Zeichen):

>>> credstash.getSecret('alex_test_key', region='ap-southeast-2')[0:162] 
u'-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx\nxk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45\n' 

Und:

>>> print d[0:162]                                               
-----BEGIN RSA PRIVATE KEY----- 
MIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx 
xk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45 

Ich schreibe in eine YAML-Datei:

>>> import yaml 
>>> with open('foo.yaml', 'w') as f:                                           
...  yaml.dump(d, f, default_flow_style=False, explicit_start=True) 
... 

Jetzt sieht es wie folgt aus:

$ head -5 foo.yaml 
--- !!python/unicode '-----BEGIN RSA PRIVATE KEY----- 

    MIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx 

    xk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45 

das heißt jede Zeile zwei Zeilenumbrüche hat.

Nun, wenn ich es zurück in einen String gelesen Ich sehe, dass alle in dem Round-Trip in Ordnung sind: (. Ich verstehe nicht, warum aber)

>>> with open('foo.yaml', 'r') as f: 
...  d = yaml.load(f) 
... 
>>> print d[0:162] 
-----BEGIN RSA PRIVATE KEY----- 
MIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx 
xk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45 

Mein wirkliches Problem ist, Wenn Menschen diese YAML-Datei lesen, nehmen sie wahrscheinlich an, dass mein Programm die Formatierung der privaten Schlüsseldatei durchbrochen hat.

Gibt es eine Möglichkeit, yaml.dump zu verwenden, um etwas ohne die zusätzlichen Zeilenvorschubzeichen auszugeben?

Antwort

1

Wenn das die einzige Sache ist, die in Ihre YAML Akte geht, dann können Sie mit der Option default_style='|' dumpen, die Ihnen Blockartliteral für alle Ihre Skalare gibt (vermutlich nicht, was Sie wünschen).

Ihre Zeichenfolge, enthält keine Sonderzeichen (die \ Escaping und doppelte Anführungszeichen benötigen), wegen der Zeilenumbruch PyYAML beschließt, einzelne zitiert darzustellen. Im einfachen Anführungszeichen ist eine doppelte Zeilenschaltung die Art, eine einzelne neue Zeile darzustellen, die in der dargestellten Zeichenfolge aufgetreten ist. Dies wird beim Laden "rückgängig gemacht", ist aber in der Tat nicht gut lesbar.

Wenn Sie den Block-Stil Literale auf individueller Basis erhalten mögen, können Sie mehrere Dinge tun:

  • passen die Representer zur Ausgabe alle Strings mit eingebetteten Zeilenumbrüchen des wörtlichen skalare Blockstil mit (vorausgesetzt, sie braucht nicht \ Flucht von Sonderzeichen, die doppelten Anführungszeichen zwingen wird)

    import sys 
    import yaml 
    
    x = u"""\ 
    -----BEGIN RSA PRIVATE KEY----- 
    MIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx 
    xk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45 
    ... 
    """ 
    
    yaml.SafeDumper.org_represent_str = yaml.SafeDumper.represent_str 
    
    def repr_str(dumper, data): 
        if '\n' in data: 
         return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='|') 
        return dumper.org_represent_str(data) 
    
    yaml.add_representer(str, repr_str, Dumper=yaml.SafeDumper) 
    
    yaml.safe_dump(dict(a=1, b='hello world', c=x), sys.stdout) 
    
  • eine Unterklasse von String machen, das seinen besonderen Representer hat.

    import sys 
    import yaml 
    
    class PSS(str): 
        pass 
    
    x = PSS("""\ 
    -----BEGIN RSA PRIVATE KEY----- 
    MIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx 
    xk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45 
    ... 
    """) 
    
    def pss_representer(dumper, data): 
         tag = None 
         style = '|' 
         # if sys.versioninfo < (3,) and not isinstance(data, unicode): 
         #  data = unicode(data, 'ascii') 
         tag = u'tag:yaml.org,2002:str' 
         return dumper.represent_scalar(tag, data, style=style) 
    
    yaml.add_representer(PSS, pss_representer, Dumper=yaml.SafeDumper) 
    
    yaml.safe_dump(dict(a=1, b='hello world', c=x), sys.stdout) 
    
  • Verwendung ruamel.yaml:

    import sys 
    from ruamel.yaml import YAML 
    from ruamel.yaml.scalarstring import PreservedScalarString as pss 
    
    x = pss("""\ 
    -----BEGIN RSA PRIVATE KEY----- 
    MIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx 
    xk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45 
    ... 
    """) 
    
    yaml = YAML() 
    
    yaml.dump(dict(a=1, b='hello world', c=x), sys.stdout) 
    

Alle diese geben:

a: 1 
b: hello world 
c: | 
    -----BEGIN RSA PRIVATE KEY----- 
    MIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx 
    xk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45 
    ... 

Sie sollten den Code für das von here, here und here nehmen können Bitte beachten Sie, dass dies nicht erforderlich ist default_flow_style=False als literale Skalare können nur im Blockstil angezeigt werden.

0

Hinzufügen Anthon Antwort, fand ich einige Dokumentation für andere Optionen, die ich an default_style unter diesem Link here übergeben kann.

Der beste Kompromiss ich für die Darstellung all meiner Daten finden konnte, war:

with open('foo.yaml', 'w') as f: 
    yaml.safe_dump(secrets, f, explicit_start=True, default_style='\"', width=4096) 

Und dies führte zu einer YAML-Datei, die wie folgt aussieht:

--- 
"alex_test": "yyyyyyyy" 
"alex_test_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA6oySC+8/N9VNpk0gJS7Gk8vn9sYN7FhjpAQnoHRqTN/Oaiyx\nxk2AleP2vXpojA/DHldT1JO+o3j56AHD+yfNFFeYvgWKDY35g49HsZZhbyCEAB45\ni6LLqO6aixyhvabSy7r1bP8QBrHWUIEZRerrw0TlhuKHDoFpmRAjAAIZ/5q9PSxg\n1yCwTVMlMvBiRksPsKi0fcA/v8G+yqFBL7IeaNCPSoa/3ZdgPWbh9P69DyOlB97a\nh1+0Jmh1gtAhyiz1/hmiN7LAclKHyOOnTEEyIMJioZqJURshKdF85RKILgw2X8Lp\n78mO5VyvvGxo3BNjVr0BOrSJ3t17ugijROx3HwIBIwKCAQAUGq1uvLxGnUErgvQg\ncbk/3kcVJutAJNVXM45eNd05ygpg30JwFUWJMMwBnMch8rjz+NtMvDTpcMT2oRDM\nYn9K4u/VxfXj55kLRsuhgesYJ1vFfu79VxjFVkfCx/CbOi9TSooQqCXx8fxtTOTo\nvF1Z4VWAlxLj/HbD+hGg6jy+Iwq/8HWsHN/VFPqhNqdKvzXGOtyynSZBOUf7upMX\nPh4REE4hYMZwdDnl+NRNmm8XA9TOE+Uf8WLDooKcXjp70CES0ehiC+VD0wG5JEVQ\nbZmDTdBxPcQsO31sNwRwUIX0J4K4Z9npa3dJdRqXJuof48RLzSGwM42eJzmTRNSw\n6I77AoGBAP9LO2A2ZAD7LJBKe48GE8wzkgaQd9vc3RImwrMAXPMVP9wdKR4m/X73\ngWxQ1QbueTtBRaNwkF8l9+Iham3H3kAbBONsbvJIO9Co0n1k+S9mutO1ZWfTMWZp\nIfMz2lncLonxXCXnDndzXtTjcqHeZFmSmDZZZugPXYWtC5N2ic3pAoGBAOsypk5z\na9FG3H46TIjYKyV0Z/R0Hvrp8w+AXdogKyHh0nj9Sevr+JMgOR4ayqYUKGG3sRtM\nzyoWCJ+Wb7Rd0olc2SeouQYSzk2wFKvnnq5o0Q8YZIYkiQN82FXoN2jcELdcVdW6\n1VJuUk9K3nDe+Gz6dkHZnthFC6usL15pHs/HAoGBAIqWjfJmq1D9YVWkxrtbEg/E\nOVQFSGFpRM9W3rjxkYtGDLlRqJtW/qQCs/j4rihVkkS9CIvspiUF+5gDgusjW2Sg\n9AZuEFejji9xltZbYrNVBlWrnXLgXKVPA80qxv2UyM6KVpg7miOWZq4VElffIIhl\nhdRcaxBC2v9skUFsPC3zAoGBAN3CCoR7dEj5q1Jxe1x0C2x1EY62oN3yhhXuD1ih\n/MgssIC0TQMDDvEeYb1Mde0LsQutMfUrKbn3hHk2EYzNfVzxJIR6gpCypUHvKW7h\nst71HOJY087vP1sPT6F0jAPILQSnhCFJwdFgtAGeXLOQZpKjAckPA3t0TNUQD2ek\n8SpNAoGAfQrNfepCTbc/9BCv/sJLLMEdlB/PyzenucBeXKfsfSU6+hYM14+gLp7+\nmOgoaM7F4UkqzJTRDQJnYo1NowRHjs0xHJoQoXzlV43ZkCmTwKtZ/9APLi060Md1\n+fDJX+yvxnZsY5hw6cYwC3C/axS9jq63oQ7i8FXwG/a0breCGu8=\n-----END RSA PRIVATE KEY-----" 

ich bevorzugt hätte ruamel zu verwenden .yaml, aber dieser Code muss in einer Umgebung ausgeführt werden, in der ich nur die Standard-Python-Pakete verwenden kann, die ich zur Verfügung habe.

+1

Auch Code hinzugefügt, wie dies in PyYAML für die erste Option zu tun ist. Fertig aktualisiert, zurück zur Arbeit. – Anthon

+1

Nun, vielen Dank noch einmal - das ist eine wirklich gute Referenz für die nächste Person, die dieses Problem lösen muss. –

Verwandte Themen