Package: kinto-http
Kinto python clientkinto-httpis the Python library to interact with aKintoserver.There is also a similarclient in JavaScript.InstallationUse pip:$ pip install kinto-httpUsageHere is an overview of what the API provides:importkinto_httpclient=kinto_http.Client(server_url="http://localhost:8888/v1",auth=('alexis','p4ssw0rd'))records=client.get_records(bucket='default',collection='todos')fori,recordinenumerate(records):record['title']='Todo{}'.format(i)client.update_record(data=record)Instantiating a clientThe passedauthparameter is arequestsauthentication policy.By default, a simple tuple will become aBasic Authauthorization request header, that can authenticate users withKinto Accounts.importkinto_httpauth=('alexis','p4ssw0rd')client=kinto_http.Client(server_url='http://localhost:8888/v1',auth=auth)It is also possible to pass abucketID and/orcollectionID to set them as default values for the parameters of the client operations.client=Client(bucket="payments",collection="receipts",auth=auth)After creating a client, you can also replicate an existing one and overwrite
some key arguments.client2=client.clone(collection="orders")An asynchronous client is also available. It has all the same endpoints as the sync client except for the batch operations.fromkinto_httpimportAsyncClientauth=('alexis','p4ssw0rd')client=AsyncClient(server_url='http://localhost:8888/v1',auth=auth)info=awaitclient.server_info()assert'schema'ininfo['capabilities'],"Server doesn't support schema validation."Using a Bearer access token to authenticate (OpenID)importkinto_httpclient=kinto_http.Client(auth=kinto_http.BearerTokenAuth("XYPJTNsFKV2"))The authorization header is prefixed withBearerby default. If theheader_typeiscustomized on the server,
the client must specify the expected type:kinto_http.BearerTokenAuth("XYPJTNsFKV2",type="Bearer+OIDC")NotePassing a string containingBearerwill be instantiate akinto_http.BearerTokenAuth()object automatically.In other words,kinto_http.Client(auth="Bearer+OIDCXYPJTNsFKV2")is equivalent tokinto_http.Client(auth=kinto_http.BearerTokenAuth("XYPJTNsFKV2",type="Bearer+OIDC"))Custom headersCustom headers can be specified in the Client constructor, and will be sent in every request:importkinto_httpclient=kinto_http.Client(server_url="http://server/v1",headers={"Allow-Access":"CDN","User-Agent":"blocklist-updater"})Getting server informationYou can use theserver_info()method to fetch the server information:fromkinto_httpimportClientclient=Client(server_url='http://localhost:8888/v1')info=client.server_info()assert'schema'ininfo['capabilities'],"Server doesn't support schema validation."Bucket operationsget_bucket(id=None, **kwargs): retrieve single bucketget_buckets(**kwargs): retrieve all readable bucketscreate_bucket(id=None, data=None, **kwargs): create a bucketupdate_bucket(id=None, data=None, **kwargs): create or replace an existing bucketpatch_bucket(id=None, changes=None, **kwargs): modify some fields in an existing bucketdelete_bucket(id=None, **kwargs): delete a bucket and everything under itdelete_buckets(**kwargs): delete every writable bucketsGroups operationsget_group(id=None, bucket=None, **kwargs): retrieve single groupget_groups(bucket=None, **kwargs): retrieve all readable groupscreate_group(id=None, data=None, bucket=None, **kwargs): create a groupupdate_group(id=None, data=None, bucket=None, **kwargs): create or replace an existing grouppatch_group(id=None, changes=None, bucket=None, **kwargs): modify some fields in an existing groupdelete_group(id=None, bucket=None, **kwargs): delete a group and everything under itdelete_groups(bucket=None, **kwargs): delete every writable groupsCollectionsget_collection(id=None, bucket=None, **kwargs): retrieve single collectionget_collections(bucket=None, **kwargs): retrieve all readable collectionscreate_collection(id=None, data=None, bucket=None, **kwargs): create a collectionupdate_collection(id=None, data=None, bucket=None, **kwargs): create or replace an existing collectionpatch_collection(id=None, changes=None, bucket=None, **kwargs): modify some fields in an existing collectiondelete_collection(id=None, bucket=None, **kwargs): delete a collection and everything under itdelete_collections(bucket=None, **kwargs): delete every writable collectionsRecordsget_record(id=None, bucket=None, collection=None, **kwargs): retrieve single recordget_records(bucket=None, collection=None, **kwargs): retrieve all readable recordsget_paginated_records(bucket=None, collection=None, **kwargs): paginated list of recordsget_records_timestamp(bucket=None, collection=None, **kwargs): return the records timestamp of this collectioncreate_record(id=None, data=None, bucket=None, collection=None, **kwargs): create a recordupdate_record(id=None, data=None, bucket=None, collection=None, **kwargs): create or replace an existing recordpatch_record(id=None, changes=None, bucket=None, collection=None, **kwargs): modify some fields in an existing recorddelete_record(id=None, bucket=None, collection=None, **kwargs): delete a record and everything under itdelete_records(bucket=None, collection=None, **kwargs): delete every writable recordsPermissionsThe objects permissions can be specified or modified by passing apermissionstocreate_*(),patch_*(), orupdate_*()methods:client.create_record(data={'foo':'bar'},permissions={'read':['group:groupid']})record=client.get_record('123',collection='todos',bucket='alexis')record['permissions']['write'].append('leplatrem')client.update_record(data=record)Get or createIn some cases, you might want to create a bucket, collection, group or record only if
it doesn’t exist already. To do so, you can pass theif_not_exists=Trueto thecreate_*()methods:client.create_bucket(id='blog', if_not_exists=True)
client.create_collection(id='articles', bucket='blog', if_not_exists=True)Delete if existsIn some cases, you might want to delete a bucket, collection, group or record only if
it exists already. To do so, you can pass theif_exists=Trueto thedelete_*methods:client.delete_bucket(id='bucket', if_exists=True)Patch operationsThe.patch_*()operations receive achangesparameter.fromkinto_http.patch_typeimportBasicPatch,MergePatch,JSONPatchclient.patch_record(id='abc',changes=BasicPatch({'over':'write'}))client.patch_record(id='todo',changes=MergePatch({'assignee':'bob'}))client.patch_record(id='receipts',changes=JSONPatch([{'op':'add','path':'/data/members/0','value':'ldap:user@corp.com'}]))Concurrency controlThecreate_*(),patch_*(), andupdate_*()methods take asafeargument (default:True).IfTrue, the client will ensure that the object doesn’t exist already for creations, or wasn’t modified on the server side since we fetched it. The timestamp will be implicitly read from thelast_modifiedfield in the passeddataobject, or taken explicitly from theif_matchparameter.Batching operationsRather than issuing a request for each and every operation, it is possible to
batch several operations in one request (sync client only).Using thebatch()method as a Python context manager (with):withclient.batch()asbatch:foridxinrange(0,100):batch.update_record(data={'id':idx})NoteBesides theresults()method, a batch object shares all the same methods as
another client.Reading data from batch operations is achieved by using theresults()method
available after a batch context is closed.withclient.batch()asbatch:batch.get_record('r1')batch.get_record('r2')batch.get_record('r3')r1,r2,r3=batch.results()ErrorsFailing operations will raise aKintoException, which hasrequestandresponseattributes.try:client.create_group(id="friends")exceptkinto_http.KintoExceptionase:ife.responseande.response.status_code==403:print("Not allowed!")Requests TimeoutAtimeoutvalue in seconds can be specified in the client constructor:client=KintoClient(server_url="...",timeout=5)To distinguish the connect from the read timeout, use a tuple:client=KintoClient(server_url="...",timeout=(3.05,27))For an infinit timeout, useNone:client=KintoClient(server_url="...",timeout=None)See thetimeout documentationof the underlyingrequestslibrary.Retry on errorWhen the server is throttled (under heavy load or maintenance) it can
return error responses.The client can hence retry to send the same request until it succeeds.
To enable this, specify the number of retries on the client:client=Client(server_url='http://localhost:8888/v1',auth=credentials,retry=10)The Kinto protocol lets the serverdefine the duration in seconds between retries.
It is possible (but not recommended) to force this value in the clients:client=Client(server_url='http://localhost:8888/v1',auth=credentials,retry=10,retry_after=5)PaginationWhen the server responses are paginated, the client will download every page and
merge them transparently.Theget_paginated_records()method returns a generator that will yield each page:forpageinclient.get_paginated_records():records=page["data"]It is possible to specify a limit for the number of items to be retrieved in one page:records=client.get_records(_limit=10)In order to retrieve every available pages with a limited number of items in each
of them, you can specify the number of pages:records=client.get_records(_limit=10,pages=float('inf'))# InfinityHistoryIf the built-inhistory pluginis enabled, it is possible to retrieve the history of changes:# Get the complete history of a bucketchanges=client.get_history(bucket='default')# and optionally use filtershist=client.get_history(bucket='default',_limit=2,_sort='-last_modified',_since='1533762576015')hist=client.get_history(bucket='default',resource_name='collection')The history of a bucket can also be purged with:client.purge_history(bucket='default')Endpoint URLsTheget_endpoint()method returns an endpoint URL on the server:client=Client(server_url='http://localhost:8888/v1',auth=('token','your-token'),bucket="payments",collection="receipts")print(client.get_endpoint("record",id="c6894b2c-1856-11e6-9415-3c970ede22b0"))# '/buckets/payments/collections/receipts/records/c6894b2c-1856-11e6-9415-3c970ede22b0'Handling datetime and date objectsIn addition to the data types supported by JSON, kinto-http.py also
supports native Python date and datetime objects.In case a payload contain a date or a datetime object, kinto-http.py
will encode it as an ISO formatted string.Please note that this transformation is only one-way. While reading a
record, if a string contains a ISO formated string, kinto-http.py will
not convert it to a native Python date or datetime object.If you know that a field will be a datetime, you might consider
encoding it yourself to be more explicit about it being a string for
Kinto.Command-line scriptsIn order to have common arguments and options for scripts, some utilities are provided
to ease configuration and initialization of client from command-line arguments.importargparseimportloggingfromkinto_httpimportcli_utilslogger=logging.getLogger(__name__)if__name__=="__main__":parser=argparse.ArgumentParser(description="Download records")cli_utils.set_parser_server_options(parser)args=parser.parse_args()cli_utils.setup_logger(logger,args)logger.debug("Instantiate Kinto client.")client=cli_utils.create_client_from_args(args)logger.info("Fetch records.")records=client.get_records()logger.warn("{}records.".format(len(records)))The script now accepts basic options:$ python example.py --help

