diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9d30e1c4e..a4fed2fab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,9 +119,70 @@ All code files must include the NVIDIA copyright header: Use `make update-license-headers` to add headers automatically. -## Signing Off on Your Work (DCO) +## Signing Your Work (DCO) -When contributing, you must agree that you have authored 100% of the content, that you have the necessary rights to the content, and that the content you contribute may be provided under the project license. All contributors are asked to sign the [Developer Certificate of Origin (DCO)](DCO) when submitting their first pull request. The process is automated by a bot that will comment on the pull request. +Every commit in a contribution must include a `Signed-off-by` trailer. By signing off, you certify that you have the right to submit the contribution under the project's open source license, as set out in the Developer Certificate of Origin (DCO) below. + +Add your sign-off with `git commit -s`: + +```bash +git commit -s -m "describe your change" +``` + +Git adds a trailer using the name and email address in your Git configuration: + +```text +Signed-off-by: Your Name +``` + +Review the certification before signing off. When submitting a pull request, ensure that all of its commits contain the required sign-off. + +First-time contributors must also complete the DCO Assistant's PR-comment signature. When the bot asks you to sign, read the DCO and post this exact comment on your pull request: + +```text +I have read the DCO document and I hereby sign the DCO. +``` + +Complete both steps: sign off every commit and, when prompted, sign through the bot. If the bot needs to check again after you have signed, post `recheck` on the pull request. + +### Developer Certificate of Origin + +```text +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` ## Code of Conduct diff --git a/LICENSE b/LICENSE index d67d6cffa..343654b2a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ diff --git a/Makefile b/Makefile index d805f5273..73a1cd873 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + # ============================================================================== # VARIABLES AND FUNCTIONS # ============================================================================== diff --git a/README.md b/README.md index eddbc1e58..8b5306ea4 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,7 @@ pip install data-designer > With uv, use `uv pip install` or `uv add` with the same `-c` URL. See [dependency security](https://docs.nvidia.com/nemo/datadesigner/concepts/security#dependency-security) for details. > [!NOTE] -> This project will download and install additional third-party open source -> software projects. Review the license terms of these open source projects -> before use. +> NOTICE AND DISCLAIMER: This software automatically retrieves, accesses or interacts with external materials. Those retrieved materials are not distributed with this software and are governed solely by separate terms, conditions and licenses. You are solely responsible for finding, reviewing and complying with all applicable terms, conditions, and licenses, and for verifying the security, integrity and suitability of any retrieved materials for your specific use case. This software is provided "AS IS", without warranty of any kind. The author makes no representations or warranties regarding any retrieved materials, and assumes no liability for any losses, damages, liabilities or legal consequences from your use or inability to use this software or any retrieved materials. Use this software and the retrieved materials at your own risk. Or install from source: @@ -200,7 +198,7 @@ _Last updated on October 27, 2026_ ## License -Apache License 2.0 – see [LICENSE](LICENSE) for details. +Apache License 2.0 – see [LICENSE](LICENSE) for details. Each separately published Python package includes an identical copy of this license. In particular, `packages/data-designer-slurm/LICENSE` is retained to accompany the independently distributed Slurm package. --- diff --git a/docs/colab_notebooks/1-the-basics.ipynb b/docs/colab_notebooks/1-the-basics.ipynb index dea28827a..e155b5296 100644 --- a/docs/colab_notebooks/1-the-basics.ipynb +++ b/docs/colab_notebooks/1-the-basics.ipynb @@ -10,30 +10,6 @@ "\"Open" ] }, - { - "cell_type": "markdown", - "id": "5ef696bd", - "metadata": {}, - "source": [ - "# 🎨 Data Designer Tutorial: The Basics\n", - "\n", - "#### πŸ“š What you'll learn\n", - "\n", - "This notebook demonstrates the basics of Data Designer by generating a simple product review dataset.\n" - ] - }, - { - "cell_type": "markdown", - "id": "b18ff627", - "metadata": {}, - "source": [ - "### πŸ“¦ Import Data Designer\n", - "\n", - "- `data_designer.config` provides access to the configuration API.\n", - "\n", - "- `DataDesigner` is the main interface for data generation.\n" - ] - }, { "cell_type": "markdown", "id": "8fa4025d", @@ -79,6 +55,41 @@ " os.environ[\"NVIDIA_API_KEY\"] = getpass.getpass(\"Enter your NVIDIA API key: \")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "345cc4f9", + "metadata": {}, + "outputs": [], + "source": [ + "# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n", + "# SPDX-License-Identifier: Apache-2.0" + ] + }, + { + "cell_type": "markdown", + "id": "5ef696bd", + "metadata": {}, + "source": [ + "# 🎨 Data Designer Tutorial: The Basics\n", + "\n", + "#### πŸ“š What you'll learn\n", + "\n", + "This notebook demonstrates the basics of Data Designer by generating a simple product review dataset.\n" + ] + }, + { + "cell_type": "markdown", + "id": "b18ff627", + "metadata": {}, + "source": [ + "### πŸ“¦ Import Data Designer\n", + "\n", + "- `data_designer.config` provides access to the configuration API.\n", + "\n", + "- `DataDesigner` is the main interface for data generation.\n" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/colab_notebooks/2-structured-outputs-and-jinja-expressions.ipynb b/docs/colab_notebooks/2-structured-outputs-and-jinja-expressions.ipynb index 9f8e05929..2af3c5900 100644 --- a/docs/colab_notebooks/2-structured-outputs-and-jinja-expressions.ipynb +++ b/docs/colab_notebooks/2-structured-outputs-and-jinja-expressions.ipynb @@ -10,32 +10,6 @@ "\"Open" ] }, - { - "cell_type": "markdown", - "id": "458a84da", - "metadata": {}, - "source": [ - "# 🎨 Data Designer Tutorial: Structured Outputs, Jinja Expressions, and Conditional Generation\n", - "\n", - "#### πŸ“š What you'll learn\n", - "\n", - "In this notebook, we will continue our exploration of Data Designer, demonstrating more advanced data generation using structured outputs, Jinja expressions, and conditional generation with `skip.when`.\n", - "\n", - "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" - ] - }, - { - "cell_type": "markdown", - "id": "7bd6f907", - "metadata": {}, - "source": [ - "### πŸ“¦ Import Data Designer\n", - "\n", - "- `data_designer.config` provides access to the configuration API.\n", - "\n", - "- `DataDesigner` is the main interface for data generation.\n" - ] - }, { "cell_type": "markdown", "id": "3f97b658", @@ -81,6 +55,43 @@ " os.environ[\"NVIDIA_API_KEY\"] = getpass.getpass(\"Enter your NVIDIA API key: \")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab80f4f5", + "metadata": {}, + "outputs": [], + "source": [ + "# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n", + "# SPDX-License-Identifier: Apache-2.0" + ] + }, + { + "cell_type": "markdown", + "id": "458a84da", + "metadata": {}, + "source": [ + "# 🎨 Data Designer Tutorial: Structured Outputs, Jinja Expressions, and Conditional Generation\n", + "\n", + "#### πŸ“š What you'll learn\n", + "\n", + "In this notebook, we will continue our exploration of Data Designer, demonstrating more advanced data generation using structured outputs, Jinja expressions, and conditional generation with `skip.when`.\n", + "\n", + "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" + ] + }, + { + "cell_type": "markdown", + "id": "7bd6f907", + "metadata": {}, + "source": [ + "### πŸ“¦ Import Data Designer\n", + "\n", + "- `data_designer.config` provides access to the configuration API.\n", + "\n", + "- `DataDesigner` is the main interface for data generation.\n" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/colab_notebooks/3-seeding-with-a-dataset.ipynb b/docs/colab_notebooks/3-seeding-with-a-dataset.ipynb index d80e6c324..c29d89557 100644 --- a/docs/colab_notebooks/3-seeding-with-a-dataset.ipynb +++ b/docs/colab_notebooks/3-seeding-with-a-dataset.ipynb @@ -10,32 +10,6 @@ "\"Open" ] }, - { - "cell_type": "markdown", - "id": "ff27e870", - "metadata": {}, - "source": [ - "# 🎨 Data Designer Tutorial: Seeding Synthetic Data Generation with an External Dataset\n", - "\n", - "#### πŸ“š What you'll learn\n", - "\n", - "In this notebook, we will demonstrate how to seed synthetic data generation in Data Designer with an external dataset.\n", - "\n", - "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" - ] - }, - { - "cell_type": "markdown", - "id": "0f3e6128", - "metadata": {}, - "source": [ - "### πŸ“¦ Import Data Designer\n", - "\n", - "- `data_designer.config` provides access to the configuration API.\n", - "\n", - "- `DataDesigner` is the main interface for data generation.\n" - ] - }, { "cell_type": "markdown", "id": "cd25d0dc", @@ -81,6 +55,43 @@ " os.environ[\"NVIDIA_API_KEY\"] = getpass.getpass(\"Enter your NVIDIA API key: \")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "101038e4", + "metadata": {}, + "outputs": [], + "source": [ + "# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n", + "# SPDX-License-Identifier: Apache-2.0" + ] + }, + { + "cell_type": "markdown", + "id": "ff27e870", + "metadata": {}, + "source": [ + "# 🎨 Data Designer Tutorial: Seeding Synthetic Data Generation with an External Dataset\n", + "\n", + "#### πŸ“š What you'll learn\n", + "\n", + "In this notebook, we will demonstrate how to seed synthetic data generation in Data Designer with an external dataset.\n", + "\n", + "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" + ] + }, + { + "cell_type": "markdown", + "id": "0f3e6128", + "metadata": {}, + "source": [ + "### πŸ“¦ Import Data Designer\n", + "\n", + "- `data_designer.config` provides access to the configuration API.\n", + "\n", + "- `DataDesigner` is the main interface for data generation.\n" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/colab_notebooks/4-providing-images-as-context.ipynb b/docs/colab_notebooks/4-providing-images-as-context.ipynb index 26ff1b057..5ba9998f2 100644 --- a/docs/colab_notebooks/4-providing-images-as-context.ipynb +++ b/docs/colab_notebooks/4-providing-images-as-context.ipynb @@ -10,43 +10,6 @@ "\"Open" ] }, - { - "cell_type": "markdown", - "id": "9336f640", - "metadata": {}, - "source": [ - "# 🎨 Data Designer Tutorial: Providing Images as Context for Vision-Based Data Generation" - ] - }, - { - "cell_type": "markdown", - "id": "439d7fec", - "metadata": {}, - "source": [ - "#### πŸ“š What you'll learn\n", - "\n", - "This notebook demonstrates how to provide images as context to generate text descriptions using vision-language models.\n", - "The same `multi_modal_context` field can also carry audio or video context when the selected model supports those modalities.\n", - "\n", - "- ✨ **Visual Document Processing**: Converting images to chat-ready format for model consumption\n", - "- πŸ” **Vision-Language Generation**: Using vision models to generate detailed summaries from images\n", - "- 🧩 **Media Context Pattern**: Understanding how `ImageContext`, `AudioContext`, and `VideoContext` fit into the same configuration field\n", - "\n", - "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" - ] - }, - { - "cell_type": "markdown", - "id": "e3b8eb25", - "metadata": {}, - "source": [ - "### πŸ“¦ Import Data Designer\n", - "\n", - "- `data_designer.config` provides access to the configuration API.\n", - "\n", - "- `DataDesigner` is the main interface for data generation.\n" - ] - }, { "cell_type": "markdown", "id": "8d8e8db6", @@ -92,6 +55,54 @@ " os.environ[\"NVIDIA_API_KEY\"] = getpass.getpass(\"Enter your NVIDIA API key: \")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "37689d51", + "metadata": {}, + "outputs": [], + "source": [ + "# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n", + "# SPDX-License-Identifier: Apache-2.0" + ] + }, + { + "cell_type": "markdown", + "id": "9336f640", + "metadata": {}, + "source": [ + "# 🎨 Data Designer Tutorial: Providing Images as Context for Vision-Based Data Generation" + ] + }, + { + "cell_type": "markdown", + "id": "439d7fec", + "metadata": {}, + "source": [ + "#### πŸ“š What you'll learn\n", + "\n", + "This notebook demonstrates how to provide images as context to generate text descriptions using vision-language models.\n", + "The same `multi_modal_context` field can also carry audio or video context when the selected model supports those modalities.\n", + "\n", + "- ✨ **Visual Document Processing**: Converting images to chat-ready format for model consumption\n", + "- πŸ” **Vision-Language Generation**: Using vision models to generate detailed summaries from images\n", + "- 🧩 **Media Context Pattern**: Understanding how `ImageContext`, `AudioContext`, and `VideoContext` fit into the same configuration field\n", + "\n", + "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" + ] + }, + { + "cell_type": "markdown", + "id": "e3b8eb25", + "metadata": {}, + "source": [ + "### πŸ“¦ Import Data Designer\n", + "\n", + "- `data_designer.config` provides access to the configuration API.\n", + "\n", + "- `DataDesigner` is the main interface for data generation.\n" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/colab_notebooks/5-generating-images.ipynb b/docs/colab_notebooks/5-generating-images.ipynb index a3326bdfe..42d9536d0 100644 --- a/docs/colab_notebooks/5-generating-images.ipynb +++ b/docs/colab_notebooks/5-generating-images.ipynb @@ -10,39 +10,6 @@ "\"Open" ] }, - { - "cell_type": "markdown", - "id": "c4e6e092", - "metadata": {}, - "source": [ - "# 🎨 Data Designer Tutorial: Generating Images\n", - "\n", - "#### πŸ“š What you'll learn\n", - "\n", - "This notebook shows how to generate synthetic image data with Data Designer using image-generation models.\n", - "\n", - "- πŸ–ΌοΈ **Image generation columns**: Add columns that produce images from text prompts\n", - "- πŸ“ **Jinja2 prompts**: Drive diversity by referencing other columns in your prompt template\n", - "- πŸ’Ύ **Preview vs create**: Preview stores base64 in the dataframe; create saves images to disk and stores paths\n", - "\n", - "Data Designer supports both **diffusion** (e.g. DALLΒ·E, Stable Diffusion, Imagen) and **autoregressive** (e.g. Gemini image, GPT image) models.\n", - "\n", - "> **Prerequisites**: This tutorial uses [OpenRouter](https://openrouter.ai) with the Flux 2 Pro image model. Set `OPENROUTER_API_KEY` in your environment before running.\n", - "\n", - "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" - ] - }, - { - "cell_type": "markdown", - "id": "ee4483fa", - "metadata": {}, - "source": [ - "### πŸ“¦ Import Data Designer\n", - "\n", - "- `data_designer.config` provides the configuration API.\n", - "- `DataDesigner` is the main interface for generation.\n" - ] - }, { "cell_type": "markdown", "id": "51d483c7", @@ -88,6 +55,50 @@ " os.environ[\"NVIDIA_API_KEY\"] = getpass.getpass(\"Enter your NVIDIA API key: \")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "9c41f76c", + "metadata": {}, + "outputs": [], + "source": [ + "# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n", + "# SPDX-License-Identifier: Apache-2.0" + ] + }, + { + "cell_type": "markdown", + "id": "c4e6e092", + "metadata": {}, + "source": [ + "# 🎨 Data Designer Tutorial: Generating Images\n", + "\n", + "#### πŸ“š What you'll learn\n", + "\n", + "This notebook shows how to generate synthetic image data with Data Designer using image-generation models.\n", + "\n", + "- πŸ–ΌοΈ **Image generation columns**: Add columns that produce images from text prompts\n", + "- πŸ“ **Jinja2 prompts**: Drive diversity by referencing other columns in your prompt template\n", + "- πŸ’Ύ **Preview vs create**: Preview stores base64 in the dataframe; create saves images to disk and stores paths\n", + "\n", + "Data Designer supports both **diffusion** (e.g. DALLΒ·E, Stable Diffusion, Imagen) and **autoregressive** (e.g. Gemini image, GPT image) models.\n", + "\n", + "> **Prerequisites**: This tutorial uses [OpenRouter](https://openrouter.ai) with the Flux 2 Pro image model. Set `OPENROUTER_API_KEY` in your environment before running.\n", + "\n", + "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" + ] + }, + { + "cell_type": "markdown", + "id": "ee4483fa", + "metadata": {}, + "source": [ + "### πŸ“¦ Import Data Designer\n", + "\n", + "- `data_designer.config` provides the configuration API.\n", + "- `DataDesigner` is the main interface for generation.\n" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/colab_notebooks/6-editing-images-with-image-context.ipynb b/docs/colab_notebooks/6-editing-images-with-image-context.ipynb index 453cfdb01..eae196a6c 100644 --- a/docs/colab_notebooks/6-editing-images-with-image-context.ipynb +++ b/docs/colab_notebooks/6-editing-images-with-image-context.ipynb @@ -10,39 +10,6 @@ "\"Open" ] }, - { - "cell_type": "markdown", - "id": "1b2fa378", - "metadata": {}, - "source": [ - "# 🎨 Data Designer Tutorial: Image-to-Image Editing\n", - "\n", - "#### πŸ“š What you'll learn\n", - "\n", - "This notebook shows how to chain image generation columns: first generate animal portraits from text, then edit those generated images by adding accessories and changing stylesβ€”all without loading external datasets.\n", - "\n", - "- πŸ–ΌοΈ **Text-to-image generation**: Generate images from text prompts\n", - "- πŸ”— **Chaining image columns**: Use `ImageContext` to pass generated images to a follow-up editing column\n", - "- 🎲 **Sampler-driven diversity**: Combine sampled accessories and settings for varied edits\n", - "\n", - "This tutorial uses an **autoregressive** model (one that supports both text-to-image *and* image-to-image generation via the chat completions API). Diffusion models (DALLΒ·E, Stable Diffusion, etc.) do not support image contextβ€”see [Tutorial 5](https://docs.nvidia.com/nemo/datadesigner/tutorials/generating-images) for text-to-image generation with diffusion models.\n", - "\n", - "> **Prerequisites**: This tutorial uses [OpenRouter](https://openrouter.ai) with the Flux 2 Pro model. Set `OPENROUTER_API_KEY` in your environment before running.\n", - "\n", - "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" - ] - }, - { - "cell_type": "markdown", - "id": "76ab2f1d", - "metadata": {}, - "source": [ - "### πŸ“¦ Import Data Designer\n", - "\n", - "- `data_designer.config` provides the configuration API.\n", - "- `DataDesigner` is the main interface for generation.\n" - ] - }, { "cell_type": "markdown", "id": "fb13df5a", @@ -88,6 +55,50 @@ " os.environ[\"NVIDIA_API_KEY\"] = getpass.getpass(\"Enter your NVIDIA API key: \")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad7a9a49", + "metadata": {}, + "outputs": [], + "source": [ + "# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n", + "# SPDX-License-Identifier: Apache-2.0" + ] + }, + { + "cell_type": "markdown", + "id": "1b2fa378", + "metadata": {}, + "source": [ + "# 🎨 Data Designer Tutorial: Image-to-Image Editing\n", + "\n", + "#### πŸ“š What you'll learn\n", + "\n", + "This notebook shows how to chain image generation columns: first generate animal portraits from text, then edit those generated images by adding accessories and changing stylesβ€”all without loading external datasets.\n", + "\n", + "- πŸ–ΌοΈ **Text-to-image generation**: Generate images from text prompts\n", + "- πŸ”— **Chaining image columns**: Use `ImageContext` to pass generated images to a follow-up editing column\n", + "- 🎲 **Sampler-driven diversity**: Combine sampled accessories and settings for varied edits\n", + "\n", + "This tutorial uses an **autoregressive** model (one that supports both text-to-image *and* image-to-image generation via the chat completions API). Diffusion models (DALLΒ·E, Stable Diffusion, etc.) do not support image contextβ€”see [Tutorial 5](https://docs.nvidia.com/nemo/datadesigner/tutorials/generating-images) for text-to-image generation with diffusion models.\n", + "\n", + "> **Prerequisites**: This tutorial uses [OpenRouter](https://openrouter.ai) with the Flux 2 Pro model. Set `OPENROUTER_API_KEY` in your environment before running.\n", + "\n", + "If this is your first time using Data Designer, we recommend starting with the [first notebook](https://docs.nvidia.com/nemo/datadesigner/tutorials/the-basics) in this tutorial series.\n" + ] + }, + { + "cell_type": "markdown", + "id": "76ab2f1d", + "metadata": {}, + "source": [ + "### πŸ“¦ Import Data Designer\n", + "\n", + "- `data_designer.config` provides the configuration API.\n", + "- `DataDesigner` is the main interface for generation.\n" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/notebook_source/1-the-basics.py b/docs/notebook_source/1-the-basics.py index b83ccf832..7ed7dbd16 100644 --- a/docs/notebook_source/1-the-basics.py +++ b/docs/notebook_source/1-the-basics.py @@ -12,6 +12,9 @@ # name: python3 # --- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + # %% [markdown] # # 🎨 Data Designer Tutorial: The Basics # diff --git a/docs/notebook_source/2-structured-outputs-and-jinja-expressions.py b/docs/notebook_source/2-structured-outputs-and-jinja-expressions.py index dd9dc5acb..f252f435d 100644 --- a/docs/notebook_source/2-structured-outputs-and-jinja-expressions.py +++ b/docs/notebook_source/2-structured-outputs-and-jinja-expressions.py @@ -12,6 +12,9 @@ # name: python3 # --- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + # %% [markdown] # # 🎨 Data Designer Tutorial: Structured Outputs, Jinja Expressions, and Conditional Generation # diff --git a/docs/notebook_source/3-seeding-with-a-dataset.py b/docs/notebook_source/3-seeding-with-a-dataset.py index 62645ea08..7a20e656c 100644 --- a/docs/notebook_source/3-seeding-with-a-dataset.py +++ b/docs/notebook_source/3-seeding-with-a-dataset.py @@ -12,6 +12,9 @@ # name: python3 # --- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + # %% [markdown] # # 🎨 Data Designer Tutorial: Seeding Synthetic Data Generation with an External Dataset # diff --git a/docs/notebook_source/4-providing-images-as-context.py b/docs/notebook_source/4-providing-images-as-context.py index afb1b609a..c04d66f1e 100644 --- a/docs/notebook_source/4-providing-images-as-context.py +++ b/docs/notebook_source/4-providing-images-as-context.py @@ -12,6 +12,9 @@ # name: python3 # --- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + # %% [markdown] # # 🎨 Data Designer Tutorial: Providing Images as Context for Vision-Based Data Generation diff --git a/docs/notebook_source/5-generating-images.py b/docs/notebook_source/5-generating-images.py index ba8ed00fc..593958c6a 100644 --- a/docs/notebook_source/5-generating-images.py +++ b/docs/notebook_source/5-generating-images.py @@ -12,6 +12,9 @@ # name: python3 # --- +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + # %% [markdown] # # 🎨 Data Designer Tutorial: Generating Images # diff --git a/docs/notebook_source/6-editing-images-with-image-context.py b/docs/notebook_source/6-editing-images-with-image-context.py index cfe655be3..86ea2113b 100644 --- a/docs/notebook_source/6-editing-images-with-image-context.py +++ b/docs/notebook_source/6-editing-images-with-image-context.py @@ -12,6 +12,9 @@ # name: python3 # --- +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + # %% [markdown] # # 🎨 Data Designer Tutorial: Image-to-Image Editing # diff --git a/fern/styles/local-preview.css b/fern/styles/local-preview.css index db325d195..21b065fa1 100644 --- a/fern/styles/local-preview.css +++ b/fern/styles/local-preview.css @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + :root { --nv-green: #76b900; --nv-green-dark: #004b31; diff --git a/fern/versions/latest/pages/CONTRIBUTING.mdx b/fern/versions/latest/pages/CONTRIBUTING.mdx index d3c98eb80..2c13a927c 100644 --- a/fern/versions/latest/pages/CONTRIBUTING.mdx +++ b/fern/versions/latest/pages/CONTRIBUTING.mdx @@ -109,9 +109,70 @@ All code files must include the NVIDIA copyright header: Use `make update-license-headers` to add headers automatically. -## Signing Off on Your Work (DCO) +## Signing Your Work (DCO) -When contributing, you must agree that you have authored 100% of the content, that you have the necessary rights to the content, and that the content you contribute may be provided under the project license. All contributors are asked to sign the [Developer Certificate of Origin (DCO)](https://github.com/NVIDIA-NeMo/DataDesigner/blob/main/DCO) when submitting their first pull request. The process is automated by a bot that will comment on the pull request. +Every commit in a contribution must include a `Signed-off-by` trailer. By signing off, you certify that you have the right to submit the contribution under the project's open source license, as set out in the Developer Certificate of Origin (DCO) below. + +Add your sign-off with `git commit -s`: + +```bash +git commit -s -m "describe your change" +``` + +Git adds a trailer using the name and email address in your Git configuration: + +```text +Signed-off-by: Your Name +``` + +Review the certification before signing off. When submitting a pull request, ensure that all of its commits contain the required sign-off. + +First-time contributors must also complete the DCO Assistant's PR-comment signature. When the bot asks you to sign, read the DCO and post this exact comment on your pull request: + +```text +I have read the DCO document and I hereby sign the DCO. +``` + +Complete both steps: sign off every commit and, when prompted, sign through the bot. If the bot needs to check again after you have signed, post `recheck` on the pull request. + +### Developer Certificate of Origin + +```text +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` ## Code of Conduct diff --git a/fern/versions/latest/pages/concepts/security.mdx b/fern/versions/latest/pages/concepts/security.mdx index 3da0b711b..59470fc65 100644 --- a/fern/versions/latest/pages/concepts/security.mdx +++ b/fern/versions/latest/pages/concepts/security.mdx @@ -35,6 +35,10 @@ The repository audits the committed workspace lockfile and separately resolved e Constraints and dependency audits cover known advisories and depend on the coverage and freshness of advisory databases. Consult upstream advisories when assessing a finding; constraints and a passing scan do not guarantee that every vulnerability has been resolved. +## Third-party Materials and Distribution + +The dependency-license checker evaluates the installed Python environment. It does not establish approval or license-material completeness for a separately distributed dependency bundle or container. If you distribute a wheelhouse, runtime bundle, or serving container, review the components actually included and provide their required license texts and notices. Registering or downloading an image does not grant redistribution rights. + ## Jinja Rendering Modes Data Designer exposes the renderer choice through `RunConfig`: diff --git a/fern/versions/latest/pages/index.mdx b/fern/versions/latest/pages/index.mdx index f73d9a842..402551478 100644 --- a/fern/versions/latest/pages/index.mdx +++ b/fern/versions/latest/pages/index.mdx @@ -46,7 +46,7 @@ See [Dependency Security](/concepts/security#dependency-security) for details an -This project will download and install additional third-party open source software projects. Review the license terms of these open source projects before use. +NOTICE AND DISCLAIMER: This software automatically retrieves, accesses or interacts with external materials. Those retrieved materials are not distributed with this software and are governed solely by separate terms, conditions and licenses. You are solely responsible for finding, reviewing and complying with all applicable terms, conditions, and licenses, and for verifying the security, integrity and suitability of any retrieved materials for your specific use case. This software is provided "AS IS", without warranty of any kind. The author makes no representations or warranties regarding any retrieved materials, and assumes no liability for any losses, damages, liabilities or legal consequences from your use or inability to use this software or any retrieved materials. Use this software and the retrieved materials at your own risk. ## Setup diff --git a/packages/data-designer-config/LICENSE b/packages/data-designer-config/LICENSE new file mode 100644 index 000000000..343654b2a --- /dev/null +++ b/packages/data-designer-config/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2025 NVIDIA + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/data-designer-config/pyproject.toml b/packages/data-designer-config/pyproject.toml index ab6b0ba65..b13a49be5 100644 --- a/packages/data-designer-config/pyproject.toml +++ b/packages/data-designer-config/pyproject.toml @@ -5,6 +5,7 @@ description = "Configuration layer for DataDesigner synthetic data generation" readme = "README.md" requires-python = ">=3.11" license = "Apache-2.0" +license-files = ["LICENSE"] classifiers = [ "Development Status :: 4 - Beta", diff --git a/packages/data-designer-engine/LICENSE b/packages/data-designer-engine/LICENSE new file mode 100644 index 000000000..343654b2a --- /dev/null +++ b/packages/data-designer-engine/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2025 NVIDIA + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/data-designer-engine/pyproject.toml b/packages/data-designer-engine/pyproject.toml index e27c77c1c..f0a30a2b3 100644 --- a/packages/data-designer-engine/pyproject.toml +++ b/packages/data-designer-engine/pyproject.toml @@ -5,6 +5,7 @@ description = "Generation engine for DataDesigner synthetic data generation" readme = "README.md" requires-python = ">=3.11" license = "Apache-2.0" +license-files = ["LICENSE"] classifiers = [ "Development Status :: 4 - Beta", diff --git a/packages/data-designer-slurm/LICENSE b/packages/data-designer-slurm/LICENSE index d67d6cffa..343654b2a 100644 --- a/packages/data-designer-slurm/LICENSE +++ b/packages/data-designer-slurm/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ diff --git a/packages/data-designer/LICENSE b/packages/data-designer/LICENSE new file mode 100644 index 000000000..343654b2a --- /dev/null +++ b/packages/data-designer/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2025 NVIDIA + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/data-designer/pyproject.toml b/packages/data-designer/pyproject.toml index 971d1e713..2afc0366b 100644 --- a/packages/data-designer/pyproject.toml +++ b/packages/data-designer/pyproject.toml @@ -5,6 +5,7 @@ description = "General framework for synthetic data generation" readme = "README.md" requires-python = ">=3.11" license = "Apache-2.0" +license-files = ["LICENSE"] classifiers = [ "Development Status :: 4 - Beta", diff --git a/packages/data-designer/tests/docs/test_notebook_license_headers.py b/packages/data-designer/tests/docs/test_notebook_license_headers.py new file mode 100644 index 000000000..f94dd740f --- /dev/null +++ b/packages/data-designer/tests/docs/test_notebook_license_headers.py @@ -0,0 +1,53 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import importlib.util +import sys +from pathlib import Path + +import pytest + +ROOT = Path(__file__).parents[4] +SPEC = importlib.util.spec_from_file_location("license_header_checks", ROOT / "scripts/update_license_headers.py") +assert SPEC and SPEC.loader +HEADER_CHECKS = importlib.util.module_from_spec(SPEC) +sys.modules[SPEC.name] = HEADER_CHECKS +SPEC.loader.exec_module(HEADER_CHECKS) +HEADER = HEADER_CHECKS.generate_license_header("2026") + + +@pytest.mark.parametrize("existing", ["", HEADER_CHECKS.generate_license_header("2025"), HEADER]) +def test_header_updates_preserve_jupytext_front_matter(tmp_path: Path, existing: str) -> None: + metadata = "# ---\n# jupyter:\n# kernelspec:\n# name: python3\n# ---\n\n" + body = "# %% [markdown]\n# Tutorial\n\n# %%\nprint('hello')\n" + path = tmp_path / "tutorial.py" + path.write_text(metadata + existing + body) + + HEADER_CHECKS.update_license_header_in_file(path, HEADER) + + assert path.read_text() == metadata + HEADER + body + assert HEADER_CHECKS.check_license_header_matches(path, HEADER) == (True, "match") + assert HEADER_CHECKS.update_license_header_in_file(path, HEADER) == (False, "unchanged") + + +@pytest.mark.parametrize("source", ["# ---\n# ordinary comment\n# ---\n", "# ---\n# jupyter:\n"]) +def test_non_jupytext_or_incomplete_front_matter_is_not_skipped(tmp_path: Path, source: str) -> None: + path = tmp_path / "ordinary.py" + path.write_text(source) + + HEADER_CHECKS.update_license_header_in_file(path, HEADER) + + assert path.read_text() == HEADER + source + + +def test_empty_notebook_keeps_its_metadata_when_adding_a_header(tmp_path: Path) -> None: + metadata = "# ---\n# jupyter:\n# kernelspec:\n# name: python3\n# ---\n\n" + path = tmp_path / "empty.py" + path.write_text(metadata) + + HEADER_CHECKS.update_license_header_in_file(path, HEADER) + + assert path.read_text() == metadata + HEADER.rstrip() + "\n" + assert HEADER_CHECKS.check_license_header_matches(path, HEADER) == (True, "match") diff --git a/packages/data-designer/tests/test_distribution_licenses.py b/packages/data-designer/tests/test_distribution_licenses.py new file mode 100644 index 000000000..ec0f3d32f --- /dev/null +++ b/packages/data-designer/tests/test_distribution_licenses.py @@ -0,0 +1,62 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import importlib.util +import io +import tarfile +import tomllib +from pathlib import Path +from zipfile import ZipFile + +import pytest + +ROOT = Path(__file__).parents[3] +SPEC = importlib.util.spec_from_file_location("package_install_checks", ROOT / "scripts/test_slurm_package_install.py") +assert SPEC and SPEC.loader +PACKAGE_CHECKS = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(PACKAGE_CHECKS) + + +@pytest.mark.parametrize("package", PACKAGE_CHECKS.PACKAGE_PATHS) +def test_package_license_copy_matches_repository(package: str) -> None: + directory = ROOT / package + assert (directory / "LICENSE").read_bytes() == (ROOT / "LICENSE").read_bytes() + metadata = tomllib.loads((directory / "pyproject.toml").read_text())["project"] + assert metadata["license-files"] == ["LICENSE"] + + +@pytest.mark.parametrize("kind", ["wheel", "sdist"]) +@pytest.mark.parametrize("license_state", ["valid", "missing", "altered", "missing_metadata", "wrong_expression"]) +def test_distribution_requires_full_license_text(tmp_path: Path, kind: str, license_state: str) -> None: + license_text = (ROOT / "LICENSE").read_bytes() + metadata = b"Name: example\nVersion: 1.0\nLicense-Expression: Apache-2.0\nLicense-File: LICENSE\n" + if license_state == "missing_metadata": + metadata = metadata.replace(b"License-File: LICENSE\n", b"") + elif license_state == "wrong_expression": + metadata = metadata.replace(b"Apache-2.0", b"MIT") + members = {} + if license_state != "missing": + members["LICENSE"] = b"Apache-2.0\n" if license_state == "altered" else license_text + if kind == "wheel": + path = tmp_path / "example-1.0-py3-none-any.whl" + with ZipFile(path, "w") as archive: + archive.writestr("example-1.0.dist-info/METADATA", metadata) + for name, content in members.items(): + archive.writestr(f"example-1.0.dist-info/licenses/{name}", content) + else: + path = tmp_path / "example-1.0.tar.gz" + members["PKG-INFO"] = metadata + with tarfile.open(path, "w:gz") as archive: + for name, content in members.items(): + info = tarfile.TarInfo(f"example-1.0/{name}") + info.size = len(content) + archive.addfile(info, io.BytesIO(content)) + if license_state == "valid": + PACKAGE_CHECKS.verify_package_license(path) + else: + with pytest.raises( + AssertionError, match="metadata" if license_state in {"missing_metadata", "wrong_expression"} else "LICENSE" + ): + PACKAGE_CHECKS.verify_package_license(path) diff --git a/scripts/test_slurm_package_install.py b/scripts/test_slurm_package_install.py index 0d245bb81..2a3c22d8d 100644 --- a/scripts/test_slurm_package_install.py +++ b/scripts/test_slurm_package_install.py @@ -9,6 +9,7 @@ import statistics import subprocess import sys +import tarfile import tempfile import time from collections.abc import Iterator @@ -71,6 +72,29 @@ def wheel_metadata(path: Path) -> Message: return BytesParser().parsebytes(wheel.read(metadata_path)) +def verify_package_license(path: Path) -> None: + """Require the complete repository license in a wheel or source distribution.""" + canonical_license = (REPOSITORY_ROOT / "LICENSE").read_bytes() + if path.name.endswith(".whl"): + with ZipFile(path) as archive: + names = [name for name in archive.namelist() if name.endswith(".dist-info/licenses/LICENSE")] + assert len(names) == 1, f"{path.name}: expected one packaged LICENSE" + assert archive.read(names[0]) == canonical_license, f"{path.name}: packaged LICENSE differs" + metadata = wheel_metadata(path) + else: + with tarfile.open(path) as archive: + members = {member.name.partition("/")[2]: member for member in archive if member.isfile()} + assert "LICENSE" in members, f"{path.name}: missing source LICENSE" + license_stream = archive.extractfile(members["LICENSE"]) + assert license_stream is not None + assert license_stream.read() == canonical_license, f"{path.name}: source LICENSE differs" + metadata_stream = archive.extractfile(members["PKG-INFO"]) + assert metadata_stream is not None + metadata = BytesParser().parsebytes(metadata_stream.read()) + assert metadata["License-Expression"] == "Apache-2.0", f"{path.name}: incorrect license metadata" + assert "LICENSE" in metadata.get_all("License-File", []), f"{path.name}: missing License-File metadata" + + def audit_public_artifacts(*paths: Path) -> None: result = run( [sys.executable, str(REPOSITORY_ROOT / "scripts" / "audit_slurm_public_artifacts.py"), *map(str, paths)], @@ -97,10 +121,13 @@ def verify_documented_examples() -> None: def build_wheels(uv: str, wheel_directory: Path) -> dict[str, Path]: for package_path in PACKAGE_PATHS: run( - [uv, "build", "--wheel", "--out-dir", str(wheel_directory), package_path], + [uv, "build", "--out-dir", str(wheel_directory), package_path], cwd=REPOSITORY_ROOT, ) + for artifact in (*wheel_directory.glob("*.whl"), *wheel_directory.glob("*.tar.gz")): + verify_package_license(artifact) + wheels = {} for wheel_path in wheel_directory.glob("*.whl"): name = canonicalize_name(wheel_metadata(wheel_path)["Name"]) diff --git a/scripts/update_license_headers.py b/scripts/update_license_headers.py index 6ca78c33f..a97f96aac 100644 --- a/scripts/update_license_headers.py +++ b/scripts/update_license_headers.py @@ -1,6 +1,8 @@ # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + import argparse import re import subprocess @@ -132,8 +134,16 @@ def _analyze_file_header(lines: list[str]) -> HeaderAnalysis: has_content_after=False, ) - # Header goes after shebang if present + # Keep Jupytext front matter at the start so notebook metadata survives conversion. insert_pos = 1 if lines[0].startswith("#!") else 0 + if insert_pos < len(lines) and lines[insert_pos].strip() == "# ---": + for index in range(insert_pos + 1, len(lines)): + if lines[index].strip() == "# ---": + if any(line.strip() == "# jupyter:" for line in lines[insert_pos + 1 : index]): + insert_pos = index + 1 + while insert_pos < len(lines) and not lines[insert_pos].strip(): + insert_pos += 1 + break # Skip blank lines to find where header actually starts header_search_start = insert_pos @@ -205,7 +215,7 @@ def update_license_header_in_file(file_path: Path, license_header: str) -> tuple lines.insert(analysis.header_start, expected_header) file_path.write_text("".join(lines), encoding="utf-8") else: - file_path.write_text(expected_header, encoding="utf-8") + file_path.write_text("".join(lines[: analysis.header_start]) + expected_header, encoding="utf-8") return True, "added" except (UnicodeDecodeError, PermissionError) as e: