# Editing SDK Docs

Speakeasy-managed SDKs include a `README.md` file that contains at least the following sections by default:

- `## Summary`: A brief introduction based on the `info` and `externalDocs` attributes defined in the OpenAPI document.
- `## Table of Contents`: A list of links to all available sections in the README.
- `## SDK Installation`: An installation snippet based on the package name provided in the `gen.yaml` file.
- `## SDK Example Usage`: An example usage snippet based on the first operation in the OpenAPI document.
- `## SDK Available Operations`: Links to documentation that covers all the SDK's methods.

Here's what it looks like put together:

```markdown
# github.com/client-sdk

  <!-- Start Summary [summary] -->

## Summary

<The `info.summary` provided in your OpenAPI specification>

<The `info.description` provided in your OpenAPI specification>

For more information about the API: [<externalDocs.description>](externalDocs.url)

  <!-- End Summary [summary] -->

  <!-- Start Table of Contents [toc] -->

## Table of Contents

<!-- $toc-max-depth=2 -->

- [OpenAPI SDK](#openapi-sdk)
  - [SDK Installation](#sdk-installation)
  - [SDK Example Usage](#sdk-example-usage)
  - [Available Resources and Operations](#available-resources-and-operations)
  - ...
- [Development](#development)
  - [Maturity](#maturity)
  - [Contributions](#contributions)
    <!-- End Table of Contents [toc] -->

      <!-- Start SDK Installation [installation] -->

## SDK Installation

```bash
go get github.com/client-sdk
```

## SDK Example Usage

```go
package main

using PetStore.Models.Pets;

var sdk = new PetstoreSDK();

var req = new Pet();

var res = await sdk.Pets.AddPetAsync(req);
```

### List the pets

Now you can get all of the pets that have been added.

```csharp
using PetStore;
using PetStore.Models.Pets;

var sdk = new PetstoreSDK();
var res = await sdk.Pets.ListPetsAsync();
```
````

### Table of Contents

To generate a more detailed Table of Contents, you can edit the value of the `$toc-max-depth` parameter in your `README.md` and subheadings will get updated upon regeneration:

```markdown
<!-- $toc-max-depth=3 -->

