Interacting with Metadata¶
Metadata is abstracted via a high-level interface in the Coscine Python SDK
such that its users wonât have to deal with the intrinsics of how it is
implemented in Coscine (though it is still possible to interact with metadata
on a lower level).
The main interface for metadata comes in the form of the abstract data type
MetadataForm. The MetadataForm attempts to closely mimic the behavior
of the Coscine web interface input mask for metadata. As such, interacting
with a MetadataForm feels natural to users that are already accustomed to the
Coscine web interface.
To create an instance of a MetadataForm for a given resource, one may use
the metadata = resource.metadata_form() method. It creates a MetadataForm
and fills it with the default values set in the resource settings.
Users are then able to add, modify or delete values from the form via the
following manners:
from datetime import datetime
metadata["Title"] = "My Title Value"
metadata["Created"] = datetime.now().date()
...
print(metadata)
It is important to note, that metadata fields are generally type-sensitive! In most cases the Application Profile for a resource specifies datatypes for each of its metadata fields and the Python SDK uses the python-native forms of these datatypes. If a field requires an Integer, you must supply an Integer - a string wonât suffice. Similarly if a field requires a date, you must supply a datetime.date value - even a ânormalâ datetime timestamp wonât suffice, as that also includes a time segment.
As of lately Application Profiles can inherit other Application Profiles and incorporate them under a field of their own. The Python SDK supports interacting with those profiles using the following manner:
metadata = resource.metadata_form()
subform = metadata.field("Subprofile Key").metadata_form()
metadata["Normal Key"] = 12345
metadata["Subprofile Key"] = subform
# Subprofile Key contains a whole new MetadataForm as a value
...
To check what kind of value a field takes, several methods are available:
Get the field:
field = metadata_form.field(key)field.is_controlled: The field is controlled by a vocabulary or selectionfield.has_selection: The field is controlled by a selectionfield.has_vocabulary: The field is controlled by a vocabularyfield.is_inherited: The field takes a MetadataForm as a value
Fields controlled by a vocabulary
field.vocabulary(key) -> value
The metadata of a file can be fetched as a metadata form with
FileObject.metadata_form()
Datatypes¶
The following datatypes are currently supported by FormFields:
bool | date | datetime | Decimal | int | float | str | time | timedelta
Internally XSD types are mapped to Python types and vice versa via the following relation:
xsd |
python |
|---|---|
any |
str |
anyURI |
str |
anyType |
str |
byte |
int |
int |
int |
integer |
int |
long |
int |
unsignedShort |
int |
unsignedByte |
int |
negativeInteger |
int |
nonNegativeInteger |
int |
nonPositiveInteger |
int |
positiveInteger |
int |
short |
int |
unsignedLong |
int |
unsignedInt |
int |
double |
float |
float |
float |
decimal |
Decimal |
boolean |
bool |
date |
date |
dateTime |
datetime |
duration |
timedelta |
gDay |
datetime |
gMonth |
datetime |
gMonthDay |
datetime |
gYear |
datetime |
gYearMonth |
datetime |
time |
time |
ENTITIES |
str |
ENTITY |
str |
ID |
str |
IDREF |
str |
IDREFS |
str |
language |
str |
Name |
str |
NCName |
str |
NMTOKEN |
str |
NMTOKENS |
str |
normalizedString |
str |
QName |
str |
string |
str |
token |
str |
Uploading metadata to Coscine¶
Coscine differentiates between the upload of new metadata and updating
existing metadata. For the upload of new metadata, one has to use the
coscine.Resource.post_metadata() method. If metadata already exists for
the given path, Coscine will return an error.
For updating existing metadata, one will use
the coscine.Resource.put_metadata() method. If there is no metadata to update
Coscine will again return an error.
To combine both methods, one can first use put and in case of an error
fall back to post. This will ensure an upload of metadata in either case.
import coscine
client = coscine.ApiClient(TOKEN)
resource = client.project("My Project").resource("My Resource")
metadata = resource.metadata_form()
metadata["Some Field"] = "Some Value"
...
serialized_metadata = metadata.serialize("file-path-in-coscine.extension")
try:
resource.put_metadata(serialized_metadata)
except coscine.CoscineException:
resource.post_metadata(serialized_metadata)