Skip to content

Commit

Permalink
Merge branch '45-bump-to-4.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
greenrobot committed May 15, 2024
2 parents 1395fa9 + 3be80f7 commit ae0cf3b
Show file tree
Hide file tree
Showing 51 changed files with 3,113 additions and 729 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ jobs:
matrix:
os: ["ubuntu", "windows", "macos"]
python: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] # https://devguide.python.org/versions/#versions

exclude:
- os: "macos"
python: "3.7" # Prevent "The version '3.7' with architecture 'arm64' was not found for macOS 14.4.1"
runs-on: ${{ matrix.os }}-latest

steps:
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ share/python-wheels/
.installed.cfg
*.egg
MANIFEST
**/__pycache__
**/__pycache__
env/
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ObjectBox Python ChangeLog
==========================

4.0.0 (2024-05-16)
------------------

* ObjectBox now supports vector search ("vector database") to enable efficient similarity searches.
This is particularly useful for AI/ML/RAG applications, e.g. image, audio, or text similarity.
Other use cases include sematic search or recommendation engines.
See https://docs.objectbox.io/ann-vector-search for details.
* Queries: support for Property-based conditions and logic combinations
* Convenient "Store" API deprecates ObjectBox and Builder API
* New examples added, illustrating an VectorSearch and AI/RAG application
* Dependency flatbuffers: Updated to 24.3.50
* Adjusting the version number to match the core version (4.0); we will be aligning on major versions from now on.

Older Versions
--------------
Please check https://github.com/objectbox/objectbox-python/releases for details.
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,10 @@ clean: ## Clean build artifacts
rm -rf *.egg-info

publish: ## Publish the package built by `make build`
set -e ; \
${PYTHON} -m twine upload --verbose dist/objectbox*.whl
set -e
@echo "****************************************************************"
@echo ">>> Please enter the API token when asked for a password. <<<"
@echo ">>> The API token starts with the prefix 'pypi-'. <<<"
@echo ">>> See https://pypi.org/help/#apitoken for details. <<<"
@echo "****************************************************************"
${PYTHON} -m twine upload -u "__token__" --verbose dist/objectbox*.whl
177 changes: 66 additions & 111 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,83 +1,57 @@
ObjectBox Python API
====================
[ObjectBox](https://objectbox.io) is a superfast database for objects, now also available for Python (3.4+) with a simple CRUD API.
ObjectBox Python
================
[ObjectBox](https://objectbox.io) Python is a lightweight yet powerful on-device database & vector database.
Store Python objects and vectors directly with an easy-to-use CRUD API while enjoying exceptional speed and efficiency.
And because it's an embedded database, there's no setup required.

## Table of Contents:
- [Getting Started](#getting-started)
- [Model IDs and UIDs](#model-ids-and-uids)
- [model.py](#modelpy)
- [Using ObjectBox](#using-objectbox)
- [Some features](#some-features)
- [Coming in the future](#coming-in-the-future)
- [Help wanted](#help-wanted)
- [Feedback](#feedback)
- [License](#license)

---
Its advanced vector search empowers AI for a variety of applications, including RAG AI, generative AI,
and similarity searches.

Getting started
---------------
First of all, install the latest version:
Designed for high performance, the ObjectBox database runs locally on-device.
As an offline-first solution, ObjectBox makes sure your app reliably works offline as well as online
(via [Sync](https://objectbox.io/sync/)).

```bash
pip install --upgrade objectbox
```

To start using ObjectBox as a storage for your data, you need to define your model first.
The model consists of Python classes annotated with `@Entity` decorator.

### Model IDs and UIDs
_Table of Contents_

Each Entity has to have an ID (unique among entities).
Properties need an ID as well (unique inside one Entity).
Both Entities and Properties must also have an UID, which is a globally unique identifier.

For other ObjectBox supported languages, the binding takes care of assigning these IDs/UIDs but this feature is not yet implemented for Python.
To learn more, see [ObjectBox Java documentation](https://docs.objectbox.io/advanced/meta-model-ids-and-uids)

#### model.py
- [Feature Highlights](#feature-highlights)
- [Code Example (CRUD - Create, Read, Update, Delete)](#code-example-crud---create-read-update-delete)
- [Getting Started](#getting-started)
- [Alpha Notes](#alpha-notes)
- [Help wanted](#help-wanted)
- [Feedback](#feedback)
- [License](#license)

```python
from objectbox.model import *

@Entity(id=1, uid=1)
class Person:
id = Id(id=1, uid=1001)
name = Property(str, id=2, uid=1002)
is_enabled = Property(bool, id=3, uid=1003)
# int can be stored with 64 (default), 32, 16 or 8 bit precision.
int64 = Property(int, id=4, uid=1004)
int32 = Property(int, type=PropertyType.int, id=5, uid=1005)
int16 = Property(int, type=PropertyType.short, id=6, uid=1006)
int8 = Property(int, type=PropertyType.byte, id=7, uid=1007)
# float can be stored with 64 or 32 (default) bit precision.
float64 = Property(float, id=8, uid=1008)
float32 = Property(float, type=PropertyType.float, id=9, uid=1009)
byte_array = Property(bytes, id=10, uid=1010)
# Regular properties are not stored.
transient = ""
```
Feature Highlights
------------------

### Using ObjectBox
🏁 **On-device vector database** - for AI apps that work any place.\
🏁 **High performance** - superfast response rates enabling real-time applications.\
🪂 **ACID compliant** - Atomic, Consistent, Isolated, Durable.\
🌱 **Scalable** - grows with your app, handling millions of objects with ease.\
💚 **Sustainable** - frugal on CPU, Memory and battery / power use, reducing CO2 emissions.\
💐 **[Queries](https://docs.objectbox.io/queries)** - filter data as needed, even across relations.\
💻 **Multiplatform** - Get native speed on your favorite platforms.\
* Linux x86-64 (64-bit)
* Linux ARMv6hf (e.g. Raspberry PI Zero)
* Linux ARMv7hf (e.g. Raspberry PI 3)
* Linux ARMv8 (e.g. Raspberry PI 4, 5, etc.)
* MacOS x86-64 and arm64 (Intel 64-bit and Apple Silicon)
* Windows x86-64 (64-bit)

To actually use the database, you launch (or "build") it with the model you've just defined.
Afterwards, you can reuse the instance (`ob` in the example below) and use it to access "Entity Boxes" which hold your objects.
#### Code Example (CRUD - Create, Read, Update, Delete)

#### program.py
What does using ObjectBox in Python look like?

```python
import objectbox

# from mypackage.model import Person

# Configure ObjectBox: should be done only once in the whole program and the "ob" variable should be kept around
model = objectbox.Model()
model.entity(Person, last_property_id=objectbox.model.IdUid(10, 1010))
model.last_entity_id = objectbox.model.IdUid(1, 1)
ob = objectbox.Builder().model(model).directory("db").build()
# The ObjectBox Store represents a database; keep it around...
store = objectbox.Store(model=model)

# Open the box of "Person" entity. This can be called many times but you can also pass the variable around
box = objectbox.Box(ob, Person)
# Get a box for the "Person" entity; a Box is the main interaction point with objects and the database.
box = store.box(Person)

person = Person()
person.name = "Joe Green"
Expand All @@ -88,65 +62,46 @@ box.put(person) # Update
box.remove(person) # Delete
```

Additionally, see the [TaskList example app](https://github.com/objectbox/objectbox-python/tree/main/example). After checking out this repository to run the example:
Getting started
---------------
Latest version: 4.0.0a0 (2024-05-15)

To install or update the latest version of ObjectBox, run this:

```bash
pip install --upgrade --pre objectbox # "--pre" because you want to get the 4.0.0 alpha version
```
// Set up virtual environment, download ObjectBox libraries
make depend
Now you are ready to use ObjectBox in your Python project.

// Activate virtual environment...
// ...on Linux
source .venv/bin/activate
// ...on Windows
.venv\Scripts\activate
Head over to the **[ObjectBox documentation](https://docs.objectbox.io)**
and learn how to setup your first entity classes.

// Run the example
python3 -m example
### Examples

// Once done, leave the virtual environment
deactivate
```
Do you prefer to dive right into working examples?
We have you covered in the [example](example/) folder.
It comes with a task list application and a vector search example using cities.
Additionally, for AI enthusiasts, we provide an "ollama" example,
which integrates a local LLM (via [ollama](https://ollama.com))
with ObjectBox to manage and search embeddings effectively.

For more information and code examples, see the tests folder. The docs for other languages may also help you understand the basics.

* ObjectBox Java/Dart/Flutter - https://docs.objectbox.io
* ObjectBox Go - https://golang.objectbox.io
* ObjectBox Swift - https://swift.objectbox.io

Some features
-------------
* Automatic transactions (ACID compliant)
* Bulk operations
* Vector types, e.g. for AI vector embeddings
* Platforms supported with native speed:
* Linux x86-64 (64-bit)
* Linux ARMv6hf (e.g. Raspberry PI Zero)
* Linux ARMv7hf (e.g. Raspberry PI 3; available only on request)
* Linux ARMv8 (e.g. Raspberry PI 4)
* MacOS x86-64 and arm64 (Intel 64-bit and Apple Silicon)
* Windows x86-64 (64-bit)

Coming in the future
--------------------
The goodness you know from the other ObjectBox language-bindings, e.g.,

* model management (no need to manually set id/uid)
* automatic model migration (no schema upgrade scripts etc.)
* powerful queries
* relations (to-one, to-many)
* asynchronous operations
* secondary indexes
Alpha Notes
-----------
While ObjectBox Python is powered by a rock stable core written in C/C++, we label our Python binding still "alpha."
We do this to manage expectations as some quality of life improvements are yet to come to our Python binding.
This is mostly about "model management," which still requires you to do some manual coding setup, e.g. for model IDs.
The final release will take care of this for you automatically.

Help wanted
-----------
ObjectBox for Python is still in an early stage with limited feature set (compared to our other supported languages).
To bring all these features to Python, we're asking the community to help out. PRs are more than welcome!
ObjectBox for Python is open to contributions.
The ObjectBox team will try its best to guide you and answer questions.
See [CONTRIBUTING.md](https://github.com/objectbox/objectbox-python/blob/main/CONTRIBUTING.md) to get started.

Feedback
--------
Also, please let us know your feedback by opening an issue: for example, if you experience errors or if you have ideas
for how to improve the API. Thanks!
We are looking for your feedback!
Please let us know what you think about ObjectBox for Python and how we can improve it.

License
-------
Expand Down
6 changes: 3 additions & 3 deletions benchmark.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import objectbox
import time
from tests.model import TestEntity
from tests.common import remove_test_dir, load_empty_test_objectbox
from tests.common import remove_test_dir, load_empty_test_default_store


class ObjectBoxPerf:
Expand All @@ -10,8 +10,8 @@ class ObjectBoxPerf:
"""

def __init__(self):
self.ob = load_empty_test_objectbox()
self.box = objectbox.Box(self.ob, TestEntity)
self.store = load_empty_test_default_store()
self.box = store.box(TestEntity)

def remove_all(self):
self.box.remove_all()
Expand Down
3 changes: 2 additions & 1 deletion download-c-lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Script used to download objectbox-c shared libraries for all supported platforms. Execute by running `make get-lib`
# on first checkout of this repo and any time after changing the objectbox-c lib version.

version = "v0.21.0" # see objectbox/c.py required_version
version = "v4.0.0" # see objectbox/c.py required_version
variant = 'objectbox' # or 'objectbox-sync'

base_url = "https://github.com/objectbox/objectbox-c/releases/download/"
Expand Down Expand Up @@ -49,6 +49,7 @@ def download(rel_path: str):

# Download the file from `url`, save it in a temporary directory and get the path to it (e.g. '/tmp/tmpb48zma')
source_url = url_for(rel_path);
print(f"URL {source_url}")
tmp_file, headers = urllib.request.urlretrieve(source_url)

# extract the file
Expand Down
75 changes: 75 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# ObjectBox-Python Examples

The following examples are available from this repository.

## Application Example: Tasks

This is our classic Tasks application using a CLI.

```
cd example
python -m tasks
Welcome to the ObjectBox tasks-list app example. Type help or ? for a list of commands.
> new buy oat
> new buy yeast
> new bake bread
> ls
ID Created Finished Text
1 Mon Apr 22 11:02:27 2024 buy oat
2 Mon Apr 22 11:02:30 2024 buy yeast
3 Mon Apr 22 11:02:34 2024 bake bread
> done 1
> done 2
> ls
> ls
ID Created Finished Text
1 Mon Apr 22 11:02:27 2024 Mon Apr 22 11:03:02 2024 buy oat
2 Mon Apr 22 11:02:30 2024 Mon Apr 22 11:03:18 2024 buy yeast
3 Mon Apr 22 11:02:34 2024 bake bread
> exit
```

## Vector-Search Example: Cities

This example application starts with a pre-defined set of capital cities and their geo coordinates.
It allows to search for nearest neighbors of a city (`city_neighbors`) or by coordinates (`neighbors`) as well as adding more locations (`add`).

```
python -m vectorsearch-cities
Welcome to the ObjectBox vectorsearch-cities example. Type help or ? for a list of commands.
> ls
ID Name Latitude Longitude
1 Abuja 9.08 7.40
2 Accra 5.60 -0.19
[..]
212 Yerevan 40.19 44.52
213 Zagreb 45.81 15.98
> ls Ber
ID Name Latitude Longitude
28 Berlin 52.52 13.40
29 Bern 46.95 7.45
> city_neighbors Berlin
ID Name Latitude Longitude Score
147 Prague 50.08 14.44 7.04
49 Copenhagen 55.68 12.57 10.66
200 Vienna 48.21 16.37 27.41
34 Bratislava 48.15 17.11 32.82
89 Ljubljana 46.06 14.51 42.98
> neighbors 6,52.52,13.405
ID Name Latitude Longitude Score
28 Berlin 52.52 13.40 0.00
147 Prague 50.08 14.44 7.04
49 Copenhagen 55.68 12.57 10.66
200 Vienna 48.21 16.37 27.41
34 Bratislava 48.15 17.11 32.82
89 Ljubljana 46.06 14.51 42.98
> add Area51, 37.23, -115.81
> city_neighbors Area51
ID Name Latitude Longitude Score
107 Mexico City 19.43 -99.13 594.86
27 Belmopan 17.25 -88.76 1130.92
64 Guatemala City 14.63 -90.51 1150.79
164 San Salvador 13.69 -89.22 1261.12
67 Havana 23.11 -82.37 1317.73
```
Loading

0 comments on commit ae0cf3b

Please sign in to comment.