Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: updated welcome page and changed sdk docs for seo #3802

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
31 changes: 29 additions & 2 deletions fern/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,42 @@ navigation:
layout:
- section: Introduction
contents:
- page: Overview
path: ./pages/sdks/introduction/overview.mdx
- page: What is an SDK?
path: ./pages/sdks/introduction/what-is-an-sdk.mdx
- page: SDKs built with Fern
path: ./pages/sdks/introduction/fern-sdks.mdx
- section: Getting Started
contents:
- page: Generate your first SDK
path: ./pages/sdks/getting-started/generate-your-first-sdk.mdx
- page: Publish a public-facing SDK
path: ./pages/sdks/publish-sdk/publish-your-sdk.mdx
hidden: true
- section: Supported Languages
contents:
- page: Overview
path: ./pages/sdks/supported-languages/overview.mdx
- section: Generally Available
slug: available
contents:
- page: TypeScript
path: ./pages/sdks/supported-languages/available/typescript.mdx
slug: typescript
- page: Python
path: ./pages/sdks/supported-languages/available/python.mdx
slug: python
- page: Go
path: ./pages/sdks/supported-languages/available/go.mdx
slug: go
- page: .Net
path: ./pages/sdks/supported-languages/available/.net.mdx
slug: .net
- page: Java
path: ./pages/sdks/supported-languages/available/java.mdx
slug: java
- page: Ruby
path: ./pages/sdks/supported-languages/available/ruby.mdx
slug: ruby
- section: Features
contents:
- page: Strongly typed
Expand Down
4 changes: 2 additions & 2 deletions fern/pages/api-definition/openapi/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ paths:
$ref: '#/components/examples/PetExample'
```

## How Examples are used in Fern SDKs
## How Examples are used in Fern-generated SDKs

Fern SDKs use examples from your OpenAPI document to generate comments that show up in your IDE. For example, in a Node.js SDK:
SDKs built with Fern use examples from your OpenAPI document to generate comments that show up in your IDE. For example, in a Node.js SDK:

<CodeBlock title="resources/pets/types/Pet.ts">
```ts
Expand Down
2 changes: 1 addition & 1 deletion fern/pages/api-definition/openapi/extensions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ components:
This adds a header of the form `X-API-Key: Token <value>` to the request.

## Global headers
At times, your API will leverage certain headers for every endpoint, or the majority of them, we call these "global headers". For convenience, generated Fern SDKs expose "global headers" to easily be updated on API calls. Take for example an API key, if we declare the API key as a global header, a user will be able to plug theirs in easily:
At times, your API will leverage certain headers for every endpoint, or the majority of them, we call these "global headers". For convenience, SDKs built with Fern expose "global headers" to easily be updated on API calls. Take for example an API key, if we declare the API key as a global header, a user will be able to plug theirs in easily:

