This page documents how to customize method generation for the emitters. For an overview of the setup, please visit the setup page.
Default behaviors
By default, any language code generator will generate both protocol methods and convenient methods.
NOTE: Python and Typescript don’t have a separation of convenient/protocol methods.
namespace PetStoreNamespace ;
/** This is the input I need */
op GetModel is ResourceRead < OutputModel >;
name: str = rest_field( readonly = True )
response: OutputModel = client.get( name = "name" )
namespace PetStoreNamespace . Models
public partial class OutputModel
public string Name { get ; }
namespace PetStoreNamespace
public partial class PetStoreNamespaceClient
public virtual async Task < Response > GetModelAsync ( string name , RequestContext context ) {}
public virtual Response GetModel ( string name , RequestContext context ) {}
public virtual async Task < Response < OutputModel >> GetModelAsync ( string name , CancellationToken cancellationToken = default ) {}
public virtual Response < OutputModel > GetModel ( string name , CancellationToken cancellationToken = default ) {}
const model : OutputModel = await client. path ( "/petStore/model/{name}" ). get ();
package petstorenamespace.models;
public final class OutputModel {
package petstorenamespace;
public final class PetStoreNamespaceClient {
public Response< BinaryData > getModelWithResponse (String name , RequestOptions requestOptions )
public OutputModel getModel (String name )
Customizations
The detailed generation configuration of protocol and/or convenient methods that can be done:
As emitters global parameters:
generate-protocol-methods
: boolean flag to shift the entire generation for the process (true
by default)
generate-convenience-methods
: boolean flag to shift the entire generation for the process (true
by default)
To set global emitters parameters, read the documentation of emitters configuration .
For fine tuning, the set of decorators @protocolAPI
and @convenientAPI
can be used. They take a required boolean as parameter.
Shifting the generation of protocol and convenience on and off
This can be achieved with the augment operator and the emitter package
import "@azure-tools/typespec-client-generator-core" ;
using Azure . ClientGenerator . Core ;
@@convenientAPI ( PetStoreNamespace . GetModel , false );
# Python do not change behavior based on protocolAPI or convenientAPI
// Model class is not generated.
// Convenient method is not generated.
namespace PetStoreNamespace
public partial class PetStoreNamespaceClient
public virtual async Task < Response > GetModelAsync ( string name , RequestContext context ) {}
public virtual Response GetModel ( string name , RequestContext context ) {}
// Typescript do not change behavior based on protocolAPI or convenientAPI
// Model class is not generated.
// Convenient method is not generated.
public final class PetStoreNamespaceClient {
public Response< BinaryData > getModelWithResponse (String name , RequestOptions requestOptions )
Make methods private/internal
Sometimes it may be useful to still generate the method, but to make it private, so it can be re-used by a manual code wrapper.
The two possible value for the Access
enum are internal
and public
.
import "@azure-tools/typespec-client-generator-core" ;
using Azure . ClientGenerator . Core ;
@@access ( PetStoreNamespace . GetModel , "internal" );
# can't import form models directly
from petstorenamespace.models import GetModel # will report error
// Model class is internal
namespace PetStoreNamespace . Models
internal partial class OutputModel
public string Name { get ; }
// Client method is internal
namespace PetStoreNamespace
public partial class PetStoreNamespaceClient
internal virtual async Task < Response > GetModelAsync ( string name , RequestContext context ) {}
internal virtual Response GetModel ( string name , RequestContext context ) {}
internal virtual async Task < Response < OutputModel >> GetModelAsync ( string name , CancellationToken cancellationToken = default ) {}
internal virtual Response < OutputModel > GetModel ( string name , CancellationToken cancellationToken = default ) {}
// Typescript do not change behavior based on protocolAPI or convenientAPI
// Model class resides in implementation package.
// Client method is package private.
package petstorenamespace.implementation.models;
public final class OutputModel {
package petstorenamespace;
public final class PetStoreNamespaceClient {
Response< BinaryData > getModelWithResponse (String name , RequestOptions requestOptions )
OutputModel getModel (String name )
Decide the usage of a model
Models can be used for input, output, or both at the same time. In some languages, this
changes the way the API is exposed for those models.
By default, the code generator will infer the usage based on the TypeSpec. If this inference doesn’t
correspond to expectation, this can be customized with the usage
decorator. Possible values are
input
and output
, and can be combined with Usage.input | Usage.output
.
NOTE: If a model is never used, it will not be generated. Assigning a usage will force generation.
import "@azure-tools/typespec-client-generator-core" ;
using Azure . ClientGenerator . Core ;
// This model is input only
@@usage ( Azure . OpenAI . AzureCognitiveSearchIndexFieldMappingOptions , Usage . input );
// This models is input/output
@@usage ( Azure . OpenAI . ImageGenerations , Usage . input | Usage . output );
# Python doesn't generate different code based on usage
# However, the model may not be generated if it's never used
# In that case, set a usage for the model
// If a model is input-only, it has one public constructor with all required properties as parameters.
// The required properties only have getter. Optional properties have both getter and setter.
// A collection property which is not nullable only has getter whatever it is required or not.
namespace Azure . AI . OpenAI . Models
public partial class AzureCognitiveSearchIndexFieldMappingOptions
public AzureCognitiveSearchIndexFieldMappingOptions ()
public string TitleFieldName { get; set; }
public string UrlFieldName { get ; set ; }
public string FilepathFieldName { get ; set ; }
public IList < string > ContentFieldNames { get ; }
public string ContentFieldSeparator { get ; set ; }
public IList < string > VectorFieldNames { get ; }
public IList < string > ImageVectorFieldNames { get ; }
// If a model is output-only, it does not have any public constructor, and all properties only have getter, no setter.
// If a model is roundtrip (input + output), it has one public constructor with all required properties as parameters.
// All properties except colletion properties which are not nullable will have both getter and setter.
// A collection property which is not nullable only has getter.
namespace Azure . AI . OpenAI . Models
public partial class ImageGenerations
public ImageGenerations ( DateTimeOffset created , IEnumerable < ImageGenerationData > data )
public DateTimeOffset Created { get; set; }
public IList < ImageGenerationData > Data { get ; }
// JS doesn't generate different code based on usage
// However, the model may not be generated if it's never used
// In that case, set a usage for the model
// If a model class is output-only, its constructor is not public.
// Adding Usage.input to it would make its constructor public.
package azure.openai.models;
public final class AzureCognitiveSearchIndexFieldMappingOptions {
public AzureCognitiveSearchIndexFieldMappingOptions ()
public String getTitleField ()
public AzureCognitiveSearchIndexFieldMappingOptions setTitleField (String titleField )
public final class ImageGenerations {
public ImageGenerations (OffsetDateTime createdAt , List< ImageGenerationData > data )
public OffsetDateTime getCreatedAt ()
public List< ImageGenerationData > getData ()