vdf


Namevdf JSON
Version 3.4 PyPI version JSON
download
home_pagehttps://github.com/ValvePython/vdf
SummaryLibrary for working with Valve's VDF text format
upload_time2021-05-22 09:26:05
maintainer
docs_urlNone
authorRossen Georgiev
requires_python
licenseMIT
keywords valve keyvalue vdf tf2 dota2 csgo
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            | |pypi| |license| |coverage| |master_build|
| |sonar_maintainability| |sonar_reliability| |sonar_security|

Pure python module for (de)serialization to and from VDF that works just like ``json``.

Tested and works on ``py2.7``, ``py3.3+``, ``pypy`` and ``pypy3``.

VDF is Valve's KeyValue text file format

https://developer.valvesoftware.com/wiki/KeyValues

| Supported versions: ``kv1``
| Unsupported: ``kv2`` and ``kv3``

Install
-------

You can grab the latest release from https://pypi.org/project/vdf/ or via ``pip``

.. code:: bash

    pip install vdf

Install the current dev version from ``github``

.. code:: bash

    pip install git+https://github.com/ValvePython/vdf


Problems & solutions
--------------------

- There are known files that contain duplicate keys. This is supported the format and
  makes mapping to ``dict`` impossible. For this case the module provides ``vdf.VDFDict``
  that can be used as mapper instead of ``dict``. See the example section for details.

- By default de-serialization will return a ``dict``, which doesn't preserve nor guarantee
  key order on Python versions prior to 3.6, due to `hash randomization`_. If key order is
  important on old Pythons, I suggest using ``collections.OrderedDict``, or ``vdf.VDFDict``.

Example usage
-------------

For text representation

.. code:: python

    import vdf

    # parsing vdf from file or string
    d = vdf.load(open('file.txt'))
    d = vdf.loads(vdf_text)
    d = vdf.parse(open('file.txt'))
    d = vdf.parse(vdf_text)

    # dumping dict as vdf to string
    vdf_text = vdf.dumps(d)
    indented_vdf = vdf.dumps(d, pretty=True)

    # dumping dict as vdf to file
    vdf.dump(d, open('file2.txt','w'), pretty=True)


For binary representation

.. code:: python

    d = vdf.binary_loads(vdf_bytes)
    b = vdf.binary_dumps(d)

    # alternative format - VBKV

    d = vdf.binary_loads(vdf_bytes, alt_format=True)
    b = vdf.binary_dumps(d, alt_format=True)

    # VBKV with header and CRC checking

    d = vdf.vbkv_loads(vbkv_bytes)
    b = vdf.vbkv_dumps(d)

Using an alternative mapper

.. code:: python

  d = vdf.loads(vdf_string, mapper=collections.OrderedDict)
  d = vdf.loads(vdf_string, mapper=vdf.VDFDict)

``VDFDict`` works much like the regular ``dict``, except it handles duplicates and remembers
insert order. Additionally, keys can only be of type ``str``. The most important difference
is that when trying to assigning a key that already exist it will create a duplicate instead
of reassign the value to the existing key.

.. code:: python

  >>> d = vdf.VDFDict()
  >>> d['key'] = 111
  >>> d['key'] = 222
  >>> d
  VDFDict([('key', 111), ('key', 222)])
  >>> d.items()
  [('key', 111), ('key', 222)]
  >>> d['key']
  111
  >>> d[(0, 'key')]  # get the first duplicate
  111
  >>> d[(1, 'key')]  # get the second duplicate
  222
  >>> d.get_all_for('key')
  [111, 222]

  >>> d[(1, 'key')] = 123  # reassign specific duplicate
  >>> d.get_all_for('key')
  [111, 123]

  >>> d['key'] = 333
  >>> d.get_all_for('key')
  [111, 123, 333]
  >>> del d[(1, 'key')]
  >>> d.get_all_for('key')
  [111, 333]
  >>> d[(1, 'key')]
  333

  >>> print vdf.dumps(d)
  "key" "111"
  "key" "333"

  >>> d.has_duplicates()
  True
  >>> d.remove_all_for('key')
  >>> len(d)
  0
  >>> d.has_duplicates()
  False


.. |pypi| image:: https://img.shields.io/pypi/v/vdf.svg?style=flat&label=latest%20version
    :target: https://pypi.org/project/vdf/
    :alt: Latest version released on PyPi

.. |license| image:: https://img.shields.io/pypi/l/vdf.svg?style=flat&label=license
    :target: https://pypi.org/project/vdf/
    :alt: MIT License

.. |coverage| image:: https://img.shields.io/coveralls/ValvePython/vdf/master.svg?style=flat
    :target: https://coveralls.io/r/ValvePython/vdf?branch=master
    :alt: Test coverage

