From 7a22f4ed5d2d9b8bbe545862f78f7d86013d1ee0 Mon Sep 17 00:00:00 2001 From: gregsym Date: Mon, 10 Feb 2025 21:47:52 +0200 Subject: [PATCH] Not working with Micropython v1.23.0 Fixes #7 --- ufirestore/json.py | 57 +++++++++++++++++++--------------------- ufirestore/ufirestore.py | 57 ++++++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 56 deletions(-) diff --git a/ufirestore/json.py b/ufirestore/json.py index 4369f0f..08d2a07 100644 --- a/ufirestore/json.py +++ b/ufirestore/json.py @@ -24,10 +24,7 @@ def to_value_type(cls, value): elif value.startswith("/g"): typ = "geoPointValue" value = value[2:].split(",") - value = { - "latitude": value[0], - "longitude": value[1] - } + value = {"latitude": value[0], "longitude": value[1]} elif isinstance(value, str): typ = "stringValue" elif isinstance(value, bytes): @@ -37,7 +34,9 @@ def to_value_type(cls, value): return {typ: {"values": [cls.to_value_type(item) for item in value]}} elif isinstance(value, dict): typ = "mapValue" - return {typ: {"fields": {k: cls.to_value_type(v) for k, v in value.items()}}} + return { + typ: {"fields": {k: cls.to_value_type(v) for k, v in value.items()}} + } return {typ: str(value)} @@ -120,22 +119,25 @@ def cb(cur, s): return self.cursor(path, cb) - def process(self, name): + def process( + self, + # name, + ): return { - "name": name, + # "name": name, "fields": self.data } @classmethod def from_raw(cls, raw): + print(raw) fields = raw["fields"] doc_data = { "name": raw["name"], "createTime": raw["createTime"], - "updateTime": raw["updateTime"] + "updateTime": raw["updateTime"], } - doc_data.update(fields={k: cls.from_value_type(v) - for k, v in fields.items()}) + doc_data.update(fields={k: cls.from_value_type(v) for k, v in fields.items()}) return FirebaseJson(doc_data) @@ -150,7 +152,7 @@ class Query(FirebaseJson): "array-contains": "ARRAY_CONTAINS", "in": "IN", "array-contains-any": "ARRAY_CONTAINS_ANY", - "not-in": "NOT_IN" + "not-in": "NOT_IN", } def __init__(self, *args, **kwargs): @@ -158,25 +160,19 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def from_(self, collection_id, all_descendants=False): - self.add_item("from", { - "collectionId": collection_id, - "allDescendants": all_descendants - }) + self.add_item( + "from", {"collectionId": collection_id, "allDescendants": all_descendants} + ) return self def select(self, field): - self.add_item("select/fields", { - "fieldPath": field - }) + self.add_item("select/fields", {"fieldPath": field}) return self def order_by(self, field, direction="DESCENDING"): - self.add_item("orderBy", { - "field": { - "fieldPath": field - }, - "direction": direction - }) + self.add_item( + "orderBy", {"field": {"fieldPath": field}, "direction": direction} + ) return self def limit(self, value): @@ -192,13 +188,14 @@ def where(self, field, op, value): self.remove("where/fieldFilter") self.set("where/compositeFilter/op", "AND") self.add_item("where/compositeFilter/filters", cur_filter) - self.add_item("where/compositeFilter/filters", { - "field": { - "fieldPath": field + self.add_item( + "where/compositeFilter/filters", + { + "field": {"fieldPath": field}, + "op": self.OPERATIONS[op], + "value": self.to_value_type(value), }, - "op": self.OPERATIONS[op], - "value": self.to_value_type(value) - }) + ) else: self.set("where/fieldFilter/field/fieldPath", field) self.set("where/fieldFilter/op", self.OPERATIONS[op]) diff --git a/ufirestore/ufirestore.py b/ufirestore/ufirestore.py index ebec4e6..7f31aab 100644 --- a/ufirestore/ufirestore.py +++ b/ufirestore/ufirestore.py @@ -1,7 +1,6 @@ -import ujson -import urequests +import ujson # type: ignore import _thread - +import urequests # type: ignore class FirestoreException(Exception): def __init__(self, message, code=400): @@ -34,46 +33,47 @@ def construct_url(resource_path=None): def to_url_params(params=dict()): - return "?" + "&".join( - [(str(k) + "=" + str(v)) for k, v in params.items() if v is not None]) + return "?" + "&".join([(f"{k}={v}") for k, v in params.items() if v is not None]) def get_resource_name(url): return url[url.find("projects"):] -def send_request(path, method="get", params=dict(), data=None, dump=True): +def send_request(path, method="GET", params=dict(), data=None, dump=True): headers = {} - if FIREBASE_GLOBAL_VAR.ACCESS_TOKEN: headers["Authorization"] = "Bearer " + FIREBASE_GLOBAL_VAR.ACCESS_TOKEN - - response = urequests.request( - method, path, params=params, headers=headers, json=data) + if method in ["POST", "PATCH", "PUT"]: + # headers["Accept"] = "application/json" + # headers["Content-Type"] = "application/json" + response = urequests.request(method, path, data=None, json=data, headers=headers) + else: + response = urequests.request(method, path, headers=headers) if dump == True: if response.status_code < 200 or response.status_code > 299: print(response.text) raise FirestoreException(response.reason, response.status_code) - json = response.json() - if json.get("error"): - error = json["error"] + jsonResponse = response.json() + if jsonResponse.get("error"): + error = jsonResponse["error"] code = error["code"] message = error["message"] raise FirestoreException(message, code) - return json + return jsonResponse class INTERNAL: def patch(DOCUMENT_PATH, DOC, cb, update_mask=None): PATH = construct_url(DOCUMENT_PATH) - LOCAL_PARAMS = to_url_params() - if update_mask: - for field in update_mask: - LOCAL_PARAMS += "updateMask.fieldPaths=" + field - DATA = DOC.process(get_resource_name(PATH)) - LOCAL_OUTPUT = send_request(PATH+LOCAL_PARAMS, "post", data=DATA) + LOCAL_PARAMS = to_url_params() + "&".join([f"updateMask.fieldPaths={field}" for field in update_mask]) + DATA = DOC.process() # name in here has been deprecated I believe + # https://firebase.google.com/docs/firestore/reference/rest/v1beta1/projects.databases.documents/patch + # name is added as a part of the path + # updateMask is a query parameter + LOCAL_OUTPUT = send_request(PATH+LOCAL_PARAMS, "PATCH", data=DATA) if cb: try: return cb(LOCAL_OUTPUT) @@ -85,8 +85,13 @@ def patch(DOCUMENT_PATH, DOC, cb, update_mask=None): def create(COLLECTION_PATH, DOC, cb, document_id=None): PATH = construct_url(COLLECTION_PATH) PARAMS = {"documentId": document_id} - DATA = DOC.process(get_resource_name(PATH)) - LOCAL_OUTPUT = send_request(PATH, "post", PARAMS, DATA) + if document_id is not None: + LOCAL_PARAMS = to_url_params(PARAMS) + else: + LOCAL_PARAMS = "" + # DATA = DOC.process(get_resource_name(PATH)) + DATA = DOC.process() + LOCAL_OUTPUT = send_request(PATH+LOCAL_PARAMS, "POST", PARAMS, DATA) if cb: try: return cb(LOCAL_OUTPUT) @@ -101,7 +106,7 @@ def get(DOCUMENT_PATH, cb, mask=None): if mask: for field in mask: LOCAL_PARAMS += "mask.fieldPaths=" + field - LOCAL_OUTPUT = send_request(PATH+LOCAL_PARAMS, "get") + LOCAL_OUTPUT = send_request(PATH+LOCAL_PARAMS, "GET") if cb: try: return cb(LOCAL_OUTPUT) @@ -167,7 +172,7 @@ def list_collection_ids(DOCUMENT_PATH, cb, page_size=None, page_token=None): "pageSize": page_size, "pageToken": page_token } - LOCAL_OUTPUT = send_request(PATH, "post", data=DATA) + LOCAL_OUTPUT = send_request(PATH, "POST", data=DATA) if cb: try: return cb(LOCAL_OUTPUT.get("collectionIds"), @@ -183,7 +188,7 @@ def run_query(DOCUMENT_PATH, query, cb): DATA = { "structuredQuery": query.data } - LOCAL_OUTPUT = send_request(PATH, "post", data=DATA) + LOCAL_OUTPUT = send_request(PATH, "POST", data=DATA) if cb: try: return cb(LOCAL_OUTPUT.get("document")) @@ -266,4 +271,4 @@ def run_query(PATH, query, bg=True, cb=None): _thread.start_new_thread( INTERNAL.run_query, [PATH, query, cb]) else: - return INTERNAL.run_query(PATH, query, cb) + return INTERNAL.run_query(PATH, query, cb) \ No newline at end of file