```python
import os
Expand Down
2 changes: 1 addition & 1 deletion fern/pages/sdks/features/auto-pagination.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: Paginate through API responses easily with offset, cursor, and link
This feature is only available on paid plans. [Contact us](https://buildwithfern.com/contact) to get started.
</Warning>

Instead of forcing SDK users to learn the intricacies of your pagination system, Fern SDKs will return an iterator so that user's can simply loop through all the results.
Instead of forcing SDK users to learn the intricacies of your pagination system, SDKs built with Fern will return an iterator so that user's can simply loop through all the results.

<Tabs>
<Tab title="TypeScript">
Expand Down
2 changes: 1 addition & 1 deletion fern/pages/sdks/features/discriminated-unions.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Discriminated Unions
description: Fern SDKs include idiomatic support for discriminated unions
description: SDKs built with Fern include idiomatic support for discriminated unions
---

The SDKs natively support discriminated [unions](../../api-definition/fern/types#unions) for both OpenAPI and Fern APIs.
Expand Down
2 changes: 1 addition & 1 deletion fern/pages/sdks/features/forward-compatibility.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Forward compatibility
description: SDKs that are fault-tolerant as your API evolves
---

Fern SDKs are designed so that you can evolve your API without breaking users on
SDKs built with Fern are designed so that you can evolve your API without breaking users on
legacy SDKs. You can safely add additional response properties, enum values, and union variants.
The legacy SDKs will safely handle deserializing extra information.

Expand Down
2 changes: 1 addition & 1 deletion fern/pages/sdks/features/retries-with-backoff.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: Automatically retry failures with exponential backoff
or [email us](mailto:support@buildwithfern.com) to get started.
</Warning>

Fern SDKs will automatically retry failed requests with exponential backoff. A request will be retried as
SDKs built with Fern will automatically retry failed requests with exponential backoff. A request will be retried as
long as the request is deemed retriable and the number of retry attempts has
not grown larger than the configured retry limit.

Expand Down
156 changes: 156 additions & 0 deletions fern/pages/sdks/introduction/fern-sdks.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
title: SDKs built with Fern
description: Generate robust, flexible, and automated SDKs in multiple programming languages.
---

Fern generates robust, flexible, and automated SDKs, enabling developers to use
your API effectively in popular languages.

- **Extensible and customizable.** Enhance your Fern-generated SDK with
handwritten functions and customize your SDK method and group names.
- **Automatically generated.** When your API definition changes, a CI/CD
job kicks off to build, version, and release your updated SDKs.
- **Idiomatic code.**: SDKs built with Fern read as if a language expert wrote them.
Each SDK generator is built from scratch, maintained by the Fern team,
and designed to follow the best practices of each language (i.e., a Python SDK is Pythonic).

SDKs built with Fern offer autocomplete in code editors, type checking,
schema validation at compile time, support for server-sent events streaming, and more.

## Features

### Autocomplete and Docs Pop Ups

<Tabs>
<Tab title="Autocomplete">
<Frame>
<img src="./sdk-autocomplete.png" alt="SDK autocomplete example"/>
</Frame>
</Tab>
<Tab title="Pop-Ups">
<Frame>
<img src="./sdk-pop-ups.png" alt="SDK popup example"/>
</Frame>
</Tab>
</Tabs>

### Code Examples

Example API requests, responses, and schemas (i.e., data models) from your API Spec automatically populate in the codebase of the client library.
SDK snippets showcasing the examples also automatically populate in your Fern Docs API Reference.

<Tabs>
<Tab title="Examples in codebase">
<CodeBlock>
```TypeScript focus={1-13} maxLines=13
/**
* @example
* {
* optimize_streaming_latency: ElevenLabs.OptimizeStreamingLatency.Zero,
* output_format: ElevenLabs.OutputFormat.Mp32205032,
* text: "It sure does, Jackie... My mama always said: \"In Carolina, the air's so thick you can wear it!\"",
* voice_settings: {
* stability: 0.1,
* similarity_boost: 0.3,
* style: 0.2
* }
* }
*/
export interface TextToSpeechRequest {
/** You can turn on latency optimizations at some cost of quality. The best possible final latency varies by model. */
optimize_streaming_latency?: ElevenLabs.OptimizeStreamingLatency;
/** The output format of the generated audio. */
output_format?: ElevenLabs.OutputFormat;
/** The text that will get converted into speech. */
text: string;
/** Identifier of the model that will be used, you can query them using GET /v1/models. The model needs to have support for text to speech, you can check this using the can_do_text_to_speech property. */
model_id?: string;
/** Voice settings overriding stored setttings for the given voice. They are applied only on the given request. */
voice_settings?: ElevenLabs.VoiceSettings;
/** A list of pronunciation dictionary locators (id, version_id) to be applied to the text. They will be applied in order. You may have up to 3 locators per request */
pronunciation_dictionary_locators?: ElevenLabs.PronunciationDictionaryVersionLocator[];
}
```
</CodeBlock>
</Tab>
<Tab title="SDK Snippets in API Reference">
<Frame>
<img src="./sdk-snippet.png" alt="Example of API Reference SDK snippet"/>
</Frame>
</Tab>
</Tabs>

### Helper Functions

SDKs generated by Fern automatically retry failed API requests and handle other common
API tasks like refreshing OAuth tokens, paginating responses, and verifying webhook requests.
They're also easily extensible with custom wrappers.

<Tabs>
<Tab title="Refreshing OAuth tokens">
<CodeBlock>
```Python maxLines=12
import datetime as dt
import typing
from ..auth.client import AuthClient
from .client_wrapper import SyncClientWrapper

class OAuthTokenProvider:
BUFFER_IN_MINUTES = 2

def __init__(self, *, client_id: str, client_secret: str, client_wrapper: SyncClientWrapper):
self._client_id = client_id
self._client_secret = client_secret
self._access_token: typing.Optional[str] = None
self._expires_at: dt.datetime = dt.datetime.now()
self._auth_client = AuthClient(client_wrapper=client_wrapper)

def get_token(self) -> str:
if self._access_token and self._expires_at > dt.datetime.now():
return self._access_token
return self._refresh()

def _refresh(self) -> str:
token_response = self._auth_client.get_token(client_id=self._client_id, client_secret=self._client_secret)
self._access_token = token_response.access_token
self._expires_at = self._get_expires_at(
expires_in_seconds=token_response.expires_in, buffer_in_minutes=self.BUFFER_IN_MINUTES
)
return self._access_token

def _get_expires_at(self, *, expires_in_seconds: int, buffer_in_minutes: int):
return dt.datetime.now() + dt.timedelta(seconds=expires_in_seconds) - dt.timedelta(minutes=buffer_in_minutes)
```
</CodeBlock>

Example from [Sayari Labs](https://github.com/sayari-analytics/sayari-python/blob/64a72553cf642126cfcde6da865384b15b2688f8/src/sayari/core/oauth_token_provider.py#L10)

</Tab>

<Tab title="Custom wrappers">
<CodeBlock>
```TypeScript maxLines=12
import { Collections } from "../api/resources/collections/client/Client";
import { Client as Items } from "./ItemsClient";

// Client adapts the base client to permit extra properties in
// the client.Collections.Items.createItem request.
export class Client extends Collections {
constructor(protected readonly _options: Collections.Options) {
super(_options);
}

protected _items: Items | undefined;

public get items(): Items {
return (this._items ??= new Items(this._options));
}
}
```
</CodeBlock>

See more examples in Webflow's [GitHub repo](https://github.com/webflow/js-webflow-api/tree/master/src/wrapper) for their TypeScript SDK.

</Tab>

</Tabs>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fern/pages/sdks/introduction/sdk-pop-ups.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fern/pages/sdks/introduction/sdk-snippet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading