Code Monkey home page Code Monkey logo

deta-python's Introduction

Deta Python Library (SDK)

Please use a supported version of Python. This package requires a minimum of Python 3.6. Read the docs.

Install from PyPi

pip install deta

If you are interested in contributing, please look at CONTRIBUTING.md

How to release (for maintainers)

  1. Add changes to CHANGELOG.md
  2. Merge the master branch with the release branch.
  3. After scripts finish, update release and tag with relevant info

deta-python's People

Contributors

aavshr avatar abdelhai avatar blackary avatar cclauss avatar daniel-demelo avatar deepaerial avatar hozan23 avatar leits avatar lemonyte avatar mweyaruider avatar ninja243 avatar rabingaire avatar rohanshiva avatar sadikkuzu avatar xeust avatar yankeexe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

deta-python's Issues

Get count of entries matching a given query.

I'd like to find out how many entries are there in total that match a given query. Is there any fast and elegant way to do it?

Even the HTTP API offers only pages that are chained to each other.

Questions: Does Deta supports npm?

Hello. I am interested to use Deta as my main server. Thus I would like to know if Deta support npm and add either angular, react or vuejs?

AttributeError: 'Deta' object has no attribute 'Drive'

I tried to follow the docs regarding the Deta Drive and got the following traceback:

Traceback (most recent call last):
  File "/opt/python/detalib/debugger.py", line 142, in wrap
    result = func(event, context)
  File "/var/task/_entry.py", line 12, in handler
    import main  # noqa
  File "/var/task/main.py", line 14, in <module>
    drive = deta_base.Drive("blob_storage")
AttributeError: 'Deta' object has no attribute 'Drive'

this is my code (basically exact the guide):

from deta import Deta

app = FastAPI()
deta_base = Deta('special-secret-key')
drive = deta_base.Drive("blob_storage")


@app.get("/", response_class=HTMLResponse)
def render():
    return """
    <form action="/upload" enctype="multipart/form-data" method="post">
        <input name="file" type="file">
        <input type="submit">
    </form>
    """

@app.post("/upload")
def upload_img(file: UploadFile = File(...)):
    name = file.filename
    f = file.file
    res = drive.put(name, f)
    return res

@app.get("/download/{name}")
def download_img(name: str):
    res = drive.get(name)
    return StreamingResponse(res.iter_chunks(1024), media_type="image/png")

Issue downloading file from drive

Hi there, I've uploaded a png file to a Deta Drive, I can download it fine using the HTTP API but not using the Python library.

def download_file(attachment_stored_filename):
   return drive.get(attachment_stored_filename)
@app.get("/workorders/attachment/{attachmentStoredFilename}")
async def get_work_order_attachment(attachmentStoredFilename: str):
    drive_streaming_body = deta_drive.download_file(attachmentStoredFilename)
    return StreamingResponse(
        drive_streaming_body.iter_chunks()
    )

These are the relevant methods, as you can see I'm simply passing the DriveStreamingBody from the first method into the second and then using iter_chunks as suggested in the tutorial.

The error in the logs is as follows, can anyone suggest where I'm going wrong?

[ERROR] 2021-07-22T13:29:21.529Z 8dc4c713-992c-474c-bf45-526a5cc71cbe Exception in ASGI application Traceback (most recent call last): File "/opt/python/detalib/adapters/asgi/protocols/http.py", line 47, in run await app(self.scope, self.receive, self.send) File "/opt/python/fastapi/applications.py", line 199, in __call__ await super().__call__(scope, receive, send) File "/opt/python/starlette/applications.py", line 112, in __call__ await self.middleware_stack(scope, receive, send) File "/opt/python/starlette/middleware/errors.py", line 181, in __call__ raise exc from None File "/opt/python/starlette/middleware/errors.py", line 159, in __call__ await self.app(scope, receive, _send) File "/opt/python/starlette/exceptions.py", line 82, in __call__ raise exc from None File "/opt/python/starlette/exceptions.py", line 71, in __call__ await self.app(scope, receive, sender) File "/opt/python/starlette/routing.py", line 580, in __call__ await route.handle(scope, receive, send) File "/opt/python/starlette/routing.py", line 241, in handle await self.app(scope, receive, send) File "/opt/python/starlette/routing.py", line 55, in app await response(scope, receive, send) File "/opt/python/starlette/responses.py", line 226, in __call__ (self.listen_for_disconnect, {"receive": receive}), File "/opt/python/starlette/concurrency.py", line 24, in run_until_first_complete [task.result() for task in done] File "/opt/python/starlette/concurrency.py", line 24, in <listcomp> [task.result() for task in done] File "/opt/python/starlette/responses.py", line 221, in stream_response await send({"type": "http.response.body", "body": b"", "more_body": False}) File "/opt/python/starlette/exceptions.py", line 68, in sender await send(message) File "/opt/python/starlette/middleware/errors.py", line 156, in _send await send(message) File "/opt/python/detalib/adapters/asgi/protocols/http.py", line 113, in send self.response["body"] = body.decode() UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte No errors

