From 60daaaade041c75fff9721b491f1295048ea8de6 Mon Sep 17 00:00:00 2001 From: Rachel Willmer Date: Wed, 6 May 2015 09:12:34 +0100 Subject: [PATCH 01/11] Work with Python3.4 --- tests/jsonutil_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/jsonutil_test.py b/tests/jsonutil_test.py index 29a3a81..5971596 100644 --- a/tests/jsonutil_test.py +++ b/tests/jsonutil_test.py @@ -11,7 +11,7 @@ def setUp(self): self.data = {'now': datetime.datetime.now(), 'oneday': datetime.timedelta(days=1), 'five': decimal.Decimal(5), - 'date': datetime.date(2014, 03, 11)} + 'date': datetime.date(2014, 3, 11)} def test_conversion(self): serialized = json.dumps(self.data, cls=JSONEncoder) From 8ce56451fcad66fb346c42bf3d1efc954aeb6856 Mon Sep 17 00:00:00 2001 From: Honeybadgr Date: Tue, 1 Dec 2015 15:09:16 +0000 Subject: [PATCH 02/11] add ability to customize requests ReadTimeout if session with timeout attribute is passed in, otherwise default to decorators value --- firebase/decorators.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firebase/decorators.py b/firebase/decorators.py index 66d0a11..1db2079 100644 --- a/firebase/decorators.py +++ b/firebase/decorators.py @@ -14,7 +14,9 @@ def wrapped(*args, **kwargs): kwargs['connection'] = connection else: connection = kwargs['connection'] - connection.timeout = timeout + + if not getattr(connection, 'timeout', False): + connection.timeout = timeout connection.headers.update({'Content-type': 'application/json'}) return f(*args, **kwargs) return wraps(f)(wrapped) From 914a2ad50788340152d43dfc15e6abc400c13667 Mon Sep 17 00:00:00 2001 From: Adesh Date: Sun, 6 Mar 2016 15:43:16 +0530 Subject: [PATCH 03/11] Fixed broken link to firebase logo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 63ddb75..f9954aa 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Python interface to the Firebase's REST API -[![Firebase](https://www.firebase.com/images/logo.png)](http://www.firebase.com) +[![Firebase](https://szimek.github.io/presentation-firebase-intro/images/firebase_logo.png)](http://www.firebase.com) ## Installation From 131d1faf6b1bd5a0b9bbd5f554bd85bf1406bad6 Mon Sep 17 00:00:00 2001 From: Ian Giestas Pauli Date: Sun, 11 Sep 2016 22:41:03 -0300 Subject: [PATCH 04/11] Fixes "400 Client Error: Bad Request" error --- firebase/firebase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase/firebase.py b/firebase/firebase.py index 2e55865..a36a487 100644 --- a/firebase/firebase.py +++ b/firebase/firebase.py @@ -258,7 +258,7 @@ def _authenticate(self, params, headers): """ if self.authentication: user = self.authentication.get_user() - params.update({'auth': user.firebase_auth_token}) + params.update({'auth_token': user.firebase_auth_token}) headers.update(self.authentication.authenticator.HEADERS) @http_connection(60) From 9fccf87303a27a6b7d871b0bae8336bb6070ff5b Mon Sep 17 00:00:00 2001 From: Christo Goosen Date: Mon, 4 Feb 2019 12:50:37 +0200 Subject: [PATCH 05/11] Initial rename of async to multiprocess_pool for python3.7 compatibility --- firebase/__init__.py | 2 +- firebase/firebase.py | 2 +- firebase/{async.py => multiprocess_pool.py} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename firebase/{async.py => multiprocess_pool.py} (100%) diff --git a/firebase/__init__.py b/firebase/__init__.py index 8c84e53..b6e9db2 100644 --- a/firebase/__init__.py +++ b/firebase/__init__.py @@ -1,6 +1,6 @@ import atexit -from .async import process_pool +from .multiprocess_pool import process_pool from firebase import * diff --git a/firebase/firebase.py b/firebase/firebase.py index 2e55865..6c6ba23 100644 --- a/firebase/firebase.py +++ b/firebase/firebase.py @@ -9,7 +9,7 @@ from .firebase_token_generator import FirebaseTokenGenerator from .decorators import http_connection -from .async import process_pool +from .multiprocess_pool import process_pool from .jsonutil import JSONEncoder __all__ = ['FirebaseAuthentication', 'FirebaseApplication'] diff --git a/firebase/async.py b/firebase/multiprocess_pool.py similarity index 100% rename from firebase/async.py rename to firebase/multiprocess_pool.py From 6b96b326f6d8f477503ca42fdfbd81bcbe1f9e0d Mon Sep 17 00:00:00 2001 From: Oshane Bailey Date: Tue, 12 Mar 2019 13:16:53 -0500 Subject: [PATCH 06/11] Update setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 995f3e5..8f08a9c 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ setup(name='python-firebase', - version='1.2', + version='1.2.1', description="Python interface to the Firebase's REST API.", long_description=long_description, classifiers=[ From dc269eec7502c875b6ed024d927e6ccf1aabd1b2 Mon Sep 17 00:00:00 2001 From: Kevin Mader Date: Mon, 22 Jul 2019 11:09:55 +0200 Subject: [PATCH 07/11] Don't overwrite firebase name (import is made invisible) The demo code overwrites the import which could be confusing for beginners. Calling the tool `fb_app` instead should make it clearer. --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f9954aa..de85b99 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ To fetch all the users in your storage simply do the following: ```python from firebase import firebase -firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) -result = firebase.get('/users', None) +fb_app = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) +result = fb_app.get('/users', None) print result {'1': 'John Doe', '2': 'Jane Doe'} ``` @@ -35,8 +35,8 @@ The second argument of **get** method is the name of the snapshot. Thus, if you ```python from firebase import firebase -firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) -result = firebase.get('/users', '1') +fb_app = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) +result = fb_app.get('/users', '1') print result {'1': 'John Doe'} ``` @@ -45,8 +45,8 @@ You can also provide extra query parameters that will be appended to the url or ```python from firebase import firebase -firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) -result = firebase.get('/users/2', None, {'print': 'pretty'}, {'X_FANCY_HEADER': 'VERY FANCY'}) +fb_app = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) +result = fb_app.get('/users/2', None, {'print': 'pretty'}, {'X_FANCY_HEADER': 'VERY FANCY'}) print result {'2': 'Jane Doe'} ``` @@ -55,14 +55,14 @@ Creating new data requires a POST or PUT request. Assuming you don't append **pr ```python from firebase import firebase -firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) +fb_app = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) new_user = 'Ozgur Vatansever' -result = firebase.post('/users', new_user, {'print': 'pretty'}, {'X_FANCY_HEADER': 'VERY FANCY'}) +result = fb_app.post('/users', new_user, {'print': 'pretty'}, {'X_FANCY_HEADER': 'VERY FANCY'}) print result {u'name': u'-Io26123nDHkfybDIGl7'} -result = firebase.post('/users', new_user, {'print': 'silent'}, {'X_FANCY_HEADER': 'VERY FANCY'}) +result = fb_app.post('/users', new_user, {'print': 'silent'}, {'X_FANCY_HEADER': 'VERY FANCY'}) print result == None True ``` @@ -71,8 +71,8 @@ Deleting data is relatively easy compared to other actions. You just set the url ```python from firebase import firebase -firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) -firebase.delete('/users', '1') +fb_app = firebase.FirebaseApplication('https://your_storage.firebaseio.com', None) +fb_app.delete('/users', '1') # John Doe goes away. ``` @@ -82,13 +82,13 @@ Authentication in Firebase is nothing but to simply creating a token that confor ```python from firebase import firebase -firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', authentication=None) -result = firebase.get('/users', None, {'print': 'pretty'}) +fb_app = firebase.FirebaseApplication('https://your_storage.firebaseio.com', authentication=None) +result = fb_app.get('/users', None, {'print': 'pretty'}) print result {'error': 'Permission denied.'} authentication = firebase.FirebaseAuthentication('THIS_IS_MY_SECRET', 'ozgurvt@gmail.com', extra={'id': 123}) -firebase.authentication = authentication +fb_app.authentication = authentication print authentication.extra {'admin': False, 'debug': False, 'email': 'ozgurvt@gmail.com', 'id': 123, 'provider': 'password'} @@ -99,7 +99,7 @@ hdCI6IDEzNjE5NTAxNzQsICJkIjogeyJkZWJ1ZyI6IGZhbHNlLCAiYWRtaW4iOiBmYWxzZSwgInByb3Z InBhc3N3b3JkIiwgImlkIjogNSwgImVtYWlsIjogIm96Z3VydnRAZ21haWwuY29tIn0sICJ2IjogMH0.lq4IRVfvE GQklslOlS4uIBLSSJj88YNrloWXvisRgfQ" -result = firebase.get('/users', None, {'print': 'pretty'}) +result = fb_app.get('/users', None, {'print': 'pretty'}) print result {'1': 'John Doe', '2': 'Jane Doe'} ``` @@ -114,13 +114,13 @@ import json from firebase import firebase from firebase import jsonutil -firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', authentication=None) +fb_app = firebase.FirebaseApplication('https://your_storage.firebaseio.com', authentication=None) def log_user(response): with open('/tmp/users/%s.json' % response.keys()[0], 'w') as users_file: users_file.write(json.dumps(response, cls=jsonutil.JSONEncoder)) -firebase.get_async('/users', None, {'print': 'pretty'}, callback=log_user) +fb_app.get_async('/users', None, {'print': 'pretty'}, callback=log_user) ``` # TODO From b5422390b669b9f2d30ffed78e6ae7a0cb5a995e Mon Sep 17 00:00:00 2001 From: emrcftci Date: Tue, 12 Nov 2019 09:14:02 +0300 Subject: [PATCH 08/11] docs(README): Fix TODO badges - Fix TODO badges `*` to `- [ ]` --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f9954aa..d349079 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,6 @@ firebase.get_async('/users', None, {'print': 'pretty'}, callback=log_user) # TODO - * Async calls must deliver exceptions raised back to the main process. - * More regression/stress tests on asynchronous calls. - * Docs must be generated. +- [ ] Async calls must deliver exceptions raised back to the main process. +- [ ] More regression/stress tests on asynchronous calls. +- [ ] Docs must be generated. From 18adce9c763a5d1ece872a9056ae7f5de47913f4 Mon Sep 17 00:00:00 2001 From: darrelfrancis <20881844+darrelfrancis@users.noreply.github.com> Date: Wed, 13 Nov 2019 20:54:46 +0800 Subject: [PATCH 09/11] Minor grammar/clarity edits in Readme --- README.rst | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/README.rst b/README.rst index ebb8651..9d9accc 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Python Firebase ================= -Python interface to the Firebase's REST API +Python interface to Firebase's REST API .. image:: https://travis-ci.org/ozgur/python-firebase.png?branch=master :target: https://travis-ci.org/ozgur/python-firebase @@ -9,7 +9,7 @@ Python interface to the Firebase's REST API Installation ----------------- -python-firebase highly makes use of the **requests** library so before you begin, you need to have that package installed. +python-firebase depends heavily on the **requests** library. .. code-block:: bash @@ -19,12 +19,11 @@ python-firebase highly makes use of the **requests** library so before you begin Getting Started ------------------ -You can fetch any of your data in JSON format by appending '.json' to the end of the URL in which your data resides and, then send an HTTPS request through your browser. Like all other REST specific APIs, Firebase offers a client to update(PATCH, PUT), create(POST), or remove(DELETE) his stored data along with just to fetch it. +You can read or write any of your data in JSON format. Append '.json' to the end of the URL in which your data resides. Send an HTTPS request from the browser. You can read (GET), replace (PUT), selectively update (PATCH), append (POST), or remove (DELETE) data From firebase. -The library provides all the correspoding methods for those actions in both synchoronous and asynchronous manner. You can just start an asynchronous GET request with your callback function, and the method +The library provides all the correspoding methods for those actions in both synchoronous and asynchronous manner. - -To fetch all the users in your storage simply do the following: +To read some data, start an asynchronous GET request with your callback function. For example, to fetch the entire content of "/users" in your Firebase database called "your_storage", do the following: .. code-block:: python @@ -34,7 +33,7 @@ To fetch all the users in your storage simply do the following: print result {'1': 'John Doe', '2': 'Jane Doe'} -The second argument of **get** method is the name of the snapshot. Thus, if you leave it NULL, you get the data in the URL **/users.json**. Besides, if you set it to **1**, you get the data in the url **/users/1.json**. In other words, you get the user whose ID equals to 1. +The second argument of **get** method is the branch of the database you wish to read. If you leave it None, you get all the data in the URL **/users.json**. If, instead, you set it to **1**, you get the data in the url **/users/1.json**. In other words, you get the user whose ID equals to 1. .. code-block:: python @@ -54,7 +53,9 @@ You can also provide extra query parameters that will be appended to the url or print result {'2': 'Jane Doe'} -Creating new data requires a POST or PUT request. Assuming you don't append **print=silent** to the url, if you use POST the returning value becomes the name of the snapshot, if PUT you get the data you just sent. If print=silent is provided, you get just NULL because the backend never sends an output. +Creating new data requires a PUT or POST request. If you know exactly where you want to put the data, use PUT. If you just want to append some data under a new key, but don't want to tell Firebase what key to use, use POST and it will create a unique time-ordered key. + +By default, in POST the function returns the a dictionary containing in "name", the key it has created for the data you have written, and in PUT the function returns the data you have just sent. If, instead, you set print=silent, the function returns None because the backend never sends an output. .. code-block:: python @@ -70,7 +71,7 @@ Creating new data requires a POST or PUT request. Assuming you don't append **pr print result == None True -Deleting data is relatively easy compared to other actions. You just set the url and that's all. Backend sends no output as a result of a delete operation. +Deleting data is relatively easy compared to other actions. You just specify the url. The backend sends no output. .. code-block:: python @@ -82,7 +83,7 @@ Deleting data is relatively easy compared to other actions. You just set the url Authentication ------------------ -Authentication in Firebase is nothing but to simply creating a token that conforms to the JWT standarts and, putting it into the querystring with the name **auth**. The library creates that token for you so you never end up struggling with constructing a valid token on your own. If the data has been protected against write/read operations with some security rules, the backend sends an appropriate error message back to the client with the status code **403 Forbidden**. +Authentication in Firebase involves simply creating a token that conforms to the JWT standarts and putting it into the querystring with the name **auth**. The library creates that token for you so you never end up struggling with constructing a valid token on your own. If the data has been protected against write/read operations with some security rules, the backend sends an appropriate error message back to the client with the status code **403 Forbidden**. .. code-block:: python @@ -116,9 +117,9 @@ The interface heavily depends on the standart **multiprocessing** library when c .. code-block:: python - import json - from firebase import firebase - from firebase import jsonutil + import json + from firebase import firebase + from firebase import jsonutil firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', authentication=None) From fe982987f56f82bc83dac4cb36502b960aeeb327 Mon Sep 17 00:00:00 2001 From: darrelfrancis <20881844+darrelfrancis@users.noreply.github.com> Date: Wed, 13 Nov 2019 21:00:38 +0800 Subject: [PATCH 10/11] Clarification --- .vscode/settings.json | 3 +++ README.rst | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c022e41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "restructuredtext.confPath": "" +} \ No newline at end of file diff --git a/README.rst b/README.rst index 9d9accc..c093561 100644 --- a/README.rst +++ b/README.rst @@ -53,7 +53,7 @@ You can also provide extra query parameters that will be appended to the url or print result {'2': 'Jane Doe'} -Creating new data requires a PUT or POST request. If you know exactly where you want to put the data, use PUT. If you just want to append some data under a new key, but don't want to tell Firebase what key to use, use POST and it will create a unique time-ordered key. +Creating new data requires a PUT or POST request. If you know exactly where you want to put the data, use PUT. If you just want to append some data under a new key, but don't want to tell Firebase what key to use, use POST and Firebase will create a unique time-ordered key. By default, in POST the function returns the a dictionary containing in "name", the key it has created for the data you have written, and in PUT the function returns the data you have just sent. If, instead, you set print=silent, the function returns None because the backend never sends an output. From a997ffca9ae16c684421a86ffee0c197b6d889b9 Mon Sep 17 00:00:00 2001 From: anonymousdouble <112695649+anonymousdouble@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:30:57 +1100 Subject: [PATCH 11/11] Update firebase.py refactor with fstring to format string to make code more Pythonic. --- firebase/firebase.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/firebase/firebase.py b/firebase/firebase.py index e62576d..aac5980 100644 --- a/firebase/firebase.py +++ b/firebase/firebase.py @@ -243,8 +243,7 @@ def _build_endpoint_url(self, url, name=None): url = url + self.URL_SEPERATOR if name is None: name = '' - return '%s%s%s' % (urlparse.urljoin(self.dsn, url), name, - self.NAME_EXTENSION) + return f'{urlparse.urljoin(self.dsn, url)}{name}{self.NAME_EXTENSION}' def _authenticate(self, params, headers): """