Metadata-Version: 2.4
Name: bachs-sdk
Version: 0.0.1
Summary: An unofficial python client SDK for BACHS
Keywords: bachs,sdk,api,wrapper
Author: Gbenga Adeyi
Author-email: Gbenga Adeyi <adeyigbenga005@gmail.com>
License-Expression: MIT
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Requires-Dist: pydantic[email]>=2.13.4
Requires-Dist: pyreqwest>=0.12.0
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# Bachs SDK (Python)

[![Downloads](https://static.pepy.tech/badge/bachs-sdk)](https://pepy.tech/project/bachs-sdk)
[![Downloads](https://static.pepy.tech/badge/bachs-sdk/month)](https://pepy.tech/project/bachs-sdk)
[![Downloads](https://static.pepy.tech/badge/bachs-sdk/week)](https://pepy.tech/project/bachs-sdk)

An unofficial python client SDK for [BACHS](https://bachs.io/)

## Features

- Fully Typed.
- [Pydantic](https://pydantic.dev/docs/validation/latest/get-started/) for
payload and response data modeling.
- Custom response data model injection.
- Synchronous and Asynchronous clients

## Installation

Requires Python version `>=3.11`

### With [uv](docs.astral.sh/uv/)

```bash
uv add bachs-sdk
```

### With pip

```bash
pip install bachs-sdk
```

## Usage

```python
# You may provide your credentials through environment variables.
# The client automatically loads the following variables:
#
# BACHS_API_KEY="<your bachs api key>"
#
# Credentials passed to the client on instantiation take precedence over
# environment variables.

from bachs_sdk import BachsClient, AsyncBachsClient, Enviroment, CreateCheckoutSessionBody

# Instantiate the client
# Credentials may be passed directly if they are not available
# in the environment.
# May raise `MissingCredentialError` if no credentials was passed in 
# on instantiation or found in the environmental variables.
client = BachsClient()
# In a async context, you may use the async client
aclient = AsyncBachsClient()
# NOTE: The clients are configured to work in the sandboxed mode by default,
# you have to explicitly pass in `Enviroment.PRODUCTION` and use your production
# secret key i.e. `client = BachsClient(environment=Enviroment.PRODUCTION)`

# Now we create a payload for creating a checkout session.
body_data = {
            "customer": {"email": "adeyigbenga005@gmail.com", "name": "Gbenga Adeyi"},
            "product_cart": [
                {"product_id": "prod_199e781a66b04446a74d", "quantity": 1}
            ],
        }
body = CreateCheckoutSessionBody.model_validate(body_data)
# NOTE: `body` parameter of client methods are all pydantic models and you may 
# choose to instantiate it however you please. They follow a naming convention 
# of converting the method name (i.e. `create` in this case),and resource 
# (i.e. checkout sessions in this case ) and appending `body` to it after which
# the resulting string is converted to PascalCase.
# "create" + "checkout_session" + "body" = "CreateCheckoutSessionBody"

# Now we call our client method designated for creating a checkout session
# with our payload. (Calling a client method that makes a request, may raise 
# `ClientError` You need to handle this. `client.checkout_sessions` has methods
# that maps to enpoints from the official API reference)
response = client.checkout_sessions.create(body)
# If you're using the async clients, the method names remain the same, they just
# need to be awaited (This only works in a async context. Note that we're using 
# `aclient `and not `client`).
response =await aclient.checkout_sessions.create(body)

# Use the response data in your application
print(response)
# NOTE: responses are pydantic models of type `APIResponse[T]` where `T` is the
# type of the `data` field. The response also includes fields like `http_status`
# `request_id` and `raw` when the request is successful else the response is of
# type `APIErrorResponse` which is also a pydantic model with the details of what
# went wrong with the request. The `raw` field of `APIResponse[T]`
# which is the exact response data gotten from Bachs without any serialization.
# It's also worth noting that you may pass a custom response model while calling
# the client method via the `response_model_class` parameter, for the most part,
# you'll only need to change the `T` of the `APIResponse` e.g if i have
# `MyCustomResponseData`, then `response_model_class=APIResponse[MyCustomResponseData]`.
# When the client is unable to serialize the data returned by Bachs, it sets the
# `data` field to unserialized data and logs a warning if `raise_serialization_error=False`,
# which is the default otherwise it raises a `ResponseSerializationError`, 
# the original data is still present in the `raw` field.

# Another example creating a test product
# Update your imports
from bachs_sdk import (
    BachsClient, 
    AsyncBachsClient, 
    Enviroment, 
    Currency, # newly added
    PriceType, # newly added
)

body_data = {
            "name": "Aura Farming Course edition 01",
            "description": "A demo product",
            "price": {
                "currency": Currency.NGN,
                "price_type": PriceType.FIXED,
                "amount": "1500.50",
                "currency_options": [],
            },
        }
body = CreateProductBody.model_validate(body_data)
response = client.products.create(body)
```

| Client bindings            | Functionality                                             |
|----------------------------|-----------------------------------------------------------|
| `client.checkout_sessions` | provides methods that maps to checkout sessions endpoints |
| `client.customers`         | provides methods that maps to customers endpoints         |
| `client.media`             | provides methods that maps to media upload endpoints      |
| `client.misc`              | provides methods that maps to miscellaneous endpoints     |
| `client.payments`          | provides methods that maps to payments endpoints          |
| `client.products`          | provides methods that maps to products endpoints          |
| `client.refunds`           | provides methods that maps to refunds endpoints           |
| `client.subscriptions`     | provides methods that maps to subscriptions endpoints     |

Client bindings have the same name on both `BachsClient` and `AsyncBachsClient`

| Client methods                                 | Functionality                                            |
|------------------------------------------------|----------------------------------------------------------|
| `client.checkout_sessions.create`              | create a checkout session, see usage above               |
| `client.checkout_sessions.get`                 | retrieve a checkout session                              |
| `client.customers.create`                      | create a customer                                        |
| `client.customers.get`                         | retrieve a customer                                      |
| `client.customers.update`                      | update a customer's information                          |
| `client.customers.list`                        | retrieve a list of customers with pagination             |
| `client.media.upload`                          | upload a media file                                      |
| `client.media.get`                             | retrieve an uploaded media file                          |
| `client.media.delete`                          | delete an uploaded media file                            |
| `client.misc.get_balances`                     | retrieve account balances                                |
| `client.misc.list_payment_methods`             | retrieve a list of supported payment methods             |
| `client.misc.list_payment_rails`               | retrieve a list of payment rails                         |
| `client.misc.list_payout_supported_currencies` | retrieve a list of payout supported currencies           |
| `client.misc.list_supported_currencies`        | retrieve a list of supported currencies                  |
| `client.payments.list`                         | retrieve a list of payments with pagination support      |
| `client.payments.get`                          | retrieve a payments (transaction)                        |
| `client.products.create`                       | create a product                                         |
| `client.products.get`                          | retrieve a product                                       |
| `client.products.update`                       | update the details of a product                          |
| `client.products.list`                         | retrieve a list of products with pagination support      |
| `client.products.archive`                      | archive a product                                        |
| `client.products.unarchive`                    | unarchive a product                                      |
| `client.refunds.create`                        | create a refund                                          |
| `client.refunds.list`                          | retrieve a list of refunds with pagination support       |
| `client.refunds.get`                           | retrieve a refund                                        |
| `client.subscriptions.list`                    | retrieve a list of subscriptions with pagination support |
| `client.subscriptions.get`                     | retrieve a subscription                                  |
| `client.subscriptions.update`                  | update a subscription                                    |
| `client.subscriptions.delete`                  | delete a subscription                                    |

### NOTE

This SDK is still under active development and the APIs may change. All you'll ever need to import from the SDK,
can be imported from the
top level (i.e.`from bachs_sdk import x,y,z`) for ease of you but might change
if the need arises.
Doc strings documentation coming soon.

---

## Issues and Contributions

If you discover bugs, missing endpoints, incorrect typings, or any other issues,
please open an issue or submit a pull request. Contributions are welcome.