Redundant send_email

Hi, Deta team!
Looks like I found the code for your internal needs in the client 😅

def send_email(to, subject, message, charset="UTF-8"):
pid = os.getenv("AWS_LAMBDA_FUNCTION_NAME")
url = os.getenv("DETA_MAILER_URL")
api_key = os.getenv("DETA_PROJECT_KEY")
endpoint = f"{url}/mail/{pid}"
to = to if type(to) == list else [to]
data = {
"to": to,
"subject": subject,
"message": message,
"charset": charset,
}
headers = {"X-API-Key": api_key}
req = urllib.request.Request(endpoint, json.dumps(data).encode("utf-8"), headers)
try:
resp = urllib.request.urlopen(req)
if resp.getcode() != 200:
raise Exception(resp.read().decode("utf-8"))
except urllib.error.URLError as e:
raise Exception(e.reason)

Base needs remove

A remove function in the Base class to delete objects matching a certain query would be nice.
for example

from fastapi import FastAPI
from deta import Deta 

deta = Deta("SECRET_KEY")
db = deta.Base('db')

app = FastAPI()

@app.get("/")
async def func():     
        db.remove({})#removes all entries

Deta Command Not Found

I am trying to install Deta but the curl commands work and a hidden folder is also created under /Users/ktay.
But when I run the sole command "deta" my terminal throws a classic error,
"deta" command not found.

Any ideas what I am doing wrong would be of great help

Empty keys not allowed

The Base API doesn't allow you to put dictionaries with empty keys (""). Currently, the progress on this is the false traceback modified by #76 so it returns None instead of producing a KeyError.

How to run tests localy?

I found at least 3 variables that try to get out of the environment in the tests.

What to put there?
Please, provide some docs!

key = os.getenv("DETA_SDK_TEST_PROJECT_KEY")
name = os.getenv("DETA_SDK_TEST_DRIVE_NAME")
host = os.getenv("DETA_SDK_TEST_DRIVE_HOST")

Don't raise with the Exception class

In a few places in deta/base.py exceptions are raised with the Exception class.

See https://github.com/deta/deta-python/blob/5e68173ffea4b3dd2c3d75fadda4e3c9854d3199/deta/base.py.

raise Exception("Item with key '{4}' already exists".format(key))

raise Exception("Key '{}' not found".format(key))

It'd be better practice if custom exceptions were defined and derived from the general Exception class.

Micro erroring due to detalib

Keep getting this error when trying to run python micros: Runtime.ImportModuleError: Unable to import module '_entry': No module named 'detalib'

I don't include detalib in my requirements.txt but it keeps getting added automatically.

Async Base TimeoutError

I'm using the Deta Base Python Async SDK, got the following TimeoutError exception:

Traceback (most recent call last):
  File "/var/task/main.py", line 110, in db_2_notion
    unSynced = await DB.fetch({"synced": False}, limit=1000)
  File "/opt/python/deta/_async/client.py", line 110, in fetch
    async with self._session.post(f"{self._base_url}/query", json=payload) as resp:
  File "/opt/python/aiohttp/client.py", line 1138, in __aenter__
    self._resp = await self._coro
  File "/opt/python/aiohttp/client.py", line 634, in _request
    break
  File "/opt/python/aiohttp/helpers.py", line 721, in __exit__
    raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError

The query line:
await DB.fetch({"synced": False}, limit=1000)

It works well in my local env, but got the error from deta logs command

The read operation timed out

trying to connect to deta fails , the base is there and has data in it ...

`

db.get('mybase')
Traceback (most recent call last):
File "", line 1, in
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\deta\base.py", line 90, in get
_, res = self._request("/items/{}".format(key), "GET")
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\deta\service.py", line 76, in _request
res = self._send_request_with_retry(method, url, headers, body)
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\deta\service.py", line 126, in _send_request_with_retry
res = self.client.getresponse()
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1349, in getresponse
response.begin()
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 316, in begin
version, status, reason = self._read_status()
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 277, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\socket.py", line 704, in readinto
return self._sock.recv_into(b)
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1241, in recv_into
return self.read(nbytes, buffer)
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1099, in read
return self._sslobj.read(len, buffer)`

socket.timeout: The read operation timed out

ImportError (circular import)

When running the sample code from the website...

from deta import Deta

# initialize with a project key
deta = Deta("{key}")

# create and use as many Drives as you want!
photos = deta.Drive("Test")
photos.put("car.jpg", path="./test/car.jpg")

