meaningless


Namemeaningless JSON
Version 0.7.0 PyPI version JSON
download
home_pagehttps://github.com/daniel-tran/meaningless
SummaryRetrieves, processes and downloads Bible passages from Bible Gateway
upload_time2023-01-25 20:10:12
maintainer
docs_urlNone
authorDaniel Tran
requires_python>=3.8
licenseMIT License
keywords bible yaml json xml csv biblegateway
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![Test Status](https://github.com/daniel-tran/meaningless/actions/workflows/run_tests.yaml/badge.svg)](https://github.com/daniel-tran/meaningless/actions/workflows/run_tests.yaml)

Meaningless is a Python library used to retrieve, process and download Bible passages from Bible Gateway.

Features include:
- Passage retrieval from the [Bible Gateway](https://www.biblegateway.com) site or from a local YAML/JSON/XML/CSV file.
- Different output formats for different purposes:
  - Multi-line strings for printing Bible passages.
  - Python list of strings (or in-memory data structure) for passing Bible passages to other Python logic.
  - YAML/JSON/XML/CSV files for persistent storage of Bible passages or as input for other applications and scripts.
- Handling of edge case passages, such as those with tabular data and omitted passages in certain translations.
- Flags to enable particular content modifications, such as ignoring passage numbers.
- Filtering on Bible passages from a local file based on a given text input or regular expression.

**Now accepting feature requests!** If you want to see a certain feature included, please create an issue describing all the necessary details.

# Installation

```
pip install meaningless
```

# API Documentation

Documentation is generated using Sphinx.

## Online

The API documentation is hosted through GitHub Pages at the following link: https://daniel-tran.github.io/meaningless/

## Offline

You can view the API documentation as static HTML documents from `docs\index.html`. After cloning this repo, you can load the HTML files in a web browser, which allows you to navigate to other sections.

# Supported translations

## English

- ASV
- AKJV
- BRG
- EHV
- ESV
- ESVUK
- GNV
- GW
- ISV
- JUB
- KJV
- KJ21
- LEB
- MEV
- NASB
- NASB1995
- NET
- NIV
- NIVUK
- NKJV
- NLT
- NLV
- NOG
- NRSV
- NRSVUE
- WEB
- YLT

## Español

- RVA

# Usage

## Web Extractor
The Web Extractor is used to obtain passage information directly from [Bible Gateway](https://www.biblegateway.com).
```python
from meaningless import WebExtractor

if __name__ == '__main__':
    bible = WebExtractor()
    passage = bible.get_passage('Ecclesiastes', 1, 2)
    print(passage)
```
Output:
```
² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”
```

## YAML Downloader
The YAML Downloader is which formats passages obtained from the Bible Gateway website (using the Web Extractor) into a YAML structure and writes it out to a file:
```python
from meaningless import YAMLDownloader

if __name__ == '__main__':
    downloader = YAMLDownloader()
    downloader.download_passage('Ecclesiastes', 1, 2)
```
Output:

Running the above code would produce a file called `Ecclesiastes.yaml` in the current working directory with the approximate contents:
```yaml
Ecclesiastes:
  1:
    2: "² “Meaningless! Meaningless!”\n    says the Teacher.\n“Utterly meaningless!\n\
      \    Everything is meaningless.”"
Info:
  Language: English
  Translation: NIV
  Timestamp: '0000-00-00T00:00:00.000000+00:00'
  Meaningless: 0.0.0
```

## YAML Extractor
The YAML Extractor uses the generated files from the YAML Downloader to find passages. This is faster than the Web Extractor, since it is not retrieving information from the Internet and is also unaffected by bandwidth limitations.
```python
from meaningless import YAMLExtractor

if __name__ == '__main__':
    bible = YAMLExtractor()
    passage = bible.get_passage('Ecclesiastes', 1, 2)
    print(passage)
```
Output:

Assuming the YAML downloader has already generated a YAML file in the current directory called `Ecclesiastes.yaml` which contains the book of Ecclesiastes in YAML format:
```
² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”
```

## YAML File Interface
The YAML File Interface is a set of helper methods used to read and write YAML files. This can be useful if you need to do some customised processing on a downloaded YAML file.
```python
from meaningless import YAMLDownloader, yaml_file_interface

if __name__ == '__main__':
    downloader = YAMLDownloader()
    downloader.download_passage('Ecclesiastes', 1, 2)
    bible = yaml_file_interface.read('./Ecclesiastes.yaml')
    bible['Info']['Customised?'] = True
    yaml_file_interface.write('./Ecclesiastes.yaml', bible)
```
Output:

Running the above code would produce a file called `Ecclesiastes.yaml` in the current working directory with the approximate contents:
```yaml
Ecclesiastes:
  1:
    2: "² “Meaningless! Meaningless!”\n    says the Teacher.\n“Utterly meaningless!\n\
      \    Everything is meaningless.”"
Info:
  Language: English
  Translation: NIV
  Timestamp: '0000-00-00T00:00:00.000000+00:00'
  Meaningless: 0.0.0
  Customised?: true
```

## JSON Downloader
The JSON Downloader is effectively the same as the YAML Downloader except the resulting file is in JSON format and has a different file extension.
```python
from meaningless import JSONDownloader

if __name__ == '__main__':
    downloader = JSONDownloader()
    downloader.download_passage('Ecclesiastes', 1, 2)
```
Output:

Running the above code would produce a file called `Ecclesiastes.json` in the current working directory with the approximate contents:
```json
{
  "Ecclesiastes": {
    "1": {
      "2": "² “Meaningless! Meaningless!”\n    says the Teacher.\n“Utterly meaningless!\n    Everything is meaningless.”"
    }
  },
  "Info": {
    "Language": "English",
    "Meaningless": "0.0.0",
    "Timestamp": "0000-00-00T00:00:00.000000+00:00",
    "Translation": "NIV"
  }
}
```

## JSON Extractor
Much like the YAML Extractor, the JSON Extractor uses the generated files from the JSON Downloader to find passages.
```python
from meaningless import JSONExtractor

if __name__ == '__main__':
    bible = JSONExtractor()
    passage = bible.get_passage('Ecclesiastes', 1, 2)
    print(passage)
```
Output:

Assuming the JSON downloader has already generated a JSON file in the current directory called `Ecclesiastes.json` which contains the book of Ecclesiastes in JSON format:
```
² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”
```

## JSON File Interface
The JSON File Interface is a set of helper methods used to read and write JSON files. Similar to the YAML File Interface, it can be used to do customised processing on a JSON file or its contents.
```python
from meaningless import JSONDownloader, json_file_interface

if __name__ == '__main__':
    downloader = JSONDownloader()
    downloader.download_passage('Ecclesiastes', 1, 2)
    bible = json_file_interface.read('./Ecclesiastes.json')
    bible['Info']['Customised?'] = True
    json_file_interface.write('./Ecclesiastes.json', bible)
```
Output:

Running the above code would produce a file called `Ecclesiastes.json` in the current working directory with the approximate contents:
```json
{
  "Ecclesiastes": {
    "1": {
      "2": "² “Meaningless! Meaningless!”\n    says the Teacher.\n“Utterly meaningless!\n    Everything is meaningless.”"
    }
  },
  "Info": {
    "Customised?": true,
    "Language": "English",
    "Meaningless": "0.0.0",
    "Timestamp": "0000-00-00T00:00:00.000000+00:00",
    "Translation": "NIV"
  }
}
```

## XML Downloader
The XML Downloader is effectively the same as the YAML Downloader except the resulting file is in a specific XML format and has a different file extension.
```python
from meaningless import XMLDownloader

if __name__ == '__main__':
    downloader = XMLDownloader()
    downloader.download_passage('Ecclesiastes', 1, 2)
```
Output:

Running the above code would produce a file called `Ecclesiastes.xml` in the current working directory with the approximate contents:
```xml
<?xml version="1.0" encoding="utf-8"?>
<root>
  <info>
    <language>English</language>
    <translation>NIV</translation>
    <timestamp>0000-00-00T00:00:00.000000+00:00</timestamp>
    <meaningless>0.0.0</meaningless>
  </info>
  <book name="Ecclesiastes" tag="_Ecclesiastes">
    <chapter number="1" tag="_1">
      <passage number="2" tag="_2">² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”</passage>
    </chapter>
  </book>
</root>
```

## XML Extractor
Much like the YAML Extractor, the XML Extractor uses the generated files from the XML Downloader to find passages.
```python
from meaningless import XMLExtractor

if __name__ == '__main__':
    bible = XMLExtractor()
    passage = bible.get_passage('Ecclesiastes', 1, 2)
    print(passage)
```
Output:

Assuming the XML downloader has already generated an XML file in the current directory called `Ecclesiastes.xml` which contains the book of Ecclesiastes in XML format:
```
² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”
```

## XML File Interface
The XML File Interface is a set of helper methods used to read and write XML files. Unlike the other file interfaces, this is more geared towards the specific document format used by the XML Downloader and Extractor, so you may observe some strange behaviour if you try using this for general purpose XML file interactions.
```python
from meaningless import XMLDownloader, xml_file_interface

if __name__ == '__main__':
    downloader = XMLDownloader()
    downloader.download_passage('Ecclesiastes', 1, 2)
    bible = xml_file_interface.read('./Ecclesiastes.xml')
    bible['Info']['Customised'] = True
    xml_file_interface.write('./Ecclesiastes.xml', bible)
```
Output:

Running the above code would produce a file called `Ecclesiastes.xml` in the current working directory with the approximate contents:
```xml
<?xml version="1.0" encoding="utf-8"?>
<root>
  <info>
    <language>English</language>
    <translation>NIV</translation>
    <timestamp>0000-00-00T00:00:00.000000+00:00</timestamp>
    <meaningless>0.0.0</meaningless>
    <customised>true</customised>
  </info>
  <book name="Ecclesiastes" tag="_Ecclesiastes">
    <chapter number="1" tag="_1">
      <passage number="2" tag="_2">² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”</passage>
    </chapter>
  </book>
</root>
```

**Note that you are allowed to write badly formed XML documents using this file interface, but they will cause runtime errors in your code upon trying to read and process them.**

## Legacy XML Downloader
The Legacy XML Downloader is effectively the same as the XML Downloader prior to version 0.7.0.
```python
from meaningless import XMLDownloader

if __name__ == '__main__':
    downloader = XMLDownloader(use_legacy_mode=True)
    downloader.download_passage('Ecclesiastes', 1, 2)
```
Output:

Running the above code would produce a file called `Ecclesiastes.xml` in the current working directory with the approximate contents:
```xml
<?xml version="1.0" encoding="utf-8"?>
<root>
  <Info>
    <Language>English</Language>
    <Translation>NIV</Translation>
    <Timestamp>0000-00-00T00:00:00.000000+00:00</Timestamp>
    <Meaningless>0.0.0</Meaningless>
  </Info>
  <Ecclesiastes>
    <_1>
      <_2>² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”</_2>
    </_1>
  </Ecclesiastes>
</root>
```

Note that the following adjustments are made to the downloaded contents to ensure it is a well-formed XML document:

1. A top-level "root" tag is present.
2. All tag names starting with a number are prefixed.
3. Tags corresponding to book names use a placeholder character for spaces.

## Legacy XML Extractor
The Legacy XML Extractor is effectively the same as the XML Downloader prior to version 0.7.0, and as such, only supports processing of XML files from versions prior to 0.7.0 or produced by the Legacy XML File Interface
```python
from meaningless import XMLExtractor

if __name__ == '__main__':
    bible = XMLExtractor(use_legacy_mode=True)
    passage = bible.get_passage('Ecclesiastes', 1, 2)
    print(passage)
```
Output:

Assuming the Legacy XML downloader has already generated a XML file in the current directory called `Ecclesiastes.xml` which contains the book of Ecclesiastes in XML format:
```
² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”
```

## Legacy XML File Interface
The Legacy XML File Interface is a set of helper methods used to read and write XML files using the document structure prior to version 0.7.0. You may observe some strange behaviour if you try using this for general purpose XML file interactions, so it is only recommended for use with files produced by the Legacy XML Downloader.
```python
from meaningless import XMLDownloader, legacy_xml_file_interface

if __name__ == '__main__':
    downloader = XMLDownloader(use_legacy_mode=True)
    downloader.download_passage('Ecclesiastes', 1, 2)
    bible = legacy_xml_file_interface.read('./Ecclesiastes.xml')
    bible['Info']['Customised'] = True
    legacy_xml_file_interface.write('./Ecclesiastes.xml', bible)
```
Output:

Running the above code would produce a file called `Ecclesiastes.xml` in the current working directory with the approximate contents:
```xml
<?xml version="1.0" encoding="utf-8"?>
<root>
  <Info>
    <Language>English</Language>
    <Translation>NIV</Translation>
    <Timestamp>0000-00-00T00:00:00.000000+00:00</Timestamp>
    <Meaningless>0.0.0</Meaningless>
    <Customised>true</Customised>
  </Info>
  <Ecclesiastes>
    <_1>
      <_2>² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”</_2>
    </_1>
  </Ecclesiastes>
</root>
```

**Note that you allowed to write badly formed XML documents using this file interface, but they will cause runtime errors in your code upon trying to read and process them.**

## CSV Downloader
The CSV Downloader is effectively the same as the YAML Downloader except the resulting file is in CSV format and has a different file extension.
```python
from meaningless import CSVDownloader

if __name__ == '__main__':
    downloader = CSVDownloader()
    downloader.download_passage('Ecclesiastes', 1, 2)
```
Output:

Running the above code would produce a file called `Ecclesiastes.csv` in the current working directory with the approximate contents:
```
Book,Chapter,Passage,Text,Language,Translation,Timestamp,Meaningless
Ecclesiastes,1,2,"² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”",English,NIV,0000-00-00T00:00:00.000000+00:00,0.0.0
```

## CSV Extractor
Much like the YAML Extractor, the CSV Extractor uses the generated files from the CSV Downloader to find passages.
```python
from meaningless import CSVExtractor

if __name__ == '__main__':
    bible = CSVExtractor()
    passage = bible.get_passage('Ecclesiastes', 1, 2)
    print(passage)
```
Output:

Assuming the CSV downloader has already generated a CSV file in the current directory called `Ecclesiastes.csv` which contains the book of Ecclesiastes in CSV format:
```
² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”
```

## CSV File Interface
The CSV File Interface is a set of helper methods used to read and write CSV files. This is geared towards the CSV document format used by the CSV Downloader and Extractor and cannot be used to add custom attributes to the output file when writing CSV data.
```python
from meaningless import CSVDownloader, csv_file_interface

if __name__ == '__main__':
    downloader = CSVDownloader()
    downloader.download_passage('Ecclesiastes', 1, 2)
    bible = csv_file_interface.read('./Ecclesiastes.csv')
    bible['Info']['Language'] = 'English (EN)'
    csv_file_interface.write('./Ecclesiastes.csv', bible)
```
Output:

Running the above code would produce a file called `Ecclesiastes.csv` in the current working directory with the approximate contents:
```
Book,Chapter,Passage,Text,Language,Translation,Timestamp,Meaningless
Ecclesiastes,1,2,"² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”",English (EN),NIV,0000-00-00T00:00:00.000000+00:00,0.0.0
```

## Text searching within files
All file-based extractors support passage filtering by search text or by regular expression.

The section below is a simple example that prints passages containing "meaningless" from Ecclesiastes 1:
```python
from meaningless import YAMLDownloader, YAMLExtractor

if __name__ == '__main__':
    downloader = YAMLDownloader()
    downloader.download_chapter('Ecclesiastes', 1)

    bible = YAMLExtractor()
    print(bible.find_text_in_chapter('meaningless', 'Ecclesiastes', 1))
```

Output:
```
² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”
¹⁴ I have seen all the things that are done under the sun; all of them are meaningless, a chasing after the wind.
```

The section below is another simple example that prints passages containing "meaningless" or "wisdom" from Ecclesiastes 1:
```python
from meaningless import YAMLDownloader, YAMLExtractor

if __name__ == '__main__':
    downloader = YAMLDownloader()
    downloader.download_chapter('Ecclesiastes', 1)

    bible = YAMLExtractor()
    print(bible.find_text_in_chapter('meaningless|wisdom', 'Ecclesiastes', 1, is_regex=True))
```

Output:
```
² “Meaningless! Meaningless!”
    says the Teacher.
“Utterly meaningless!
    Everything is meaningless.”
¹³ I applied my mind to study and to explore by wisdom all that is done under the heavens. What a heavy burden God has laid on mankind!
¹⁴ I have seen all the things that are done under the sun; all of them are meaningless, a chasing after the wind.
¹⁶ I said to myself, “Look, I have increased in wisdom more than anyone who has ruled over Jerusalem before me; I have experienced much of wisdom and knowledge.”
¹⁷ Then I applied myself to the understanding of wisdom, and also of madness and folly, but I learned that this, too, is a chasing after the wind.
¹⁸ For with much wisdom comes much sorrow;
    the more knowledge, the more grief.
```

# Q&A

## How to report potential bugs and other feedback?

To report bugs and other problems, create an issue in this repo that details:
- A brief description of the problem encountered
- Steps to recreate the problem (or a code sample that demonstrates the problem)
- Expected result
- The version of this library being used

If you have any questions, complaints, compliments or even ideas to improve this library, you can also leave them as a GitHub issue with the appropriate label.
Or you can also send an email to [dantran.au@gmail.com](mailto:dantran.au@gmail.com), although a response will likely take longer than replying to a GitHub issue.

## Should I manually edit the downloaded file?

**This is NOT recommended** under normal circumstances, as it may cause problems with the library API when using the modified file.

## If multiple translations are supported, why aren't there more unit tests for these?

The Base Extractor and Downloader all use the same overall structure to represent passage contents for all translations.

For the Web Extractor, the page structure of the [Bible Gateway](https://www.biblegateway.com) site is mostly the same across different translations, so as long as the translation-specific differences are handled correctly, the same set of unit tests should suffice.

## Will this library ever drop support for certain translations?

Short answer: It depends.

The primary case for dropping support for a certain Bible translation is if there is an observed problem in the extracted Bible contents which is considerably difficult to address due to how the Biblical contents is structured (in terms of HTML) on the [Bible Gateway](https://www.biblegateway.com) site. With that in mind, reinstating support for Bible translations can be reconsidered when such problems subside.

## How are omitted passages determined for each translation?

Without having to go through every single passage and check if it is omitted, a set of common omitted passages are found here: 
- https://en.wikipedia.org/wiki/List_of_New_Testament_verses_not_included_in_modern_English_translations
- http://textus-receptus.com/wiki/List_of_Omitted_Bible_Verses#List_of_Bible_verses_totally_omitted

These passages are checked on the [Bible Gateway](https://www.biblegateway.com) site, and then added to the Base Downloader's internal list of omitted passages for the relevant translation.

If you notice any problems such as unhandled omitted passages or incorrect tagging of an omitted passage in the Base Downloader, please create an issue to report it.

## Does this library provide support for the Apocrypha books?

At the moment, you can use the Web Extractor's `search()`, `search_multiple()` and other related functions to obtain passages from the Apocrypha books.
There is currently no official support for the Apocrypha books in the other downloaders and extractors, at least until the issues identified [here](https://github.com/daniel-tran/meaningless/pull/10#issuecomment-1236274786) become easier to work around.

# Contributors
- [daniel-tran](https://github.com/daniel-tran) (Creator & current maintainer)

To make a contribution to this library, refer to `CONTRIBUTING.md`.

# Disclaimer

This library is not endorsed by nor affiliated with Bible Gateway or any of its partners.

# Change Log

## 0.7.0
- Refined xml_file_interface to use a more standard XML document structure with easier integration with XSLT
  - Added `use_legacy_mode` flag to XML Downloader and Extractor to continue using the original behaviour and assist with transitioning to the updated XML file interface
  - Added legacy_xml_file_interface module for backward compatibility with XML files using the previous (deprecated) document structure
- Added download timestamp and library version information to output files
- Drop library support for Python 3.7

## 0.6.1
- Fixed an issue where the JSON file interface was writing Unicode characters incorrectly to output files

## 0.6.0
- Added text searching functionality into Base Extractor
- Added a dedicated area for experimental functionality and helper scripts
  - With enough refinement, some of these might become new features in future releases
- Added translation support for: NRSVUE
- Removed translation support for: CJB

## 0.5.0
- Added CSV Extractor and CSV Downloader
- Added csv_file_interface module to assist with CSV file access
- Added translation support for: NIVUK
- Drop library support for Python 3.6

## 0.4.0
- Documentation is now publicly available through GitHub Pages. See https://daniel-tran.github.io/meaningless/
  - This was previously an undocumented change as part of the 0.3.0 release.
- Added XML Extractor and XML Downloader
- Added xml_file_interface module to assist with XML file access
- Added translation support for: RVA

## 0.3.0
- Added initial continuous integration workflow with GitHub Actions
- Added translation support for: BRG, CJB, EHV, ESVUK, GNV, GW, ISV, JUB, NASB1995, NOG
- Drop library support for Python 3.5

## 0.2.0
- Added Base Extractor, Base Downloader, JSON Extractor and JSON Downloader
  - Base Extractor contains shared logic for both the YAML and JSON Extractors
  - Base Downloader contains shared logic for both the YAML and JSON Downloaders
- Added json_file_interface module to assist with generic JSON file access
- Added translation support for: ASV, AKJV, KJ21, LEB, MEV, NET, NLV, YLT

## 0.1.0

- Initial release!
- Added Web Extractor, YAML Extractor and YAML Downloader
- Added yaml_file_interface module to assist with generic YAML file access
- Added translation support for: ESV, KJV, NASB, NIV, NKJV, NLT, NRSV, WEB



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/daniel-tran/meaningless",
    "name": "meaningless",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "bible yaml json xml csv biblegateway",
    "author": "Daniel Tran",
    "author_email": "dantran.au@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/72/8f/df33cb25b59295ab744656402b0ded89d0be6700f29de7d55c729329da21/meaningless-0.7.0.tar.gz",
    "platform": null,
    "description": "[![Test Status](https://github.com/daniel-tran/meaningless/actions/workflows/run_tests.yaml/badge.svg)](https://github.com/daniel-tran/meaningless/actions/workflows/run_tests.yaml)\n\nMeaningless is a Python library used to retrieve, process and download Bible passages from Bible Gateway.\n\nFeatures include:\n- Passage retrieval from the [Bible Gateway](https://www.biblegateway.com) site or from a local YAML/JSON/XML/CSV file.\n- Different output formats for different purposes:\n  - Multi-line strings for printing Bible passages.\n  - Python list of strings (or in-memory data structure) for passing Bible passages to other Python logic.\n  - YAML/JSON/XML/CSV files for persistent storage of Bible passages or as input for other applications and scripts.\n- Handling of edge case passages, such as those with tabular data and omitted passages in certain translations.\n- Flags to enable particular content modifications, such as ignoring passage numbers.\n- Filtering on Bible passages from a local file based on a given text input or regular expression.\n\n**Now accepting feature requests!** If you want to see a certain feature included, please create an issue describing all the necessary details.\n\n# Installation\n\n```\npip install meaningless\n```\n\n# API Documentation\n\nDocumentation is generated using Sphinx.\n\n## Online\n\nThe API documentation is hosted through GitHub Pages at the following link: https://daniel-tran.github.io/meaningless/\n\n## Offline\n\nYou can view the API documentation as static HTML documents from `docs\\index.html`. After cloning this repo, you can load the HTML files in a web browser, which allows you to navigate to other sections.\n\n# Supported translations\n\n## English\n\n- ASV\n- AKJV\n- BRG\n- EHV\n- ESV\n- ESVUK\n- GNV\n- GW\n- ISV\n- JUB\n- KJV\n- KJ21\n- LEB\n- MEV\n- NASB\n- NASB1995\n- NET\n- NIV\n- NIVUK\n- NKJV\n- NLT\n- NLV\n- NOG\n- NRSV\n- NRSVUE\n- WEB\n- YLT\n\n## Espa\u00f1ol\n\n- RVA\n\n# Usage\n\n## Web Extractor\nThe Web Extractor is used to obtain passage information directly from [Bible Gateway](https://www.biblegateway.com).\n```python\nfrom meaningless import WebExtractor\n\nif __name__ == '__main__':\n    bible = WebExtractor()\n    passage = bible.get_passage('Ecclesiastes', 1, 2)\n    print(passage)\n```\nOutput:\n```\n\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\n```\n\n## YAML Downloader\nThe YAML Downloader is which formats passages obtained from the Bible Gateway website (using the Web Extractor) into a YAML structure and writes it out to a file:\n```python\nfrom meaningless import YAMLDownloader\n\nif __name__ == '__main__':\n    downloader = YAMLDownloader()\n    downloader.download_passage('Ecclesiastes', 1, 2)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.yaml` in the current working directory with the approximate contents:\n```yaml\nEcclesiastes:\n  1:\n    2: \"\u00b2 \u201cMeaningless! Meaningless!\u201d\\n    says the Teacher.\\n\u201cUtterly meaningless!\\n\\\n      \\    Everything is meaningless.\u201d\"\nInfo:\n  Language: English\n  Translation: NIV\n  Timestamp: '0000-00-00T00:00:00.000000+00:00'\n  Meaningless: 0.0.0\n```\n\n## YAML Extractor\nThe YAML Extractor uses the generated files from the YAML Downloader to find passages. This is faster than the Web Extractor, since it is not retrieving information from the Internet and is also unaffected by bandwidth limitations.\n```python\nfrom meaningless import YAMLExtractor\n\nif __name__ == '__main__':\n    bible = YAMLExtractor()\n    passage = bible.get_passage('Ecclesiastes', 1, 2)\n    print(passage)\n```\nOutput:\n\nAssuming the YAML downloader has already generated a YAML file in the current directory called `Ecclesiastes.yaml` which contains the book of Ecclesiastes in YAML format:\n```\n\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\n```\n\n## YAML File Interface\nThe YAML File Interface is a set of helper methods used to read and write YAML files. This can be useful if you need to do some customised processing on a downloaded YAML file.\n```python\nfrom meaningless import YAMLDownloader, yaml_file_interface\n\nif __name__ == '__main__':\n    downloader = YAMLDownloader()\n    downloader.download_passage('Ecclesiastes', 1, 2)\n    bible = yaml_file_interface.read('./Ecclesiastes.yaml')\n    bible['Info']['Customised?'] = True\n    yaml_file_interface.write('./Ecclesiastes.yaml', bible)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.yaml` in the current working directory with the approximate contents:\n```yaml\nEcclesiastes:\n  1:\n    2: \"\u00b2 \u201cMeaningless! Meaningless!\u201d\\n    says the Teacher.\\n\u201cUtterly meaningless!\\n\\\n      \\    Everything is meaningless.\u201d\"\nInfo:\n  Language: English\n  Translation: NIV\n  Timestamp: '0000-00-00T00:00:00.000000+00:00'\n  Meaningless: 0.0.0\n  Customised?: true\n```\n\n## JSON Downloader\nThe JSON Downloader is effectively the same as the YAML Downloader except the resulting file is in JSON format and has a different file extension.\n```python\nfrom meaningless import JSONDownloader\n\nif __name__ == '__main__':\n    downloader = JSONDownloader()\n    downloader.download_passage('Ecclesiastes', 1, 2)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.json` in the current working directory with the approximate contents:\n```json\n{\n  \"Ecclesiastes\": {\n    \"1\": {\n      \"2\": \"\u00b2 \u201cMeaningless! Meaningless!\u201d\\n    says the Teacher.\\n\u201cUtterly meaningless!\\n    Everything is meaningless.\u201d\"\n    }\n  },\n  \"Info\": {\n    \"Language\": \"English\",\n    \"Meaningless\": \"0.0.0\",\n    \"Timestamp\": \"0000-00-00T00:00:00.000000+00:00\",\n    \"Translation\": \"NIV\"\n  }\n}\n```\n\n## JSON Extractor\nMuch like the YAML Extractor, the JSON Extractor uses the generated files from the JSON Downloader to find passages.\n```python\nfrom meaningless import JSONExtractor\n\nif __name__ == '__main__':\n    bible = JSONExtractor()\n    passage = bible.get_passage('Ecclesiastes', 1, 2)\n    print(passage)\n```\nOutput:\n\nAssuming the JSON downloader has already generated a JSON file in the current directory called `Ecclesiastes.json` which contains the book of Ecclesiastes in JSON format:\n```\n\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\n```\n\n## JSON File Interface\nThe JSON File Interface is a set of helper methods used to read and write JSON files. Similar to the YAML File Interface, it can be used to do customised processing on a JSON file or its contents.\n```python\nfrom meaningless import JSONDownloader, json_file_interface\n\nif __name__ == '__main__':\n    downloader = JSONDownloader()\n    downloader.download_passage('Ecclesiastes', 1, 2)\n    bible = json_file_interface.read('./Ecclesiastes.json')\n    bible['Info']['Customised?'] = True\n    json_file_interface.write('./Ecclesiastes.json', bible)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.json` in the current working directory with the approximate contents:\n```json\n{\n  \"Ecclesiastes\": {\n    \"1\": {\n      \"2\": \"\u00b2 \u201cMeaningless! Meaningless!\u201d\\n    says the Teacher.\\n\u201cUtterly meaningless!\\n    Everything is meaningless.\u201d\"\n    }\n  },\n  \"Info\": {\n    \"Customised?\": true,\n    \"Language\": \"English\",\n    \"Meaningless\": \"0.0.0\",\n    \"Timestamp\": \"0000-00-00T00:00:00.000000+00:00\",\n    \"Translation\": \"NIV\"\n  }\n}\n```\n\n## XML Downloader\nThe XML Downloader is effectively the same as the YAML Downloader except the resulting file is in a specific XML format and has a different file extension.\n```python\nfrom meaningless import XMLDownloader\n\nif __name__ == '__main__':\n    downloader = XMLDownloader()\n    downloader.download_passage('Ecclesiastes', 1, 2)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.xml` in the current working directory with the approximate contents:\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <info>\n    <language>English</language>\n    <translation>NIV</translation>\n    <timestamp>0000-00-00T00:00:00.000000+00:00</timestamp>\n    <meaningless>0.0.0</meaningless>\n  </info>\n  <book name=\"Ecclesiastes\" tag=\"_Ecclesiastes\">\n    <chapter number=\"1\" tag=\"_1\">\n      <passage number=\"2\" tag=\"_2\">\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d</passage>\n    </chapter>\n  </book>\n</root>\n```\n\n## XML Extractor\nMuch like the YAML Extractor, the XML Extractor uses the generated files from the XML Downloader to find passages.\n```python\nfrom meaningless import XMLExtractor\n\nif __name__ == '__main__':\n    bible = XMLExtractor()\n    passage = bible.get_passage('Ecclesiastes', 1, 2)\n    print(passage)\n```\nOutput:\n\nAssuming the XML downloader has already generated an XML file in the current directory called `Ecclesiastes.xml` which contains the book of Ecclesiastes in XML format:\n```\n\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\n```\n\n## XML File Interface\nThe XML File Interface is a set of helper methods used to read and write XML files. Unlike the other file interfaces, this is more geared towards the specific document format used by the XML Downloader and Extractor, so you may observe some strange behaviour if you try using this for general purpose XML file interactions.\n```python\nfrom meaningless import XMLDownloader, xml_file_interface\n\nif __name__ == '__main__':\n    downloader = XMLDownloader()\n    downloader.download_passage('Ecclesiastes', 1, 2)\n    bible = xml_file_interface.read('./Ecclesiastes.xml')\n    bible['Info']['Customised'] = True\n    xml_file_interface.write('./Ecclesiastes.xml', bible)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.xml` in the current working directory with the approximate contents:\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <info>\n    <language>English</language>\n    <translation>NIV</translation>\n    <timestamp>0000-00-00T00:00:00.000000+00:00</timestamp>\n    <meaningless>0.0.0</meaningless>\n    <customised>true</customised>\n  </info>\n  <book name=\"Ecclesiastes\" tag=\"_Ecclesiastes\">\n    <chapter number=\"1\" tag=\"_1\">\n      <passage number=\"2\" tag=\"_2\">\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d</passage>\n    </chapter>\n  </book>\n</root>\n```\n\n**Note that you are allowed to write badly formed XML documents using this file interface, but they will cause runtime errors in your code upon trying to read and process them.**\n\n## Legacy XML Downloader\nThe Legacy XML Downloader is effectively the same as the XML Downloader prior to version 0.7.0.\n```python\nfrom meaningless import XMLDownloader\n\nif __name__ == '__main__':\n    downloader = XMLDownloader(use_legacy_mode=True)\n    downloader.download_passage('Ecclesiastes', 1, 2)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.xml` in the current working directory with the approximate contents:\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <Info>\n    <Language>English</Language>\n    <Translation>NIV</Translation>\n    <Timestamp>0000-00-00T00:00:00.000000+00:00</Timestamp>\n    <Meaningless>0.0.0</Meaningless>\n  </Info>\n  <Ecclesiastes>\n    <_1>\n      <_2>\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d</_2>\n    </_1>\n  </Ecclesiastes>\n</root>\n```\n\nNote that the following adjustments are made to the downloaded contents to ensure it is a well-formed XML document:\n\n1. A top-level \"root\" tag is present.\n2. All tag names starting with a number are prefixed.\n3. Tags corresponding to book names use a placeholder character for spaces.\n\n## Legacy XML Extractor\nThe Legacy XML Extractor is effectively the same as the XML Downloader prior to version 0.7.0, and as such, only supports processing of XML files from versions prior to 0.7.0 or produced by the Legacy XML File Interface\n```python\nfrom meaningless import XMLExtractor\n\nif __name__ == '__main__':\n    bible = XMLExtractor(use_legacy_mode=True)\n    passage = bible.get_passage('Ecclesiastes', 1, 2)\n    print(passage)\n```\nOutput:\n\nAssuming the Legacy XML downloader has already generated a XML file in the current directory called `Ecclesiastes.xml` which contains the book of Ecclesiastes in XML format:\n```\n\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\n```\n\n## Legacy XML File Interface\nThe Legacy XML File Interface is a set of helper methods used to read and write XML files using the document structure prior to version 0.7.0. You may observe some strange behaviour if you try using this for general purpose XML file interactions, so it is only recommended for use with files produced by the Legacy XML Downloader.\n```python\nfrom meaningless import XMLDownloader, legacy_xml_file_interface\n\nif __name__ == '__main__':\n    downloader = XMLDownloader(use_legacy_mode=True)\n    downloader.download_passage('Ecclesiastes', 1, 2)\n    bible = legacy_xml_file_interface.read('./Ecclesiastes.xml')\n    bible['Info']['Customised'] = True\n    legacy_xml_file_interface.write('./Ecclesiastes.xml', bible)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.xml` in the current working directory with the approximate contents:\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <Info>\n    <Language>English</Language>\n    <Translation>NIV</Translation>\n    <Timestamp>0000-00-00T00:00:00.000000+00:00</Timestamp>\n    <Meaningless>0.0.0</Meaningless>\n    <Customised>true</Customised>\n  </Info>\n  <Ecclesiastes>\n    <_1>\n      <_2>\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d</_2>\n    </_1>\n  </Ecclesiastes>\n</root>\n```\n\n**Note that you allowed to write badly formed XML documents using this file interface, but they will cause runtime errors in your code upon trying to read and process them.**\n\n## CSV Downloader\nThe CSV Downloader is effectively the same as the YAML Downloader except the resulting file is in CSV format and has a different file extension.\n```python\nfrom meaningless import CSVDownloader\n\nif __name__ == '__main__':\n    downloader = CSVDownloader()\n    downloader.download_passage('Ecclesiastes', 1, 2)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.csv` in the current working directory with the approximate contents:\n```\nBook,Chapter,Passage,Text,Language,Translation,Timestamp,Meaningless\nEcclesiastes,1,2,\"\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\",English,NIV,0000-00-00T00:00:00.000000+00:00,0.0.0\n```\n\n## CSV Extractor\nMuch like the YAML Extractor, the CSV Extractor uses the generated files from the CSV Downloader to find passages.\n```python\nfrom meaningless import CSVExtractor\n\nif __name__ == '__main__':\n    bible = CSVExtractor()\n    passage = bible.get_passage('Ecclesiastes', 1, 2)\n    print(passage)\n```\nOutput:\n\nAssuming the CSV downloader has already generated a CSV file in the current directory called `Ecclesiastes.csv` which contains the book of Ecclesiastes in CSV format:\n```\n\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\n```\n\n## CSV File Interface\nThe CSV File Interface is a set of helper methods used to read and write CSV files. This is geared towards the CSV document format used by the CSV Downloader and Extractor and cannot be used to add custom attributes to the output file when writing CSV data.\n```python\nfrom meaningless import CSVDownloader, csv_file_interface\n\nif __name__ == '__main__':\n    downloader = CSVDownloader()\n    downloader.download_passage('Ecclesiastes', 1, 2)\n    bible = csv_file_interface.read('./Ecclesiastes.csv')\n    bible['Info']['Language'] = 'English (EN)'\n    csv_file_interface.write('./Ecclesiastes.csv', bible)\n```\nOutput:\n\nRunning the above code would produce a file called `Ecclesiastes.csv` in the current working directory with the approximate contents:\n```\nBook,Chapter,Passage,Text,Language,Translation,Timestamp,Meaningless\nEcclesiastes,1,2,\"\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\",English (EN),NIV,0000-00-00T00:00:00.000000+00:00,0.0.0\n```\n\n## Text searching within files\nAll file-based extractors support passage filtering by search text or by regular expression.\n\nThe section below is a simple example that prints passages containing \"meaningless\" from Ecclesiastes 1:\n```python\nfrom meaningless import YAMLDownloader, YAMLExtractor\n\nif __name__ == '__main__':\n    downloader = YAMLDownloader()\n    downloader.download_chapter('Ecclesiastes', 1)\n\n    bible = YAMLExtractor()\n    print(bible.find_text_in_chapter('meaningless', 'Ecclesiastes', 1))\n```\n\nOutput:\n```\n\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\n\u00b9\u2074 I have seen all the things that are done under the sun; all of them are meaningless, a chasing after the wind.\n```\n\nThe section below is another simple example that prints passages containing \"meaningless\" or \"wisdom\" from Ecclesiastes 1:\n```python\nfrom meaningless import YAMLDownloader, YAMLExtractor\n\nif __name__ == '__main__':\n    downloader = YAMLDownloader()\n    downloader.download_chapter('Ecclesiastes', 1)\n\n    bible = YAMLExtractor()\n    print(bible.find_text_in_chapter('meaningless|wisdom', 'Ecclesiastes', 1, is_regex=True))\n```\n\nOutput:\n```\n\u00b2 \u201cMeaningless! Meaningless!\u201d\n    says the Teacher.\n\u201cUtterly meaningless!\n    Everything is meaningless.\u201d\n\u00b9\u00b3 I applied my mind to study and to explore by wisdom all that is done under the heavens. What a heavy burden God has laid on mankind!\n\u00b9\u2074 I have seen all the things that are done under the sun; all of them are meaningless, a chasing after the wind.\n\u00b9\u2076 I said to myself, \u201cLook, I have increased in wisdom more than anyone who has ruled over Jerusalem before me; I have experienced much of wisdom and knowledge.\u201d\n\u00b9\u2077 Then I applied myself to the understanding of wisdom, and also of madness and folly, but I learned that this, too, is a chasing after the wind.\n\u00b9\u2078 For with much wisdom comes much sorrow;\n    the more knowledge, the more grief.\n```\n\n# Q&A\n\n## How to report potential bugs and other feedback?\n\nTo report bugs and other problems, create an issue in this repo that details:\n- A brief description of the problem encountered\n- Steps to recreate the problem (or a code sample that demonstrates the problem)\n- Expected result\n- The version of this library being used\n\nIf you have any questions, complaints, compliments or even ideas to improve this library, you can also leave them as a GitHub issue with the appropriate label.\nOr you can also send an email to [dantran.au@gmail.com](mailto:dantran.au@gmail.com), although a response will likely take longer than replying to a GitHub issue.\n\n## Should I manually edit the downloaded file?\n\n**This is NOT recommended** under normal circumstances, as it may cause problems with the library API when using the modified file.\n\n## If multiple translations are supported, why aren't there more unit tests for these?\n\nThe Base Extractor and Downloader all use the same overall structure to represent passage contents for all translations.\n\nFor the Web Extractor, the page structure of the [Bible Gateway](https://www.biblegateway.com) site is mostly the same across different translations, so as long as the translation-specific differences are handled correctly, the same set of unit tests should suffice.\n\n## Will this library ever drop support for certain translations?\n\nShort answer: It depends.\n\nThe primary case for dropping support for a certain Bible translation is if there is an observed problem in the extracted Bible contents which is considerably difficult to address due to how the Biblical contents is structured (in terms of HTML) on the [Bible Gateway](https://www.biblegateway.com) site. With that in mind, reinstating support for Bible translations can be reconsidered when such problems subside.\n\n## How are omitted passages determined for each translation?\n\nWithout having to go through every single passage and check if it is omitted, a set of common omitted passages are found here: \n- https://en.wikipedia.org/wiki/List_of_New_Testament_verses_not_included_in_modern_English_translations\n- http://textus-receptus.com/wiki/List_of_Omitted_Bible_Verses#List_of_Bible_verses_totally_omitted\n\nThese passages are checked on the [Bible Gateway](https://www.biblegateway.com) site, and then added to the Base Downloader's internal list of omitted passages for the relevant translation.\n\nIf you notice any problems such as unhandled omitted passages or incorrect tagging of an omitted passage in the Base Downloader, please create an issue to report it.\n\n## Does this library provide support for the Apocrypha books?\n\nAt the moment, you can use the Web Extractor's `search()`, `search_multiple()` and other related functions to obtain passages from the Apocrypha books.\nThere is currently no official support for the Apocrypha books in the other downloaders and extractors, at least until the issues identified [here](https://github.com/daniel-tran/meaningless/pull/10#issuecomment-1236274786) become easier to work around.\n\n# Contributors\n- [daniel-tran](https://github.com/daniel-tran) (Creator & current maintainer)\n\nTo make a contribution to this library, refer to `CONTRIBUTING.md`.\n\n# Disclaimer\n\nThis library is not endorsed by nor affiliated with Bible Gateway or any of its partners.\n\n# Change Log\n\n## 0.7.0\n- Refined xml_file_interface to use a more standard XML document structure with easier integration with XSLT\n  - Added `use_legacy_mode` flag to XML Downloader and Extractor to continue using the original behaviour and assist with transitioning to the updated XML file interface\n  - Added legacy_xml_file_interface module for backward compatibility with XML files using the previous (deprecated) document structure\n- Added download timestamp and library version information to output files\n- Drop library support for Python 3.7\n\n## 0.6.1\n- Fixed an issue where the JSON file interface was writing Unicode characters incorrectly to output files\n\n## 0.6.0\n- Added text searching functionality into Base Extractor\n- Added a dedicated area for experimental functionality and helper scripts\n  - With enough refinement, some of these might become new features in future releases\n- Added translation support for: NRSVUE\n- Removed translation support for: CJB\n\n## 0.5.0\n- Added CSV Extractor and CSV Downloader\n- Added csv_file_interface module to assist with CSV file access\n- Added translation support for: NIVUK\n- Drop library support for Python 3.6\n\n## 0.4.0\n- Documentation is now publicly available through GitHub Pages. See https://daniel-tran.github.io/meaningless/\n  - This was previously an undocumented change as part of the 0.3.0 release.\n- Added XML Extractor and XML Downloader\n- Added xml_file_interface module to assist with XML file access\n- Added translation support for: RVA\n\n## 0.3.0\n- Added initial continuous integration workflow with GitHub Actions\n- Added translation support for: BRG, CJB, EHV, ESVUK, GNV, GW, ISV, JUB, NASB1995, NOG\n- Drop library support for Python 3.5\n\n## 0.2.0\n- Added Base Extractor, Base Downloader, JSON Extractor and JSON Downloader\n  - Base Extractor contains shared logic for both the YAML and JSON Extractors\n  - Base Downloader contains shared logic for both the YAML and JSON Downloaders\n- Added json_file_interface module to assist with generic JSON file access\n- Added translation support for: ASV, AKJV, KJ21, LEB, MEV, NET, NLV, YLT\n\n## 0.1.0\n\n- Initial release!\n- Added Web Extractor, YAML Extractor and YAML Downloader\n- Added yaml_file_interface module to assist with generic YAML file access\n- Added translation support for: ESV, KJV, NASB, NIV, NKJV, NLT, NRSV, WEB\n\n\n",
    "bugtrack_url": null,
    "license": "MIT License",
    "summary": "Retrieves, processes and downloads Bible passages from Bible Gateway",
    "version": "0.7.0",
    "split_keywords": [
        "bible",
        "yaml",
        "json",
        "xml",
        "csv",
        "biblegateway"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c3642951414c4f06a77a1022494e2ed4a4f1d081f1a0dea54e6da799ec360589",
                "md5": "f654c92ffc6eda51878cd09e32b74bf0",
                "sha256": "108fc3c9e6a6fa00393001e32f9bf7c3d81248c043129513999aa0bdae2e995e"
            },
            "downloads": -1,
            "filename": "meaningless-0.7.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f654c92ffc6eda51878cd09e32b74bf0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 43554,
            "upload_time": "2023-01-25T20:10:11",
            "upload_time_iso_8601": "2023-01-25T20:10:11.218925Z",
            "url": "https://files.pythonhosted.org/packages/c3/64/2951414c4f06a77a1022494e2ed4a4f1d081f1a0dea54e6da799ec360589/meaningless-0.7.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "728fdf33cb25b59295ab744656402b0ded89d0be6700f29de7d55c729329da21",
                "md5": "da29ab7702d1ab87c27c0adcff1b8dc4",
                "sha256": "bcd64b2d0ae26440dac3ff93e9ff1c82f1bd32b5fccbb851adbd40f91a7c2f21"
            },
            "downloads": -1,
            "filename": "meaningless-0.7.0.tar.gz",
            "has_sig": false,
            "md5_digest": "da29ab7702d1ab87c27c0adcff1b8dc4",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 39307,
            "upload_time": "2023-01-25T20:10:12",
            "upload_time_iso_8601": "2023-01-25T20:10:12.730932Z",
            "url": "https://files.pythonhosted.org/packages/72/8f/df33cb25b59295ab744656402b0ded89d0be6700f29de7d55c729329da21/meaningless-0.7.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-01-25 20:10:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "daniel-tran",
    "github_project": "meaningless",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "meaningless"
}
        
Elapsed time: 0.03231s