- [openapi](#openapi)
  - [SDK Installation](#sdk-installation)
  - [SDK Example Usage](#sdk-example-usage)
    - [Example 1](#example-1)
    - [Example 2](#example-2)
    - [Example 3](#example-3)
  - [Custom Header](#custom-header)
- ...
```

To ensure custom headings are properly referenced when manually adding sections to your `README.md` file, the basic markdown syntax should be respected:

```markdown
## Section Heading (level 2)

### Subsection Heading (level 3)

...
```

### Feature sections

Specific usage snippets can also be selected for other sections in the main `README.md`, provided they meet the requirements to showcase the feature at play. To do so, use the `x-speakeasy-usage-example` extension and specify a list of section `tags` (referring to `<-- Start Section [tag] -->` placeholders).

For example, if you wish to select an operation for both the **Override Server URL Per-Operation** and the **Retries** sections, you can use the following:

```yaml
/webhooks/subscribe:
  post:
    operationId: subscribeToWebhooks
    servers:
      - url: https://speakeasy.bar
    x-speakeasy-usage-example:
      tags:
        - server
        - retries
    x-speakeasy-retries:
      strategy: backoff
      backoff:
        initialInterval: 10
        maxInterval: 200
        maxElapsedTime: 1000
        exponent: 1.15
```

The supported `tags` and their associated conditions are listed in this table:

If you wish to select an operation for the main usage section as well as other sections, you can use the `usage` tag:

```yaml
/drinks/{page}:
  get:
    operationId: listDrinks
    x-speakeasy-pagination:
      type: offsetLimit
      inputs:
        - name: page
          in: parameters
          type: page
    x-speakeasy-usage-example:
      title: "Browse available drinks"
      position: 2
      tags:
        - usage
        - pagination
```

Note: The `title`, `description`, and `position` attributes only affect the main **SDK Example Usage** section.

### Values

When generating usage examples, Speakeasy defaults to using any `example` values provided for schemas within your OpenAPI document. If no examples are present, Speakeasy will try to determine the most relevant example to generate from either the `format` field of a schema or the property name of a schema in an object.

For example, if the schema has `format: email` or is within a property called `email`, Speakeasy will generate a random email address as an example value.

### Security Schemes

For security schemes, the OpenAPI Specification does not allow you to specify examples of the values needed to populate the security details when initializing the SDKs. To provide custom examples for these values, add the `x-speakeasy-example` extension to the `securitySchemes` in your OpenAPI document.

For example:

```yaml
components:
  securitySchemes:
    apiKey:
      type: apiKey
      name: api_key
      in: header
      x-speakeasy-example: YOUR_API_KEY
```

The `x-speakeasy-example` value must be a string value and will be used as the example value for the Security Scheme. If the Security Scheme is a basic auth scheme, the example value will be a key-value pair that consists of a username and password split by a `;` character, such as `YOUR_USERNAME;YOUR_PASSWORD`.

## Comments

### Code Comments

As part of the SDK generation, the Speakeasy CLI will generate comments for operations and models in generated SDKs. These comments are generated from the OpenAPI specification, based on the summary or description of the operation or schema. Comments are generated in the target language docstring format.

For example, in Python, the comments will be generated as [PEP 257](https://www.python.org/dev/peps/pep-0257/)-compliant docstrings.

By default, comments are generated for all operations and models. To disable comment generation for your SDK, modify your `gen.yaml` file to disable them, like so:

```yaml
## ...
generation:
  comments:
    disabled: true
```

### Operation Comments

Comments for each method in the generated SDK will be generated from the summary or description of the Operation. For example, if you have an Operation like the following:

```yaml
paths:
  /pets:
    get:
      operationId: listPets
      summary: List all pets
      description: Get a list of all pets in the system
      responses:
        "200":
          description: A list of pets
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Pet"
```

The generated SDK will have a method commented like so:

<CodeWithTabs client:visible
  tabs={[
    {
      label: "Go",
      language: "go",
      code: `// ListPets - List all pets
  // Get a list of all pets in the system
  func (s *SDK) ListPets(ctx context.Context) (*operations.ListPetsResponse, error) {
  // ...
  }`,
    },
    {
      label: "Python",
      language: "python",
      code: `def list_pets(self) -> operations.ListPetsResponse:
      r"""List all pets
      Get a list of all pets in the system
      """
      # ...`,
    },
    {
      label: "TypeScript",
      language: "typescript",
      code: `  /**
      * ListPets - List all pets
      *
      * Get a list of all pets in the system
      */
    ListPets(
      config?: AxiosRequestConfig
    ): Promise<operations.ListPetsResponse> {
      // ...
    }`,
    },
    {
      label: "Java",
      language: "java",
      code: `  /**
      * ListPets - List all pets
      *
      * Get a list of all pets in the system
      **/
      public ListPetsResponse listPets() {
        // ...
    }`,
    },
    {
      label: "C#",
      language: "csharp",
      code: `/// <summary>
  /// List all pets
  ///
  /// <remarks>
  /// Get a list of all pets in the system
  /// </remarks>
  /// </summary>
  Task<ListPetsResponse> ListPetsAsync();`,
    },
  ]}
/>

If both the summary and description are present, the summary will be used as the first line of the comment and the description will be used as the second line of the comment. If just the description is present, it will be used as the first line of the comment. If both are present, but you would like to omit the description as it might be too verbose, you can use the `omitdescriptionifsummarypresent` option in your `gen.yaml` file, as follows:

```yaml
## ...
generation:
  comments:
    omitDescriptionIfSummaryPresent: true
```

### Model Comments

For each model in the generated SDK, comments are generated from the description of the schema. For example, if you have the following schema:

```yaml
components:
  schemas:
    Pet:
      type: object
      description: A pet sold in the pet store
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
```

The generated SDK will have a model commented like so:

<CodeWithTabs client:visible
  tabs={[
    {
      label: "Go",
      language: "go",
      code: `// Pet
  // A pet sold in the pet store
  type Pet struct {
    // ...`,
    },
    {
      label: "Python",
      language: "python",
      code: `@dataclass_json
@dataclass
class Pet:
      r"""Pet
      A pet sold in the pet store
      """
      # ...`,
    },
    {
      label: "TypeScript",
      language: "typescript",
      code: `// Pet
  /**
    * A pet sold in the pet store
    **/
  export class Pet extends SpeakeasyBase {
      // ...`,
    },
    {
      label: "Java",
      language: "java",
      code: `/**
    * Pet
    *
    * A pet sold in the pet store
    */
  public class Pet {
      // ...
  }`,
    },
    {
      label: "C#",
      language: "csharp",
      code: `/// <summary>
/// A pet sold in the pet store
/// </summary>
public class Pet {
    // ...
}`,
    },
  ]}
/>

### Per-SDK Comments

You can configure comments that only display in the SDK for a single language. For example, if you need the comment for the TypeScript or the Golang SDK to say something different from the others, or you want to control the documentation separately for each language, you can use the Speakeasy `x-speakeasy-docs` extension. Anywhere you can set the `summary` or `description`, you can also add `x-speakeasy-docs` with per-language text for the docs.

Consider the following parameter description:

```yaml
parameters:
  - name: type
    in: query
    description: This query parameter names the type of drink to filter the results by. If not provided, all drinks will be returned.
    required: false
    schema:
      $ref: "#/components/schemas/DrinkType"
    x-speakeasy-docs:
      go:
        description: The type field names the type of drink to filter the results by. If set to nil, all drinks will be returned.
      python:
        description: The ``type`` field names the type of drink to filter the results by. If set to ``None``, all drinks will be returned.
      typescript:
        description: This field is the type of drink to filter the results by. If set to null, all drinks will be returned.
```

The documentation generated for each SDK will contain different comments specific to the respective programming languages.

## Class Names

By default, Speakeasy SDKs will be generated with the class name, `SDK`. However, you can configure a custom class name by modifying your `gen.yaml` file to include:

```yaml
generation:
  sdkClassName: "myClassName"
```

This will yield a package like this:

```go
package petshop

import (
	"net/http"

	"openapi/pkg/utils"
)

var ServerList = []string{
	"http://petstore.speakeasy.io/v1",
}

type HTTPClient interface {
	Do(req *http.Request) (*http.Response, error)
}

type PetShop struct {
	Pets *Pets

	_defaultClient  HTTPClient
	_securityClient HTTPClient

	_serverURL  string
	_language   string
	_sdkVersion string
	_genVersion string
}
```