... i get the following error:

ImportError: cannot import name 'Deta' from partially initialized module 'deta' (most likely due to a circular import) (C:\Users\user\Documents\...\...\...\...\deta.py)

Edit: This is the case with the package versions 1.0.0rc0, 0.9 and 0.8

Keyword argument expire_at for base.put() method not found (Python)

I am writing to a Deta base and trying to use the expire_at functionality of Deta bases.
Whenever I run the project locally everything works fine, however when I deploy my project to a micro, the following exception is raised:

put() got an unexpected keyword argument 'expire_at'

Python 3.9

Deta is storing the wrong int

        await inter.response.defer()
        print(channel.id)
        await self.db.put(channel.id, "v_channel")

it prints, 921301271112187924 but what it stores in the database is, 921301271112187900

send_email function in __init__.py

I was browsing the source code for Deta and I noticed a send_email function. Is this feature fully implemented yet? And if so, does it work when the code is not running in a micro?

The update() method seems to have a problem

I have data like this

屏幕截图 2023-06-02 033429

When I use the db.update(key='test', updates={'text': ''}) method to update it and specify text as '', I want it to save an empty string, but it will actually save null.

屏幕截图 2023-06-02 034149

The same situation occurs when updating the object.

屏幕截图 2023-06-02 034804

Is this the correct behavior? How do I save an empty string?

TypeError: 'FetchResponse' object is not an iterator

I tried the example snippet under https://web.deta.sh/home/user/project/bases:

# 1) pip install deta
from deta import Deta

# 2) initialize with a project key
deta = Deta("project key")

# 3) create and use as many DBs as you want!
users = deta.Base("users")

users.insert({
    "name": "Geordi",
    "title": "Chief Engineer"
})

geordi = next(users.fetch({"name": "Geordi"}))[0]

users.delete(geordi["key"])

But had a TypeError:

>>> from deta import Deta
>>> deta = Deta("<my_token>")
>>> users = deta.Base("users")
>>>
users.insert({
    "name": "Geordi",
    "title": "Chief Engineer"
})>>> ... ... ...
{'key': 'qzb6preouoau', 'name': 'Geordi', 'title': 'Chief Engineer'}
>>> geordi = next(users.fetch({"name": "Geordi"}))[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'FetchResponse' object is not an iterator

pip show deta
Name: deta
Version: 1.0.0
Summary: Python SDK for Deta Base & Deta Drive.
Home-page: http://github.com/deta/deta-python
Author: Deta
Author-email: [email protected]
License: MIT
Location: /Users/user/.pyenv/versions/3.8.5/lib/python3.8/site-packages
Requires:
Required-by:

Deta Base "last" can be used to filter without having the full key

Hi,

I'm currently implementing some pagination feature. In the code I found the "last" parameter in the _fetch method.

"last": last if not isinstance(last, bool) else None,

While implementing I have played around with the "last" parameter and I'm not sure if I discovered a bug or a feature. For me, it sounded like I have to provide the full provide key in order to jump to the "last" reference. But it's possible to provide just a value and then last will be used to retrieve the next values after the provided value. Check the example below where I pass "12" and retrieve other values.

test_area = deta.Base("test_area")
test_area.put({"key": "1", "value": "1"})
test_area.put({"key": "11", "value": "1"})
test_area.put({"key": "2", "value": "1"})
test_area.put({"key": "21", "value": "1"})
test_area.put({"key": "33", "value": "1"})

resp = test_area._fetch(last="12")
# (200, {'paging': {'size': 3}, 'items': [{'key': '2', 'value': '1'}, {'key': '21', 'value': '1'}, {'key': '33', 'value': '1'}]})

As a developer I would expect that last is actually the real key and that it throws an exception if the value doesn't exists or at least have some hint in the documentation. But maybe I'm wrong. Thanks for the amazing project!

ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2426) when trying to upload file to Deta drive

Machine:
Docker container from image: python:3.10-bullseye

Deta lbrary version: 1.1.0

Description:
Error bellows occurs when I'm trying to upload file to Deta drive:

