{ "info": { "author": "Kyle Piper", "author_email": "kylepiper29@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Financial and Insurance Industry", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3 :: Only", "Topic :: Security" ], "description": "# txtferret\nIdentify and classify data in your text files with Python.\n\n## Description\n**Definition:** txtferret\n- A weasel-like mammal that feasts on rodents... and apparently social security numbers,\ncredit card numbers, or any other data that's in your text or gzipped text files.\n\nUse custom regular expressions and sanity checks (ex: `luhn` algorithm for account numbers) to find\nsensitive data in virtually any size file via your command line.\n\nWhy use txtferret? See the __How/why did this come about?__ section below.\n\n# Table of Contents\n- Quick Start\n- Configuration\n- How/why did this come about?\n- Development\n\n# Quick Start\n\n### PyPi\n\n1. Install it\n\n ```bash\n $ pip3 install txtferret\n ```\n\n### Repo\n1. Clone it.\n ```bash\n $ git clone git@github.com:krayzpipes/txt-ferret.git\n $ cd txt-ferret\n ```\n2. Setup environment.\n ```bash\n $ python3.7 -m venv venv\n $ source venv/bin/activate\n ```\n3. Install it.\n ```bash\n (venv) $ python setup.py install\n ```\n\n### Run it\n- Example file size:\n ```bash\n # Decent sized file.\n\n $ ls -alh | grep my_test_file.dat\n -rw-r--r-- 1 mrferret ferrets 19G May 7 11:15 my_test_file.dat\n ```\n\n- Scanning the file.\n ```bash\n # Scan the file.\n # Default behavior is to mask the string that was matched.\n\n $ txtferret scan my_test_file.dat\n 2019:05:20-22:18:01:-0400 Beginning scan for /home/mrferret/Documents/test_file_1.dat\n 2019:05:20-22:18:18:-0400 PASSED sanity and matched regex - /home/mrferret/Documents/test_file_1.dat - Filter: fake_ccn_account_filter, Line 712567, String: 100102030405060708094\n 2019:05:20-22:19:09:-0400 Finished scan for /home/mrferret/Documents/test_file_1.dat\n 2019:05:20-22:19:09:-0400 SUMMARY:\n 2019:05:20-22:19:09:-0400 - Matched regex, failed sanity: 2\n 2019:05:20-22:19:09:-0400 - Matched regex, passed sanity: 1\n 2019:05:20-22:19:09:-0400 Finished in 78 seconds (~1 minutes).\n ```\n- Scanning the file with a delimiter.\n ```bash\n # Break up each line of a CSV into columns by declaring a comma for a delimiter.\n # Scan each field in the row and return column numbers as well as line numbers.\n\n $ txtferret scan --delimiter , test_file_1.csv\n 2019:05:20-21:41:57:-0400 Beginning scan for /home/mrferret/Documents/test_file_1.csv\n 2019:05:20-21:44:34:-0400 PASSED sanity and matched regex - /home/mrferret/Documents/test_file_1.csv - Filter: fake_ccn_account_filter, Line 712567, String: 100102030405060708094, Column: 171\n 2019:05:20-21:49:16:-0400 Finished scan for /home/mrferret/Documents/test_file_1.csv\n 2019:05:20-21:49:16:-0400 SUMMARY:\n 2019:05:20-21:49:16:-0400 - Matched regex, failed sanity: 2\n 2019:05:20-21:49:16:-0400 - Matched regex, passed sanity: 1\n 2019:05:20-21:49:16:-0400 Finished in 439 seconds (~7 minutes).\n ```\n - Scan all files in a directory. Write results to a file and `stdout`\n ```bash\n # Uses multiprocessing to speed up scans of a bulk group of files\n\n $ txtferret scan -o bulk_testing.log --bulk ../test_files/\n 2019:06:09-15:15:27:-0400 Detected non-text file '/home/mrferret/Documents/test_file_1.dat.gz'... attempting GZIP mode (slower).\n 2019:06:09-15:15:27:-0400 Detected non-text file '/home/mrferret/Documents/test_file_2.dat.gz'... attempting GZIP mode (slower).\n 2019:06:09-15:15:27:-0400 Beginning scan for /home/mrferret/Documents/test_file_1.dat.gz\n 2019:06:09-15:15:27:-0400 Beginning scan for /home/mrferret/Documents/test_file_2.dat.gz\n 2019:06:09-15:15:27:-0400 Beginning scan for /home/mrferret/Documents/test_file_3.dat\n 2019:06:09-15:15:27:-0400 PASSED sanity and matched regex - /home/mrferret/Documents/test_file_2.dat.gz - Filter: fake_ccn_account_filter, Line 4, String: 100102030405060708094\n 2019:06:09-15:15:27:-0400 Finished scan for /home/mrferret/Documents/test_file_2.dat.gz\n 2019:06:09-15:16:04:-0400 PASSED sanity and matched regex - /home/mrferret/Documents/test_file_3.dat - Filter: fake_ccn_account_filter, Line 712567, String: 100102030405060708094\n 2019:06:09-15:16:51:-0400 PASSED sanity and matched regex - /home/mrferret/Documents/test_file_1.dat.gz - Filter: fake_ccn_account_filter, Line 712567, String: 100102030405060708094\n 2019:06:09-15:17:15:-0400 Finished scan for /home/mrferret/Documents/test_file_3.dat\n 2019:06:09-15:19:24:-0400 Finished scan for /home/mrferret/Documents/test_file_1.dat.gz\n 2019:06:09-15:19:24:-0400 SUMMARY:\n 2019:06:09-15:19:24:-0400 - Scanned 3 file(s).\n 2019:06:09-15:19:24:-0400 - Matched regex, failed sanity: 16\n 2019:06:09-15:19:24:-0400 - Matched regex, passed sanity: 3\n 2019:06:09-15:19:24:-0400 - Finished in 236 seconds (~3 minutes).\n 2019:06:09-15:19:24:-0400 FILE SUMMARIES:\n 2019:06:09-15:19:24:-0400 Matches: 1 passed sanity checks and 2 failed, Time Elapsed: 236 seconds / ~3 minutes - /home/mrferret/Documents/test_file_1.dat.gz\n 2019:06:09-15:19:24:-0400 Matches: 1 passed sanity checks and 3 failed, Time Elapsed: 0 seconds / ~0 minutes - /home/mrferret/Documents/test_file_2.dat.gz\n 2019:06:09-15:19:24:-0400 Matches: 1 passed sanity checks and 2 failed, Time Elapsed: 107 seconds / ~1 minutes - /home/mrferret/Documents/test_file_3.dat\n ```\n\n\n# Configuration\n\nThere are two ways to configure txt-ferret. You can make changes or add filters through making a\ncustom configuration file (based on the default YAML file) or you can add some settings via\nCLI switches.\n\n- CLI Switches will always win/take precedence.\n- User-defined configuration file will always beat the default configuration.\n- If any settings are not defined in a user-file configuration by cli switches, then the default\nsetting will be applied.\n\n\nTxt-ferret comes with a default config which you can dump into any directory\nyou wish and change it or use it for reference. If you change the file, you have to\nspecifiy it with the appropriate CLI switch in order for the script to use it. See the\nCLI section below.\n\n```bash\n(venv) $ txtferret dump-config /file/to/write/to.yaml\n```\nThere are two sections of the config file: `filters` and `settings`.\n\n### Filters\n\nFilters are regular expressions with some metadata. You can use this metadata to\nperform sanity checks on regex matches to sift out false positives. (Ex: luhn\nalgorithm for credit card numbers). You can also mask the output of the matched string \nas it is logged to a file or displayed on a terminal.\n\n```yaml\nfilters:\n- label: american_express_15_ccn\n pattern: '((?:34|37)\\d{2}(?:(?:[\\W_]\\d{6}[\\W_]\\d{5})|\\d{11}))'\n substitute: '[\\W_]'\n sanity: luhn\n mask:\n index: 2,\n value: XXXXXXXX\n type: Credit Card Number\n```\n\n- **label:**\n - This will be displayed in the logs when the filter in question has matched a string.\n- **pattern:**\n - The regular expression which will be used to find data in the file.\n - Regular expression must be compatible with the python `re` module in the standard library.\n - Be sure that your regular expression only contains ONE and ONLY ONE capture group. For example,\n if you are capturing a phone number:\n - Don't do this: `'(555-(867|555)-5309)'`\n - Do this: `'(555-(?:867|555)-5309)'`\n - The former example has two capture groups, and inner and an outer.\n - The latter has one capture group (the outer). The inner is a non-capturing\n group as defined by starting the capture group with `?:`.\n - __Note: If you run into issues with loading a custom filter, try adding\n single-quotes around your regular expression.__\n- **substitute:**\n - Allows you to define what characters are removed from a string before it is passed to the sanity check(s).\n - Must be a valid regular expression.\n - If missing or empty, the default substitute is `[\\W_]`.\n- **sanity:**\n - This is the algorithm to use with this filter in order to validate the data is really what you're\n looking for. For example, 16 digits might just be a random number and not a credit card. Putting the\n numbers through the `luhn` algorithm will validate they could potentially be an account number and\n reduce false positives.\n - You can also pass through a list of strings that represent algorithms as long as the algorithm exists\n in the library. If not, please add it and make a pull request!\n- **mask:**\n - index:\n - This is the position in the matched string in which the masking will begin.\n - value\n - The string which will be used to mask the matched string.\n- **type:**\n - This is basically a description of the 'type' of data you're looking for with this filter.\n\n### Settings\n\n```yaml\nsettings:\n mask: No\n log_level: INFO\n summarize: No\n output_file:\n show_matches: Yes\n delimiter:\n ignore_columns: [1, 5, 6]\n file_encoding: 'utf-8'\n```\n- **bulk**\n - This setting is accessible via CLI arguments `-b` or `--bulk`.\n - When those switches are used, pass the directory to scan instead of a single file name.\n - Example:\n ```bash\n $ txtferret scan --bulk /home/mrferret/Documents\n ```\n- **mask**\n - If set to true, the mask value defined in the filter will be used to mask the data during output.\n - If no mask is set for a filter, the program will mask with a default mask value.\n - This is set to 'true' by default.\n - **CLI** - The `-m` switch can be used to turn on masking'\n ```bash\n $ txtferret scan -m ../fake_ccn_data.txt\n 2017:05:20-00:24:52:-0400 PASSED sanity and matched regex - Filter: fake_ccn_account_filter, Line 1, String: 10XXXXXXXXXXXXXXXXXXX\n\n $ txtferret scan ../fake_ccn_data.txt\n 2017:05:20-00:26:18:-0400 PASSED sanity and matched regex - Filter: fake_ccn_account_filter, Line 1, String: 100102030405060708094\n ```\n- **log_level:**\n - This is the log level which you wish to use. `INFO` will only provide output for filters that\n have matched AND passed the associated sanity check(s). `DEBUG` will log both matched/checked filters\n as well as filters that matched but did NOT pass the sanity check(s).\n - **CLI** - The `-l` switch will allow you to change log levels:\n ```bash\n $ txtferret scan ../fake_ccn_data.txt\n 2019:05:20-00:36:00:-0400 PASSED sanity and matched regex - Filter: fake_ccn_account_filter, Line 1, String: 100102030405060708094\n\n $ txtferret scan -l DEBUG ../fake_ccn_data.txt\n 2019:05:20-01:02:07:-0400 PASSED sanity and matched regex - Filter: fake_ccn_account_filter, Line 1, String: 100102030405060708094\n 2019:05:20-01:02:07:-0400 FAILED sanity and matched regex - Filter: fake_ccn_account_filter, Line: 2\n ```\n- **summarize**\n - If set to true, the script will only output a list of three data points:\n - The number of matches that did not pass sanity checks.\n - The number of matches that did pass sanity checks.\n - The time it took to finish searching the file.\n - **CLI** - The `-s` switch will kickoff the summary.\n ```bash\n $ txtferret scan ../fake_ccn_data.txt\n 2019:05:20-00:36:00:-0400 PASSED sanity and matched regex - Filter: fake_ccn_account_filter, Line 1, String: 100102030405060708094\n\n $ txtferret scan -s ../fake_ccn_data.txt\n 2019:05:20-01:05:29:-0400 SUMMARY:\n 2019:05:20-01:05:29:-0400 - Matched regex, failed sanity: 1\n 2019:05:20-01:05:29:-0400 - Matched regex, passed sanity: 1\n 2019:05:20-01:05:29:-0400 Finished in 0 seconds (~0 minutes)\n\n ```\n- **output_file**\n - Add the absolute path to a file in which you would like to write results to.\n - **CLI** - Use the `-o` switch to set an output file.\n ```bash\n $ txtferret scan -o my_output.log file_to_scan.txt\n ```\n- **show_matches**\n - If this is set to 'No', then it will redact the matched string all-together in output.\n Be careful that you do not override this setting via a CLI switch unless it is on purpose.\n- **delimiter**\n - Define a delimiter. This delimiter will be used to split each line from the txt file into\n columns. The output of the script will provide you with the column in which the regex matched in\n addition to the line number.\n - **CAUTION:** Searching by columns GREATLY slows down the script since you are applying a regular\n expression to each column instead of the entire line. \n - You can define a byte-code delimiter by using `b` followed by the code. For example, `b1` will\n use Start of Header as a delimiter (\\x01 in hex)\n - **CLI** - Use the `-d` switch to set a delimiter and scan per column instead of line.\n ```bash\n $ txtferret scan ../fake_ccn_data.txt\n 2019:05:20-00:36:00:-0400 PASSED sanity and matched regex - Filter: fake_ccn_account_filter, Line 1, String: 100102030405060708094\n\n # Comma delimiter\n\n $ txtferret scan -d , ../fake_ccn_CSV_file.csv\n 2019:05:20-01:12:18:-0400 PASSED sanity and matched regex - Filter: fake_ccn_account_filter, Line 1, String: 100102030405060708094, Column: 3\n ```\n - **ignore_columns**\n - This setting is ignored if the `delimiter` setting or switch is not set.\n - Add a list of integers and txtferret will skip those columns.\n - If `ignore_columns: [2, 6]` is configured and a csv row is `hello,world,how,are,you,doing,today`, then\n `world` and `doing` will not be scanned but will be ignored.\n - This is particularly useful in columnar datasets when you know there is a column that is full of false positives.\n - **file_encoding**\n - Two uses:\n - Used to encode your `delimiter` value to the appropriate encoding of your file.\n - Used to encode the data matched in the file before being applied to sanity check.\n - Default value is `'utf-8'`\n# How/why did this come about?\n\nThere are a few shortcomings with commercial Data Loss Prevention (DLP) products:\n- They often rely on context. It would be too noisy for a commercial solution to alert every time it\nmatched a sixteen digit string as not all of their customers handle credit card data.\n- Many vendors don't have a cheap method of handling large files over 1 GB. Even less can handle\nfiles that are many GBs in size.\n- Some DLP solutions will only classify data files based on the first so many megabytes.\n- Many DLP solutions are black boxes of magic that do not give you say in what they are looking for\nin your data or how they know what they're looking at.\n\nTxtferret was born out after realizing some of these limitations. It isn't perfect, but it's a great\nsanity check which can be paired with a DLP solution. Here are some things it was designed to do:\n- __Virtually no size limitation__\n - Can run against any size file as long as you can fit it on a drive.\n - It's python... so... no speed guarantee on huge files, but at least it will eventually get it done.\n We've found that txtferret can scan a ~20 GB file between 1 and 3 minutes on our systems.\n- __Customizable__\n - Define your own regular expressions and pair them with a sanity check. For example, using the\n built-in `luhn` algorithm will sift out many false positives for credit card numbers. The matched\n credit card number will be run through the `luhn` algorithm first. If it doesn't pass, it is discarded.\n- __No context needed__\n - Yeah, this can cause a lot of false positives with certain files; However,\n if you're dealing with a file that doesn't contain context like 'VISA' or 'CVE', then you need\n to start somewhere.\n- __Helpful output__\n - Indicates which line the string was found.\n - Indicates which column if you've defined a delimiter (ex: comma for CSV files).\n - You can choose to mask your output data to make sure you're not putting sensitive data\n into your log files or outputting them to your terminal. \n- __It's free__\n - No contracts\n - No outrageous licensing per GB of data scanned.\n- __You can contribute!__\n\n## Releases\n\n#### Version 0.2.1 - 2019-08-11\n- Fixed allowed keys bug introduced in v0.2.0\n#### Version 0.2.0 - 2019-08-05\n- Changed `tokenize` to `mask` because tokenize was a lie.. it's masking.\n - Replaced `--no-tokenize` switch with `--mask` switch.\n- Turned masking off by default.\n\n#### Version 0.1.3 - 2019-08-05\n- Added `file_encoding` setting for multi-encoding support.\n - Reads in bytes and assumes `'utf-8'` encoding by default.\n#### Version 0.1.2 - 2019-08-01\n- Fixed bug with regex when reading gzipped files.\n#### Version 0.1.1 - 2019-07-30\n- Added `substitute` option to filters.\n#### Version 0.1.0 - 2019-07-30\n- Removed the `config-override` option.\n- Added `ignore_columns` setting.\n#### Version 0.0.4 - 2019-06-09\n- Added bulk file scanning by the `--bulk` switch.\n- Added multiprocessing for bulk scanning.\n#### Version 0.0.3 - 2019-06-01\n- Added gzip detection and support.\n\n\n# Development\nSome info about development.\n\n## Running Tests\n\n```bash\n$ pytest txt-ferret/tests/\n```\n\n## Contributing\n#### Process\n1. Create an issue.\n2. Fork the repo.\n3. Do your work.\n4. **WRITE TESTS**\n4. Make a pull request.\n - Preferably, include the issue # in the pull request.\n\n#### Style\n- Black for formatting.\n- Pylint for linting.\n\n# License\nSee [License](LICENSE)\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/krayzpipes/txt-ferret", "keywords": "pci,dlp,text,scan,regex", "license": "License :: OSI Approved :: Apache Software License", "maintainer": "", "maintainer_email": "", "name": "txtferret", "package_url": "https://pypi.org/project/txtferret/", "platform": "", "project_url": "https://pypi.org/project/txtferret/", "project_urls": { "Homepage": "https://github.com/krayzpipes/txt-ferret" }, "release_url": "https://pypi.org/project/txtferret/0.2.1/", "requires_dist": [ "click", "loguru", "pyyaml" ], "requires_python": "", "summary": "Scan text files for sensitive (or non-sensitive) data.", "version": "0.2.1" }, "last_serial": 5786418, "releases": { "0.0.3": [ { "comment_text": "", "digests": { "md5": "90698210cc1dae881e1e4e45b1b5a5a9", "sha256": "c3bdae91882d56b0b25fdab065f9f6ec5e992967216aa4e3c0a4982bc4067f25" }, "downloads": -1, "filename": "txtferret-0.0.3-py3.7.egg", "has_sig": false, "md5_digest": "90698210cc1dae881e1e4e45b1b5a5a9", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": null, "size": 29162, "upload_time": "2019-06-09T23:02:36", "url": "https://files.pythonhosted.org/packages/d0/79/3a98d09e4c7e5d4614137a6f6fd5e9201b12c119bc052924b23ec96624ae/txtferret-0.0.3-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "14a059f2517eb49457915cf002d8a4b6", "sha256": "5d7176c2b11fe6fdfcd7f8b584ba7f3538e77cdd416e8dde5fea3eb3e2e9ba88" }, "downloads": -1, "filename": "txtferret-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "14a059f2517eb49457915cf002d8a4b6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28227, "upload_time": "2019-06-01T16:02:38", "url": "https://files.pythonhosted.org/packages/46/ae/b4a7d130a12119a212ebbb24df421c5be71dcd019a41001c4aefdc0ab956/txtferret-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "dab3926351a9c9d8b4a7b93d4fc422dc", "sha256": "b295778113a181febb9b6c3dbb424e87fc307c7283ef71ed434eed33ec79d6eb" }, "downloads": -1, "filename": "txtferret-0.0.3.tar.gz", "has_sig": false, "md5_digest": "dab3926351a9c9d8b4a7b93d4fc422dc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19478, "upload_time": "2019-06-01T16:02:41", "url": "https://files.pythonhosted.org/packages/45/35/80b29b7abeee45662d0d4f67b8c89e7c26b65af28bec25a271108a254750/txtferret-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "d706fec16a58fe463de8f150b405155a", "sha256": "29859326c60296f7d5f2ef98c062692f66fe8931179e44432ed184d005a1239e" }, "downloads": -1, "filename": "txtferret-0.0.4-py3.7.egg", "has_sig": false, "md5_digest": "d706fec16a58fe463de8f150b405155a", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": null, "size": 29163, "upload_time": "2019-06-09T23:02:37", "url": "https://files.pythonhosted.org/packages/c4/ea/78b6b3a233c0ad03c6056507739c00b650b6a9316d0d8d7eadd873e61817/txtferret-0.0.4-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "2619ce91dba82c57aae1f528e25f531a", "sha256": "9e3aa0c3280d83d2cf430c30de7880934f4953c2e9505c0324c76c1f534047d7" }, "downloads": -1, "filename": "txtferret-0.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "2619ce91dba82c57aae1f528e25f531a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21495, "upload_time": "2019-06-09T23:02:34", "url": "https://files.pythonhosted.org/packages/77/96/3f87bf9be1d0d9550589898f4ea43b4746ca649ca9f2ed77f10a51ae4d86/txtferret-0.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bcbd992779296e83d0295c97dc20c6e2", "sha256": "99fe943742967912f58a18204f514a2f00bdd7baf7b427b630546977f807c62b" }, "downloads": -1, "filename": "txtferret-0.0.4.tar.gz", "has_sig": false, "md5_digest": "bcbd992779296e83d0295c97dc20c6e2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21916, "upload_time": "2019-06-09T23:02:39", "url": "https://files.pythonhosted.org/packages/b3/e0/d3cc71bd278fea1c949c809b7102085831992725aa1bce75432008591049/txtferret-0.0.4.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "2b19235b01cb826a3f3efc45afdf1b17", "sha256": "c8ee7af5d24c6714ca7be357f7bdf93016f09e2b677f9db108e67015d5c71986" }, "downloads": -1, "filename": "txtferret-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "2b19235b01cb826a3f3efc45afdf1b17", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21849, "upload_time": "2019-07-31T02:02:28", "url": "https://files.pythonhosted.org/packages/02/fb/fbf653fbc670aea84cd875cf80e6f5f1dad1c387ee47904578ec622044c0/txtferret-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6d281c3e9e6c5eed9b4f7cce9e33ad98", "sha256": "5e1d5f2e043e73a08d2c4d4a376c4943712d0ca8da3a1dc5c9027773d93d43a8" }, "downloads": -1, "filename": "txtferret-0.1.0.tar.gz", "has_sig": false, "md5_digest": "6d281c3e9e6c5eed9b4f7cce9e33ad98", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22545, "upload_time": "2019-07-31T02:02:29", "url": "https://files.pythonhosted.org/packages/7b/7b/c731536808d11d3c757a6ddf922c7ffa87355c14ef1f44ce4f31cc1eb48a/txtferret-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "210cccf0f31b9d4e9a938f7d6f293173", "sha256": "c86593c78ab1491c0fcc85d59693bc805c32b13f8ef594bd029eebf7c3e77d47" }, "downloads": -1, "filename": "txtferret-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "210cccf0f31b9d4e9a938f7d6f293173", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22162, "upload_time": "2019-07-31T04:52:51", "url": "https://files.pythonhosted.org/packages/68/c6/547ef1fb217019db87b0c317ac17046690354d2688b834f7af9f9630fa1f/txtferret-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "47709c9b5c817c3c0e1d104ffcebcf18", "sha256": "9524301aee9730a7f489f11e9607765d14ef6674241a5c6655cdd4379863866b" }, "downloads": -1, "filename": "txtferret-0.1.1.tar.gz", "has_sig": false, "md5_digest": "47709c9b5c817c3c0e1d104ffcebcf18", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22936, "upload_time": "2019-07-31T04:52:53", "url": "https://files.pythonhosted.org/packages/21/ca/01e5b0e71d43474f62a752e8034fe2cf1f60c0f2dbafd5301d347c5a586b/txtferret-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "50016f88010fc74abf33afb773539125", "sha256": "041433a2af171acc08f9178adc5f45cdcd2f59ff45cfe1fb9b7d364d3b217a1d" }, "downloads": -1, "filename": "txtferret-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "50016f88010fc74abf33afb773539125", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22248, "upload_time": "2019-08-02T02:39:42", "url": "https://files.pythonhosted.org/packages/54/22/386bb96a7f5ab34ccf589417728e2bbd25584024e801c557609ce54ebd27/txtferret-0.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f47c895e937af51aeb4d669c85dc59f2", "sha256": "cf10c84ef14ef81576b9cf8cdebc9fca0856880b5dc94e7d32915ca8a42ec5e9" }, "downloads": -1, "filename": "txtferret-0.1.2.tar.gz", "has_sig": false, "md5_digest": "f47c895e937af51aeb4d669c85dc59f2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23060, "upload_time": "2019-08-02T02:39:44", "url": "https://files.pythonhosted.org/packages/a1/07/846c4778a3fb93996930f383768883788f6bca4706b5a6396abc66b70ef1/txtferret-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "c1eaf489d081aaba8eca4b1e9a4e4a47", "sha256": "dd768503ba7d829703aee30dbbc32be8ce428c47131af5fbe117bf87673a56fa" }, "downloads": -1, "filename": "txtferret-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "c1eaf489d081aaba8eca4b1e9a4e4a47", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22673, "upload_time": "2019-08-06T02:38:58", "url": "https://files.pythonhosted.org/packages/1f/12/d65f3c3571dd2d2dc08d23c028ea1ee855b799069dc316de0bcabe38ccee/txtferret-0.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3e27e059529c37c1eb542c00b5ba8911", "sha256": "a4025a2b98401784a9fb5568e8068eae8ffc5727fcadcec51c413e60b79985d3" }, "downloads": -1, "filename": "txtferret-0.1.3.tar.gz", "has_sig": false, "md5_digest": "3e27e059529c37c1eb542c00b5ba8911", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23653, "upload_time": "2019-08-06T02:39:00", "url": "https://files.pythonhosted.org/packages/5f/49/b81445802526d91796aad38cfd88b1b0abb688d6004990a6e5ddf963060d/txtferret-0.1.3.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "f7393db61f18283f977c1d69773cfe76", "sha256": "9f496dc8d2b2e53a6ee18a4a2cadfd825b166fb00a9a0d6e435381262bad80dc" }, "downloads": -1, "filename": "txtferret-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f7393db61f18283f977c1d69773cfe76", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22756, "upload_time": "2019-08-11T19:57:49", "url": "https://files.pythonhosted.org/packages/89/64/2be04d8ed66deff709477c01024ef60a04a4718c58809804800d75e8e0a7/txtferret-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8cb820995774f5d6a360b509237dd3d4", "sha256": "6a2713f86e9e1492f944acb472e9f30f1810c0ef52141493b9de1509a451487d" }, "downloads": -1, "filename": "txtferret-0.2.0.tar.gz", "has_sig": false, "md5_digest": "8cb820995774f5d6a360b509237dd3d4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20006, "upload_time": "2019-08-11T19:57:51", "url": "https://files.pythonhosted.org/packages/3c/a6/210ed5e7c314addeaf98b6d85488d6c503a50cb0bcb74506c1c6a6cdcc87/txtferret-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "a772778a0efc9404c5dc9cbc31e1cab9", "sha256": "218b6372a0d9a27c3dbe2d902830974e9f3d663fc3a4fde64f8d1ade1f419079" }, "downloads": -1, "filename": "txtferret-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "a772778a0efc9404c5dc9cbc31e1cab9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22786, "upload_time": "2019-08-11T20:22:30", "url": "https://files.pythonhosted.org/packages/6f/17/0f4f6504e8da25f674e11a182b6dcd452ea5d3c6f7fdb4689435f6c3d28e/txtferret-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "da65d0985a05c320dcaaadbd033e2fc7", "sha256": "97cb4c3cdc498a9df8249397a91dca11e026741508d0381548827aa7d60aca82" }, "downloads": -1, "filename": "txtferret-0.2.1.tar.gz", "has_sig": false, "md5_digest": "da65d0985a05c320dcaaadbd033e2fc7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20062, "upload_time": "2019-08-11T20:22:32", "url": "https://files.pythonhosted.org/packages/33/1d/b7fe744934702584243a64e6fe6f05c69a9ca069747ea3804ded7646b470/txtferret-0.2.1.tar.gz" } ], "0.3.0a0": [ { "comment_text": "", "digests": { "md5": "50775a3ccb0ef3ff12301a862c1af0f3", "sha256": "f5dcc9df7b32f7509841603a258e822e33cf5272ec54c9954a0b9be0af5d77af" }, "downloads": -1, "filename": "txtferret-0.3.0a0-py3-none-any.whl", "has_sig": false, "md5_digest": "50775a3ccb0ef3ff12301a862c1af0f3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23446, "upload_time": "2019-09-05T13:00:21", "url": "https://files.pythonhosted.org/packages/a6/90/96ef27d762ab6c827dd3ead7b8e62bc65b993556dc5d7716bd9e6434228b/txtferret-0.3.0a0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ee1e914093bbcce00d90f83d4731db71", "sha256": "89b649a80380f619cb2874d0fecc8fa05575fbe3f63566350d30b4b98090f07d" }, "downloads": -1, "filename": "txtferret-0.3.0a0.tar.gz", "has_sig": false, "md5_digest": "ee1e914093bbcce00d90f83d4731db71", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20649, "upload_time": "2019-09-05T13:00:22", "url": "https://files.pythonhosted.org/packages/94/31/0419345ef9894004b9875663fee528a1399a06bd51d3552b807d381ce360/txtferret-0.3.0a0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a772778a0efc9404c5dc9cbc31e1cab9", "sha256": "218b6372a0d9a27c3dbe2d902830974e9f3d663fc3a4fde64f8d1ade1f419079" }, "downloads": -1, "filename": "txtferret-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "a772778a0efc9404c5dc9cbc31e1cab9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22786, "upload_time": "2019-08-11T20:22:30", "url": "https://files.pythonhosted.org/packages/6f/17/0f4f6504e8da25f674e11a182b6dcd452ea5d3c6f7fdb4689435f6c3d28e/txtferret-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "da65d0985a05c320dcaaadbd033e2fc7", "sha256": "97cb4c3cdc498a9df8249397a91dca11e026741508d0381548827aa7d60aca82" }, "downloads": -1, "filename": "txtferret-0.2.1.tar.gz", "has_sig": false, "md5_digest": "da65d0985a05c320dcaaadbd033e2fc7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20062, "upload_time": "2019-08-11T20:22:32", "url": "https://files.pythonhosted.org/packages/33/1d/b7fe744934702584243a64e6fe6f05c69a9ca069747ea3804ded7646b470/txtferret-0.2.1.tar.gz" } ] }