usage: example.py [-h] [-s SERVER] [-a AUTH] [-b BUCKET] [-c COLLECTION] [-v]
                  [-q] [-D]

Download records

optional arguments:
  -h, --help            show this help message and exit
  -s SERVER, --server SERVER
                        The location of the remote server (with prefix)
  -a AUTH, --auth AUTH  BasicAuth credentials: `token:my-secret` or
                        Authorization header: `Bearer token`
  -b BUCKET, --bucket BUCKET
                        Bucket name.
  -c COLLECTION, --collection COLLECTION
                        Collection name.
  --retry RETRY         Number of retries when a request fails
  --retry-after RETRY_AFTER
                        Delay in seconds between retries when requests fail
                        (default: provided by server)
  -v, --verbose         Show all messages.
  -q, --quiet           Show only critical errors.
  -D, --debug           Show all messages, including debug messages.Run testsIn one terminal, run a Kinto server:$ make run-kintoIn another, run the tests against it:$ make tests(Optional) Install a git hook:therapist installCHANGELOGThis document describes changes between each past release.11.0.1 (2023-04-05)Bug fixesFixclone()method with subclasses (#307)Do not send body inGETrequests (#306)11.0.0 (2022-08-22)Remove pinned versions in dependencies10.10.1 (2022-07-05)Bug fixesFix breaking change introduced in previous version, accept empty string inauthparameter10.10.0 (2022-06-27)New featuresUse Bearer token Auth object if specified string forauthcontainsBearerUse Basic Auth if specified string forauthcontains:10.9.0 (2022-02-04)New featuresAccess client configured bucket and collection names atclient.bucket_nameandclient.collection_namerespectively.10.8.0 (2021-12-03)New featuresAsynchronous client is now available:from kinto_http import AsyncClient(#268)Internal changesReplacedunittestwithpytest10.7.0 (2020-01-09)New featuresAdd ability to specify headers from Client constructor10.6.1 (2019-11-13)Bug fixesDo not try to parse content on204 No Contentresponses10.6.0 (2019-09-20)New featuresSpecify requests timeout in client constructor10.5.0 (2019-09-10)New featuresAdd history support (fixes #112), Thanks @FlorianKuckelkorn!10.4.1 (2019-05-22)Bug fixesHandle bearer tokens without a colon.10.4.0 (2019-05-09)Add support for Bearer tokens in the CLI utilities.Use black for code formatting.10.3.0 (2019-03-07)New featuresAdd support for OAuth access tokens (OpenID) with theBearerTokenAuth()helper. See README. (#197)10.2.0 (2018-12-17)New featuresCreated new method on client to get paginated recordsget_paginated_records. (#175)Allow additional querystring params inget_*()methods10.1.1 (2018-11-13)Bug fixesFix JSON support forin_andexclude_. (#188)10.1.0 (2018-11-05)New featureConvert params values as JSON values before passing them to requests. (#185)10.0.0 (2018-10-15)Breaking changesBy default, the client now raises an exception when a 4XX error occurs in a batch request (#154)In order to ignore those errors as before, instantiate the client withignore_batch_4xx=True.New featureRaise a specificCollectionNotFoundexception rather than a genericKintoException.Bug fixesHandle date and datetime object in a Kinto payload. They will be
formated as ISO date JSON strings.Internal changesUpdate tests to work with Kinto 11.0.0.Update tests to use stdlib mock module.9.1.2 (2018-04-17)Internal changesGet rid ofsix9.1.1 (2018-02-07)Bug fixesFix patch methods in batch requests (fixes #171)9.1.0 (2018-02-05)Significant changesWhen the server returns a409 Conflicterror response, the request will
be retried if theretryparameter is superior to zero (fixes #167)New FeaturesExpose kinto-http and Python module version in the User-Agent (#157)Support different PATCH types. Now, instead of settling for the
“default” patch method offered by the Kinto server, you can choose
by importing a PatchType subclass fromkinto_http.patch_type. (Fixes #125.)Bug fixesNo longer supportmethodarguments on theupdate_bucket,update_group,update_collection, andupdate_recordmethods. This argument only existed to support thepatch_*methods and was never intended to be part of the public API.9.0.1 (2017-05-30)Bug fixesFix exception rendering (fixes #153)9.0.0 (2017-05-25)Breaking changesThe client will fail a batch only when a 5XX error occurs (#148)New FeaturesLog all the batch responses (#148)Log the request and the batch responses in debug (#148)Allow reading responses from batch requests with theresults()method. (#146)8.0.1 (2017-05-16)Bug fixesFix get_records_timestamp JSONDecode error while trying to decode
the body of a HEAD response. (#144)8.0.0 (2017-05-11)Breaking changesFetch only one page when_limitis specified and allow to override this
with apagesargument (fixes #136)Make client methods API consistent by forcing keyword parameters (#119)Deduce theidof a resource with the value ofidindataif present (#143)Drop Python 2.7 support. Now supports Python 3.5+New FeaturesKeep tracks of Backoff headers and raise anBackoffExceptionif
we are not waiting enough between two calls. (#53)Add--retryand--retry-afterto CLI utils helpers (fixes #126)Bug fixesFix retry behaviour when responses are successful (fixes #129)Fix Retry-After value to be read as integer rather than string. (#131)Fix No JSON could be decoded ValueError (fixes #116)Internal changesmaketests-onceto run functional tests in order to calculate coverage correctly (#131)7.2.0 (2017-03-17)Only provide thedataJSON field when data is provided. (#122)7.1.0 (2017-03-16)Bug fixesMethod for plural endpoints now return list of objects instead ofodict_values.New featuresAdd logging (fixes #36, #110, thanks @sahildua2305)DocumentationFix explanation about safe/if_match/last_modifiedFix missing methods in docs (#102, thanks @gabisurita)Improve contributing guide (#104, #111,  thanks @Sayli-Karnik)Show how to use the FxABearerTokenAuth auth (#117)7.0.0 (2016-09-30)Breaking changesRemovedif_existsargument from thedelete_*smethods for plural endpoints
(#98, thanks @mansimarkaur!)New featuresAdded CRUD methods for the group endpoints (#95, thanks @mansimarkaur!)DocumentationAdd contributing guide (#90, thanks @sahildua2305!)6.2.1 (2016-09-08)New featuresAdd aif_existsflag to delete methods to avoid raising if the
item was already deleted. (#82)Improving theclonemethod to keep all the previous parameters values
if missing as parameters. (#91)6.1.0 (2016-08-04)New featuresAdd aget_records_timestampmethod to get the collectionETag. (#81)6.0.0 (2016-06-10)Breaking changesRename kinto_client to kinto_http (#74)5.0.0 (2016-05-12)Breaking changesRename thelast_modifiedclient parameter intoif_match(#68)New featuresDisplay a better message when having 403 on create_collection and
create_record methods (#49)Exposeget_endpointsas part of the client API (#60)Add aserver_infomethod to retrieve the root url info (#70)Internal changesRename the Batch class into BatchSession (#52)Change readthedocs.org urls in readthedocs.io (#71)4.1.0 (2016-04-26)New featuresAdd new methodsget_buckets(),delete_buckets(),delete_bucket(),delete_collections(),delete_records(),patch_record()(#55)Internal changesFunctional tests are now tested on Kinto master version (#65)4.0.0 (2016-03-08)Breaking changesThe functioncli_utils.set_parser_server_options()was renamedcli_utils.add_parser_options()(#63)New featuresadd_parser_optionscan now exclude bucket and collection
parameters. (#63)create_client_from_argscan now works even with no bucket or
collection arguments (#63)Bug fixesDo not sent body in GET requests. (#62)3.1.0 (2016-02-16)New featuresAdd CLI helpers to configure and instantiate a Client from command-line arguments
(#59)3.0.0 (2016-02-10)Breaking changesUpdated theupdate_collection()signature: data is now the fisr argument
(#47)New featuresAdded a retry option for batch requests (#51)Use the “default” bucket if nothing is specified (#50)Added aif_not_existsargument to the creation methods (#42)Added a replication mechanism inkinto_http.replication(#26)Handle thelast_modifiedargument on update or create operations (#24)Bug fixesDo not force the JSON content-type in requests if multipart-encoded files are
sent (#27)Fail the batch operations early (#47)Remove un-needed requirements (FxA) (#43)Usemax_batch_requestfrom the server to issue more than one batch request
(#30)Make sure batch raises an error when needed (#28)Fix an invalid platform error for some versions of python (#31)Do not lowercase valid IDs (#33)DocumentationAdd documentation about client.batch (#44)2.0.0 (2015-11-18)Added support for pagination in records requests (#13)Added support for If-Match / If-None-Match headers for not overwriting
existing records (#14)Changed the API of the batch support. There is now aclient.batch()context
manager (#17)Added support of the PATCH methods to update records / collections (#19)1.0.0 (2015-11-09)Breaking changesRewrote the API to be easier to use (#10)0.2.0 (2015-10-28)Breaking changesRename kintoclient to kinto_client (#8)FeaturesAdd the endpoints class. (#9)Add batching utilities. (#9)Internal changesAdd universal wheel configuration.0.1.1 (2015-09-03)Initial versionA client to synchroneously call a Kinto server.