Package: gapipy
G API Python ClientA client for the G Adventures REST API (https://developers.gadventures.com)GitHub Repository:https://github.com/gadventures/gapipy/Documentation:http://gapipy.readthedocs.org.Free software: MIT LicenseQuick Start>>>fromgapipyimportClient>>>api=Client(application_key='MY_SECRET_KEY')>>># Get a resource by id>>>tour_dossier=api.tour_dossiers.get(24309)>>>tour_dossier.product_lineu'AHEH'>>>tour_dossier.departures.count()134>>>tour_dossier.nameu'Essential India'>>>itinerary=tour_dossier.structured_itineraries[0]>>>{day.day:day.summaryfordayinitinerary.days[:3]}{1:u'Arrive at any time. Arrival transfer included through the G Adventures-supported Women on Wheels project.',2:u'Take a morning walk through the city with a young adult from the G Adventures-supported New Delhi Streetkids Project. Later, visit Old Delhi, explore the spice markets, and visit Jama Masjid and Connaught Place.',3:u"Arrive in Jaipur and explore this gorgeous 'pink city'."}>>># Create a new resource>>>booking=api.bookings.create({'currency':'CAD','external_id':'abc'})>>># Modify an existing resource>>>booking.external_id='def'>>>booking.save()Since2.25.0 (2020-01-02)>>># since 2.25.0 reference stubs that fail to fetch will return a>>># subclass of requests.HTTPError (See: https://github.com/gadventures/gapipy/pull/119)>>># This can also be done on Query.get by passing a Falsy value for the>>># httperrors_mapped_to_none kwarg.>>>>>>dep=api.departures.get('404_404',httperrors_mapped_to_none=None)...# omitted stacktraceHTTPError:404ClientError:{"http_status_code":404,"message":"Not found.","errors":[],"time":"2020-01-02T19:46:07Z","error_id":"gapi_asdf1234"}forurl:https://rest.gadventures.com/departures/404_404>>>dep=api.departures.get('404404')>>>dep.start_address.country<Country:BR(stub)>>>># lets have GAPI return a _404_ error here for the country stub `fetch`>>># when we attempt to retrieve the continent attribute>>>dep.start_address.country.continent# reference/stub forces a fetch>>># pre 2.25.0 behaviour...# omitted stacktraceAttributeError:'Country'hasnofield'continent'available>>># post 2.25.0 behaviour...# omitted stacktraceHTTPError:404ClientError:{"http_status_code":404,"message":"Not found.","errors":[],"time":"2020-01-02T19:46:07Z","error_id":"gapi_qwer5678"}forurl:https://rest.gadventures.com/countries/BRResourcesResource objects are instantiated from python dictionaries created from JSON
data. The fields are parsed and converted to python objects as specified in the
resource class.A nested resource will only be instantiated when its corresponding attribute is
accessed in the parent resource. These resources may be returned as astub,
and upon access of an attribute not present, will internally call.fetch()on the resource to populate it.A field pointing to the URL for a collection of a child resources will hold aQueryobject for that resource. As for nested resources, it will only be
instantiated when it is first accessed.QueriesA Query for a resource can be used to fetch resources of that type (either a
single instance or an iterator over them, possibly filtered according to  some
conditions). Queries are roughly analogous to Django’s QuerySets.An API client instance has a query object for each available resource
(accessible by an attribute named after the resource name)Methods on Query objectsAll queries support theget,createandoptionsmethods. The other
methods are only supported for queries whose resources are listable.options()Get the options for a single resourceget(resource_id,[headers={}])Get a single resource; optionally passing in a dictionary of header
values.create(data)Create an instance of the query resource using the given data.all([limit=n])Generator over all resources in the current query. Iflimitis a
positive integern, then only the firstnresults will be returned.ATypeErrorwill be raised if limit is notNoneorinttypeAValueErrorwill be raised iflimit <= 0filter(field1=value1, [field2=value2,...])filter(**{"nested.field":"value"})Filter resources on the provided fields and values. Calls tofiltercan
be chained. The method will return a clone of theQueryobject and must
be stored in a separate variable in order to have access tostackedfilters.count()Return the number of resources in the current query (by reading thecountfield on the response returned by requesting the list of
resources in the current query).Cachinggapipycan be configured to use a cache to avoid having to send HTTP
requests for resources it has already seen. Cache invalidation is not
automatically handled: it is recommended to listen to G APIwebhooksto purge
resources that are outdated.By default,gapipywill use the cached data to instantiate a resource, but
a fresh copy can be fetched from the API by passingcached=FalsetoQuery.get. This has the side-effect of recaching the resource with the
latest data, which makes this a convenient way to refresh cached data.Caching can be configured through thecache_backendandcache_optionssettings.cached_backendshould be a string of the fully qualified path to
a cache backend, i.e. a subclass ofgapipy.cache.BaseCache. A handful of
cache backends are available out of the box:gapipy.cache.SimpleCacheA simple in-memory cache for single process environments and is not
thread safe.gapipy.cache.RedisCacheA key-value cache store using Redis as a backend.gapipy.cache.NullCache(Default)A cache that doesn’t cache.gapipy.cache.DjangoCache(requires Django)A cache which uses Django’s cache settings for configuration. Requires there
be agapientry insettings.CACHES.Since the cache backend is defined by a python module path, you are free to use
a cache backend that is defined outside of this project.Connection PoolingWe use therequestslibrary, and you can take advantage of the provided
connection pooling options by passing in a'connection_pool_options'dict
to your client.Values inside the'connection_pool_options'dict of interest are as
follows:SetenabletoTrueto enable pooling. Defaults toFalse.Usenumberto set the number of connection pools to cache.
Defaults to 10.Usemaxsizeto set the max number of connections in each pool.
Defaults to 10.SetblocktoTrueif the connection pool should block and wait
for a connection to be released when it has reachedmaxsize. IfFalseand the pool is already atmaxsizea new connection will
be created without blocking, but it will not be saved once it is used.
Defaults toFalse.See also:http://www.python-requests.org/en/latest/api/#requests.adapters.HTTPAdapterhttp://urllib3.readthedocs.io/en/latest/reference/index.html#module-urllib3.connectionpoolDependenciesThe only dependency needed to use the client isrequests.TestingRunning tests is pretty simple. We usenoseas the test runner. You can
install all requirements for testing with the following:$ pip install -r requirements-testing.txtOnce installed, run unit tests with:$ nosetests -A integration!=1Otherwise, you’ll want to include a GAPI Application Key so the integration
tests can successfully hit the API:$ export GAPI_APPLICATION_KEY=MY_SECRET_KEY; nosetestsIn addition to running the test suite against your local Python interpreter, you
can run tests usingTox. Tox allows the test suite
to be run against multiple environments, or in this case, multiple versions of
Python. Install and run thetoxcommand from any place in the gapipy source
tree. You’ll want to export your G API application key as well:$ export GAPI_APPLICATION_KEY=MY_SECRET_KEY
$ pip install tox
$ toxTox will attempt to run against all environments defined in thetox.ini. It
is recommended to use a tool likepyenvto
ensure you have multiple versions of Python available on your machine for Tox to
use.Fields_model_fieldsrepresent dictionary fields.Note_model_fields =[('address',Address)]ANDAddresssubclassesBaseModel{"address":{"street":"19 Charlotte St","city":"Toronto","state":{"id":"CA-ON","href":"https://rest.gadventures.com/states/CA-ON","name":"Ontario"},"country":{"id":"CA","href":"https://rest.gadventures.com/countries/CA","name":"Canada"},"postal_zip":"M5V 2H5"}}_model_collection_fieldsrepresent a list of dictionary fields.Note_model_collection_fields =[('emails',AgencyEmail),]ANDAgencyEmailsubclassesBaseModel{"emails":[{"type":"ALLOCATIONS_RELEASE","address":"g@gadventures.com"},{"type":"ALLOCATIONS_RELEASE","address":"g2@gadventures.com"}]}_resource_fieldsrefer to anotherResourceContributingNoteEnsure a Python 2 environmentClone the project$gitclonegit@github.com:gadventures/gapipyRunpip install-rrequirements-dev.txtto setup dev dependencies.Always make your changes in a branch and to submit a PR.$gitcheckoutmaster$gitpull$gitcheckout-bfeature-branch-name$gitpushoriginfeature-branch-nameOnce the PR has been accepted/merged into themasterbranch, follow
these steps.$cd/path/to/gapipy$gitcheckoutmaster$gitpulloriginmasterModify the following files:Updategapipy/__init__.pyincrement the__version__variableNotestylemajor.minor.patchupdatepatchwhen adding new fields, fixing bugs introduced by a
minor release.updateminorif there is some breaking change such as adding a new
resource, removing fields, adding new behaviour.updatemajorwhen we switch toPython 3only support.Seesemver.orgfor more information.UpdateHISTORY.rstupdate this file with the newversion&dateAdd some brief notes describing the changes.Usemake distto check the generated long_description rST file is valid.Noteignorewarning: nopreviously-includedfiles matchingmessages.as long as you get aCheckingdist/gapipy-a.b.c.tar.gz:PASSEDmessage, you are good!If not, fix the errors as dictated in the output, and repeat.Example output when runningmake dist:$makedistwarning:nopreviously-includedfilesmatching'*'foundunderdirectory'tests'warning:nopreviously-includedfilesmatching'__pycache__'foundunderdirectory'*'warning:nopreviously-includedfilesmatching'.eggs'foundunderdirectory'*'warning:nopreviously-includedfilesmatching'*.py[co]'foundunderdirectory'*'total123-rw-r--r--1usergroup762765Feb02:53gapipy-a.b.c.tar.gzCheckingdist/gapipy-a.b.c.tar.gz:PASSEDPush the newReleasecommitUseRelease a.b.c (YYYY-MM-DD)format for the commit title. Optionally
add a description that matches the changes made toHISTORY.rst.Create a release on github with the following description (This will be
tagged to theReleasecommit and not the PR/change commit)# Release a.b.c (YYYY-MM-DD)PR:#123A brief description describing the changes*bullet points*make for easy readingRelease!$ make releaseThanks for helping!History2.35.0 (2022-04-18)Add newClientconfiguration value that will raise an error when an empty
partial update (PATCH) payload is computed by gapipy. SeeIssue #136and
the correspondingPR #137for more details.The new Client configuration kwarg israise_on_empty_update, whose
default value isFalse, and can also be set by passing it as an
environment variableGAPI_CLIENT_RAISE_ON_EMPTY_UPDATE. If this config
value is set, then a call toResource.savewithpartial=Truewill
raise the newEmptyPartialUpdateErrorif an empty payload is computed.fromgapipyimportClientgapi=Client(application_key="your_api_key",raise_on_empty_update=True)departure_service=gapi.departure_services.get(123456)# we've changed nothing and are calling a partial save (PATCH)## NOTE: the new EmptyPartialUpdateError will be raised heredeparture_service.save(partial=True)2.34.0 (2021-08-20)Addtravel_ready_policymodel field to theDepartureresource.
* More details can be found in ourdeveloper docs <https://developers.gadventures.com/docs/departure.html#travel-ready-policy>2.33.0 (2021-07-06)Addonline_preferencesfield to theAgency Chainresource.2.32.0 (2021-06-18)Makefuturerequirement more flexible. SeePR #134for more details.2.31.1 (2021-05-14)Initialize theDjangoCachevia theBaseCachewhich exposes thedefault_timeoutattribute to the class. Prior to this change, when using
theDjangoCache, items would persist forever as no timeout would be set
on the entries. SeePR #133for more details.NoteDjangoCachewas introduced in2.30.0 (2021-02-08)2.31.0 (2021-03-02)Introducegapipy.constantsmodule that holds common constants. SeePR #132for more details.Reintroduce the ability to enable old behaviour (pre2.25.0 (2020-01-02))
forResource.fetch. It adds an optionalhttperrors_mapped_to_noneparameter to the method (defaultNone), where if a list of HTTP Status
codes is provided instead, will silently consume errors mapped to those
status codes and return aNonevalue instead of raising the HTTPError.
SeePR #131for more details.2.30.1 (2021-02-08)Fix for2.30.0 (2021-02-08)Adds a guard against configuring Django
settings again as per theDjango settings docs. SeePR #130for more
details.2.30.0 (2021-02-08)Adds a new cache backend;gapipy.cache.DjangoCache. It requiresDjangoand agapientry insettings.CACHES. SeePR #129for more details.Usage:Set theGAPI_CACHE_BACKENDEnv varible togapipy.cache.DjangoCache.ORfromgapipyimportClientgapi=Client(application_key="live_your-secret-gapi-key",cache_backend="gapipy.cache.DjangoCache",)2.29.0 (2021-02-05)AddsDeparture.relationshipsfield viaDepartureRelationshipmodelAddsTourDossier.relationshipsfield viaTourDossierRelationshipmodelWarningBREAKING!Moves thegapipy.resources.tour.itinerary.ValidDuringRangeclass over to
its own filegapipy.models.valid_duraing_range.ValidDuringRangeso that it can be reused by theTourDossierRelationshipmodel. Any code
importing the class directly will need to change the import path:# beforefromgapipy.resources.tour.itinerary.ValidDuringRange# nowfromgapipy.modelsimportValidDuringRangeSeePR #128for more details.2.28.0 (2020-11-23)Add a newClientconfig option,global_http_headers, a dict of HTTP
headers to add to each request made with that client.This is similar to theheaders=kwargs available when makinggetandcreatecalls, except that theglobal_http_headersset on a client
will apply onevery requestmade by that client instance.2.27.0 (2020-05-26)WarningBREAKING!MakeCustomer.nationalityaresource field. This allows attribute style
access to the field values, whereas before they needed to be accessed using
dictionary accessor (d["key"]) syntax.# before>>>api.customers.get(123456).nationality["name"]u'Canadian'# now>>>api.customers.get(123456).nationality.nameu'Canadian'2.26.4 (2020-04-28)Fix2.26.3 (2020-04-28) (Yanked): Add missingCONTRIBUTING.rstto the
manifest.NoteDiscovered when attempting to installgapipyviapip.2.26.3 (2020-04-28) (Yanked)Fix py2 & py3 compatibility forurlparse2.26.2 (2020-04-20)Fix for2.26.1 (2020-04-20)andIssue #113.SeePR #125.Remove the_set_resource_collection_fieldmethod inTourDossierIntroducing the_Parentnamedtuple inPR #123.
broke being able to Query-chain from Tour-Dossiers to departuresBuggy behaviour fixed from2.26.1 (2020-04-20)>>>fromgapipyimportClient>>>api=Client(application_key='MY_SECRET_KEY')>>>api.tour_dossiers(24309).departures.count()# AttributeError: 'tuple' object has no attribute 'uri'2.26.1 (2020-04-20)Fix for2.26.0 (2020-04-14)andIssue #113.Calls toAPIRequestor.list_rawwill use initialised its parameters,
unless the URI provides its own.SeePR #123.Add the ability to define themax_retriesvalues on the requestor.NewenvvalueGAPI_CLIENT_MAX_RETRIES.The default value will be0, and if provided will override theretryvalue on therequests.Session.This change will also always initialize arequests.Sessionvalue on
initialisation of thegapipy.Client.SeePR #124.Addvariation_idfield to theImageresource.SeeCommit edc8d9b.Update theActivityDossierandAccommodationDossierresources.Remove theis_prepaidfield.Adds thehas_costsfield.SeeCommit bd35531.2.26.0 (2020-04-14)WarningBREAKING!TheQuery.filtermethod will return a clone/copy of itself. This will
preserve the state offilterson the original Query object.TheQuery.allmethod willnotclear the filters after returning.TheQuery.allmethod will return aTypeErrorif a type other than
anintis passed to thelimitargument.TheQuery.countmethod willnotclear the filters after returning.SeePR #121for more details.New behaviour with theQuery.filtermethod:>>>fromgapipyimportClient>>>api=Client(application_key='MY_SECRET_KEY')# create a filter on the departures>>>query=api.departures.filter(**{"tour_dossier.id":"24309"})>>>query.count()494# we preserve the filter status of the current query>>>query.filter(**{"availability.status":"AVAILABLE"}).count()80>>>query.count()494TheAgencyChain.agenciesattribute returns a list ofAgencyobjects.
SeeCommit f34afd52.2.25.1 (2020-01-02)Improve contribution instructions to check long_description rST file in distDev Requirement updates:Addreadme_renderer==24.0Addtwine==1.15.0fortwine checkcommand2.25.0 (2020-01-02)Failing to fetch inlined Resource (from Stubs) will raise the underlying
requests.HTTPError instead of AttributeError resulting from aNone.Addshttperrors_mapped_to_nonekwarg togapipy.query.Query.getwith default valuegapipy.query.HTTPERRORS_MAPPED_TO_NONEModifiesgapipy.resources.base.Resource.fetchto
passhttperrors_mapped_to_none=NonetoQuery.getThis ensures that any underlyingrequests.HTTPErrorfromQuery.getis bubbled up to the caller. It is most prevalent when reference Resource stubs
fail to be retrieved from the G API. Prior to this changeResource.fetchwould return aNonevalue resulting in anAttributeError. Now, if the
stub fails to fetch due to an HTTPError, that will be raised instead2.24.3 (2019-12-12)Exclude thetestspackage from the package distribution2.24.2 (2019-12-12)Adds thecompute_request_signatureandcompute_webhook_validation_keyutility methods. SeePR #122.2.24.1 (2019-12-12)Addslugfield toTourDossierresource. SeePR #120.2.24.0 (2019-11-05)Add missing/new fields to the following resources. SeePR #117.AccommodationDossier:categories,suggested_dossiers,visited_countries,visited_citiesActivityDossier:suggested_dossiers,visited_countries,visited_citiesDeparture:local_paymentsItinerary:publish_stateAddcontinentandplacereferences to theCountriesresource. SeePR #115.Acceptadditional_headersoptional kwarg oncreate. SeePR #114.2.23.0 (2019-11-04)Remove deprecatedtour_dossiers.itinerariesfield and related code2.22.0 (2019-10-10)Addbooking_companyfield toBookingresource2.21.0 (2019-04-09)Addripple_scoretoItineraryresource2.20.1 (2019-02-20)HISTORY.rst doc fixes2.20.0 (2019-02-20)AddRequirementandRequirementSetresourcesMoveCheckinresource to theresources.bookingmoduleTheQueryobject will resolve to use thehrefvalue when
returning the iterator to fetchallof some resource. This is
needed becausebookings/123456/requirementsactually returns a list
ofRequirementSetresourcesSeeRelease tag 2.20.0for more details.2.19.4 (2019-02-14)Addget_category_namehelper method toTourDossierresource2.19.3 (2019-02-12)Attempt to fix rST formatting ofREADMEandHISTORYon pypi2.19.2 (2019-02-12)Become agnostic between redis2.x.x&&3.x.xversionsthesetexmethod argument order changes between the major versions2.19.1 (2019-02-12)NoteHotFix for2.19.0 (2019-02-12).addsrequirements.txtfile to the distributionMANIFEST2.19.0 (2019-02-12)Addbooking_companiesfield toItineraryresourcePin our requirement/dependency versionspinfuture == 0.16.0pinrequests >= 2.18.4, < 3.0.0readsetup.pyrequirements fromrequirements.txt2.18.1 (2019-02-07)Addcustomersnested resource tobookings2.18.0 (2018-12-14)AddmerchandiseresourceAddmerchandise_servicesresources2.17.0 (2018-11-12)Addmembership_programsfield to theCustomerresource2.16.0 (2018-11-07)Completely remove the deprecatedadd_onsfield from the Departure resourceAdd missing fields to various Dossier resourcesAccommodationDossier:flags,is_prepaid,service_time,show_on_reservation_sheetActivityDossier:is_prepaid,service_time,show_on_reservation_sheetCountryDossier:flagsPlaceDossier:flagsTransportDossier:flagsAddvalid_during_rangeslist field to the Itinerary resource. This field is
a list field of the newly addedValidDuringRangemodel (described below)AddValidDuringRangemodel. It consists of two date fields,start_date,
andend_date. It also provides a number of convenience methods to determine
if the date range provided is valid, or relative to some date.is_expired: Is it expired relative todatetime.date.todayis_valid_today: Is it valid relative todatetime.date.todayis_valid_during_range: Is it valid for some give start/end date rangeis_valid_on_or_after_date: Is it valid on or after some dateis_valid_on_or_before_date: Is it valid on or before some dateis_valid_on_date: Is it valid on some dateis_valid_sometime: Is it valid at all2.15.0 (2018-10-10)Addcountryreference toNationalityresource.Movedresources/bookings/nationality.pytoresources/geo/*.2.14.6 (2018-08-01)Check for presence ofidfield directly in the Resource__dict__in
order to prevent a chicken/egg situation when attempting tosave. This is
needed due to the change introduced in 2.14.4, where we explicitly raise an
AttributeError when trying to access theidattribute.Addedservice_codefield for Activty & Accommodation Dossier resources.2.14.5 (2018-08-01)deleted2.14.4 (2018-07-13)Raise anAttributeErrorwhen trying to accessidonResource.__getattr__.Don’t send duplicate params when paginating through list results.Implementfirst()method forQuery.2.14.3 (2018-05-29)Expose Linked Bookings via the API.2.14.1 (2018-05-15)Addbooking_companiesfield to Agency resource.Removebookingsfield from Agency resource.Addrequirementsas_is field to Departure Service resource.Addpolicy_emergency_phone_numberfield to Insurance Service resource.2.14.0 (2018-05-15)Remove deprecatedadd_onsfield fromDepartureresource.Addcostsfield toAccommodation&ActivityDossierresources.2.13.0 (2018-03-31)Addmeal_budgetslist field toCountryDossierresource.Addpublish_statefield toDossierFeaturesresource.2.12.0 (2018-02-14)Add optionalheadersparameter to Query.get to allow HTTP-Headers to be
passed. e.g.client.<resource>.get(1234,headers={'A':'a'}). SeePR #91.Addpreferred_display_namefield toAgencyresource. SeePR #92.Addbooking_companiesarray field to all Product-type resources. SeePR #93.AccommodationActivityAgencyChainDepartureSingleSupplementTourDossierTransport2.11.4 (2018-01-29)Addagency_chainfield toBookingresourceAddidfield as part of theDossierDetailmodel SeePR #89.Addagency_chainsfield to theAgencyresource. SeePR #90.SeeRelease tag 2.11.3for more details.2.11.0 (2017-12-18)TheCustomer.addressfield uses theAddressmodel, and is no longer a
dict.Passing inuuid=TruetoClientkwargs enablesuuidgeneration
for every request.2.10.0 (2017-12-01)Add theamount_pendingfield to theBookingresourceThePricePromotionmodel extends from thePromotionresource (PR/85)Update theAgentclass to use BaseModel classes for theroleandphone_numbersfields.seeRelease tag 2.10.0for more details.2.9.3 (2017-11-23)NoteWe have skipped Release2.9.2due to pypi upload issues.Exposerequirement_setfordeparture_services&activity_services.2.9.1 (2017-11-22)NoteWe have skipped Release2.9.0due to pypi upload issues.Adds theoptionsmethod on the Resource Query object. SeeRelease tag 2.9.1for more details.2.8.2 (2017-11-14)Adds fieldssale_start_datetimeandsale_finish_datetimeto the
Promotion resource. The fields mark the start/finish date-time values
for when a Promotion is applicable. The values represented are in UTC.2.8.1 (2017-10-25)Add new fields to theAgencyandAgencyChainresources2.8.0 (2017-10-23)This release adds a behaviour change to the.all()method on resource
Query objects. Prior to this release, the base Resource Query object would
retain any previously addedfiltervalues, and be used in subsequent
calls. Now the underlying filters are reset after a<resource>.all()call
is made.SeeIssue #76andPR #77for details and the resulting fix.Adds missing fields to the Agency and Flight Service resources (PR/78)2.7.6 (2017-10-04)Addagencyfield toBookingresource.2.7.5 (2017-09-25)Add test fix for Accommodation. It is a listable resource as of2.7.4Add regression test for departures.addon.product model
* Ensure Addon’s are instantiated to the correct underlying model.
* Prior to this release, all Addon.product resources were instantiated asAccommodation.2.7.4 (2017-09-20)Addvideos,images, andcategoriestoActivity,Transport,Place, andAccommodation Dossierresources.Addflagsto Itinerary resourceAdd list view ofAccommodationsresource2.7.3 (2017-09-06)Addtypefield toAgencyDocumentmodelAddstructured_itinerarymodel collection field toDepartureresource2.7.2 (2017-08-18)Fix flight_status Reference value in FlightService resource2.7.1 (2017-08-18)Fix: remove FlightStatus import reference for FlightService resourceAdd fields (fixes two broken Resource tests)Addhreffield forcheckinsresourceAdddate_cancelledfield fordeparturesresourceFix brokenUpdateCreateResourcetests2.7.0 (2017-08-18)Removeflight_statusesandflight_segmentsresources.2.6.2 (2017-08-11)Version bump2.6.1 (2017-08-11)Adds a Deprecation warning when using thetoursresource.2.6.0 (2017-08-11)FixedIssue #65: only
write data into the local cache after a fetch from the API, do not write data
into the local cache when fetching from the local cache.2.5.2 (2017-04-26)Addedfuturedependency to setup.py2.5.1 (2017-02-08)Fixed an issue in which modifying a nested dictionary caused gapipy to not
identify a change in the data.Addedtox.inifor testing across Python platforms.Capture403Status Codes as aNoneobject.2.5.0 (2017-01-20)Provided Python 3 functionality (still Python 2 compatible)Removed Python 2 only testsInstalledfuturemodule for smooth Python 2 to Python 3 migrationRemoveDictToModelclass and the associated testsAddDossierResource(s)Minor field updates to:Customer,InsuranceService,DepartureService,Booking,FlightStatus,State2.4.9 (2016-11-22)Fixed a bug with internal_get_urifunction.2.4.8 (2016-11-11)AdjustedCheckinresource to meet updated spec.2.4.7 (2016-10-25)AddedCheckinresource.2.4.6 (2016-10-19)Fix brokenDurationinit inActivityDossier(likely broke due to
changes that happened in 2.0.0)2.4.5 (2016-10-13)AddedImageresource definition and put it to use inItineraryand,PlaceDossier2.4.4 (2016-09-09)Addeddate_last_modifiedanddate_createdtoPromotion.2.4.3 (2016-09-06)AddedgendertoCustomer.Addedplaces_of_interesttoPlace.2.4.2 (2016-07-08)Addeddeparturereference toDepartureComponent2.4.1 (2016-07-06)Removed use of.iteritemswherever present in favour of.itemsAddedfeaturesrepresentation toActivityDossierand,TransportDossier2.4.0 (2016-06-29)AddedCountryDossierresource.2.3.0 (2016-06-28)AddedDossierSegmentresource.AddedServiceLevelresource.2.2.2 (2016-06-08)Added daylabelfield to theItineraryresource.2.2.1 (2016-06-06)Addedaudiencefield to theDocumentresource.2.2.0 (2016-05-17)Addedtransactional_email, andemailstoAgencyresource.2.1.2 (2016-05-17)AddedaudiencetoInvoiceresource.2.1.1 (2016-04-29)Removed invalid field,emailfromAgencyChain2.1.0 (2016-04-25)Added new resource,AgencyChain2.0.0 (2016-03-11)The global reference to the last instantiatedClienthas been removed. It
is now mandatory to pass in a Client instance when instantiating aModelorResource.In practice, this should not introduce too many changes in codebases that are
usinggapipy, since most resource interacation happens through aClientinstance (e.g.api.tours.get(123), orapi.customers.create({...})),
instead of being instantiated independently. The one possible exception is unit
testing: in that case,Client.buildcan be useful.The global variable was causing issues with connection pooling when multiple
client with different configurations were used at the same time.1.1.0 (2016-03-11)Added new resource,DossierFeature1.0.0 (2016-02-29)AdoptedSemantic Versioningfor this project.WarningBREAKING!Refactored how the cache key is set. This is a breaking change for any
modules that implemented their own cache interface. The cache modules are
no longer responsible for defining the cache value, but simply storing
whatever it is given into cache. TheQueryobject now introduces aquery_keymethod which generates the cache key sent to the cache
modules.0.6.3 (2016-01-21)Added better error handling toClient.build. An AttributeError raised when
instantiating a resource won’t be shadowed by the except block anymore.0.6.2 (2016-01-20)Fixed a regression bug when initializing DepartureServiceRoom model.0.6.1 (2016-01-20)Fixed a regression bug when initializing services.0.6.0 (2016-01-20)Fixed a bug when initializing list of resources.0.5.5 (2016-01-08)Added a component of typeACCOMMODATIONtoItineraries.0.5.4 (2016-01-04)Addedassociated_servicestoSingleSupplementService0.5.3 (2015-12-31)AddednametoDeparture.Happy New Year!0.5.2 (2015-12-15)Addedvariation_idtoBaseCacheto fix aTypeErrorwhen using
theNullCache0.5.1 (2015-12-14)Addassociated_agencytobookingsresource0.5.0 (2015-12-10)Minor adjusted in Query internals to ensure thevariation_idof an
Itinerary is handled properly.AddedItineraryHighlightsandItineraryMediaresources. These are
sub resources of theItinerary0.4.6 (2015-12-09)Added connection pool caching toRedisCache. Instances ofgapipywith
the same cache settings (in the same Python process) will share a connection
pool.0.4.5 (2015-11-05)Addedcodefield to thetypeof anItinerary’s listeddetails.0.4.4 (2015-11-04)Added thedetailsfield to theItineraryresource – a list of
textual details about an itinerary.0.4.3 (2015-11-03)Added thetour_dossierfield to theItineraryresource.0.4.2 (2015-10-28)Fixed a bug that would causeamountwhen looking atPromotionobjects
in theDepartureto be removed from the data dict.0.4.1 (2015-10-16)Moved an import ofrequestsdown from the module level. Fixes issues in
CI environments.0.4.0 (2015-10-13)Added connection pooling options, see docs for details onconnection_pool_options.0.3.0 (2015-09-24)Modified how thePromotionobject is loaded withinprice_bandson aDeparture. It now correctly captures theamountfield.0.2.0 (2015-09-15)Modified objects withincachemodule to handlevariation_id, which is
exposed within theItineraryobject. Previously, theItinerarywould
not be correctly stored in cache with its variant reference.0.1.51 (2015-08-31)Added thecomponentsfield to theDepartureresource.0.1.50 (2015-07-28)Fixed an issue with the defaultgapipy.cache.NullCachewhenis_cachedwas used.0.1.49 (2015-07-23)Added new fields toItineraryrevolving around variations.Addeddeclined_reasonto all service resources.0.1.48 (2015-07-15)Add DeclinedReason resource0.1.47 (2015-07-08)Fixed a bug inAPIRequestor.get. Requesting a resource with with an id of0won’t raise an Exception anymore.0.1.46 (2015-06-10)Addedassociated_servicesandoriginal_departure_serviceto various
service resources anddeparture_servicesmodel respectively.0.1.45 (2015-05-27)Fixedproductswithin thePromotionresource to properly retaintypeandsub_typefields after being parsed into a dictionary.0.1.44 (2015-05-22)Changed defaultcache_backendto usegapipy.cache.NullCache.
Previously,SimpleCachewas the default and led to confusion in
production environments, specifically as to why resources were not matching
the API output. Now, by default, to get any caching from gapipy you must
explicitly set it.0.1.43 (2015-04-29)FixedPlaceinit with empty admin_divisions.0.1.42 (2015-04-29)AddeddescriptiontoTourCategoryresource.0.1.41 (2015-04-14)AddedDepartureComponentresource. See the official G APIdocumentationfor details.0.1.40 (2015-04-06)AddeddeposittoDepartureServiceresource.0.1.39 (2015-03-31)RefactorAPIRequestor._request. While this should not change existing
functionality, it is now possible to override specific methods on the class.0.1.38 (2015-03-23)Fixed: Due to inconsistencies in the G API with regards to nested resources,
thefetchfunction was modified to use the raw data from the API, rather
than a specific set of allowed fields.0.1.37 (2015-03-23)Fixed: Iterating overproductswithin thepromotionsobject now works
as expected. Previously, accessing theproductsattribute would result in
a Query object with incorrect parameters.0.1.36 (2015-03-17)Support free to amount price range formatting (e.g. Free-10CAD)0.1.35 (2015-03-12)Addedduration_min&duration_maxtoActivityDossiermodel0.1.34 (2015-03-11)AddedOptionalActivitymodelAll Dossiers withdetails:
* Now represented as list ofDossierDetailmodels
* Added convenience methods for retrieving specific detailsItineraryComponentandActivityDossieruse newDurationmodel
for theirdurationfield/propertyAddedduration_labelandlocation_labeltoItineraryComponentAddedduration_label,price_per_person_label, andprice_per_group_labeltoActivityDossier0.1.33 (2015-03-02)Addednamefield to the Itinerary resource.0.1.32 (2015-02-18)Changed cache key creation to account forGAPI_LANGUAGEwhen the
environment variable is set.0.1.31 (2015-02-18)Fixed a bug when setting _resource_fields inDepartureServiceresource0.1.30 (2015-02-11)TourDossier.structured_itinerariesnow refers to a list of Itinerary
resources0.1.29 (2015-02-10)AddedTransportDossierandItineraryresources.The reference to the itinerary in aDepartureServiceis now a
full-fledgedItineraryresource.0.1.28 (2015-01-22)Bug fix to correctly sendContent-Type:application/jsonin POST, PUT,
or PATCH.0.1.27 (2015-01-19)UpdateDepartureServiceobject to contain a reference to itsItinerary0.1.26 (2015-01-14)Normalize API request headers, to promote caching.0.1.25 (2015-01-09)AddedActivityDossierandAccommodationDossierresources, as well as
references to it fromActivityandAccommodation.0.1.24 (2015-01-07)AddedPlaceDossierresource, as well as reference to it fromPlace0.1.22 (2014-12-12)Addedadvertised_departurestoTourDossier0.1.21 (2014-11-26)Fixed a bug with promotions on a Price object. When promotions were accessed,
gapipy would query for all promotions, rather than returning the inline list.0.1.20 (2014-11-20)Departure resource is now listable via filters.0.1.19 (2014-11-17)Fixed a bug withRedisCache`.is_cached`where it would not use the set ``key_prefixwhen checking for existence in cache. Effectively, it would
always return False0.1.18 (2014-11-12)When setting adate_field, initiate it as adatetime.datetype.0.1.17 (2014-11-07)DeprecatedRedisHashCachefrom cache backends available by default. Was not
well tested or reliable.0.1.16 (2014-10-28)Fixed a bug where if a model field receivednullas a value, it would fail.
Now, if the result isnull, the model field will have an appropriateNonevalue.0.1.15 (2014-10-23)Fix a bug in the DepartureRoom model. Theprice_bandsattribute is now
properly set.0.1.14 (2014-10-22)Fixed a bug where AgencyDocument was not included in the code base.0.1.13 (2014-10-21)Addlatitude,longitude, anddocumentsto theAgencyresource.0.1.12 (2014-10-20)date_createdon theAgencyresource is correctly parsed as a local
time.0.1.11 (2014-10-15)Improve the performance ofResource.fetchby handling cache get/set.0.1.10 (2014-10-09)Fix a bug in AccommodationRoom price bands. Theseason_datesandblackout_datesattributes are now properly set.0.1.9 (2014-09-23)Addiso_639_3andiso_639_1toLanguage0.1.8 (2014-09-17)Remove theadd_onsfield inDeparture, and addaddons.0.1.7 (2014-08-22)Fix a bug when initializing AccommodationRoom from cached data.0.1.6 (2014-08-19)Add Query.purge_cached0.1.5 (2014-07-29)Adddetailsfield to the list ofincomplete_requirementsin aDepartureService.0.1.4 (2014-07-21)Removed sending of headerX-HTTP-Method-Override: PATCHwhen the update
command is called. Now, when.save(partial=True)is called, the
correct PATCH HTTP method will be sent with the request.0.1.3 (2014-07-18)ReturnNoneinstead of raising a HTTPError 404 exception when fetching a
non-existing resource by id.Added ability to create resources from the Query objects on the client
instance.obj={'name':{'legal_first_name':'Pat',...},...}api.customers.create(obj)0.1.2 (2014-07-14)Added Query.is_cachedAdded cache options0.1.1 (2014-06-27)Use setuptools find_packages0.1.0 (2014-06-20)First release on PyPI.