Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b5a23e5
Add .vscode folder to .gitignore
lemonyte Sep 29, 2024
c35e614
New Base implementation
lemonyte Sep 29, 2024
25e6816
Add preliminary tests
lemonyte Sep 29, 2024
43ec114
Add delete everything example
lemonyte Oct 1, 2024
8fe0e0f
Rename Clients to ApiClients
lemonyte Oct 1, 2024
0b17a84
Update implementation for new API and fix typing issues
lemonyte Oct 1, 2024
802c2d3
Move update payload creation to constructor
lemonyte Oct 1, 2024
ac85f5b
Better exception handling and raising
lemonyte Oct 1, 2024
bcf0181
Fix a couple typing mistakes
lemonyte Oct 1, 2024
e2155d5
Dont do anything when putting no items
lemonyte Oct 1, 2024
aaea117
Fix fetch implementation
lemonyte Oct 1, 2024
ec20312
Move fetch under update
lemonyte Oct 1, 2024
5d2e20c
Rename fetch to query
lemonyte Oct 1, 2024
74047e4
Add more tests
lemonyte Oct 1, 2024
3fe421d
Add api docs
lemonyte Oct 1, 2024
27192e6
Use query instead of fetch
lemonyte Oct 1, 2024
a1b1603
Add python-dotenv for tests
lemonyte Oct 2, 2024
83e9491
Fix update payload
lemonyte Oct 2, 2024
c0dccc8
Better type validation
lemonyte Oct 2, 2024
3b2af63
Fix tests
lemonyte Oct 2, 2024
fb73cfd
Make validation optional
lemonyte Oct 9, 2024
dfb1667
Reduce code duplication
lemonyte Oct 9, 2024
b11321c
Make pyright report unnecessary ignores
lemonyte Oct 9, 2024
267dac4
Skip isinstance check on dicts
lemonyte Oct 9, 2024
a25c182
Rename FetchResponse to QueryResponse
lemonyte Oct 9, 2024
7892a42
Improve tests and exceptions
lemonyte Oct 11, 2024
90e81af
Add pytest coverage
lemonyte Oct 11, 2024
050ebbe
Update examples
lemonyte Oct 11, 2024
df1bd04
pre-commit autoupdate
lemonyte Oct 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.vscode/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
Expand All @@ -11,12 +11,12 @@ repos:
args: [--markdown-linebreak-ext=md]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.8
rev: v0.6.9
hooks:
- id: ruff
- id: ruff-format

- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.382.post1
rev: v1.1.384
hooks:
- id: pyright
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ db = connect("your-api-key", "your-project-id")
You can get an API key by fetching it in the [dashboard](https://base.contiguity.co), and a project ID is given to you when creating a project.

## <img src="https://avatars.githubusercontent.com/u/47275976?s=280&v=4" alt="Deta Logo" style="vertical-align: middle;" height="30"> For those moving from Deta Space <img src="https://avatars.githubusercontent.com/u/47275976?s=280&v=4" alt="Deta Logo" style="vertical-align: middle;" height="30">
Contiguity Base is a one-to-one replacement for the old Deta Base API, Deta Base JavaScript SDK, Deta Base Python SDK, and Deta Base Go SDK. The only thing that has changed is initialization.
Contiguity Base is a one-to-one replacement for the old Deta Base API, Deta Base JavaScript SDK, Deta Base Python SDK, and Deta Base Go SDK. The only thing that has changed is initialization.

Instead of `deta = Deta(project_key)`, you'll use `db = connect(api_key, project_id)`

The rest stays the same, because at Contiguity, we think it's crazy for a cloud provider to give you 45 days to move dozens of apps from their proprietary database.

If you're transitioning from Deta Space to Contiguity, welcome!
If you're transitioning from Deta Space to Contiguity, welcome!

## Creating your first "base" 📊

Expand Down Expand Up @@ -129,15 +129,15 @@ results = my_base.fetch({

```python
{
"age": 22,
"age": 22,
"name": "Sarah"
}
```

- **Hierarchical**
```python
{
"user.profile.age": 22,
"user.profile.age": 22,
"user.profile.name": "Sarah"
}
```
Expand All @@ -152,8 +152,8 @@ results = my_base.fetch({
- **Nested Object**
```python
{
"time": {
"day": "Tuesday",
"time": {
"day": "Tuesday",
"hour": "08:00"
}
}
Expand Down
189 changes: 189 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# Base API

## GET /items/{key}

SDK method: `get(key: str) -> Item`

Response `200`:
Returns a single item.

```json
{
"key": "foo",
"field1": "bar"
// ...other item fields
}
```

Response `404`:
Key does not exist.

```text
No content
```

## DELETE /items/{key}

SDK method: `delete(key: str) -> None`

Response `204`:
Returns nothing.

```text
No content
```

## POST /items

SDK method: `insert(item: Item) -> Item`

Request body:

```json
{
"item": {
"key": "foo",
"field1": "bar",
// ...other item fields
"__expires": 1727765807 // optional Unix timestamp
}
}
```

Response `201`:
Returns a list of items.

```json
[
{
"key": "foo",
"field1": "bar"
// ...other item fields
}
// ...other items
]
```

Response `409`:
Key already exists.

```text
No content
```

## PUT /items

SDK method: `put(items: Item[]) -> Item[]`

Request body:

```json
{
"items": [
{
"key": "foo",
"field1": "bar",
// ...other item fields
"__expires": 1727765807 // optional Unix timestamp
}
// ...other items
]
}
```

Response `201`:
Returns a list of items.

```json
[
{
"key": "foo",
"field1": "bar"
// ...other item fields
}
// ...other items
]
```

## PATCH /items/{key}

SDK method: `update(updates: Mapping, key: str) -> Item`

Request body:

```json
{
"set": {
"field1": "bar",
// ...other item fields
"__expires": 1727765807 // optional Unix timestamp
},
"increment": {
"field2": 1,
"field3": -2
},
"append": {
"field4": ["baz"]
},
"prepend": {
"field5": ["foo", "bar"]
},
"delete": ["field6"]
}
```

Response `200`:
Returns a single item.

```json
{
"key": "foo",
"field1": "bar"
// ...other item fields
}
```

Response `404`:
Key does not exist.

```text
No content
```

## GET /query

SDK method: `fetch(*query: Query) -> Item[]`

Request body:

```json
{
"limit": 10,
"last_key": "foo",
"query": [
{
"field1": "foo",
"field4?contains": "bar"
// multiple conditions are ANDed
},
{
"field3?gt": 2
}
// multiple queries are ORed
]
}
```

Response `200`:
Returns a list of items.

```json
[
{
"key": "foo",
"field1": "bar"
// ...other item fields
}
// ...other items
]
```
Empty file added examples/__init__.py
Empty file.
84 changes: 40 additions & 44 deletions examples/basic_usage.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo we should go back to how the old SDK was initialised.

Original file line number Diff line number Diff line change
@@ -1,44 +1,40 @@
from contiguity_base import connect

# Initialize the Contiguity client
db = connect("api-key", "project-id")

# Create a Base instance
my_base = db.Base("randomBase9000")

# Helper function to print results
def print_result(operation, result):
print(f"{operation} result: {result}")
if result is None:
print(f"Warning: {operation} operation failed!")

# Put an item with a specific key
result1 = my_base.put({"value": "Hello world!"}, "my-key-py")
print_result("Put", result1)

# Insert an item with a specific key
result2 = my_base.insert({"name": "John Doe", "age": 30}, "john-doe-py")
print_result("Insert", result2)

# Insert an item with a specific key and expireIn
result3 = my_base.insert({"name": "Jane Doe", "age": 28}, "jane-doe-py", expire_in=3600)
print_result("Insert with expireIn", result3)

# Get an item
get_result = my_base.get("john-doe-py")
print_result("Get", get_result)

# Update an item
update_result = my_base.update({"age": 31}, "john-doe-py")
print_result("Update", update_result)

# Fetch items
try:
fetch_result = my_base.fetch({"age": {"$gt": 25}}, limit=10)
print_result("Fetch", fetch_result)
except Exception as e:
print(f"Fetch operation failed: {str(e)}")

# Delete an item
delete_result = my_base.delete("jane-doe-py")
print_result("Delete", delete_result)
# ruff: noqa: T201
from contiguity_base import Base

# Create a Base instance.
db = Base("my-base")

# Put an item with a specific key.
put_result = db.put({"key": "foo", "value": "Hello world!"})
print("Put result:", put_result)

# Put multiple items.
put_result = db.put({"key": "bar", "value": "Bar"}, {"key": "baz", "value": "Baz"})
print("Put many result:", put_result)

# Insert an item with a specific key.
insert_result = db.insert({"key": "john-doe", "name": "John Doe", "age": 30})
print("Insert result:", insert_result)

# Insert an item with a specific key that expires in 1 hour.
expiring_insert_result = db.insert({"key": "jane-doe", "name": "Jane Doe", "age": 28}, expire_in=3600)
print("Insert with expiry result:", expiring_insert_result)

# Get an item using a key.
get_result = db.get("foo")
print("Get result:", get_result)

# Update an item.
update_result = db.update({"age": db.util.increment(2), "name": "Mr. Doe"}, key="john-doe")
print("Update result:", update_result)

# Query items.
query_result = db.query({"age?gt": 25}, limit=10)
print("Query result:", query_result)

# Delete an item.
db.delete("jane-doe-py")

# Delete all items.
for item in db.query().items:
db.delete(str(item["key"]))
Loading