EOF occurred in violation of protocol (_ssl.c:2426)
Traceback (most recent call last):
  File "/app/./ytdl_api/downloaders.py", line 180, in download
    asyncio.run(self.on_finish_callback(download, converted_file_path))
  File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/app/./ytdl_api/callbacks.py", line 99, in on_finish_callback
    in_storage_filename = storage.save_download_from_file(download, download_tmp_path)
  File "/app/./ytdl_api/storage.py", line 68, in save_download_from_file
    self.drive.put(download.storage_filename, path=path)
  File "/app/.venv/lib/python3.10/site-packages/deta/drive.py", line 195, in put
    raise e
  File "/app/.venv/lib/python3.10/site-packages/deta/drive.py", line 188, in put
    self._upload_part(name, chunk, upload_id, part, content_type)
  File "/app/.venv/lib/python3.10/site-packages/deta/drive.py", line 137, in _upload_part
    self._request(
  File "/app/.venv/lib/python3.10/site-packages/deta/service.py", line 74, in _request
    res = self._send_request_with_retry(method, url, headers, body)
  File "/app/.venv/lib/python3.10/site-packages/deta/service.py", line 114, in _send_request_with_retry
    self.client.request(
  File "/usr/local/lib/python3.10/http/client.py", line 1283, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1329, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1278, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1077, in _send_output
    self.send(chunk)
  File "/usr/local/lib/python3.10/http/client.py", line 999, in send
    self.sock.sendall(data)
  File "/usr/local/lib/python3.10/ssl.py", line 1237, in sendall
    v = self.send(byte_view[count:])
  File "/usr/local/lib/python3.10/ssl.py", line 1206, in send
    return self._sslobj.write(data)
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:2426)

AttributeError: module 'orjson' has no attribute 'JSONEncoder' in /opt/python/detalib/helpers.py class CustomJSONEncoder(json.JSONEncoder):

I'm trying to deploy my first app in deta. But I get this error:

[2021-09-27T19:17:24+03:00] [ERROR] AttributeError: module 'orjson' has no attribute 'JSONEncoder'
Traceback (most recent call last):
  File "/var/lang/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/var/task/_entry.py", line 1, in <module>
    from detalib.handler import handle
  File "/opt/python/detalib/handler.py", line 3, in <module>
    from . import handlers
  File "/opt/python/detalib/handlers.py", line 1, in <module>
    from .event import parse_event
  File "/opt/python/detalib/event.py", line 1, in <module>
    from .helpers import json
  File "/opt/python/detalib/helpers.py", line 16, in <module>
    class CustomJSONEncoder(json.JSONEncoder):

i follow first setups in fastapi deploy

My main.py:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {"item_id": item_id}

my requirements.txt

wheel
python-dotenv
fastapi[all]
python-multipart
python-jose[cryptography]
passlib[bcrypt]
uvicorn[standard]
jinja2
dill
pytest-asyncio
httpx
orjson

My app in brower:

image

My .prog_info

{
"id":<my_id>,
"space":3049,
"runtime":"python3.9",
"name":"tunnel",
"path":"984mpg",
"project":"a0gojavz",
"account":"144798365827",
"region":"ap-southeast-1",
"deps":[
        "wheel",
        "python-dotenv",
        "fastapi[all]",
        "python-multipart",
        "python-jose[cryptography]",
        "passlib[bcrypt]",
        "uvicorn[standard]",
        "jinja2",
        "dill",
        "pytest-asyncio",
        "httpx",
        "orjson"
        ],
"envs":null,
"public":true,
"log_level":"debug",
"cron":""
}

Project structure:

.
└── .deta
└── prog_info
└── state
└── main.py
└── requirements.txt


My deta version: `deta v1.2.0-beta x86_64-windows`

Suggestion. Allow to create a local Deta Base

Congratulations for this amazing project!
I would like to make a suggestion for the Deta Base.
It will be great if you allow users to create a local database using the same Deta class, this could be helpful in some cases, like the user user has no internet connection to deploy, but still want to keep up coding his project, or just want to keep the files locally.

Could be something like this:

deta = Deta('my_db', local=True)
# creates a local db confi/serving folder
books = deta.Base("books")
# creates books.json file on my_db/

Thanks for your support ;)

broken app

I had my app prototype working fine, served at https://feed_filtering-1-t6768635.deta.app/

Now I was checking it out if it is still alive, but got the module 'orjson' has no attribute 'JSONEncoder'.
In https://deta.space/builder/a09Ng5MgqmYW/develop?tab=overview I see:

[ERROR] AttributeError: module 'orjson' has no attribute 'JSONEncoder'
Traceback (most recent call last):
  File "/var/lang/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/var/task/_entry.py", line 1, in <module>
    from detalib.handler import handle
  File "/opt/python/detalib/handler.py", line 3, in <module>
    from . import handlers
  File "/opt/python/detalib/handlers.py", line 1, in <module>
    from .event import parse_event
  File "/opt/python/detalib/event.py", line 1, in <module>
    from .helpers import json
  File "/opt/python/detalib/helpers.py", line 16, in <module>
    class CustomJSONEncoder(json.JSONEncoder):

Spacefile used:

cat Spacefile
# Spacefile Docs: https://go.deta.dev/docs/spacefile/v0
v: 0
micros:
  - name: feed-filtering
    src: .
    engine: python3.9
    primary: true
    public_routes:
        - "/*"

The app still works locally, although I have upd to python3.11 already.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.