Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

WIP: major clean ups for the codebase #86

Merged
merged 2 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 11 additions & 8 deletions deta/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@
import urllib.error
import urllib.request
import json
from typing import Union

from .base import _Base
from .drive import _Drive
from .utils import _get_project_key_id


try:
from detalib.app import App
from detalib.app import App # pyright: ignore

app = App()
except Exception:
pass

try:
from ._async.client import AsyncBase
from ._async.client import AsyncBase # pyright: ignore
except ImportError:
pass

__version__ = "1.2.0"


def Base(name: str):
project_key, project_id = _get_project_key_id()
return _Base(name, project_key, project_id)
Expand All @@ -34,20 +34,20 @@ def Drive(name: str):


class Deta:
def __init__(self, project_key: str = None, *, project_id: str = None):
def __init__(self, project_key: Union[str, None] = None, *, project_id: Union[str, None] = None):
project_key, project_id = _get_project_key_id(project_key, project_id)
self.project_key = project_key
self.project_id = project_id

def Base(self, name: str, host: str = None):
def Base(self, name: str, host: Union[str, None] = None):
return _Base(name, self.project_key, self.project_id, host)

def AsyncBase(self, name: str, host: str = None):
def AsyncBase(self, name: str, host: Union[str, None] = None):
from ._async.client import _AsyncBase

return _AsyncBase(name, self.project_key, self.project_id, host)

def Drive(self, name: str, host: str = None):
def Drive(self, name: str, host: Union[str, None] = None):
return _Drive(
name=name,
project_key=self.project_key,
Expand All @@ -73,9 +73,12 @@ def send_email(to, subject, message, charset="UTF-8"):
"charset": charset,
}

assert api_key

headers = {"X-API-Key": api_key}

req = urllib.request.Request(endpoint, json.dumps(data).encode("utf-8"), headers)
req = urllib.request.Request(
endpoint, json.dumps(data).encode("utf-8"), headers)

try:
resp = urllib.request.urlopen(req)
Expand Down
49 changes: 27 additions & 22 deletions deta/_async/client.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import typing

from typing import Union, List
import datetime
import os
import aiohttp
from urllib.parse import quote

import aiohttp

from deta.utils import _get_project_key_id
from deta.base import FetchResponse, Util, insert_ttl, BASE_TTL_ATTTRIBUTE

Expand All @@ -15,7 +15,7 @@ def AsyncBase(name: str):


class _AsyncBase:
def __init__(self, name: str, project_key: str, project_id: str, host: str = None):
def __init__(self, name: str, project_key: str, project_id: str, host: Union[str, None] = None):
if not project_key:
raise AssertionError("No Base name provided")

Expand Down Expand Up @@ -56,11 +56,11 @@ async def delete(self, key: str):

