# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['schemasheets', 'schemasheets.conf', 'schemasheets.utils']

package_data = \
{'': ['*']}

install_requires = \
['Jinja2>=3.0.3,<4.0.0',
 'bioregistry>=0.4.30,<0.5.0',
 'linkml>=1.1.15,<2.0.0',
 'ontodev-cogs>=0.3.3,<0.4.0']

entry_points = \
{'console_scripts': ['sheets2linkml = fairstructure.schemamaker:convert',
                     'sheets2project = '
                     'fairstructure.sheets_to_project:multigen']}

setup_kwargs = {
    'name': 'schemasheets',
    'version': '0.1.1',
    'description': 'Package to author schemas using spreadsheets',
    'long_description': '# schemasheets - structuring your data using spreadsheets\n\nCreate a data dictionary / schema for your data using simple spreadsheets - no coding required.\n\n- Author your schema as a google sheet or excel spreadsheet\n- [Generate schemas](https://linkml.io/linkml/generators/index.html):\n   - LinkML\n   - SHACL and ShEx\n   - JSON-Schema\n   - SQL DDL\n   - OWL\n- Validate data automatically\n\nSee the [test google sheets](https://docs.google.com/spreadsheets/d/1wVoaiFg47aT9YWNeRfTZ8tYHN8s8PAuDx5i2HUcDpvQ/edit#gid=55566104) for examples\n\nSee also the [examples](examples) folder which has an end-to-end example\n\n## How it works\n\nThe following example shows a schema sheet for a schema that is focused around\nthe concept of a Person. The rows in the sheet describe either *classes* or *slots* (fields)\n\n|record|field|key|multiplicity|range|desc|schema.org\n|---|---|---|---|---|---|---|\n|`>` class|slot|identifier|cardinality|range|description|`exact_mappings: {curie_prefix: sdo}`\n|-|id|yes|1|string|any identifier|identifier\n|-|description|no|0..1|string|a textual description|description\n|Person||n/a|n/a|n/a|a person,living or dead|Person\n|Person|id|yes|1|string|identifier for a person|identifier\n|Person, Organization|name|no|1|string|full name|name\n|Person|age|no|0..1|decimal|age in years|-\n|Person|gender|no|0..1|decimal|age in years|-\n|Person|has medical history|no|0..*|MedicalEvent|medical history|-\n|MedicalEvent||n/a|n/a|n/a|-|-\n\n * [personinfo google sheet](https://docs.google.com/spreadsheets/d/1wVoaiFg47aT9YWNeRfTZ8tYHN8s8PAuDx5i2HUcDpvQ/edit#gid=55566104)\n\nThe sheet is structured as follows:\n\n- The first line is a header line. You get to decide the column headers\n- Subsequent lines starting with `>` are *column descriptors*\n   - these provide a way to interpret the columns\n   - descriptors can be drawn from the [linkml](https://linkml.io) vocabulary\n- Remaining rows are elements of your schema\n   - Each element gets its own row\n   - A row can represent a class (record, table), field (column), enumeration, or other element types\n\nThe most basic schema concepts are *classes* and *slots*\n\n- classes represent record types, similar to tables in a database or sheets in a spreadsheet\n- slots represent fields, similar to columns in a database or spreadsheet \n\nThese can be used in combination:\n\n- If a *class* is provided, but a *slot* is not, then the row represents a class. \n- If a *slot* is provided, but a *class* is not, then the row represents a slot (field)\n- If both *class* and *slot* are provided, then the row represents the *usage* of a slot in the context of a class\n\n\n### Generating schemas\n\nAssuming your schema is arranged as a set of sheets (TSV files) in the `src` folder:\n\n```bash\nsheets2project -d . src/*.tsv\n```\n\nThis will generate individual folders for jsonschema, shacl, ... as well as\na website that can be easily hosted on github.\n\nTo create only LinkML yaml:\n\n```bash\nschemasheets -o my.yaml  src/*.tsv\n```\n\n\n## Simple data dictionaries\n\nThis framework allows you to represent complex relation-style schemas\nusing spreadsheets/TSVs. But it also allows for representation of simple "data dictionaries" or "minimal information lists".\nThese can be thought of as "wide tables", e.g. representing individual observations or observable units such as persons or samples.\n\nTODO\n\n\n## Prefixes\n\nIf you specify a column descriptor of `prefix`, then rows with that column\npopulated will represent prefixes. The prefix expansion is specified using [prefix_reference](https://w3id.org/linkml/prefix_reference) \n\nExample:\n\n|prefix|URI\n|---|---|\n|`>` prefix|prefix_reference\n|sdo|http://schema.org/\n|personinfo|https://w3id.org/linkml/examples/personinfo/\n|famrel|https://example.org/FamilialRelations#\n|GSSO|http://purl.obolibrary.org/obo/GSSO_|\n\nWe recommend you specify prefixes in their own sheet.\n\nIf prefixes are not provided, and you do not specify `--no-repair` then prefixes\nwill be inferred using [bioregistry](https://bioregistry.io)\n\n## Schema-level metadata\n\nIf you specify a column descriptor of `schema`, then rows with that column\npopulated will represent schemas.\n\nExample:\n\n|Schema|uri|Desc|Schema Prefix\n|---|---|---|---|\n|`>` schema|id|description|default_prefix\n|PersonInfo|https://w3id.org/linkml/examples/personinfo|Information about people, based on [schema.org](http://schema.org)|personinfo\n\nThe list of potential descriptors for a schema can be found by consulting\n[SchemaDefinition](https://w3id.org/linkml/SchemaDefinition) in the LinkML metamodel.\n\nBoth `id` and `name` are required, these will be auto-filled if you don\'t fill this in.\n\nPopulating the fields `description` and `license` is strongly encouraged.\n\nCurrently multiple schemas are not supported, we recommend providing a single-row sheet for\nschema metadata\n\n## Enums\n\nTwo descriptors are provided for enumerations:\n\n- `enum`\n- `permissible_value`\n\nThese can be used in combination:\n\n- If `enum` is provided, and `permissible_value` is not, then the row represents an enumeration\n- If both `enum` and `permissible_value` are provided, the row represents a particular enum value\n\nThe following example includes two enums:\n\n|ValueSet|Value|Mapping|Desc\n|---|---|---|---|\n|`>` enum|permissible_value|meaning|description\n|FamilialRelationshipType|-|-|familial relationships\n|FamilialRelationshipType|SIBLING_OF|famrel:01|share the same parent\n|FamilialRelationshipType|PARENT_OF|famrel:02|biological parent\n|FamilialRelationshipType|CHILD_OF|famrel:03|inverse of parent\n|GenderType|-|-|gender\n|GenderType|nonbinary man|GSSO:009254|-\n|GenderType|nonbinary woman|GSSO:009253|-\n|...|...|...|-\n\n * [enums google sheet](https://docs.google.com/spreadsheets/d/1wVoaiFg47aT9YWNeRfTZ8tYHN8s8PAuDx5i2HUcDpvQ/edit#gid=823426713)\n \nAll other descriptors are optional, but we recommend you provide descriptions of\nboth the enumeration and the [meaning](https://w3id.org/linkml/meaning) descriptor which\nmaps the value to a vocabulary or ontology term.\n\nFor more on enumerations, see [the linkml tutorial](https://linkml.io/linkml/intro/tutorial06.html)\n\n## Specifying cardinality\n\nSee configschema.yaml for all possible vocabularies, these include:\n\n- UML strings, e.g. \'0..1\'\n- text strings matching the cardinality vocabulary, e.g. \'zero to one\'\n- codes used in cardinality vocabulary, e.g. O, M, ...\n\nThe vocabulary maps to underlying LinkML primitives:\n\n- [required](https://w3id.org/linkml/required)\n- [multivalued](https://w3id.org/linkml/multivalued)\n- [recommended](https://w3id.org/linkml/recommended)\n\n## Slot-class grids\n\nIf you have a large number of fields/columns, with varying applicability/cardinality\nacross different classes, it can be convenient to specify this as a grid.\n\nAn example is a minimal information standard that includes different packages or checklists, e.g. MIxS.\n\nFor example:\n\n|term|title|desc|mi_patient|mi_mod|mi_terrestrial|mi_marine|mi_extraterrestrial|\n|---|---|---|---|---|---|---|---|\n|`>` slot|title|description|cardinality|cardinality|cardinality|cardinality|cardinality|\n|`>`|||`applies_to_class: MI patient`|`applies_to_class: MI model organism`|`applies_to_class: MI terrestrial sample`|`applies_to_class: MI marine sample`|`applies_to_class: MI extraterrestrial sample`|\n|id|unique identifier|a unique id|M|M|M|M|M|\n|alt_ids|other identifiers|any other identifiers|O|O|O|O|O|\n|body_site|body site|location where sample is taken from|M|R|-|-|-|\n|disease|disease status|disease the patient had|M|O|-|-|-|\n|age|age|age|M|R|-|-|-|\n|depth|depth|depth in ground or water|-|-|R|R|R|\n|alt|altitude|height above sea level|||R|R|R|\n|salinity|salinity|salinity|||R|R|R|\n|porosity|porosity|porosity||||||\n|location|location|location on earth||||||\n|astronomical_body|astronomical body|planet or other astronomical object where sample was collected|||||M|\n\n * [data dictionary google sheet](https://docs.google.com/spreadsheets/d/1wVoaiFg47aT9YWNeRfTZ8tYHN8s8PAuDx5i2HUcDpvQ/edit#gid=1290069715)\n\nHere the `applies_to_class` descriptor indicates that the column value for the slot indicated in the row\nis interpreted as slot usage for that class. \n\n## Metatype fields\n\nIn all of the examples above, distinct descriptors are used for class names, slot names, type names, enum names, etc\n\nAn alternative pattern is to mix element types in a single sheet, indicate the name of the element using `name` and the type using `metatype`.\n\nFor example:\n\n|type|item|applies to|key|multiplicity|range|parents|desc|schema.org|wikidata|belongs|status|notes|\n|---|---|---|---|---|---|---|---|---|---|---|---|---|\n|`>` metatype|name|class|identifier|cardinality|range|is_a|description|`exact_mappings: {curie_prefix: sdo}`|`exact_mappings: {curie_prefix: wikidata}`|in_subset|status|ignore|\n|`> vmap: {C: class, F: slot}`|||||||||||||\n|`>`|||||||||curie_prefix: wikidata||`vmap: {T: testing, R: release}`||\n|F|id||yes|1|string||any identifier|identifier|||||\n|F|name|Person, Organization|no|1|string||full name|name|||||\n|F|description||no|0..1|string||a textual description|description|||||\n|F|age|Person|no|0..1|decimal||age in years||||||\n|F|gender|Person|no|0..1|decimal||age in years||||||\n|F|has medical history|Person|no|0..*|MedicalEvent||medical history||||T||\n|C|Person||||||a person,living or dead|Person|Q215627||R||\n|C|Event||||||grouping class for events||Q1656682|a|R||\n|C|MedicalEvent|||||Event|a medical encounter|||b|T||\n|C|ForProfit|||||Organization|||||||\n|C|NonProfit|||||Organization|||Q163740|||foo|\n\n * [personinfo with tyoes](https://docs.google.com/spreadsheets/d/1wVoaiFg47aT9YWNeRfTZ8tYHN8s8PAuDx5i2HUcDpvQ/edit#gid=509198484)\n\n# Formal specification\n\nIn progress. The following is a sketch. Please refer to the above examples for elucidation.\n\n- The first line is a HEADER line.\n   - Each column must be non-null and unique\n   - In future grouping columns may be possible\n- Subsequent lines starting with `>` are *column configurations*\n   - A column configuration can be split over multiple lines\n   - Each line must be a valid yaml string (note that a single token is valid yaml for that token)\n   - The first config line must include a *descriptor*\n   - Subsequent lines are *settings* for that descriptor\n   - A descriptor can be one of:\n      - Any LinkML metamodel slot (e.g. description, comments, required, recommended, multivalued)\n      - The keyword `cardinality`\n      - An element metatype (schema, prefix, class, enum, slot, type, subset, permissible_value)\n   - Setting can be taken from configschema.yaml\n      - vmap provides a mapping used to translate column values. E.g. a custom "yes" or "no" to "true" or "false"\n      - various keys provide ways to auto-prefix or manipulate strings\n- Remaining rows are elements of your schema\n   - Each element gets its own row\n   - A row can represent a class (record, table), field (column), enumeration, or other element types\n   - The type of the row is indicated by whether columns with metatype descriptors are filled\n      - E.g. if a column header "field" has a descriptor "slot" then any row with a non-null value is interpreted as a slot\n   - If a `metatype` descriptor is present then this is used\n   - A row must represent exactly one element type\n   - If both class and slot descriptors are present then the row is interpreted as a slot in the context of that class (see slot_usage)\n- All sheets/TSVs are combined together into a single LinkML schema as YAML\n- This LinkML schema can be translated to other formats as per the LinkML [generators](https://linkml.io/linkml/generators/index.html)\n\n# Working with files / google sheets\n\nThis tool takes as input a collection of sheets, which are\nstored as TSV files.\n\nYou can make use of various ways of managing/organizing these:\n\n- TSVs files maintained in GitHub\n- Google sheets\n- Excel spreadsheets\n- SQLite databases\n\nTips for each of these and for organizing your information are provided below\n\n## Multiple sheets vs single sheets\n\nIt is up to you whether you represent your schema as a single sheet or as multiple sheets\n\nHowever, if your schema includes a mixture of different element types, you may end up with\na lot of null values if you have a single sheet. It can be more intuitive to "normalize" your schema\ndescription into different sheets:\n\n- sheets for classes/slots\n- sheets for enums\n- sheets for types\n\nCurrently schemasheets has no built in facilities for interacting directly with google sheets - it is up to you to both download and upload these\n\nTODO: scripts for merging/splitting sheets\n\n## Manual upload/download\n\nNote that you can create a URL from a google sheet to the TSV download - TODO\n\n## COGS\n\nWe recommend the COGS framework for working with google sheets\n\n- [cogs](https://github.com/ontodev/cogs)\n\nA common pattern is a single sheet document for a schema, with\ndifferent sheets/tabs for different parts of the schema\n\nTODO: example\n\n# Working with Excel spreadsheets\n\nCurrently no direct support, it is up to you to load/save as individual TSVs\n\n# Working with SQLite\n\n',
    'author': 'cmungall',
    'author_email': 'cjm@berkeleybop.org',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/linkml/schemasheets',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'entry_points': entry_points,
    'python_requires': '>=3.9,<4.0',
}


setup(**setup_kwargs)
