vaphes / pocketbase Goto Github PK
View Code? Open in Web Editor NEWPocketBase client SDK for python
Home Page: https://pypi.org/project/pocketbase/
License: MIT License
PocketBase client SDK for python
Home Page: https://pypi.org/project/pocketbase/
License: MIT License
Currently any exception in the SSEClient/Eventloop will result in the the thead exiting. In my testing I see the http.ReadTimeout exception when the connection to the server is dropped. There is no indication to the subscriber that new events are no longer getting through.
I'm happy to help with the fix, but I'm looking for some guidence on how to push the event through to the calling code and how the situation should be resolved.
To patch this for my appication I have just caught the exception, slept, and allowed a new connection to be established. Perhaps this was always the intention as there is already a while loop that causes the reconnect.
Dao.RunInTransaction() ?
I encounter "httpx.RemoteProtocolError: peer closed connection without sending complete message body (incomplete chunked read)" when the server does not receive any updates within a specific time frame. While it is possible to work around this issue in certain cases by creating new data on the server that is ignored by the client, such an approach is not considered appropriate or ideal.
I saw 0.8.2 came out 3 days ago, and the pypi has updated it's version and name, but looking at the source dist, and the built dist. it's missing some of the changes made for example #43 (A feature I wanted from this version)
SDK Version : v0.3.0-beta
client.collection("col").get_list(1,50,{filter: 'channel_id = "567"'})
Excepted request :
https://endpoint.example/api/collections/col/records?collections?filter=(shop_id='567')&page=1&perPage=50
request send :
https://endpoint.example/api/collections/col/records?collections?<class 'filter'>=(shop_id='567')&page=1&perPage=50
I try to prepare a local auth store where to save the token.
tmp = tempfile.mkdtemp()
l_store = LocalAuthStore(filepath=tmp)
la_client = PocketBase(client.base_url, auth_store=l_store)
la_client.auth_store.save(client.auth_store.token, client.auth_store.model)
However LocalAuthStore raises an error when running for the first time as it cannot load the file (that is not there yet).
I recommend to make this less error prone and treat a missing file identical to an empty file.
note that also the LocalAuthStore.clear()
function deletes the storage file and leads to an exception next time the store is tried to be loaded.
I noticed the argument for redirect_url is misspelt. It should be corrected to redirect_url from redirct_url. Thanks.
def auth_with_oauth2(
self,
provider: str,
code: str,
code_verifier: str,
redirct_url: str,
create_data={},
body_params={},
query_params={},
):
should be
def auth_with_oauth2(
self,
provider: str,
code: str,
code_verifier: str,
redirect_url: str,
create_data={},
body_params={},
query_params={},
):
Pocketbase v0.20 has moved the logs service endpoint from /api/logs/requests/* to /api/logs/*
The change was introduced in commit pocketbase/pocketbase#821aae4
This effectively breaks the logs service making its related integration tests fail
I'm trying to fetch a record with a file, so I can use the client.get_file_url()
method on it. I immediately noticed in the debugger, that all the record's values are being deserialized to collection_id
which is most likely an error.
My code:
record = client.collection("files").get_one(file_id)
url = client.get_file_url(record, record.collection_id["file"], {})
Is there a possibility of having an async client, which'd compliment the current httpx synchronous client.
admin.collections.get_full_list()
File "...\pocketbase\models\collection.py", line 37, in load
self.schema.append(SchemaField(**field))
^^^^^^^^^^^^^^^^^^^^
TypeError: SchemaField.init() got an unexpected keyword argument 'presentable'
@dataclass
class SchemaField:
id: str = ""
name: str = ""
type: str = "text"
system: bool = False
required: bool = False
presentable: bool = False
unique: bool = False
options: dict = field(default_factory=dict)
add pls
presentable: bool = False
thx =)
Hi,
After debug a lot your code, i found my problem.
You need use only the token in authentication header.
Need change inside file client.py
from:
auth_type = "Admin"
if hasattr(self.auth_store.model, "verified"):
auth_type = "User"
config["headers"] = config.get("headers", {})
config["headers"].update(
{"Authorization": f"{auth_type} {self.auth_store.token}"}
)
to:
config["headers"] = config.get("headers", {})
config["headers"].update(
{"Authorization": f"{self.auth_store.token}"}
)
or
config["headers"] = config.get("headers", {})
config["headers"].update(
{"Authorization": f"Bearer {self.auth_store.token}"}
)
This is documented in: https://pocketbase.io/docs/authentication/#authenticate-as-admin
Can you make a fast hotfix?
Thanks.
When calling the delete and update methods in AdminService I get the error
AttributeError: 'super' object has no attribute 'update'
Side note: the methods also have strange positional arguments such as body_params in delete() even though the delete API method underlying does not process any body_params
. Even more strangely the value for body_params is passed in to the query_params positional argument of the super().delete() method.
The pocketbase v0.18.0 and above have added a new attribute named presentable
in the SchemaField
with this commit
This leads to an exception if such an element is unmarshaled into the SchemaField python dataclass which breaks lots of related functionality and integration tests.
See e.g. the failed integration tests on #67 in this integration test run
I kindly request the implementation of a feature that would allow users to utilize custom headers when establishing a connection to Pocketbase.
Ex:
client = PocketBase(url, headers={'User-Agent': 'Test-User-Agent'})
Hi!
I am using pocketbase but I coded a project in python and I didn't want to move over to js or ts. So I found this package but the released version is old and I want to get the newer version of it. But is the beta version still in the testing process or is it done?
i want to see and display all data in collection . and output like this [<Record: 85oeuawmpqdm44y>, <Record: l99wjn9094c2193>]
how to parse it into text
i want to add data to collection
my code
record = client.collection('fletSample').create(name="bout",age=120)
BUT ERROR
File "/home/minx/belajar/colongan/pythonsidik/test.py", line 7, in
record = client.collection('fletSample').create(name="bout",age=120)
TypeError: CrudService.create() got an unexpected keyword argument 'name'
wahst solutions
Env
Code
from pocketbase import Client
client = Client('http://127.0.0.1:8090')
admin_data = client.admins.auth_with_password("[email protected]", "1234567890")
data = client.collections.get_full_list()
print(data)
Traceback
Traceback (most recent call last):
File "/Users/kelvinlee/pocketbase/pb_python/example.py", line 15, in <module>
data = client.collections.get_full_list()
File "/Users/kelvinlee/anaconda3/envs/pb_python/lib/python3.10/site-packages/pocketbase/services/utils/crud_service.py", line 17, in get_full_list
return self._get_full_list(self.base_crud_path(), batch, query_params)
File "/Users/kelvinlee/anaconda3/envs/pb_python/lib/python3.10/site-packages/pocketbase/services/utils/base_crud_service.py", line 30, in _get_full_list
return request(result, 1)
File "/Users/kelvinlee/anaconda3/envs/pb_python/lib/python3.10/site-packages/pocketbase/services/utils/base_crud_service.py", line 22, in request
list = self._get_list(base_path, page, batch_size, query_params)
File "/Users/kelvinlee/anaconda3/envs/pb_python/lib/python3.10/site-packages/pocketbase/services/utils/base_crud_service.py", line 43, in _get_list
items.append(self.decode(item))
File "/Users/kelvinlee/anaconda3/envs/pb_python/lib/python3.10/site-packages/pocketbase/services/collection_service.py", line 10, in decode
return Collection(data)
File "/Users/kelvinlee/anaconda3/envs/pb_python/lib/python3.10/site-packages/pocketbase/models/utils/base_model.py", line 16, in __init__
self.load(data)
File "/Users/kelvinlee/anaconda3/envs/pb_python/lib/python3.10/site-packages/pocketbase/models/collection.py", line 37, in load
self.schema.append(SchemaField(**field))
TypeError: SchemaField.__init__() got an unexpected keyword argument 'presentable'
In the client class (and some other classes) I have seen variables defined in the class body. Those are class variables, and a client instance per se should not share any variables with another client instance. This would, for example, be really bad for APIs security-wise).
class Foo:
x: int = 1 # class variable
class Bar:
def __init__():
x = 1 # instance variable
You don't use the class variables as you define instance variables in the init shadowing the class variables.
However, this still feels a bit insecure to me, leaving room for error.
So, I'd like to suggest two things:
Client.base_url="..."
would be neat, but is currently shadowed by instance variable.Further Explanation: https://stackoverflow.com/a/43921843
In JS SDK, there's a method to verify if a given token is still valid.
pb.authStore.isValid
I didn't find any equivalent in this Python SDK.
The problem is, it also doesn't throw an error if an expired token tries to list records that was previously authorized to, it just returns an empty list.
Is there any way to check if a token has expired or is still valid?
calling unsubscribe
in RecordService leads to an AttributeError in
Because the RealtimeService does not implement a method subscribe_by_prefix
. This seems to be a typo as it should instead call unsubscribe_by_prefix
.
However fixing this locally gives me a followup error in
pop(sub)
changes the dictionary within the loop which leads to aRuntimeError: dictionary changed size during iteration
Hello, this is a courtesy note to say that this project has been added to https://github.com/benallfree/awesome-pocketbase ๐
i want to get list from collection but with certain filter field only . but even can't
my code
comm = client.collection("comments_col").get_first_list_item('movie_id="1p5or83c14nb6j2')
print(comm)
erorr
'RecordService' object has no attribute 'get_first_list_item'
for example . i have set . only those who have logged in can see the data in the collection with rules like this
@request.auth.id != ""
and how. to log in. after that see all the data?
example
# Get full list of records from collection
result = client.collection('fletSample').auth_with_password('[email protected]', 'oop!@#!@#A')
collection_data = await client.collection('fletSample').get_full_list()
print(collection_data)
print(result)
Hello again ^^
does the SDK support protected files yet?
See here: https://pocketbase.io/docs/files-handling/#protected-files
I couldn't find the respective method in the SDK, but maybe I overlooked it?
Both in RecordService and AdminService the confirmPasswordReset()
method claims to return an instance of
pocketbase/pocketbase/services/record_service.py
Lines 250 to 257 in 82a5b39
RecordAuthResponse
However this is not the case. the official pocketbase api doc states that the API endpoint in fact returns null
. The JS client returns "True" on success.
In similar way there is no requestEmailChange / confirmEmailChange API call available at all. Having that would bring this client closer to the JS client features.
record = pb.collection('abc').get_one(id)
record['xyz'] # error
record.xyz # error
record.__getattribute__('xyz') # you guessed it, error
A little bit more examples on the readme would be nice
Hi, I need subscribe example both httpx and python sdk, please.
import json
import openpyxl
from openpyxl import Workbook
import datetime
from pocketbase import PocketBase
from pocketbase.client import FileUpload
import requests
client = PocketBase("#ip to pocketbaseserver")
help = client.collection("departures").get_list()
I'm trying to do a simple fetch from my database but it doesn't appear that there are any methods defined as collection in the client. Am i doing something wrong?
help = client.collection("departures").get_list()
^^^^^^^^^^^^^^^^^
AttributeError: 'PocketBase' object has no attribute 'collection'. Did you mean: 'collections'?
While iterating through a list of dictionaries, rarely and very randomly a ClientResponseError gets raised. From Pocketbase logs I can see that the following code somewhat tries to delete the same key twice, resulting in this issue. It does seem a kind of race condition of some sort?
I have not much to say here, I can paste the code that results in this error but it's very sporadic:
filter: dict = {"filter": f'SomeKey = "SomeValue"', "sort": "-LastSeen"}
query_response = pb_client.collection("Some_collection").get_full_list(query_params=filter)
trimmed_response: list[dict] = []
for element in query_response:
temp: dict = {}
temp["id"] = element.id
temp["LastSeen"] = element.last_seen
trimmed_response.append(temp)
for element in trimmed_response[1:]:
pb_client.collection("Some_collection").delete(element["id"])
I wouldn't expect this code to randomly try to delete the same key twice.
Somehow, it does. I think that #18 tries to fix this?
Any interest in supporting the backup API? It might be something I could contribute.
Trying to upload a single file record
record = client.collection(collid).create(
{
"image": FileUpload("filename.txt", "Hello World", "text/plain"),
}
)
leads to strange undefined behaviour as instead of creating a single file named filename.txt
with content Hello World
and text/plain
mime-type it counterintuitively uploads three file records (assuming multiple files are allowed for this pocketbase record) The three files are all getting sort of random names like upload_fE6KCgk6LR.txt
and have the content of the three strings in FileUpload respectively.
A workaround is to wrap the FileUpload argument into another python list like so:
FileUpload( ("filename.txt", "Hello World", "text/plain",) )
I think this is somewhat counter-intuitive
While reading the PocketBase docs, I stumbled upon collection hooks mechanism and I'm very curious, how do you implement this with the python sdk?
For example, a base collection has the field password
of type text
and when a record is inserted, you have to "call" an event hook that hashes the password and then saves it to PocketBase. And vice versa, when a record from that collection is listed/read then you have to "call" an event hook to decrypt it in order to show the plain text.
I know
auth
collection exists, but I need that field in abase
collection.
It is a matter of time until PocketBase adds the password
type field for base
collections, but until then I think this is a nice feature to have with an alternative solution using "encrypting" hooks. I spotted the package pluggy
in poetry but nothing uses it so I assume that it's WIP
?
Hi, I have this collection containing the following docs:
I'm trying to fetch an article where exhausted === False
# fetch a test article where exhausted is false
article = client.collection("articles").get_list(
1, 20, {"filter": 'exhausted = false"'})
print('article', article.items[0])
but it keeps failing here?
ne 37, in _get_list
response_data = self.client.send(
^^^^^^^^^^^^^^^^^
File "C:\_repo\python_pocket_base\.venv\Lib\site-packages\pocketbase\client.py", line 109, in send
raise ClientResponseError(pocketbase.utils.ClientResponseError: Response error. Status code:403
Have I used the correct syntax to fetch?
How to run subscribe() forever?
I installed pocketbase with pip install pocketbase
and pip freeze shows version 0.9.2
I notice the next error creating a collection from my custom collection loader:
There was an error creating collection my_collection: SchemaField.__init__() got an unexpected keyword argument 'presentable'
I started researching and I found the installed library was lacking presentable
from SchemaField
dataclass in models/utils/schemafield
as you can see:
But, the latest version on github (presumably 0.9.2) is showing this field:
Does anyone know why is my installed pocketbase shifted from the master
branch?
I am also learning a lot from this project, trying to build my own "create collection if not exist" in a resilient way on my FastAPI application!
Thanks!
please add documentation to register new user to pocketbase
I am trying to expand a relation, however I am getting the following error.
File "test.py", line 65, in test_func
records = pb.collection("product_details").get_full_list(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/services/utils/crud_service.py", line 17, in get_full_list
return self._get_full_list(self.base_crud_path(), batch, query_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/services/utils/base_crud_service.py", line 31, in _get_full_list
return request(result, 1)
^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/services/utils/base_crud_service.py", line 23, in request
list = self._get_list(base_path, page, batch_size, query_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/services/utils/base_crud_service.py", line 44, in _get_list
items.append(self.decode(item))
^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/services/record_service.py", line 50, in decode
return Record(data)
^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/models/utils/base_model.py", line 16, in __init__
self.load(data)
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/models/record.py", line 18, in load
self.load_expanded()
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/models/record.py", line 26, in load_expanded
self.expand[key] = self.parse_expanded(value)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/models/record.py", line 22, in parse_expanded
return cls(data)
^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/models/utils/base_model.py", line 16, in __init__
self.load(data)
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/models/record.py", line 13, in load
super().load(data)
File "/opt/homebrew/lib/python3.11/site-packages/pocketbase/models/utils/base_model.py", line 30, in load
self.id = data.pop("id", "")
^^^^^^^^^^^^^^^^^^
TypeError: pop expected at most 1 argument, got 2
After further testing with the source_code, I noticed that even though data is typed as dict, I am getting a list.
Here is the output I am printing inside the load function:
[{'collectionId': '32zt00urx7zeou4', 'collectionName': 'testcollection', 'created': '2023-03-19 18:26:45.604Z', 'id': 'rm74nish4xa4inm', 'image_url': 'https://www.example.com', 'updated': '2023-03-19 18:26:45.604Z'}, {'collectionId': '32zt00urx7zeou4', 'collectionName': 'testcollection', 'created': '2023-03-19 19:43:03.957Z', 'id': 'ju4srx55a5v7cmj', 'image_url': 'https://www.example.com', 'updated': '2023-03-19 19:43:03.957Z'}]
Here is my query to the pocketbase function get_full_list()
query_params={"expand": "image"}
Does the SDK support the back-relation expand command of pocketbase.
In the JS SDK that would be
output = await locals.pb.collection('posts').getList(data.startPage, 10, {
sort: sort,
filter: `tagline="${data?.filterTicker}" && pinned=false`,
expand: `user,comments(post),alreadyVoted(post)`,
}) ;
What would be the equivalent for "alreadyVoted(post)"?
This weekend, pocketbase:0.8.0-rc1 was released for testing and it comes with some breaking changes in its API.
Therefore the client SDKs have to update, too.
I have already worked on the updated python sdk in a fork of this repo and I want to create a pull request for my changes for you to check -> #3
Great work on this SDK.
This is a request for an enhancement to support JSON serialization for the different types supported
Eg:
import json
from pocketbase import PocketBase
client = PocketBase('http://127.0.0.1:8090')
# authenticate as regular user
user_data = client.collection("users").auth_with_password("[email protected]", "thisIsAFaksePassword123")
# get a compliance report
report = client.collection("compliance").get_list()
print(json.dumps(report, indent=4))
This currently results in:
Traceback (most recent call last):
File "/Users/dansikes/go/src/github.com/dsikes/equip/scripts/test.py", line 12, in <module>
print(json.dumps(report, indent=4))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/__init__.py", line 238, in dumps
**kw).encode(obj)
^^^^^^^^^^^
File "/opt/homebrew/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/encoder.py", line 202, in encode
chunks = list(chunks)
^^^^^^^^^^^^
File "/opt/homebrew/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/encoder.py", line 439, in _iterencode
o = _default(o)
^^^^^^^^^^^
File "/opt/homebrew/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/encoder.py", line 180, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type ListResult is not JSON serializable
Happy to work on a PR, but wanted to see if this was something you'd consider before doing so.
Thanks!
import pocketbase
import os
import dotenv
dotenv.load_dotenv()
async def export_func(data: str | None = None):
pb = pocketbase.PocketBase('http://localhost:8090/')
authData = pb.admins.auth_via_email(
email=os.environ["POCKET_ADMIN"],
password=os.environ["POCKET_ADMIN_PASS"])
return await authData
auth = asyncio.run(export_func())
print(auth)
getting pocketbase.client.ClientResponseError: Response error. Status code:404
in the ui:
i want to get data user id . but it's not in my code
loginnow = client.collection("users").auth_with_password(
"bob","12323"
)
# print(dir(loginnow))
print(loginnow.id)
# print(loginnow.token)
output
['__abstractmethods__', '__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', 'base_model', 'base_token', 'clear', 'model', 'save', 'token']
Hi there,
I've been trying to use client.collection("foo").get_list
and client.collection("foo").get_full_list
together with the expand
query parameter.
See the documentation of the JS SDK here: https://pocketbase.io/docs/working-with-relations/#expanding-relations
Apparently the load
method of the "BaseModel" class expects a dict but receives a list. I added some print statements.
def load(self, data: dict) -> None:
"""Loads `data` into the current model."""
print(data, type(data))
self.id = data.pop("id", "")
self.created = to_datetime(data.pop("created", ""))
self.updated = to_datetime(data.pop("updated", ""))
Here is the output:
In [2]: client.collection("labels").get_list(1, 30, query_params={"expand": "location"})
{'collectionId': 'c2laxzj0zheqs0l', 'collectionName': 'labels', 'created': '2023-08-07 10:06:32.374Z', 'end': '2023-04-06 23:30:00.000Z', 'expand': {'location': [{'collectionId': 'd4jq751z03smpzz', 'collectionName': 'pump_parts', 'created': '2023-08-07 08:52:03.363Z', 'id': '0yoeep2hyh0p57t', 'name': 'WB2', 'updated': '2023-08-07 08:52:03.363Z'}]}, 'id': '1hiin4yc2mzi5dd', 'label': ['l38hfht79whweza'], 'location': ['0yoeep2hyh0p57t'], 'monitoring_id': 18198, 'start': '2023-04-06 18:05:00.000Z', 'updated': '2023-08-07 10:06:32.374Z'} <class 'dict'>
[{'collectionId': 'd4jq751z03smpzz', 'collectionName': 'pump_parts', 'created': '2023-08-07 08:52:03.363Z', 'id': '0yoeep2hyh0p57t', 'name': 'WB2', 'updated': '2023-08-07 08:52:03.363Z'}] <class 'list'>
Which further results in the following exception
File <path>/pocketbase/models/utils/base_model.py:27, in BaseModel.load(self, data)
25 """Loads `data` into the current model."""
26 print(data, type(data))
---> 27 self.id = data.pop("id", "")
28 self.created = to_datetime(data.pop("created", ""))
29 self.updated = to_datetime(data.pop("updated", ""))
TypeError: pop expected at most 1 argument, got 2
Thanks for working on this by the way!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.