Repository: microsoft/onefuzz
File: src/cli/onefuzz/api.py (Python)

Code before:

    endpoint = "instance_config"

    def get(self) -> models.InstanceConfig:
        return self._req_model("GET", models.InstanceConfig)

    def update(self, config: models.InstanceConfig) -> models.InstanceConfig:
        return self._req_model(
            "POST",
            models.InstanceConfig,
            data=requests.InstanceConfigUpdate(config=config),
        )


class ValidateScriban(Endpoint):
    """Interact with Validate Scriban"""

    endpoint = "ValidateScriban"

    def post(
        self, req: requests.TemplateValidationPost
    ) -> responses.TemplateValidationResponse:
        return self._req_model("POST", responses.TemplateValidationResponse, data=req)


class Migration(Endpoint):
    """Execute migrations"""

    endpoint = "migrations"

    def jinja_to_scriban(
        self, dry_run: bool = False
    ) -> Union[
        responses.JinjaToScribanMigrationResponse,
        responses.JinjaToScribanMigrationDryRunResponse,
    ]:
        migration_endpoint = self.endpoint + "/jinja_to_scriban"
        if dry_run:
            return self._req_model(
                "POST",
                responses.JinjaToScribanMigrationDryRunResponse,
                data=requests.JinjaToScribanMigrationPost(dry_run=dry_run),
                alternate_endpoint=migration_endpoint,
            )
        else:
            return self._req_model(
                "POST",
                responses.JinjaToScribanMigrationResponse,
                data=requests.JinjaToScribanMigrationPost(dry_run=dry_run),
                alternate_endpoint=migration_endpoint,
            )

Review comment (suggestion):
can we add the new command under the `notifications` subcommand. 
I think it will make it easier to discover

Code after:

    def update(self, config: models.InstanceConfig) -> models.InstanceConfig:
        return self._req_model(
            "POST",
            models.InstanceConfig,
            data=requests.InstanceConfigUpdate(config=config),
        )


class ValidateScriban(Endpoint):
    """Interact with Validate Scriban"""

    endpoint = "ValidateScriban"

    def post(
        self, req: requests.TemplateValidationPost
    ) -> responses.TemplateValidationResponse:
        return self._req_model("POST", responses.TemplateValidationResponse, data=req)


class Command:
    def __init__(self, onefuzz: "Onefuzz", logger: logging.Logger):
        self.onefuzz = onefuzz
        self.logger = logger


class Utils(Command):
    def namespaced_guid(
        self,
        project: str,
        name: Optional[str] = None,
        build: Optional[str] = None,
        platform: Optional[str] = None,
    ) -> uuid.UUID:
        identifiers = [project]
        if name is not None:
            identifiers.append(name)
        if build is not None:
            identifiers.append(build)
        if platform is not None:
            identifiers.append(platform)
        return uuid.uuid5(ONEFUZZ_GUID_NAMESPACE, ":".join(identifiers))

    def build_container_name(
        self,
        *,
        container_type: enums.ContainerType,
        project: str,
        name: str,
        build: str,
        platform: enums.OS,