Resource metadata

What is a data resource?

In the previous sections, we have seen how to create and manage package metadata for our data package. In this section, we will explore how we can add data files and manage its metadata (e.g. documenting the type of data in each column). In a Data Package, data files are referred to as data resources, each containing a conceptually distinct set of data. We refer to the metadata for a data resource as “resource metadata”.

Creating a data resource

Creating a data resource requires that your data is in the correct format. Usually, generated or collected data starts out in a “raw” shape that needs to be cleaned and organized into so called “tidy data” before it can become a data resource. How to tidy data will differ from dataset to dataset and is outside the scope of Sprout, so we will not cover the procedure in detail here. Ideally you would use a Python package such as Polars. to tidy your data, so that you have a record of the steps taken to clean and transform the data. After cleaning, your data should follow the specification outlined in our documentation, specifically that it needs to be a Polars DataFrame.

For this guide, we have a fake dataset on the diabetes patients that is already tidy. You save any raw and/or downloaded data into the raw/ folder, so that we can keep the original “raw” data separate from the processed data. For this file, it will be called patients.csv.

The raw/patients.csv file includes data about patients with diabetes, which look like this:

Managing resource metadata with Sprout

Before you can store a data file as a resource in your data package, you need to describe its metadata properties. The resource’s metadata are what allow other people to understand what your data is about and to use it more easily.

The resource’s metadata also define what it means for data in the resource to be correctly entered, as all data in the resource must match the metadata properties. Sprout checks that the metadata properties are correctly filled in and that no required metadata fields are missing. It also checks that the data in the data resources matches the metadata properties, so that you can be sure that data actually contains what you expect it to contain. These checks can protect you from human errors introduced when adding new data or editing an existing data resource.

Creating a script to help manage resource metadata

As you did for the package metadata, you will create a script to manage the resource medata. You can do this by using the init-metadata command, which was also show in the previous section. To create a file for the resources, you would use the --type argument:

uvx seedcase-sprout init-metadata src/diabetes_study/metadata/patients.py --type resource

If you open this newly created file, you will see that it looks similar to the package metadata script, but with different names for the metadata properties. Since the file content is somewhat lengthy, it’s hidden by default on this page, but you are encouraged to create one yourself and look it over.

As with the template for the package metadata, the comments in this file indicate which properties are required and which are optional. You can see that you would need to fill out a title and a description just as we did previously for the package metadata. However, you also need to fill out the name and the type inside FieldProperties (a “field” is the same as a “column” or “variable” in your dataset). Doing this manually can be tedious for datasets with many columns, so Sprout provides a way to extract this metadata directly from the data file.

Extracting column metadata directly from the data

To ease the process of adding fields to your resource metadata, Sprout has the extract-metadata command, which allows you to extract metadata from each column in your dataset. To use this function, we need to save the data you are processing in a Parquet file, as this command can only extract from Parquet files. Taking this approach means you can take the time to process and clean up your raw data first, before finally extracting the metadata to document your data more fully. You can run the command like:

uvx seedcase-sprout extract-metadata raw/patients.parquet \
  --output-path src/diabetes_study/metadata/patients.py

This command extracts the resource’s field properties from the Polars DataFrame’s schema and maps the Polars data type to a Data Package field type. The mapping is not perfect, so you may need to edit the extracted properties to ensure that they are as you want them to be.

If you now open this newly created script, it will have many more of its fields filled in as well as including fields for all the columns.

Writing the resource metadata to datapackage.json

Before writing the metadata to file, we need to make sure that all the required properties are filled out. In the resource properties script, the name property is already set to patients. However, the two other required properties, title and description, are empty. You will need to fill these in yourself in the script, like so:

src/diabetes_study/metadata/patients.py
resource_properties_patients = sp.ResourceProperties(
    ## Required:
    name="patients",
    title="Patients Data",
    description="This data resource contains data about patients in a diabetes study.",
    ...  # Additional metadata are omitted here to save space
)
Warning

If the title and description properties are not filled in, you’ll get a CheckError when you try to use write_properties() to save the resource’s properties to the datapackage.json file. You will understand these errors more deeply after reading the next section in the guide; for now focus on making sure that the three required fields above are all filled out.

Our resource properties file include the name, title, and description of that data resource together with the name and type of each field in the data resource. To write these resource metadata to datapackage.json, you need to include the resource properties in the package.py file of your data package. You can do this by adding the following lines to the package.py file:

src/diabetes_study/metadata/package.py
# Import the resource properties object.
from .patients import resource_properties_patients

package_properties = sp.SproutProperties(
    # Your existing package metadata goes here...
    resources=[
        resource_properties_patients,
    ],
)

You can click the banner below to view the full file at this point:

src/diabetes_study/metadata/package.py
import seedcase_sprout as sp
1from .patients import resource_properties_patients

package_properties = sp.SproutProperties(
    name="diabetes-study",
    title="A Study on Diabetes",
    # You can write Markdown below, with the helper `sp.dedent()`.
    description=sp.dedent("""
        # Data from a 2021 study on diabetes prevalence

        This data package contains data from a study conducted in 2021 on the
        *prevalence* of diabetes in various populations. The data includes:

        - demographic information
        - health metrics
        - survey responses about lifestyle
        """),
    contributors=[
        sp.ContributorProperties(
            title="Jamie Jones",
            email="jamie_jones@example.com",
            path="example.com/jamie_jones",
            roles=["creator"],
        ),
        sp.ContributorProperties(
            title="Zdena Ziri",
            email="zdena_ziri@example.com",
            path="example.com/zdena_ziri",
            roles=["creator"],
        ),
    ],
    licenses=[
        sp.LicenseProperties(
            name="ODC-BY-1.0",
            path="https://opendatacommons.org/licenses/by",
            title="Open Data Commons Attribution License 1.0",
        )
    ],
2    resources=[
        resource_properties_patients,
    ],
    ## Autogenerated:
    id="8f301286-2327-45bf-bbc8-09696d059499",
    version="0.1.0",
    created="2025-11-07T11:12:56+01:00",
)
1
Import the resource metadata from the resource properties script.
2
Set the resources parameter of the package metadata to hold information about all the data resources. There would be one item in the list per data resource.

The next step is to write the resource properties to the datapackage.json file. Since we included the resource_properties object directly into the SproutProperties class in the package.py file, we only need to rerun the build.py file:

uv run src/diabetes_study/build.py

All the resource metadata is now also saved in this file! If you need to update the resource properties later on, you can simply edit the patients.py file and then rerun the build.py file to update the datapackage.json file.