Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data_collections_api/cli/data_collections_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def get_arg_parser() -> argparse.ArgumentParser:
"-f",
"--format",
choices=("json", "yaml"),
help="Parse FILE as this type (default: determine from suffix).",
help="Dump FILE as this type (default: determine from suffix).",
default=None,
)
sp.set_defaults(func=dump_example)
Expand Down
102 changes: 66 additions & 36 deletions data_collections_api/schemas/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,105 @@

from datetime import date
from urllib.parse import urlparse, urlunparse
from uuid import UUID

from schema import And, Optional, Or, Regex, Schema, Use
from schema import And, Literal, Optional, Or, Regex, Schema, Use

ORCID_ID_RE = r"(\d{4}-){3}\d{4}"
UUID_RE = r"\d{8}-(\d{4}-){3}\d{12}"

id_schema = Or(
{
"scheme": "orcid",
"identifier": Regex(ORCID_ID_RE),
Literal("scheme", description="ID scheme."): "orcid",
Literal("identifier", description="An [ORCID](https://orcid.org)."): Regex(ORCID_ID_RE),
},
{
"identifier": And(Use(urlparse), lambda x: x.scheme and x.netloc, Use(urlunparse)),
Optional("scheme", default="doi"): "doi",
Optional(Literal("scheme", description="ID scheme."), default="doi"): "doi",
Literal("identifier", description="A [DOI](https://www.doi.org)"): And(
Use(urlparse), lambda x: x.scheme and x.netloc, Use(urlunparse)
),
},
)

creator_schema = Schema(
{
Optional("affiliations"): [
Optional(Literal("affiliations", description="Member affiliations.")): [
{
"name": str,
Literal("name", description="Name of institution."): str,
},
],
"person_or_org": {
Or("name", "family_name"): And(str, len),
Optional("given_name"): And(str, len),
Optional("identifiers"): [id_schema],
"type": Or("personal"),
Literal("person_or_org", description="Person or organisation."): {
Or(
Literal("name", description="Full set of given names."),
Literal("family_name", description="Family name(s)."),
): And(str, len),
Optional(Literal("given_name", description="Given name(s).")): And(str, len),
Optional(Literal("identifiers", description="ORCIDs or other IDs")): [id_schema],
Literal("type", description="Personal or organisation."): Or("personal"),
},
},
ignore_extra_keys=True,
)

metadata_schema = Schema(
{
"title": And(str, len),
"description": And(str, len),
"creators": [creator_schema],
"rights": [
Literal("title", description="Title of resource."): And(str, len),
Literal("description", description="Summary of resource."): And(str, len),
Literal("creators", description="List of creators."): [creator_schema],
Literal("rights", description="Rights or license."): [
{
"id": Or("cc-by-4.0"),
Literal("id", description="ID of rights or license."): Or("cc-by-4.0"),
},
],
"resource_type": {
"id": Or("model"),
Literal("resource_type", description="Type of resource."): {
Literal("id", description="Resource class."): Or("model"),
},
Optional("subjects", default=[]): [{"subject": str}],
"version": Regex(r"^v\d+(\.\d+)*"),
Optional("publisher"): str,
Optional("publication_date"): Or(date.fromisoformat, date.fromtimestamp),
Optional("identifiers"): [id_schema],
Optional(
Literal("subjects", description="List of keywords defining subjects resource covers."),
default=[],
): [{Literal("subject", description="Subject keyword."): str}],
Literal("version", description="Current version of resource."): Regex(r"^v\d+(\.\d+)*"),
Optional(Literal("publisher", description="Publisher of resource.")): str,
Optional(Literal("publication_date", description="Date of publication of resource.")): Or(
date.fromisoformat, date.fromtimestamp
),
Optional(
Literal("identifiers", description="Resource identifiers such as ORCID or DOI.")
): [id_schema],
},
)

base_schema = Schema(
{
Optional("access", default={"files": "public", "record": "public"}): {
Optional("embargo"): {
"active": bool,
"reason": Or(str, None),
Optional(
Literal("access", description="Accessibility of data outside of owners."),
default={"files": "public", "record": "public"},
): {
Optional(Literal("embargo", description="Details of resource embargo.")): {
Literal("active", description="Whether resource is under embargo."): bool,
Literal("reason", description="Cause for embargo."): Or(str, None),
},
Optional("files", default="public"): Or("public", "private"),
Optional("record", default="public"): Or("public", "private"),
Optional("status"): Or("open", "closed"),
Optional(
Literal("files", description="Accessibility to individual files."), default="public"
): Or("public", "private"),
Optional(
Literal("record", description="Accessibility to record as a whole."),
default="public",
): Or("public", "private"),
Optional(Literal("status", description="Current status or resource.")): Or(
"open", "closed"
),
},
Optional("files"): {"enabled": bool},
"custom_fields": {"dsmd": [dict]},
"metadata": metadata_schema,
Optional("community"): UUID,
Optional(Literal("files", description="Details of files.")): {
Literal("enabled", description="Whether file is enabled."): bool
},
Literal("custom_fields", description="Block for custom data."): {
Literal("dsmd", description="Domain specific metadata (dsmd)."): [dict]
},
Literal("metadata", description="Resource metadata."): metadata_schema,
Optional(
Literal("community", description="UUID of community associated with resource.")
): Regex(UUID_RE),
},
description="Base schema from which community specific schemas are built.",
name="base",
)
29 changes: 29 additions & 0 deletions docs/source/api/data_collections_api.cli.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
data\_collections\_api.cli package
==================================

Submodules
----------

data\_collections\_api.cli.data\_collections\_main module
---------------------------------------------------------

.. automodule:: data_collections_api.cli.data_collections_main
:members:
:show-inheritance:
:undoc-members:

data\_collections\_api.cli.record\_upload module
------------------------------------------------

.. automodule:: data_collections_api.cli.record_upload
:members:
:show-inheritance:
:undoc-members:

Module contents
---------------

.. automodule:: data_collections_api.cli
:members:
:show-inheritance:
:undoc-members:
9 changes: 1 addition & 8 deletions docs/source/api/data_collections_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Subpackages
:maxdepth: 4

data_collections_api.cli
data_collections_api.schemas

Submodules
----------
Expand Down Expand Up @@ -36,14 +37,6 @@ data\_collections\_api.metadata module
:show-inheritance:
:undoc-members:

data\_collections\_api.schema module
------------------------------------

.. automodule:: data_collections_api.schema
:members:
:show-inheritance:
:undoc-members:

Module contents
---------------

Expand Down
21 changes: 21 additions & 0 deletions docs/source/api/data_collections_api.schemas.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
data\_collections\_api.schemas package
======================================

Submodules
----------

data\_collections\_api.schemas.base module
------------------------------------------

.. automodule:: data_collections_api.schemas.base
:members:
:show-inheritance:
:undoc-members:

Module contents
---------------

.. automodule:: data_collections_api.schemas
:members:
:show-inheritance:
:undoc-members:
4 changes: 2 additions & 2 deletions docs/source/api/modules.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
API Documentation
=================
data_collections_api
====================

.. toctree::
:maxdepth: 4
Expand Down
Loading