{ "info": { "author": "Piotr Olejarz", "author_email": "vadwook@hotmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Topic :: Software Development", "Topic :: Text Processing" ], "description": "==========\nCsvSchema\n==========\n\nCsvSchema is easy to use module designed to make CSV file checking easier. It allows to create more complex validation rules faster thanks to\nsome predefined building blocks.\n\nBasics\n------\nLike most similar modules build for CSV file checking CsvSchema allows you to describe how proper file should look like.\nIn order to do that you will need to implement a subclass of ``csv_schema.structure.BaseCsvStructure``.\n\nExample::\n\n from csv_schema.structure.base import BaseCsvStructure\n from csv_schema.columns import (\n IntColumn,\n DecimalColumn,\n StringColumn,\n )\n\n class TestCsvStructure(BaseCsvStructure):\n\n a = StringColumn()\n b = IntColumn()\n c = DecimalColumn()\n\nIn above example we defined CSV schema class that represents file with three columns. First column may contain any kind of characters.\nSecond allows only numerical values and third one may contain only decimal values.\n\n**NOTE**:\n Order of attributes in schema class is important. If you put ``b`` before ``a`` then column ``b`` in CSV file will be the first one.\n Of course this will change validation and first column will no longer allow values like e.g ``'Python'``\n\nAfter defining your schema you can use it like this::\n\n schema = TestCsvStructure(['A', '6', ''], 1)\n schema.is_valid()\n\nFirst constructor parameter is a list of data representing single line form CSV file. Second is a position in file from which it was taken.\n\n**NOTE**:\n You can use whatever CSV reading method you like. Just make sure that each CSV line is transformed into list.\n\nIf ``is_valid`` return ``False`` you can see errors that has been found in ``schema.errors``. Each error message is formatted in two ways:\n\n- *Line : * when error message applies to whole line\n- *Line , : * when error message applies to particular column\n\nMore about columns\n------------------\nThere are three types of columns. Their behavior can be altered by some additional keyword arguments:\n\n:StringColumn([blank, min_length, max_length, permissible_values]):\n - blank\n If set to ``True`` column does not has to be filled\n - min_length\n Value can not be shorter that ``min_length``\n - max_length\n Maximal lenght of value\n - permissible_values\n List of allowed values\n\n:IntColumn([blank, min_exclusive, max_exclusive, min_inclusive, max_inclusive]):\n - blank\n If set to ``True`` column does not has to be filled\n - min_exclusive\n Minimum allowed value, exclusive\n - max_exclusive\n Maximal allowed value, exclusive\n - min_inclusive\n Minimum allowed value, inclusive\n - max_inclusive\n Maximal allowed value, inclusive\n\n:DecimalColumn([blank, min_exclusive, max_exclusive, min_inclusive, max_inclusive, fraction_digits, total_digits]):\n - blank\n If set to ``True`` column does not has to be filled\n - min_exclusive\n Minimum allowed value, exclusive\n - max_exclusive\n Maximal allowed value, exclusive\n - min_inclusive\n Minimum allowed value, inclusive\n - max_inclusive\n Maximal allowed value, inclusive\n - fraction_digits\n Number of digits before comma\n - total_digits\n Total number of digits in whole value (before and after comma)\n\n**NOTE**:\n ``DecimalColumn`` operates on ``decimal.Decimal`` objects. Have that in mind when you will be setting ``min_exclusive``, ``max_exclusive``,\n ``min_inclusive`` or ``max_inclusive``.\n\nRemember that you can always make your own columns by simply subclassing ``csv_schema.columns.base.BaseColumn``::\n\n from csv_schema.columns.base import BaseColumn\n from csv_schema.exceptions import ImproperValueRestrictionException\n\n class MyColumn(BaseColumn):\n\n value_template = '' # Regular expression describing how proper value should look like in CSV file\n\n def convert(self, raw_val): # This method is called in order to transform raw value into Python object\n return None\n\n def check_restriction(self, value): # This method is optional. It allows you to specify keyword arguments that can alter column behavior.\n required_value = self.options.get('required_value', None)\n if required_value is not None:\n if required_value != value:\n # Message from ImproperValueRestrictionException will be added to structure errors\n raise ImproperValueRestrictionException('That is not the value you are looking for...')\n\n\nColumn set\n----------\nTill now you have seen how to use CsvSchema for simple CSV file description. Sometimes specifying types of columns and their behavior just is not enough.\nWhat if you would like to describe more complex validation rules? Let's say that you want a validation rule that says: you have to fill\ncolumn A or column B or both of them. This is the situation when you need ``Cs`` objects.\n\n``Cs`` stands for *Column Set* and allows you to express more complex validation rules by simply combining ``Cs`` with use of some logic operators.\nLet's consider simple validation rule that we mentioned earlier: you have to fill column A or column B or both of them::\n\n from csv_schema.structure.set import Cs\n\n class TestCsvStructure(BaseCsvStructure):\n\n a = IntColumn(blank=True)\n b = IntColumn(blank=True)\n\n class Rules(object):\n a_or_b_rule = Cs('a') | Cs('b')\n\n\n*Changed in 1.1.0: CsvSchema will now store rules in special inner class - Rules*\n\n**NOTE**:\n If you are going to use column sets remeber to set columns used in ``Cs`` instances as **blank**.\n\nEach ``Cs`` instance has assigned columns that needs to be filled in order to *evaluate* ``Cs`` as *true*. In our example each ``Cs`` instance has\nonly one column but you can assign them as many as you need. For example, if you create ``Cs`` instance like this::\n\n Cs('a', 'b')\n\nwill mean that you want **both** column, ``a`` and ``b`` to be filled because ``Cs`` will *evaluate true* only if **every** column in set is filled.\nWe used ``|`` operator to combine two ``Cs``. ``|`` can be referred as rule that demands at least one ``Cs`` instance to be evaluated as *true*.\n``Cs`` supports also ``^`` operator. It is used to express rule that demands **only one** ``Cs`` instance to be filled. If you create rule ``Cs('a') ^ Cs('b')``\nand fill both columns the whole expression will be evaluated as *false*.\n\n**NOTE**:\n Defined rules are evaluated during ``is_valid()`` call and their error messages are added to structure ``errors`` attribute. If custom error message\n is not appropriate to your needs you can override it by calling ``error`` method on whole rule::\n\n ...\n class Rules(object):\n a_or_b_rule = (Cs('a') | Cs('b')).error('Column A or B needs to be filled')\n ...\n\nIf you want to define more than one rule in single structure class you can do it like this::\n\n ...\n class Rules(object):\n rule_1 = Cs('a') | Cs('b')\n rule_2 = Cs('c') ^ (Cs('d') | Cs('e'))\n ...\n\nSimilarly as columns, ``Cs`` behavior can be altered by keyword arguments::\n\n ...\n class Rules(object):\n rule = Cs('a', b='B')\n ...\n\nIn above example ``Cs`` instance will be evaluated *true* if column ``a`` is filled and column ``b`` has value equal to ``'B'``.\nTable below shows possible ``Cs`` states depending on different data and settings:\n\n+-------------------+--------------+--------------+------------+\n| Setting | Column ``a`` | Column ``b`` | Evaluation |\n+===================+==============+==============+============+\n| Cs('a') | '' | '' | False |\n+-------------------+--------------+--------------+------------+\n| Cs('a') | 'A' | '' | True |\n+-------------------+--------------+--------------+------------+\n| Cs('a') | '' | 'B' | False |\n+-------------------+--------------+--------------+------------+\n| Cs('a') | 'A' | 'B' | True |\n+-------------------+--------------+--------------+------------+\n| Cs('a', b='B') | '' | '' | True |\n+-------------------+--------------+--------------+------------+\n| Cs('a', b='B') | 'A' | '' | False |\n+-------------------+--------------+--------------+------------+\n| Cs('a', b='B') | '' | 'B' | False |\n+-------------------+--------------+--------------+------------+\n| Cs('a', b='B') | 'A' | 'B' | True |\n+-------------------+--------------+--------------+------------+\n| Cs('a', b='B') | '' | 'C' | True |\n+-------------------+--------------+--------------+------------+\n| Cs('a', b='B') | 'A' | 'C' | False |\n+-------------------+--------------+--------------+------------+\n\nNotice that when column ``b`` is empty or has wrong value column ``a`` can not be filled.\n\n**NOTE**:\n Rememer that you can have more than one value condition in ``Cs``. Creating object like this::\n\n Cs('a', b='B', c='C')\n\n will make it *true* if ``b`` is equal to ``'B'`` **and** ``c`` is equal to ``'C'`` (and of course, ``a`` is not empty).\n You can even demand that particular column has to have specific value::\n\n Cs('a', a='A')", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://bitbucket.org/vadwook/csvschema/", "keywords": null, "license": "LICENSE.txt", "maintainer": null, "maintainer_email": null, "name": "CsvSchema", "package_url": "https://pypi.org/project/CsvSchema/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/CsvSchema/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://bitbucket.org/vadwook/csvschema/" }, "release_url": "https://pypi.org/project/CsvSchema/1.1.1/", "requires_dist": null, "requires_python": null, "summary": "Module for describing CSV data structure.", "version": "1.1.1" }, "last_serial": 1037985, "releases": { "1.1.0": [ { "comment_text": "", "digests": { "md5": "54d05bdc198fa8f45a826e2dc8525db3", "sha256": "8694e0ddf8c5f492b3a54eb8ee183d60a4346e1e012d0f9f11b021ced87f0187" }, "downloads": -1, "filename": "CsvSchema-1.1.0.zip", "has_sig": false, "md5_digest": "54d05bdc198fa8f45a826e2dc8525db3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15287, "upload_time": "2013-04-20T19:07:41", "url": "https://files.pythonhosted.org/packages/4e/e5/c54fd47aee889c6e0b0b2cf9c505a9c20f68a56784b94528b7a79903fcdb/CsvSchema-1.1.0.zip" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "5619d38e63390869293d3b833b76d6ed", "sha256": "fa3650cb39748f8fd0a755e734e237ee14520d5cb90e7565a48cea28b49029ab" }, "downloads": -1, "filename": "CsvSchema-1.1.1.zip", "has_sig": false, "md5_digest": "5619d38e63390869293d3b833b76d6ed", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15358, "upload_time": "2014-03-22T17:35:49", "url": "https://files.pythonhosted.org/packages/78/5a/6146e737bb2b4333d9b48b602b8666377db675eb18f04477cdc6936478e2/CsvSchema-1.1.1.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5619d38e63390869293d3b833b76d6ed", "sha256": "fa3650cb39748f8fd0a755e734e237ee14520d5cb90e7565a48cea28b49029ab" }, "downloads": -1, "filename": "CsvSchema-1.1.1.zip", "has_sig": false, "md5_digest": "5619d38e63390869293d3b833b76d6ed", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15358, "upload_time": "2014-03-22T17:35:49", "url": "https://files.pythonhosted.org/packages/78/5a/6146e737bb2b4333d9b48b602b8666377db675eb18f04477cdc6936478e2/CsvSchema-1.1.1.zip" } ] }