# Generating an API Client Library
source: https://developer.mastercard.com/open-finance-au/documentation/integration-and-testing/generating-an-api-client-library/index.md

You can leverage the API specification and consume the Open Finance APIs directly from your application.

Here is how to proceed:

1. Download [mastercard-openbanking.yaml](https://static.developer.mastercard.com/content/open-finance-au/swagger/mastercard-openbanking.yaml) (416KB)
2. Generate an Open Finance API client library using [OpenAPI Generator](https://openapi-generator.tech/docs/installation) and the development framework of your choice (see also: [Generators List](https://openapi-generator.tech/docs/generators/)):
   * Java
   * C#
   * Javascript
   * Python

   ```sh
   openapi-generator-cli generate -g java -i *.yaml -o api_client
   ```

   ```sh
   openapi-generator-cli generate -g csharp-netcore -i *.yaml -o api_client
   ```

   ```sh
   openapi-generator-cli generate -g javascript -i *.yaml -o api_client
   ```

   ```sh
   openapi-generator-cli generate -g python -i *.yaml -o api_client
   ```

3. Add some code to automatically attach the `App-Token` and `App-Key` HTTP headers to requests:
   * Java
   * C#
   * Javascript
   * Python

   ```java
   // An example of okHttp3 interceptor handing Open Finance authentication.
   public class OpenBankingAuthInterceptor implements Interceptor {

       private final AuthenticationApi authenticationApi;
       private final String partnerId;
       private final String partnerSecret;
       private final String appKey;

       private String token;
       private LocalDateTime tokenExpiryTime;

       public OpenBankingAuthInterceptor(String partnerId, String partnerSecret, String appKey) {
           this.partnerId = partnerId;
           this.partnerSecret = partnerSecret;
           this.appKey = appKey;
           this.authenticationApi = new AuthenticationApi();
       }

       @NotNull
       public Response intercept(@NotNull Chain chain) throws IOException {
           try {
               // Always add "App-Key"
               var request = chain.request();
               var requestBuilder = request
                       .newBuilder()
                       .addHeader("App-Key", this.appKey);

               var url = request.url().toString();
               if (url.contains("/authentication")) {
                   // No "App-Token" header needed for /authentication
                   return chain.proceed(requestBuilder.build());
               }

               if (this.tokenExpiryTime == null || this.tokenExpiryTime.isBefore(LocalDateTime.now())) {
                   this.refreshToken();
               }

               // Add access token to the "App-Token" header
               requestBuilder = requestBuilder
                       .addHeader("App-Token", this.token);
               return chain.proceed(requestBuilder.build());
           } catch (Exception e) {
               throw new IOException(e.getMessage());
           }
       }

       private void refreshToken() throws ApiException {
           this.token = createToken();
           this.tokenExpiryTime = LocalDateTime.now().plusMinutes(90);
       }

       private String createToken() throws ApiException {
           return authenticationApi.createToken(new PartnerCredentials()
                   .partnerId(partnerId)
                   .partnerSecret(partnerSecret)).getToken();
       }
     }
   ```

   ```csharp
   // Create a OpenBankingApiClient.cs file that extends the partial ApiClient from ApiClient.cs
   namespace Org.OpenAPITools.Client
   {
       public partial class ApiClient
       {
           private readonly string _partnerId;
           private readonly string _partnerSecret;
           private readonly string _appKey;

           private string _token;
           private DateTime _tokenExpiryTime;

           public ApiClient(string partnerId, string partnerSecret, string appKey)
           {
               _baseUrl = GlobalConfiguration.Instance.BasePath;
               _appKey = appKey;
               _partnerId = partnerId;
               _partnerSecret = partnerSecret;
           }

           partial void InterceptRequest(IRestRequest request)
           {
               // Always add "App-Key"
               request.AddHeader("App-Key", _appKey);

               var url = request.Resource;
               if (url.Contains("/authentication")) {
                   // No "App-Token" header needed for /authentication
                   return;
               }

               if (_tokenExpiryTime < DateTime.Now) {
                   RefreshToken();
               }

               // Add access token to the "App-Token" header
               request.AddHeader("App-Token", _token);
           }

           private void RefreshToken() {
               _token = CreateToken();
               _tokenExpiryTime = DateTime.Now.AddMinutes(90);
           }

           private string CreateToken()
           {
               var credentials = new PartnerCredentials(_partnerId, _partnerSecret);
               var authenticationApi = new AuthenticationApi { Client = this };
               return authenticationApi.CreateToken(credentials).Token;
           }
       }
   }
   ```

   ```javascript
   // Credentials
   const PARTNER_ID = "{{partnerId}}"
   const PARTNER_SECRET = "{{partnerSecret}}"
   const APP_KEY = "{{appKey}}"

   // Token
   let expiry = null
   let token = null

   // Create the API client
   const createClient = function (openAPIClient) {
     // Use a promise to ensure the token has been added before sending the request
     return new Promise((resolve) => {
       let client = openAPIClient.ApiClient.instance;
       let authApi = new AuthenticationApi(client)

       // Add the App-Key header for every request
       client.applyAuthToRequest = function (request) {
         const _end = request._end;
         request._end = function () {
           request.req.setHeader('App-Key', APP_KEY);
           _end.call(request);
         };
         return request;
       };

       // If the token doesn't exist or has expired, refresh it
       let tokenPromise = function refreshToken() {
         return new Promise((resolve) => {
           if (expiry === null || expiry < new Date()) {
             authApi.createToken(new PartnerCredentials(PARTNER_ID, PARTNER_SECRET),
                 (error, data, response) => {
                   if (!error) {
                     expiry = new Date();
                     token = data.token;
                     resolve();
                   }
                 });
           } else {
             resolve()
           }
         })
       }

       // Apply the token to the request headers
       tokenPromise().then(() => {
         client.applyAuthToRequest = function (request) {
           const _end = request._end;
           request._end = function () {
             request.req.setHeader('App-Key', APP_KEY);
             request.req.setHeader('App-Token', token);
             _end.call(request);
           };
           return request;
         };
         resolve(client);
       })
     })
   };
   ```

   ```python
   import datetime
   from functools import wraps

   import openapi_client

   from openapi_client.api.authentication_api import AuthenticationApi
   from openapi_client.api.connect_api import ConnectApi
   from openapi_client.models.connect_parameters import ConnectParameters


   class ApiClient(object):
       # Credentials
       partner_id = "{{partnerId}}"
       partner_secret = "{{partnerSecret}}"
       app_key = "{{appKey}}"

       # API Client
       api_client = None

       # Token details
       token = None
       expiry = None

       @classmethod
       def __init__(self):
           conf = openapi_client.Configuration()
           conf.verify_ssl = False
           conf.ssl_ca_cert = None
           conf.assert_hostname = False
           conf.cert_file = None

           api_client = openapi_client.ApiClient(conf)
           self.add_authentication(self=self, api_client=api_client)
           self.api_client = api_client

       def add_authentication(self, api_client):
           api_client.rest_client.request = self.authenticate(self, api_client.rest_client.request)

       def authenticate(self, func):
           @wraps(func)
           def call_api_function(*args, **kwargs):
               kwargs['headers']['Finicity-App-Key'] = self.app_key
               if self.expiry is None or self.expiry < datetime.datetime.now():
                   self.refresh_token(self)
                   kwargs['headers']['Finicity-App-Token'] = self.token

               return func(*args, **kwargs)

           return call_api_function

       def refresh_token(self):
           current_date = datetime.datetime.now()
           expiry_date = current_date + datetime.timedelta(minutes=90)
           self.expiry = expiry_date

           request_body = {
               'partner_id': self.partner_id,
               'partner_secret': self.partner_secret
           }
           auth_response = AuthenticationApi(self.api_client).create_token(partner_credentials=request_body)
           self.token = auth_response.token
   ```

4. Configure your `ApiClient` instance and use one of the `*Api` classes:
   * Java
   * C#
   * Javascript
   * Python

   ```java
   var apiClient = Configuration.getDefaultApiClient();
   apiClient.setDebugging(true);
   apiClient.setConnectTimeout(240000);
   apiClient.setReadTimeout(240000);
   apiClient.setHttpClient(
           apiClient.getHttpClient()
                   .newBuilder()
                   .addInterceptor(new OpenBankingAuthInterceptor("{{partnerId}}", "{{partnerSecret}}", "{{appKey}}"))
                   .build());

   // Generate a Connect URL
   var api = new ConnectApi(apiClient);
   var params = new ConnectParameters()
           .customerId(CUSTOMER_ID)
           .partnerId(PARTNER_ID);
   var connectUrl = api.generateConnectUrl(params);
   var link = connectUrl.getLink();
   ```

   ```csharp
   var apiClient = new ApiClient("{{partnerId}}", "{{partnerSecret}}", "{{appKey}}");

   // Generate a Connect URL
   var connectApi = new ConnectApi { Client = apiClient };
   var connectParameters = new ConnectParameters(PartnerId, CustomerId);
   var connectUrl = connectApi.GenerateConnectUrl(connectParameters);
   var link = connectUrl.Link;
   ```

   ```javascript
   let client = await createClient(OpenAPIClient);

   // Generate a Connect URL
   let connectApi = new ConnectApi(client)
   let connectParameters = new ConnectParameters(CUSTOMER_ID, PARTNER_ID)

   let connectResponse

   api.generateConnectUrl(connectParameters,
     (error, data, response) => {
       connectResponse = response
       done();
     });
   done();
   ```

   ```python
   customer_id = "{{customerId}}"
   api_client = ApiClient()
   connect_parameters = ConnectParameters(
     partner_id=api_client.partner_id,
     customer_id=customer_id)

   # Generate a Connect URL
   response = ConnectApi(api_client.api_client).generate_connect_url(connect_parameters=connect_parameters)

   print("Connect URL: ", response.link)
   ```

Well done, you're now ready to use Mastercard Open Finance in your application 👏

![Connect URL from IntelliJ](https://static.developer.mastercard.com/content/open-finance-au/uploads/intellij-test.png)

## See Also {#see-also}

* [Quick Start Guide](https://developer.mastercard.com/open-finance-au/documentation/quick-start-guide/index.md)
* [Using the Postman Collection](https://developer.mastercard.com/open-finance-au/documentation/integration-and-testing/postman-collection/index.md)
* [Test Profiles](https://developer.mastercard.com/open-finance-au/documentation/integration-and-testing/test-the-apis/index.md)
* [API Reference](https://developer.mastercard.com/open-finance-au/documentation/api-reference/index.md)
