Metadata-Version: 2.1
Name: bitdotio
Version: 2.0.0
Summary: bit.io Python SDK and CLI
Home-page: https://github.com/bitdotioinc/python-bitdotio
Author: bit.io
Author-email: python@bit.io
License: UNKNOWN
Project-URL: Bug Tracker, https://github.com/bitdotioinc/python-bitdotio/issues
Keywords: bit.io,Database,bit.io Python SDK
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Provides-Extra: psycopg2
Provides-Extra: psycopg2-binary
License-File: LICENSE

# bit.io Python SDK & Command Line Tool

## Installation

In order to support different environments, we have a few ways to install the bitdotio
package with or without the `psycopg2` dependency.

1. If you already have `psycopg2` installed, you can install the default bitdotio package:
```
pip install bitdotio
```

2. If you already have Postgres installed, you can install with the psycopg2 dependency:
```
pip install 'bitdotio[psycopg2]'
```

3. If you do not have or cannot install Postgres, you can install with the psycopg2-binary dependency:
```
pip install 'bitdotio[psycopg2-binary]'
```

# `bitdotio` module

## Usage

The `bitdotio` module consists of a `bitdotio` SDK object which provides helpful
utilities for creating and managing pre-configured connections to bit.io databases
via `psycopg2`, as well as easy methods for accessing the functionality exposed by the
[bit.io developer API](https://docs.bit.io/reference)

Once you have `bitdotio` installed all you need is your API key to start working with bit.io.

You can get your API key by logging into bit.io and opening [the "Connect" tab](https://docs.bit.io/docs/your-connection-credentials) on a database page.

### Example usage

See API reference at the bottom of this document for a full list of methods provided by
the SDK.

```python
import os

from bitdotio import bitdotio


# Load bit.io API key from environment variable
BITIO_KEY = os.environ.get("BITIO_KEY")

# Instantiate the bit.io SDK object
b = bitdotio(BITIO_KEY)

# Create a new public database on bit.io
db_metadata = b.create_database("my-db", is_private=False)
db_name = db_metadata["name"]

# Use a pooled cursor to insert some data
with b.pooled_cursor(db_name) as cur:
    cur.execute("CREATE TABLE person (name text, age integer);")
    people = [("Alice", 45), ("Bob", 84), ("Catherine", 19), ("Davis", 22), ("Emily", 34)]
    for name, age in people:
        cur.execute("INSERT INTO person (name, age) VALUES (%s, %s)", (name, age))

# Execute a query via the HTTP API
print(b.query(db_name, "SELECT * FROM person", data_format="objects"))
```

### Making queries

#### Connecting directly

The `bitdotio` SDK object provides the methods `pooled_connection`, `pooled_cursor`, and
`get_connection` for connecting directly to your database (see below for discusson on
when to use each of these). The connections/cursors returned by these methods are
`psycopg2` connections and cursors, which are fully compatible with the
[Python DB-API](https://peps.python.org/pep-0249/). Full documentation on `psycopg2` can
be found [here](https://www.psycopg.org/docs/usage.html.).

It is preferable to use direct connections in the majority of cases, since they have
superior performance and enable more features compared to the `query` method. In
particular we strongly recommend using direct connections in programs that are
long-running, require transaction management, or transfer large quantities of data.

#### The `query` method

The `query` runs queries via the bit.io HTTP API, and therefore will have worse
performance and feature support than direct connections. Importantly, each query run
via the `query` method is run in a single transaction. The `query` method is recommended
in situations where installing a database driver is undesirable or impossible, when
queries are being run very infrequently, or in very short-lived contexts such as one-off
scripts or serverless backends.

### Connection pooling and management

The recommended way to obtain a direct connection to a bit.io database is via a
connection pool. In order to support scaling to zero, bit.io automatically closes idle
connections after a period of time, and puts databases into a dormant state when there
are no live connections. If you are designing a long-running application, you should
make sure that your database access pattern is resilient to connection closures and
database shutdowns. The best way to do this is via a connection pool. Acquiring
connections from a connection pool allows connection re-use, and handles reconnects in
the event that a connection is dropped. The `bitdotio` SDK object internally manages a
thread-safe connection pool per-database that the caller connects to, and provides two
helpful context mangers for acquiring connections from a pool:
- `pooled_connection`: A context manager providing a `psycopg2` connection to the
  given database acquired from a connection pool. When exiting the context created by
  this context manager, the connection is returned to the pool if still open, or
  discarded if closed. It is recommended to use this method when executing multiple
  transacions, or in situations where explicit transaction management is required.
- `pooled_cursor`: A context manager providing a `psycopg2` cursor created from a
  connection acquired from a connection pool. When exiting the context created by this
  context manager, the cursor's tansaction will be committed, and its connection will be
  returned to the connection pool. It is recommended to use this method in situations
  where a single transaction is required without any complex handling logic. For
  example, performing a sequence of `SELECT` queries, or performing a single insertion
  or update.

There may be situations in which a self-managed, unpooled connection is needed. For
example, if the client needs to persist state onto the connection's database session using
the `SET` command. For such situations, the SDK object provides the `get_connection`
method.

For more information on all of the above, refer to the `psycopg2` documentation on
[connections](https://www.psycopg.org/docs/connection.html),
[cursors](https://www.psycopg.org/docs/cursor.html),
and [pools](https://www.psycopg.org/docs/pool.html).

### Multiprocessing

The `bitdotio` SDK object is not safe to share between multiple processes. If you are
programming in a multiprocess environment, ensure that a `bitdotio` SDK object is
created per-process, not pre-fork.

# `bit` CLI

Installing the `bitdotio` module also installs the command line tool `bit` which lets
you interact with bit.io from scripts or the command line. This is installed next to
your python binary.

You'll want to grab your API key from your bit.io account - to get the key, log into to
bit.io, go to any database, and retrieve it from the "Connect" tab.

```
Usage: bit [OPTIONS] COMMAND [ARGS]...

Options:
  -k, --key TEXT  Your bit.io API key, available when you click the connect
                  button in bit.io
  --help          Show this message and exit.

Commands:
  db
  query
```

All of the commands return JSON.

You can supply your API key either via the `-k/--key` argument, or by setting the it to
the `BITIO_KEY` environment variable. The latter option keeps the key from showing up
in, eg, a `ps` command, and allows secret injection for systems like Kubernetes.


### Examples

#### List databases
```sh
BITIO_KEY=<your key> bit db list
```

This is the same as:

```sh
bit -k <your-key> db list
```

#### Run a query
```sh
bit -k <your-key> query -d "username/dbname" -q "SELECT * FROM my_table"
```

# API Reference

#### `bitdotio(access_token, min_conn=0, max_conn=100)`

Returns an instance of the bit.io SDK object.

_Args_:
- `access_token (str)`: Your bit.io API key

_Kwargs_:
- `min_conn (int)`: The minimum number of live connections per database connection pool.
- `max_conn (int)`: The maximum number of live connections per database connection pool.

_Returns_:

A bit.io SDK instance

<hr>

#### `bitdotio.pooled_connection(db_name)`

Creates a context manager which provides a connection from the connection pool for the
given database name. When the context manager is exited, the connection will be returned
to the connection pool.

_Args_:
- `db_name (str)`: The name of the database to connect to.

_Returns_:

Context manager yielding a `psycopg2.connection`.

<hr>

#### `bitdotio.pooled_cursor(db_name)`

Creates a context manager which provides a cursor from the connection pool for the
given database name. When the context manager is exited, the cursor's transaction will
be committed, and its connection will be returned to the connection pool.

_Args_:
- `db_name (str)`: The name of the database to connect to.

_Returns_:

Context manager yielding a `psycopg2.connection`.

<hr>

#### `bitdotio.get_connection(db_name)`

Returns an unmanaged, unpooled connection to the given database.

_Args_:
- `db_name (str)`: The name of the database to connect to.

_Returns_:

A `psycopg2.connection` object configured for the given database.

<hr>

#### `bitdotio.query(db_name, query_str, data_format=None)`

Execute a query via the bit.io HTTP API

_Args_:
- `db_name (str)`: Name of the database to execute a query against.
- `query_str (str)`: Query to execute.

_Kwargs_:
- `data_format (Optional[str])`:

_Returns_:

Dictionary describing query results.

<hr>

#### `bitdotio.list_databases()`

List metadata pertaining to databases the requester is an owner or collaborator of.

_Returns_:

List of dictionaries describing database metadata.

<hr>

#### `bitdotio.create_database(name, is_private=True, storage_limit_bytes=None)`

_Args_:
- `name (str)`: Name of the database being created (excluding the owner's username)

_Kwargs_:
- `is_private (bool)`: Whether or not the database is set to private. Databases default
  to private.
- `storage_limit_bytes (Optional[int])`: Maximum storage for the database in bytes.
  Limits and defaults are enforced based on billing plan regardless of what is set here.

_Returns_:

Dict containing metadata about the newly created database.

<hr>

#### `bitdotio.get_database(db_name)`

Get metadata about a single database.

_Args_:
- `db_name (str)`: Name of the database to fetch metadata for.

_Returns_:

Dict containing metadata about the given database.

<hr>

#### `bitdotio.update_database(db_name, name=None, is_private=None, storage_limit_bytes=None)`

Update metadata parameters for a given database.

_Args_:
- `db_name (str)`: Name of the database to update.

_Kwargs_:
- `name (Optional[str])`: New name for the database (excluding the owner's username).
- `is_private (Optional[str])`: Whether or not the database is set to private.
- `storage_limit_bytes (Optional[int])`: Maximum storage for the database in bytes.
  Limits and defaults are enforced based on billing plan regardless of what is set here.

_Returns_:

Up to date metadata about the updated database.

<hr>

#### `bitdotio.delete_database(db_name)`

Delete a database. After deletion the database's name will be unusable for up to 30
days. If you need to reuse it sooner, please contact bit.io support.

_Args_:
- `db_name (str)`: Name of the database to delete

_Returns_:

None.

<hr>


