# Superspreader đź¦
Superspreader is a little helper library that simplifies working with spreadsheets.
It is built on top of [openpyxl](https://openpyxl.readthedocs.io/en/stable/).
OpenPyXL is its only dependency.
Instead of looping over rows and columns manually, the structure of a spreadsheet
is described in a class:
```
from superspreader import fields
from superspreader.sheets import BaseSheet
class AlbumSheet(BaseSheet):
"""
This class describes a sheet in an Excel document
"""
sheet_name = "Albums" # The sheet is named “albums”
header_rows = 3 # The sheet has three header rows
# The column labels are in the second row.
# It is *not* zero based to match the Excel row number
label_row = 2
# The columns
artist = fields.CharField(source="Artist", required=True)
album = fields.CharField(source="Album")
release_date = fields.DateField(source="Release Date")
average_review = fields.FloatField(source="Average Review")
chart_position = fields.IntegerField(source="Chart Position")
```
Ready? Let’s load an Excel spreadsheet!
```
if __name__ == "__main__":
sheet = AlbumSheet("albums.xlsx")
# Load and parse data from the document
sheet.load()
print(sheet.has_errors)
# False
print(sheet.errors)
# []
print(sheet.infos)
# []
for row_dict in sheet:
print(row_dict)
# {'artist': 'David Bowie', 'album': 'Toy', 'release_date': datetime.date(2022, 1, 7), 'average_review': 4.3, 'chart_position': 5}
# {'artist': 'The Wombats', 'album': 'Fix Yourself, Not The World', 'release_date': datetime.date(2022, 3, 7), 'average_review': 3.9, 'chart_position': 7}
# {'artist': 'Kokoroko', 'album': 'Could We Be More', 'release_date': datetime.date(2022, 8, 1), 'average_review': 4.7, 'chart_position': 30}
```
In `tests/spreadsheets` is a sample spreadsheet that is used for testing. Feel free to fiddle around.
There’s a lot more to say and I’ll update the documentation as I go.
## Field params
Fields must have a `source`”`parameter, that holds the column name for the spreadsheet.`unique=True` may be used to indicate that a field’s value must be unique.
## Adding static & dynamic data to rows
To provide additional data, use `extra_data`. Data from the spreadsheet take precedence over extra data.
```
extra_data = {
"status": "released"
}
sheet = AlbumSheet("albums.xlsx", extra_data=extra_data)
sheet.load()
# {'artist': 'David Bowie', 'album': 'Toy', 'release_date': datetime.date(2022, 1, 7), 'average_review': 4.3, 'chart_position': 5, 'status': 'released'}
```
Use a callable for dynamic extra data:
```
extra_data = {
"summary": lambda row: f"“{row.get('album')}” by {row.get('artist')}"
}
sheet = AlbumSheet("albums.xlsx", extra_data=extra_data)
# {'artist': 'David Bowie', 'album': 'Toy', 'release_date': datetime.date(2022, 1, 7), 'average_review': 4.3, 'chart_position': 5, 'summary': '“Toy” by David Bowie'}
```
## Changelog
### 0.2.7
- Adds support for unique validation
### 0.2.3
- Adds support for inheriting sheets (before that, fields from base classes weren’t recognized)
### 0.2.2
- Adds support for callables in `extra_data`
### 0.2.1
- Adds support for providing field defaults by setting the `default` attribute or providing an instance-label value: `fields.CharField(source="Album", default="not specified")`
---
The API is inspired by [Django’s model API](https://docs.djangoproject.com/en/dev/ref/models/) and [ElasticSearch DSL](https://elasticsearch-dsl.readthedocs.io/en/latest/persistence.html#document).
Raw data
{
"_id": null,
"home_page": "https://github.com/julianklotz/superspreader",
"name": "superspreader",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6, <4",
"maintainer_email": "",
"keywords": "excel,spreadsheets,import,csv,tsv,openpyxl",
"author": "Julian Klotz",
"author_email": "post@julianklotz.de",
"download_url": "https://files.pythonhosted.org/packages/69/92/384a09d237f40f024a9de0df3ee7eb024f2f8ee4ed7a8d8dc4d13d004f2c/superspreader-0.2.7.2.tar.gz",
"platform": null,
"description": "# Superspreader \ud83e\udda0\n\nSuperspreader is a little helper library that simplifies working with spreadsheets.\nIt is built on top of [openpyxl](https://openpyxl.readthedocs.io/en/stable/).\nOpenPyXL is its only dependency.\n\nInstead of looping over rows and columns manually, the structure of a spreadsheet\nis described in a class:\n\n```\nfrom superspreader import fields\nfrom superspreader.sheets import BaseSheet\n\n\nclass AlbumSheet(BaseSheet):\n \"\"\"\n This class describes a sheet in an Excel document\n \"\"\"\n\n sheet_name = \"Albums\" # The sheet is named \u201calbums\u201d\n header_rows = 3 # The sheet has three header rows\n\n # The column labels are in the second row.\n # It is *not* zero based to match the Excel row number\n label_row = 2\n\n\n # The columns\n artist = fields.CharField(source=\"Artist\", required=True)\n album = fields.CharField(source=\"Album\")\n release_date = fields.DateField(source=\"Release Date\")\n average_review = fields.FloatField(source=\"Average Review\")\n chart_position = fields.IntegerField(source=\"Chart Position\")\n```\n\nReady? Let\u2019s load an Excel spreadsheet!\n\n```\nif __name__ == \"__main__\":\n sheet = AlbumSheet(\"albums.xlsx\")\n # Load and parse data from the document\n sheet.load()\n\n print(sheet.has_errors)\n # False\n print(sheet.errors)\n # []\n print(sheet.infos)\n # []\n\n for row_dict in sheet:\n print(row_dict)\n\n# {'artist': 'David Bowie', 'album': 'Toy', 'release_date': datetime.date(2022, 1, 7), 'average_review': 4.3, 'chart_position': 5}\n# {'artist': 'The Wombats', 'album': 'Fix Yourself, Not The World', 'release_date': datetime.date(2022, 3, 7), 'average_review': 3.9, 'chart_position': 7}\n# {'artist': 'Kokoroko', 'album': 'Could We Be More', 'release_date': datetime.date(2022, 8, 1), 'average_review': 4.7, 'chart_position': 30}\n```\n\nIn `tests/spreadsheets` is a sample spreadsheet that is used for testing. Feel free to fiddle around.\n\nThere\u2019s a lot more to say and I\u2019ll update the documentation as I go.\n\n## Field params\n\nFields must have a `source`\u201d`parameter, that holds the column name for the spreadsheet.`unique=True` may be used to indicate that a field\u2019s value must be unique.\n\n## Adding static & dynamic data to rows\n\nTo provide additional data, use `extra_data`. Data from the spreadsheet take precedence over extra data.\n\n```\nextra_data = {\n \"status\": \"released\"\n}\nsheet = AlbumSheet(\"albums.xlsx\", extra_data=extra_data)\nsheet.load()\n# {'artist': 'David Bowie', 'album': 'Toy', 'release_date': datetime.date(2022, 1, 7), 'average_review': 4.3, 'chart_position': 5, 'status': 'released'}\n```\n\nUse a callable for dynamic extra data:\n\n```\nextra_data = {\n \"summary\": lambda row: f\"\u201c{row.get('album')}\u201d by {row.get('artist')}\"\n}\n\nsheet = AlbumSheet(\"albums.xlsx\", extra_data=extra_data)\n# {'artist': 'David Bowie', 'album': 'Toy', 'release_date': datetime.date(2022, 1, 7), 'average_review': 4.3, 'chart_position': 5, 'summary': '\u201cToy\u201d by David Bowie'}\n```\n\n## Changelog\n\n### 0.2.7\n\n- Adds support for unique validation\n\n### 0.2.3\n\n- Adds support for inheriting sheets (before that, fields from base classes weren\u2019t recognized)\n\n### 0.2.2\n\n- Adds support for callables in `extra_data`\n\n### 0.2.1\n\n- Adds support for providing field defaults by setting the `default` attribute or providing an instance-label value: `fields.CharField(source=\"Album\", default=\"not specified\")`\n\n---\n\nThe API is inspired by [Django\u2019s model API](https://docs.djangoproject.com/en/dev/ref/models/) and [ElasticSearch DSL](https://elasticsearch-dsl.readthedocs.io/en/latest/persistence.html#document).\n",
"bugtrack_url": null,
"license": "",
"summary": "Load data from spreadsheets easily",
"version": "0.2.7.2",
"project_urls": {
"Homepage": "https://github.com/julianklotz/superspreader",
"Source": "https://github.com/julianklotz/superspreader"
},
"split_keywords": [
"excel",
"spreadsheets",
"import",
"csv",
"tsv",
"openpyxl"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "558553ba0fee8c78fa1e824bb972764dbad7e9dd8b97122fe64c91b18fe6f7e6",
"md5": "7e75b9a923b1fdca3b3e737f2e6b5e50",
"sha256": "072cc2e1b078e2713a06445a18afd90561aff8c7850148951e49332e017467b5"
},
"downloads": -1,
"filename": "superspreader-0.2.7.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7e75b9a923b1fdca3b3e737f2e6b5e50",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6, <4",
"size": 9842,
"upload_time": "2023-07-18T09:35:37",
"upload_time_iso_8601": "2023-07-18T09:35:37.334456Z",
"url": "https://files.pythonhosted.org/packages/55/85/53ba0fee8c78fa1e824bb972764dbad7e9dd8b97122fe64c91b18fe6f7e6/superspreader-0.2.7.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "6992384a09d237f40f024a9de0df3ee7eb024f2f8ee4ed7a8d8dc4d13d004f2c",
"md5": "b3d757e3dc8f401e888a8005e01728fe",
"sha256": "9b5d0dc64e347823be345cef358a071b1dc8407aaa8b8f8a7e7e20c108647803"
},
"downloads": -1,
"filename": "superspreader-0.2.7.2.tar.gz",
"has_sig": false,
"md5_digest": "b3d757e3dc8f401e888a8005e01728fe",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6, <4",
"size": 11927,
"upload_time": "2023-07-18T09:35:38",
"upload_time_iso_8601": "2023-07-18T09:35:38.321095Z",
"url": "https://files.pythonhosted.org/packages/69/92/384a09d237f40f024a9de0df3ee7eb024f2f8ee4ed7a8d8dc4d13d004f2c/superspreader-0.2.7.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-07-18 09:35:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "julianklotz",
"github_project": "superspreader",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "openpyxl",
"specs": [
[
"==",
"3.0.10"
]
]
},
{
"name": "pre-commit",
"specs": []
}
],
"tox": true,
"lcname": "superspreader"
}