async def insert(
self,
data: typing.Union[dict, list, str, int, bool],
key: str = None,
data: Union[dict, list, str, int, bool],
key: Union[str, None] = None,
*,
expire_in: int = None,
expire_at: typing.Union[int, float, datetime.datetime] = None,
expire_in: Union[int, None] = None,
expire_at: Union[int, float, datetime.datetime, None] = None,
):
if not isinstance(data, dict):
data = {"value": data}
Expand All @@ -70,19 +70,20 @@ async def insert(
if key:
data["key"] = key

insert_ttl(data, self.__ttl_attribute, expire_in=expire_in, expire_at=expire_at)
insert_ttl(data, self.__ttl_attribute,
expire_in=expire_in, expire_at=expire_at)
async with self._session.post(
f"{self._base_url}/items", json={"item": data}
) as resp:
return await resp.json()

async def put(
self,
data: typing.Union[dict, list, str, int, bool],
key: str = None,
data: Union[dict, list, str, int, bool],
key: Union[str, None] = None,
*,
expire_in: int = None,
expire_at: typing.Union[int, float, datetime.datetime] = None,
expire_in: Union[int, None] = None,
expire_at: Union[int, float, datetime.datetime, None] = None,
):
if not isinstance(data, dict):
data = {"value": data}
Expand All @@ -92,8 +93,12 @@ async def put(
if key:
data["key"] = key

insert_ttl(data, self.__ttl_attribute, expire_in=expire_in, expire_at=expire_at)
async with self._session.put(f"{self._base_url}/items", json={"items": [data]}) as resp:

insert_ttl(data, self.__ttl_attribute,
expire_in=expire_in, expire_at=expire_at)
async with self._session.put(
f"{self._base_url}/items", json={"items": [data]}
) as resp:
if resp.status == 207:
resp_json = await resp.json()
if "processed" in resp_json:
Expand All @@ -102,10 +107,10 @@ async def put(

async def put_many(
self,
items: typing.List[typing.Union[dict, list, str, int, bool]],
items: List[Union[dict, list, str, int, bool]],
*,
expire_in: int = None,
expire_at: typing.Union[int, float, datetime.datetime] = None,
expire_in: Union[int, None] = None,
expire_at: Union[int, float, datetime.datetime, None] = None,
):
if len(items) > 25:
raise AssertionError("We can't put more than 25 items at a time.")
Expand All @@ -126,10 +131,10 @@ async def put_many(

async def fetch(
self,
query: typing.Union[dict, list] = None,
query: Union[dict, list, None] = None,
*,
limit: int = 1000,
last: str = None,
last: Union[str, None] = None,
desc: bool = False,
):
payload = {}
Expand All @@ -154,8 +159,8 @@ async def update(
updates: dict,
key: str,
*,
expire_in: int = None,
expire_at: typing.Union[int, float, datetime.datetime] = None,
expire_in: Union[int, None] = None,
expire_at: Union[int, float, datetime.datetime, None] = None,
):
if key == "":
raise ValueError("Key is empty")
Expand Down
71 changes: 41 additions & 30 deletions deta/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import os
import datetime
from re import I
import typing
from typing import Union, List
from urllib.parse import quote

from .service import _Service, JSON_MIME
Expand Down Expand Up @@ -62,18 +61,18 @@ def __init__(self, value):
def trim(self):
return self.Trim()

def increment(self, value: typing.Union[int, float] = None):
def increment(self, value: Union[int, float, None] = None):
return self.Increment(value)

def append(self, value: typing.Union[dict, list, str, int, float, bool]):
def append(self, value: Union[dict, list, str, int, float, bool]):
return self.Append(value)

def prepend(self, value: typing.Union[dict, list, str, int, float, bool]):
def prepend(self, value: Union[dict, list, str, int, float, bool]):
return self.Prepend(value)


class _Base(_Service):
def __init__(self, name: str, project_key: str, project_id: str, host: str = None):
def __init__(self, name: str, project_key: str, project_id: str, host: Union[str, None] = None):
assert name, "No Base name provided"

host = host or os.getenv("DETA_BASE_HOST") or "database.deta.sh"
Expand Down Expand Up @@ -110,11 +109,11 @@ def delete(self, key: str):

def insert(
self,
data: typing.Union[dict, list, str, int, bool],
key: str = None,
data: Union[dict, list, str, int, bool],
key: Union[str, None] = None,
*,
expire_in: int = None,
expire_at: typing.Union[int, float, datetime.datetime] = None,
expire_in: Union[int, None] = None,
expire_at: Union[int, float, datetime.datetime, None] = None,
):
if not isinstance(data, dict):
data = {"value": data}
Expand All @@ -124,7 +123,8 @@ def insert(
if key:
data["key"] = key

insert_ttl(data, self.__ttl_attribute, expire_in=expire_in, expire_at=expire_at)
insert_ttl(data, self.__ttl_attribute,
expire_in=expire_in, expire_at=expire_at)
code, res = self._request(
"/items", "POST", {"item": data}, content_type=JSON_MIME
)
Expand All @@ -135,11 +135,11 @@ def insert(

def put(
self,
data: typing.Union[dict, list, str, int, bool],
key: str = None,
data: Union[dict, list, str, int, bool],
key: Union[str, None] = None,
*,
expire_in: int = None,
expire_at: typing.Union[int, float, datetime.datetime] = None,
expire_in: Union[int, None] = None,
expire_at: Union[int, float, datetime.datetime, None] = None,
):
"""store (put) an item in the database. Overrides an item if key already exists.
`key` could be provided as function argument or a field in the data dict.
Expand All @@ -154,22 +154,24 @@ def put(
if key:
data["key"] = key

insert_ttl(data, self.__ttl_attribute, expire_in=expire_in, expire_at=expire_at)
insert_ttl(data, self.__ttl_attribute,
expire_in=expire_in, expire_at=expire_at)
code, res = self._request(
"/items", "PUT", {"items": [data]}, content_type=JSON_MIME
)


if code == 207 and "processed" in res:
return res["processed"]["items"][0]
else:
return None

def put_many(
self,
items: typing.List[typing.Union[dict, list, str, int, bool]],
items: List[Union[dict, list, str, int, bool]],
*,
expire_in: int = None,
expire_at: typing.Union[int, float, datetime.datetime] = None,
expire_in: Union[int, None] = None,
expire_at: Union[int, float, datetime.datetime, None] = None,
):
assert len(items) <= 25, "We can't put more than 25 items at a time."
_items = []
Expand All @@ -189,9 +191,9 @@ def put_many(

def _fetch(
self,
query: typing.Union[dict, list] = None,
buffer: int = None,
last: str = None,
query: Union[dict, list, None] = None,
buffer: Union[int, None] = None,
last: Union[str, None] = None,
desc: bool = False,
) -> typing.Optional[typing.Tuple[int, list]]:
"""This is where actual fetch happens."""
Expand All @@ -204,34 +206,43 @@ def _fetch(
if query:
payload["query"] = query if isinstance(query, list) else [query]

code, res = self._request("/query", "POST", payload, content_type=JSON_MIME)
return code, res
_, res = self._request(
"/query", "POST", payload, content_type=JSON_MIME)

assert res

return res

def fetch(
self,
query: typing.Union[dict, list] = None,
query: Union[dict, list, None] = None,
*,
limit: int = 1000,
last: str = None,
last: Union[str, None] = None,
desc: bool = False,

):
"""
fetch items from the database.
`query` is an optional filter or list of filters. Without filter, it will return the whole db.
"""

_, res = self._fetch(query, limit, last, desc)

paging = res.get("paging")

return FetchResponse(paging.get("size"), paging.get("last"), res.get("items"))
paging = res.get("paging") # pyright: ignore

return FetchResponse(paging.get("size"),
paging.get("last"),
res.get("items")) # pyright: ignore

def update(
self,
updates: dict,
key: str,
*,
expire_in: int = None,
expire_at: typing.Union[int, float, datetime.datetime] = None,
expire_in: Union[int, None] = None,
expire_at: Union[int, float, datetime.datetime, None] = None,
):
"""
update an item in the database
Expand Down
Loading
Loading