Skip to content

pyproject.toml

These models provide a resource interface to the pyproject.toml. It can be used to parse an existing file or used to generate a new project config.

Dependencies

  • pydantic
  • tomli_w

Code

from typing import List, Dict, Any, Optional
from pydantic import BaseModel, Field

import tomli_w

class Author(BaseModel):
    name: str
    email: str

class BuildSystem(BaseModel):
    requires: List[str]
    build_backend: str = Field(alias="build-backend")

class Project(BaseModel):
    name: str
    version: Optional[str] = None
    dynamic: Optional[List[str]] = None
    dependencies: Optional[List[str]] = None
    description: Optional[str] = None
    readme: Optional[str] = None
    requires_python: Optional[str] = Field(None, alias="requires-python")
    authors: Optional[List[Author]] = None
    maintainers: Optional[List[Author]] = None
    classifiers: Optional[List[str]] = None
    keywords: Optional[List[str]] = None
    license: Optional[str] = None
    optional_dependencies: Optional[Dict[str, List[str]]] = Field(
        None, alias="optional-dependencies"
    )
    scripts: Optional[Dict[str, str]] = None
    urls: Optional[Dict[str, str]] = None

class PyProject(BaseModel):
    project: Project = Field(None, factory=Project)
    build_system: Optional[BuildSystem] = Field(
        None, alias="build-system", factory=BuildSystem
    )
    tool: Optional[Dict[str, Any]] = Field(None)

    def to_dict(self):
        return self.model_dump(by_alias=True, exclude_none=True)

    def __str__(self):
        return tomli_w.dumps(self.to_dict())

Example

Usage is as follows:

project = PyProject(**{
  "project": {
    "name": "testproj",
    "description": "A simple test",
  }
})

print(project)

Which outputs

[project]
name = "testproj"
description = "A simple test"