| 1337 | | |
| 1338 | | == Download and installing == |
| 1339 | | |
| 1340 | | Check it out from the SVN repository http://svn.pyyaml.org/pyyaml/trunk. |
| 1341 | | |
| 1342 | | Install it by running |
| 1343 | | {{{ |
| 1344 | | $ python setup.py install |
| 1345 | | }}} |
| 1346 | | |
| 1347 | | |
| 1348 | | == High-level API == |
| 1349 | | |
| 1350 | | '''Warning: API is not stable and may change in the future''' |
| 1351 | | |
| 1352 | | === Basic examples === |
| 1353 | | |
| 1354 | | Start with importing the package: |
| 1355 | | {{{ |
| 1356 | | #!python |
| 1357 | | >>> import yaml |
| 1358 | | }}} |
| 1359 | | |
| 1360 | | Define the input data: |
| 1361 | | {{{ |
| 1362 | | #!python |
| 1363 | | >>> data = """ |
| 1364 | | ... - YAML |
| 1365 | | ... - is |
| 1366 | | ... - fun! |
| 1367 | | ... """ |
| 1368 | | }}} |
| 1369 | | The parser accepts string objects, unicode objects, open file objects, and unicode file objects. |
| 1370 | | |
| 1371 | | Now convert it to a native Python object: |
| 1372 | | {{{ |
| 1373 | | >>> yaml.load(data) |
| 1374 | | ['YAML', 'is', 'fun!'] |
| 1375 | | }}} |
| 1376 | | |
| 1377 | | Conversely, you may convert a Python object into a YAML document: |
| 1378 | | {{{ |
| 1379 | | >>> print yaml.dump(['YAML', 'is', 'fun!']) |
| 1380 | | - YAML |
| 1381 | | - is |
| 1382 | | - fun! |
| 1383 | | }}} |
| 1384 | | |
| 1385 | | PyYAML 3000 supports many of the types defined in the YAML tags repository: |
| 1386 | | {{{ |
| 1387 | | >>> data = """ |
| 1388 | | ... - ~ |
| 1389 | | ... - true |
| 1390 | | ... - 3_141_592.653e-6 |
| 1391 | | ... - 3000 |
| 1392 | | ... - PyYAML3000 birthday: 2006-02-11 |
| 1393 | | ... - primes (sort of): !!set { 2, 3, 5, 7, 11, 13 } |
| 1394 | | ... - pairs: !!pairs [1: 2, 3: 4, 5: 6] |
| 1395 | | ... """ |
| 1396 | | >>> for x in yaml.load(data): print x |
| 1397 | | None |
| 1398 | | True |
| 1399 | | 3.141592653 |
| 1400 | | 3000 |
| 1401 | | {'PyYAML3000 birthday': datetime.datetime(2006, 2, 11, 0, 0)} |
| 1402 | | {'primes (sort of)': set([2, 3, 5, 7, 11, 13])} |
| 1403 | | {'pairs': [(1, 2), (3, 4), (5, 6)]} |
| 1404 | | >>> print yaml.dump([None, True, False, 123, 123.456, 'a string', |
| 1405 | | ... {'a': 'dictionary'}, ['a', 'list']]) |
| 1406 | | - null |
| 1407 | | - true |
| 1408 | | - false |
| 1409 | | - 123 |
| 1410 | | - 123.456 |
| 1411 | | - a string |
| 1412 | | - a: dictionary |
| 1413 | | - - a |
| 1414 | | - list |
| 1415 | | }}} |
| 1416 | | |
| 1417 | | The following tags are supported: '''!!map''', '''!!omap''', '''!!pairs''', |
| 1418 | | '''!!set''', '''!!seq''', '''!!binary''', '''!!bool''', '''!!float''', |
| 1419 | | '''!!int''', '''!!merge''', '''!!null''', '''!!str''', '''!!timestamp''', |
| 1420 | | '''!!value'''. |
| 1421 | | |
| 1422 | | === Defining custom tags === |
| 1423 | | |
| 1424 | | You may define constructors for your own application-specific tags. You may use |
| 1425 | | either the function '''yaml.add_constructor''' or subclass from '''yaml.YAMLObject'''. |
| 1426 | | |
| 1427 | | Instances of '''yaml.YAMLObject''' are automatically serialized to YAML and vice versa. |
| 1428 | | You only need to define the YAML tag with the '''yaml_tag''' variable. |
| 1429 | | {{{ |
| 1430 | | #!python |
| 1431 | | class Person(yaml.YAMLObject): |
| 1432 | | yaml_tag = '!Person' |
| 1433 | | def __init__(self, first_name=None, last_name=None, email=None, birthday=None): |
| 1434 | | self.first_name = first_name |
| 1435 | | self.last_name = last_name |
| 1436 | | self.email = email |
| 1437 | | self.birthday = birthday |
| 1438 | | def __repr__(self): |
| 1439 | | return "%s(first_name=%r, last_name=%r, email=%r, birthday=%r)" \ |
| 1440 | | % (self.__class__.__name__, self.first_name, self.last_name, |
| 1441 | | self.email, self.birthday) |
| 1442 | | }}} |
| 1443 | | |
| 1444 | | {{{ |
| 1445 | | #!python |
| 1446 | | >>> p = yaml.load(""" |
| 1447 | | ... !Person |
| 1448 | | ... first_name: Kirill |
| 1449 | | ... last_name: Simonov |
| 1450 | | ... email: xi(at)resolvent.net |
| 1451 | | ... birthday: null |
| 1452 | | ... """) |
| 1453 | | >>> print p |
| 1454 | | Person(first_name='Kirill', last_name='Simonov', email='xi(at)resolvent.net', birthday=None) |
| 1455 | | >>> print yaml.dump(p) |
| 1456 | | !Person |
| 1457 | | last_name: Simonov |
| 1458 | | first_name: Kirill |
| 1459 | | email: xi(at)resolvent.net |
| 1460 | | birthday: null |
| 1461 | | }}} |
| 1462 | | |
| 1463 | | If you don't want to use metaclass magic, you may define the constructor |
| 1464 | | and representer as functions and register them: |
| 1465 | | {{{ |
| 1466 | | #!python |
| 1467 | | def construct_person(constructor, node): |
| 1468 | | # ... |
| 1469 | | def represent_person(representer, person): |
| 1470 | | # ... |
| 1471 | | yaml.add_constructor('!Person', construct_person) |
| 1472 | | yaml.add_representer(Person, represent_person) |
| 1473 | | }}} |
| 1474 | | |
| 1475 | | === Parsing and emitting multiple documents in a stream === |
| 1476 | | |
| 1477 | | If an input stream contains several documents, you may load all of them using the '''yaml.load_all''' function. |
| 1478 | | {{{ |
| 1479 | | #!python |
| 1480 | | >>> data = """ |
| 1481 | | ... This is the first document |
| 1482 | | ... --- # This is an empty document |
| 1483 | | ... --- |
| 1484 | | ... - this |
| 1485 | | ... - is: the |
| 1486 | | ... last: document |
| 1487 | | ... """ |
| 1488 | | >>> for document in yaml.load_all(data): print document |
| 1489 | | This is the first document |
| 1490 | | None |
| 1491 | | ['this', {'is': 'the', 'last': 'document'}] |
| 1492 | | }}} |
| 1493 | | |
| 1494 | | You may also dump several documents into the same stream using the '''yaml.dump_all''' function. |
| 1495 | | {{{ |
| 1496 | | #!python |
| 1497 | | >>> print yaml.dump_all(["The first document", None, ["The", "last", "document"]]) |
| 1498 | | The first document |
| 1499 | | --- null |
| 1500 | | --- |
| 1501 | | - The |
| 1502 | | - last |
| 1503 | | - document |
| 1504 | | }}} |
| 1505 | | |
| 1506 | | There are more features, check the source to find out. |
| 1507 | | |
| 1508 | | |
| 1509 | | == Low-level API == |
| 1510 | | |
| 1511 | | PyYAML 3000 provides low-level event-based and easy-to-use parser and emitter API. |
| 1512 | | |
| 1513 | | Example: |
| 1514 | | {{{ |
| 1515 | | #!python |
| 1516 | | >>> data = """ |
| 1517 | | ... --- !tag |
| 1518 | | ... scalar |
| 1519 | | ... --- |
| 1520 | | ... - &anchor item |
| 1521 | | ... - another item |
| 1522 | | ... - *anchor |
| 1523 | | ... --- |
| 1524 | | ... key: value |
| 1525 | | ... ? - complex |
| 1526 | | ... - key |
| 1527 | | ... : - complex |
| 1528 | | ... - value |
| 1529 | | ... """ |
| 1530 | | >>> for event in yaml.parse(data): print event |
| 1531 | | StreamStartEvent() |
| 1532 | | DocumentStartEvent() |
| 1533 | | ScalarEvent(anchor=None, tag=u'!tag', implicit=(False, False), value=u'scalar') |
| 1534 | | DocumentEndEvent() |
| 1535 | | DocumentStartEvent() |
| 1536 | | SequenceStartEvent(anchor=None, tag=None, implicit=True) |
| 1537 | | ScalarEvent(anchor=u'anchor', tag=None, implicit=(True, False), value=u'item') |
| 1538 | | ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'another item') |
| 1539 | | AliasEvent(anchor=u'anchor') |
| 1540 | | SequenceEndEvent() |
| 1541 | | DocumentEndEvent() |
| 1542 | | DocumentStartEvent() |
| 1543 | | MappingStartEvent(anchor=None, tag=None, implicit=True) |
| 1544 | | ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'key') |
| 1545 | | ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'value') |
| 1546 | | SequenceStartEvent(anchor=None, tag=None, implicit=True) |
| 1547 | | ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'complex') |
| 1548 | | ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'key') |
| 1549 | | SequenceEndEvent() |
| 1550 | | SequenceStartEvent(anchor=None, tag=None, implicit=True) |
| 1551 | | ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'complex') |
| 1552 | | ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'value') |
| 1553 | | SequenceEndEvent() |
| 1554 | | MappingEndEvent() |
| 1555 | | DocumentEndEvent() |
| 1556 | | StreamEndEvent() |
| 1557 | | >>> events = [ |
| 1558 | | ... yaml.StreamStartEvent(encoding='utf-8'), |
| 1559 | | ... yaml.DocumentStartEvent(explicit=True), |
| 1560 | | ... yaml.MappingStartEvent(anchor=None, tag=None, implicit=True), |
| 1561 | | ... yaml.ScalarEvent(anchor=None, tag=None, value=u'flow sequence', implicit=(True, True)), |
| 1562 | | ... yaml.SequenceStartEvent(anchor=None, tag=None, flow_style=True, implicit=True), |
| 1563 | | ... yaml.ScalarEvent(anchor=None, tag=None, value=u'123', implicit=(True, False)), |
| 1564 | | ... yaml.ScalarEvent(anchor=None, tag=None, value=u'456', implicit=(True, False)), |
| 1565 | | ... yaml.SequenceEndEvent(), |
| 1566 | | ... yaml.ScalarEvent(anchor=None, tag=None, value=u'block scalar', implicit=(True, True)), |
| 1567 | | ... yaml.ScalarEvent(anchor=None, tag=None, value=u'YAML\nis\nfun!\n', style='|', implicit=(True, True)), |
| 1568 | | ... yaml.MappingEndEvent(), |
| 1569 | | ... yaml.DocumentEndEvent(explicit=True), |
| 1570 | | ... yaml.StreamEndEvent(), |
| 1571 | | ... ] |
| 1572 | | |
| 1573 | | >>> print yaml.emit(events) |
| 1574 | | --- |
| 1575 | | flow sequence: [123, 456] |
| 1576 | | block scalar: | |
| 1577 | | YAML |
| 1578 | | is |
| 1579 | | fun! |
| 1580 | | ... |
| 1581 | | }}} |
| 1582 | | |
| 1583 | | |
| 1584 | | == To Do == |
| 1585 | | |
| 1586 | | Long-term goals: |
| 1587 | | * fix tabs, i~~ndentation for flow collections, indentation for scalars (min=1?), 'y' is '''!!bool'''~~, |
| 1588 | | * libyaml3000 |
| 1589 | | |
| 1590 | | == Deviations from the specification == |
| | 1337 | ''need to update this section'' |