.. |sonar_maintainability| image:: https://sonarcloud.io/api/project_badges/measure?project=ValvePython_vdf&metric=sqale_rating
    :target: https://sonarcloud.io/dashboard?id=ValvePython_vdf
    :alt: SonarCloud Rating

.. |sonar_reliability| image:: https://sonarcloud.io/api/project_badges/measure?project=ValvePython_vdf&metric=reliability_rating
    :target: https://sonarcloud.io/dashboard?id=ValvePython_vdf
    :alt: SonarCloud Rating

.. |sonar_security| image:: https://sonarcloud.io/api/project_badges/measure?project=ValvePython_vdf&metric=security_rating
    :target: https://sonarcloud.io/dashboard?id=ValvePython_vdf
    :alt: SonarCloud Rating

.. |master_build| image:: https://github.com/ValvePython/vdf/workflows/Tests/badge.svg?branch=master
    :target: https://github.com/ValvePython/vdf/actions?query=workflow%3A%22Tests%22+branch%3Amaster
    :alt: Build status of master branch

.. _DuplicateOrderedDict: https://github.com/rossengeorgiev/dota2_notebooks/blob/master/DuplicateOrderedDict_for_VDF.ipynb

.. _hash randomization: https://docs.python.org/2/using/cmdline.html#envvar-PYTHONHASHSEED



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ValvePython/vdf",
    "name": "vdf",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "valve keyvalue vdf tf2 dota2 csgo",
    "author": "Rossen Georgiev",
    "author_email": "rossen@rgp.io",
    "download_url": "https://files.pythonhosted.org/packages/44/7f/74192f47d67c8bf3c47bf0d8487b3457614c2c98d58b6617721d217f3f79/vdf-3.4.tar.gz",
    "platform": "",
    "description": "| |pypi| |license| |coverage| |master_build|\n| |sonar_maintainability| |sonar_reliability| |sonar_security|\n\nPure python module for (de)serialization to and from VDF that works just like ``json``.\n\nTested and works on ``py2.7``, ``py3.3+``, ``pypy`` and ``pypy3``.\n\nVDF is Valve's KeyValue text file format\n\nhttps://developer.valvesoftware.com/wiki/KeyValues\n\n| Supported versions: ``kv1``\n| Unsupported: ``kv2`` and ``kv3``\n\nInstall\n-------\n\nYou can grab the latest release from https://pypi.org/project/vdf/ or via ``pip``\n\n.. code:: bash\n\n    pip install vdf\n\nInstall the current dev version from ``github``\n\n.. code:: bash\n\n    pip install git+https://github.com/ValvePython/vdf\n\n\nProblems & solutions\n--------------------\n\n- There are known files that contain duplicate keys. This is supported the format and\n  makes mapping to ``dict`` impossible. For this case the module provides ``vdf.VDFDict``\n  that can be used as mapper instead of ``dict``. See the example section for details.\n\n- By default de-serialization will return a ``dict``, which doesn't preserve nor guarantee\n  key order on Python versions prior to 3.6, due to `hash randomization`_. If key order is\n  important on old Pythons, I suggest using ``collections.OrderedDict``, or ``vdf.VDFDict``.\n\nExample usage\n-------------\n\nFor text representation\n\n.. code:: python\n\n    import vdf\n\n    # parsing vdf from file or string\n    d = vdf.load(open('file.txt'))\n    d = vdf.loads(vdf_text)\n    d = vdf.parse(open('file.txt'))\n    d = vdf.parse(vdf_text)\n\n    # dumping dict as vdf to string\n    vdf_text = vdf.dumps(d)\n    indented_vdf = vdf.dumps(d, pretty=True)\n\n    # dumping dict as vdf to file\n    vdf.dump(d, open('file2.txt','w'), pretty=True)\n\n\nFor binary representation\n\n.. code:: python\n\n    d = vdf.binary_loads(vdf_bytes)\n    b = vdf.binary_dumps(d)\n\n    # alternative format - VBKV\n\n    d = vdf.binary_loads(vdf_bytes, alt_format=True)\n    b = vdf.binary_dumps(d, alt_format=True)\n\n    # VBKV with header and CRC checking\n\n    d = vdf.vbkv_loads(vbkv_bytes)\n    b = vdf.vbkv_dumps(d)\n\nUsing an alternative mapper\n\n.. code:: python\n\n  d = vdf.loads(vdf_string, mapper=collections.OrderedDict)\n  d = vdf.loads(vdf_string, mapper=vdf.VDFDict)\n\n``VDFDict`` works much like the regular ``dict``, except it handles duplicates and remembers\ninsert order. Additionally, keys can only be of type ``str``. The most important difference\nis that when trying to assigning a key that already exist it will create a duplicate instead\nof reassign the value to the existing key.\n\n.. code:: python\n\n  >>> d = vdf.VDFDict()\n  >>> d['key'] = 111\n  >>> d['key'] = 222\n  >>> d\n  VDFDict([('key', 111), ('key', 222)])\n  >>> d.items()\n  [('key', 111), ('key', 222)]\n  >>> d['key']\n  111\n  >>> d[(0, 'key')]  # get the first duplicate\n  111\n  >>> d[(1, 'key')]  # get the second duplicate\n  222\n  >>> d.get_all_for('key')\n  [111, 222]\n\n  >>> d[(1, 'key')] = 123  # reassign specific duplicate\n  >>> d.get_all_for('key')\n  [111, 123]\n\n  >>> d['key'] = 333\n  >>> d.get_all_for('key')\n  [111, 123, 333]\n  >>> del d[(1, 'key')]\n  >>> d.get_all_for('key')\n  [111, 333]\n  >>> d[(1, 'key')]\n  333\n\n  >>> print vdf.dumps(d)\n  \"key\" \"111\"\n  \"key\" \"333\"\n\n  >>> d.has_duplicates()\n  True\n  >>> d.remove_all_for('key')\n  >>> len(d)\n  0\n  >>> d.has_duplicates()\n  False\n\n\n.. |pypi| image:: https://img.shields.io/pypi/v/vdf.svg?style=flat&label=latest%20version\n    :target: https://pypi.org/project/vdf/\n    :alt: Latest version released on PyPi\n\n.. |license| image:: https://img.shields.io/pypi/l/vdf.svg?style=flat&label=license\n    :target: https://pypi.org/project/vdf/\n    :alt: MIT License\n\n.. |coverage| image:: https://img.shields.io/coveralls/ValvePython/vdf/master.svg?style=flat\n    :target: https://coveralls.io/r/ValvePython/vdf?branch=master\n    :alt: Test coverage\n\n.. |sonar_maintainability| image:: https://sonarcloud.io/api/project_badges/measure?project=ValvePython_vdf&metric=sqale_rating\n    :target: https://sonarcloud.io/dashboard?id=ValvePython_vdf\n    :alt: SonarCloud Rating\n\n.. |sonar_reliability| image:: https://sonarcloud.io/api/project_badges/measure?project=ValvePython_vdf&metric=reliability_rating\n    :target: https://sonarcloud.io/dashboard?id=ValvePython_vdf\n    :alt: SonarCloud Rating\n\n.. |sonar_security| image:: https://sonarcloud.io/api/project_badges/measure?project=ValvePython_vdf&metric=security_rating\n    :target: https://sonarcloud.io/dashboard?id=ValvePython_vdf\n    :alt: SonarCloud Rating\n\n.. |master_build| image:: https://github.com/ValvePython/vdf/workflows/Tests/badge.svg?branch=master\n    :target: https://github.com/ValvePython/vdf/actions?query=workflow%3A%22Tests%22+branch%3Amaster\n    :alt: Build status of master branch\n\n.. _DuplicateOrderedDict: https://github.com/rossengeorgiev/dota2_notebooks/blob/master/DuplicateOrderedDict_for_VDF.ipynb\n\n.. _hash randomization: https://docs.python.org/2/using/cmdline.html#envvar-PYTHONHASHSEED\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Library for working with Valve's VDF text format",
    "version": "3.4",
    "split_keywords": [
        "valve",
        "keyvalue",
        "vdf",
        "tf2",
        "dota2",
        "csgo"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "b5b53a66edfb2da020e05e26fffff8be",
                "sha256": "68c1a125cc49e343d535af2dd25074e9cb0908c6607f073947c4a04bbe234534"
            },
            "downloads": -1,
            "filename": "vdf-3.4-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b5b53a66edfb2da020e05e26fffff8be",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 10357,
            "upload_time": "2021-05-22T09:26:03",
            "upload_time_iso_8601": "2021-05-22T09:26:03.948742Z",
            "url": "https://files.pythonhosted.org/packages/96/60/6456b687cf55cf60020dcd01f9bc51561c3cc84f05fd8e0feb71ce60f894/vdf-3.4-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "8d756946693a6cd3ad3b96a02fa39c20",
                "sha256": "fd5419f41e07a1009e5ffd027c7dcbe43d1f7e8ef453aeaa90d9d04b807de2af"
            },
            "downloads": -1,
            "filename": "vdf-3.4.tar.gz",
            "has_sig": false,
            "md5_digest": "8d756946693a6cd3ad3b96a02fa39c20",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 11132,
            "upload_time": "2021-05-22T09:26:05",
            "upload_time_iso_8601": "2021-05-22T09:26:05.252775Z",
            "url": "https://files.pythonhosted.org/packages/44/7f/74192f47d67c8bf3c47bf0d8487b3457614c2c98d58b6617721d217f3f79/vdf-3.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2021-05-22 09:26:05",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "ValvePython",
    "github_project": "vdf",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "vdf"
}
        
Elapsed time: 0.01997s