- Adds
date_last_modifiedfield to theBookingCompanyresource. - See PR #149 for more details.
Add gapipy.exceptions.TimeoutError, which can be raised when the optional timeout parameter is passed to Query.get. Without providing the timeout parameter, the default behaviour remains unchanged, where a requests Timeout exception is raised.
See PR #146 for more details.
from gapipy import Client gapi = Client(application_key="your_api_key") try: departure_service = gapi.departure_services.get(123456, timeout=1) except gapi.exceptions.TimeoutError: # handle exception else: ... # success
- HOTFIX for 2.39.0 (2025-08-21) (Yanked): Reverts the removal of the
self._raw_data = deepcopy(data) in
BaseModel._fill_fields. This is necessary to ensure that the_raw_dataattribute is updated with new data returned as a result of the request made inResource.save(). This bug was introduced in PR #145. - All other changes in 2.39.0 will remain and 2.39.0 will be yanked from PyPI.
- See PR #147 for more details.
- Remove
costsandhas_costsfields from theAccommodationDossierandActivityDossierresources. - Moves the
AccommodationDossier.featuresfield from the as-is-fields to the model-collection-fields as references to theDossierFeatureresource. - Expose the
primary_countryfield on theActivityDossierresource. This references theCountryresource. - See PR #145 for more details.
- Add new resources for "room upgrade" and "regional connector" products:
room_upgrades,room_upgrade_services,regional_connectors, andregional_connectors_services. See PR #143 for more details.
- Add
abta_numberfield to theAgencyresource. This field is a string that represents the ABTA number of the agency. See PR #142 for more details.
- Add
contact_usfield to theAgenchChainresource. This field can beNone, however should a value be present, it will be an object with three accessible attributes:email,phone_number, andwebsite_url. See the PR #141 for more details.
Add new
Clientconfiguration value that will raise an error when an empty partial update (PATCH) payload is computed by gapipy. See Issue #136 and the corresponding PR #137 for more details.The new Client configuration kwarg is
raise_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.from gapipy import Client gapi = 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 here departure_service.save(partial=True)
- Add
travel_ready_policymodel field to theDepartureresource. - More details can be found in our developer documentation. c.f. Departure travel-ready-policy
- Add
online_preferencesfield to theAgency Chainresource.
- Make
futurerequirement more flexible. See PR #134 for more details.
- Initialize the
DjangoCachevia 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. See PR #133 for more details.
Note
DjangoCache was introduced in 2.30.0 (2021-02-08)
- Introduce
gapipy.constantsmodule that holds common constants. See PR #132 for more details. - Reintroduce the ability to enable old behaviour (pre 2.25.0 (2020-01-02))
for
Resource.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. See PR #131 for more details.
- Fix for 2.30.0 (2021-02-08) Adds a guard against configuring Django settings again as per the Django settings docs. See PR #130 for more details.
- Adds a new cache backend;
gapipy.cache.DjangoCache. It requiresDjangoand agapientry insettings.CACHES. See PR #129 for more details.
Usage:
- Set the
GAPI_CACHE_BACKENDEnv varible togapipy.cache.DjangoCache.
OR
from gapipy import Client
gapi = Client(
application_key="live_your-secret-gapi-key",
cache_backend="gapipy.cache.DjangoCache",
)- Adds
Departure.relationshipsfield viaDepartureRelationshipmodel - Adds
TourDossier.relationshipsfield viaTourDossierRelationshipmodel
Warning
BREAKING!
Moves the
gapipy.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:# before from gapipy.resources.tour.itinerary.ValidDuringRange # now from gapipy.models import ValidDuringRange
See PR #128 for more details.
Add a new
Clientconfig option,global_http_headers, a dict of HTTP headers to add to each request made with that client.This is similar to the
headers=kwargs available when makinggetandcreatecalls, except that theglobal_http_headersset on a client will apply on every request made by that client instance.
Warning
BREAKING!
- Make
Customer.nationalitya resource 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.name
u'Canadian'- Fix 2.26.3 (2020-04-28) (Yanked): Add missing
CONTRIBUTING.rstto the manifest.
Note
Discovered when attempting to install gapipy via pip.
- Fix py2 & py3 compatibility for
urlparse
Fix for 2.26.1 (2020-04-20) and Issue #113.
- See PR #125.
- Remove the
_set_resource_collection_fieldmethod inTourDossier - Introducing the
_Parentnamedtuple in PR #123. broke being able to Query-chain from Tour-Dossiers to departures - Buggy behaviour fixed from 2.26.1 (2020-04-20)
>>> from gapipy import Client >>> api = Client(application_key='MY_SECRET_KEY') >>> api.tour_dossiers(24309).departures.count() # AttributeError: 'tuple' object has no attribute 'uri'
Fix for 2.26.0 (2020-04-14) and Issue #113.
- Calls to
APIRequestor.list_rawwill use initialised its parameters, unless the URI provides its own. - See PR #123.
- Calls to
Add the ability to define the
max_retriesvalues on the requestor.- New
envvalueGAPI_CLIENT_MAX_RETRIES. - The default value will be
0, and if provided will override theretryvalue on therequests.Session. - This change will also always initialize a
requests.Sessionvalue on initialisation of thegapipy.Client. - See PR #124.
- New
Add
variation_idfield to theImageresource.- See Commit edc8d9b.
Update the
ActivityDossierandAccommodationDossierresources.- Remove the
is_prepaidfield. - Adds the
has_costsfield. - See Commit bd35531.
- Remove the
Warning
BREAKING!
- The
Query.filtermethod will return a clone/copy of itself. This will preserve the state offilterson the original Query object. - The
Query.allmethod will not clear the filters after returning. - The
Query.allmethod will return aTypeErrorif a type other than anintis passed to thelimitargument. - The
Query.countmethod will not clear the filters after returning. - See PR #121 for more details.
New behaviour with the Query.filter method:
>>> from gapipy import Client
>>> 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()
494- The
AgencyChain.agenciesattribute returns a list ofAgencyobjects. See Commit f34afd52.
Improve contribution instructions to check long_description rST file in dist
Dev Requirement updates:
- Add
readme_renderer==24.0 - Add
twine==1.15.0fortwine checkcommand
- Add
- Failing to fetch inlined Resource (from Stubs) will raise the underlying
requests.HTTPError instead of AttributeError resulting from a
None. - Adds
httperrors_mapped_to_nonekwarg togapipy.query.Query.getwith default valuegapipy.query.HTTPERRORS_MAPPED_TO_NONE - Modifies
gapipy.resources.base.Resource.fetchto passhttperrors_mapped_to_none=NonetoQuery.get - This ensures that any underlying
requests.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 instead
- Exclude the
testspackage from the package distribution
- Adds the
compute_request_signatureandcompute_webhook_validation_keyutility methods. See PR #122.
- Add
slugfield toTourDossierresource. See PR #120.
Add missing/new fields to the following resources. See PR #117.
- AccommodationDossier:
categories,suggested_dossiers,visited_countries,visited_cities - ActivityDossier:
suggested_dossiers,visited_countries,visited_cities - Departure:
local_payments - Itinerary:
publish_state
- AccommodationDossier:
Add
continentandplacereferences to theCountriesresource. See PR #115.Accept
additional_headersoptional kwarg oncreate. See PR #114.
- Remove deprecated
tour_dossiers.itinerariesfield and related code
- Add
booking_companyfield toBookingresource
- Add
ripple_scoretoItineraryresource
- HISTORY.rst doc fixes
- Add
RequirementandRequirementSetresources - Move
Checkinresource to theresources.bookingmodule - The
Queryobject will resolve to use thehrefvalue when returning the iterator to fetchallof some resource. This is needed becausebookings/123456/requirementsactually returns a list ofRequirementSetresources - See Release tag 2.20.0 for more details.
- Add
get_category_namehelper method toTourDossierresource
- Attempt to fix rST formatting of
READMEandHISTORYon pypi
Become agnostic between redis
2.x.x&&3.x.xversions- the
setexmethod argument order changes between the major versions
- the
Note
HotFix for 2.19.0 (2019-02-12).
- adds
requirements.txtfile to the distributionMANIFEST
Add
booking_companiesfield toItineraryresourcePin our requirement/dependency versions
- pin
future == 0.16.0 - pin
requests >= 2.18.4, < 3.0.0 - read
setup.pyrequirements fromrequirements.txt
- pin
- Add
customersnested resource tobookings
- Add
merchandiseresource - Add
merchandise_servicesresources
- Add
membership_programsfield to theCustomerresource
Completely remove the deprecated
add_onsfield from the Departure resourceAdd missing fields to various Dossier resources
- AccommodationDossier:
flags,is_prepaid,service_time,show_on_reservation_sheet - ActivityDossier:
is_prepaid,service_time,show_on_reservation_sheet - CountryDossier:
flags - PlaceDossier:
flags - TransportDossier:
flags
- AccommodationDossier:
Add
valid_during_rangeslist field to the Itinerary resource. This field is a list field of the newly addedValidDuringRangemodel (described below)Add
ValidDuringRangemodel. 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 all
- Add
countryreference toNationalityresource. - Moved
resources/bookings/nationality.pytoresources/geo/*.
- Check for presence of
idfield 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. - Added
service_codefield for Activty & Accommodation Dossier resources.
- deleted
- Raise an
AttributeErrorwhen trying to accessidonResource.__getattr__. - Don't send duplicate params when paginating through list results.
- Implement
first()method forQuery.
- Expose Linked Bookings via the API.
- Add
booking_companiesfield to Agency resource. - Remove
bookingsfield from Agency resource. - Add
requirementsas_is field to Departure Service resource. - Add
policy_emergency_phone_numberfield to Insurance Service resource.
- Remove deprecated
add_onsfield fromDepartureresource. - Add
costsfield toAccommodation&ActivityDossierresources.
- Add
meal_budgetslist field toCountryDossierresource. - Add
publish_statefield toDossierFeaturesresource.
Add optional
headersparameter to Query.get to allow HTTP-Headers to be passed. e.g.client.<resource>.get(1234, headers={'A':'a'}). See PR #91.Add
preferred_display_namefield toAgencyresource. See PR #92.Add
booking_companiesarray field to all Product-type resources. See PR #93.- Accommodation
- Activity
- AgencyChain
- Departure
- SingleSupplement
- TourDossier
- Transport
- Add
agency_chainfield toBookingresource - Add
idfield as part of theDossierDetailmodel See PR #89. - Add
agency_chainsfield to theAgencyresource. See PR #90. - See Release tag 2.11.3 for more details.
- The
Customer.addressfield uses theAddressmodel, and is no longer a dict. - Passing in
uuid=TruetoClientkwargs enablesuuidgeneration for every request.
- Add the
amount_pendingfield to theBookingresource - The
PricePromotionmodel extends from thePromotionresource (PR/85) - Update the
Agentclass to use BaseModel classes for theroleandphone_numbersfields. - see Release tag 2.10.0 for more details.
Note
We have skipped Release 2.9.2 due to pypi upload issues.
- Expose
requirement_setfordeparture_services&activity_services.
Note
- We have skipped Release
2.9.0due to pypi upload issues.
- Adds the
optionsmethod on the Resource Query object. See Release tag 2.9.1 for more details.
- Adds fields
sale_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.
- Add new fields to the
AgencyandAgencyChainresources
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.Adds missing fields to the Agency and Flight Service resources (PR/78)
- Add
agencyfield toBookingresource.
- Add test fix for Accommodation. It is a listable resource as of
2.7.4 - Add 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 as
Accommodation.
- Add
videos,images, andcategoriestoActivity,Transport,Place, andAccommodation Dossierresources. - Add
flagsto Itinerary resource - Add list view of
Accommodationsresource
- Add
typefield toAgencyDocumentmodel - Add
structured_itinerarymodel collection field toDepartureresource
- Fix flight_status Reference value in FlightService resource
- Fix: remove FlightStatus import reference for FlightService resource
- Add fields (fixes two broken Resource tests)
- Add
hreffield forcheckinsresource - Add
date_cancelledfield fordeparturesresource
- Add
- Fix broken
UpdateCreateResourcetests
- Remove
flight_statusesandflight_segmentsresources.
- Version bump
- Adds a Deprecation warning when using the
toursresource.
- Fixed Issue #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.
- Added
futuredependency to setup.py
- Fixed an issue in which modifying a nested dictionary caused gapipy to not identify a change in the data.
- Added
tox.inifor testing across Python platforms. - Capture
403Status Codes as aNoneobject.
- Provided Python 3 functionality (still Python 2 compatible)
- Removed Python 2 only tests
- Installed
futuremodule for smooth Python 2 to Python 3 migration - Remove
DictToModelclass and the associated tests - Add
DossierResource(s) - Minor field updates to:
Customer,InsuranceService,DepartureService,Booking,FlightStatus,State
- Fixed a bug with internal
_get_urifunction.
- Adjusted
Checkinresource to meet updated spec.
- Added
Checkinresource.
- Fix broken
Durationinit inActivityDossier(likely broke due to changes that happened in 2.0.0)
- Added
Imageresource definition and put it to use inItineraryand,PlaceDossier
- Added
date_last_modifiedanddate_createdtoPromotion.
- Added
gendertoCustomer. - Added
places_of_interesttoPlace.
- Added
departurereference toDepartureComponent
- Removed use of
.iteritemswherever present in favour of.items - Added
featuresrepresentation toActivityDossierand,TransportDossier
- Added
CountryDossierresource.
- Added
DossierSegmentresource. - Added
ServiceLevelresource.
- Added day
labelfield to theItineraryresource.
- Added
audiencefield to theDocumentresource.
- Added
transactional_email, andemailstoAgencyresource.
- Added
audiencetoInvoiceresource.
- Removed invalid field,
emailfromAgencyChain
- Added new resource,
AgencyChain
The global reference to the last instantiated Client has been removed. It
is now mandatory to pass in a Client instance when instantiating a Model or
Resource.
In practice, this should not introduce too many changes in codebases that are
using gapipy, since most resource interacation happens through a Client
instance (e.g. api.tours.get(123), or api.customers.create({...})),
instead of being instantiated independently. The one possible exception is unit
testing: in that case, Client.build can be useful.
The global variable was causing issues with connection pooling when multiple client with different configurations were used at the same time.
- Added new resource,
DossierFeature
- Adopted Semantic Versioning for this project.
Warning
BREAKING!
- 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. The
Queryobject now introduces aquery_keymethod which generates the cache key sent to the cache modules.
- Added better error handling to
Client.build. An AttributeError raised when instantiating a resource won't be shadowed by the except block anymore.
- Fixed a regression bug when initializing DepartureServiceRoom model.
- Fixed a regression bug when initializing services.
- Fixed a bug when initializing list of resources.
- Added a component of type
ACCOMMODATIONtoItineraries.
- Added
associated_servicestoSingleSupplementService
- Added
nametoDeparture. - Happy New Year!
- Added
variation_idtoBaseCacheto fix aTypeErrorwhen using theNullCache
- Add
associated_agencytobookingsresource
- Minor adjusted in Query internals to ensure the
variation_idof an Itinerary is handled properly. - Added
ItineraryHighlightsandItineraryMediaresources. These are sub resources of theItinerary
- Added connection pool caching to
RedisCache. Instances ofgapipywith the same cache settings (in the same Python process) will share a connection pool.
- Added
codefield to thetypeof anItinerary's listeddetails.
- Added the
detailsfield to theItineraryresource -- a list of textual details about an itinerary.
- Added the
tour_dossierfield to theItineraryresource.
- Fixed a bug that would cause
amountwhen looking atPromotionobjects in theDepartureto be removed from the data dict.
- Moved an import of
requestsdown from the module level. Fixes issues in CI environments.
- Added connection pooling options, see docs for details on
connection_pool_options.
- Modified how the
Promotionobject is loaded withinprice_bandson aDeparture. It now correctly captures theamountfield.
- Modified objects within
cachemodule to handlevariation_id, which is exposed within theItineraryobject. Previously, theItinerarywould not be correctly stored in cache with its variant reference.
- Added the
componentsfield to theDepartureresource.
- Fixed an issue with the default
gapipy.cache.NullCachewhenis_cachedwas used.
- Added new fields to
Itineraryrevolving around variations. - Added
declined_reasonto all service resources.
- Add DeclinedReason resource
- Fixed a bug in
APIRequestor.get. Requesting a resource with with an id of0won't raise an Exception anymore.
- Added
associated_servicesandoriginal_departure_serviceto various service resources anddeparture_servicesmodel respectively.
- Fixed
productswithin thePromotionresource to properly retaintypeandsub_typefields after being parsed into a dictionary.
- Changed default
cache_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.
- Fixed
Placeinit with empty admin_divisions.
- Added
descriptiontoTourCategoryresource.
- Added
DepartureComponentresource. See the official G API documentation for details.
- Added
deposittoDepartureServiceresource.
- Refactor
APIRequestor._request. While this should not change existing functionality, it is now possible to override specific methods on the class.
- Fixed: Due to inconsistencies in the G API with regards to nested resources,
the
fetchfunction was modified to use the raw data from the API, rather than a specific set of allowed fields.
- Fixed: Iterating over
productswithin thepromotionsobject now works as expected. Previously, accessing theproductsattribute would result in a Query object with incorrect parameters.
- Support free to amount price range formatting (e.g. Free-10CAD)
- Added
duration_min&duration_maxtoActivityDossiermodel
- Added
OptionalActivitymodel - All Dossiers with
details: * Now represented as list ofDossierDetailmodels * Added convenience methods for retrieving specific details ItineraryComponentandActivityDossieruse newDurationmodel for theirdurationfield/property- Added
duration_labelandlocation_labeltoItineraryComponent - Added
duration_label,price_per_person_label, andprice_per_group_labeltoActivityDossier
- Added
namefield to the Itinerary resource.
- Changed cache key creation to account for
GAPI_LANGUAGEwhen the environment variable is set.
- Fixed a bug when setting _resource_fields in
DepartureServiceresource
TourDossier.structured_itinerariesnow refers to a list of Itinerary resources
- Added
TransportDossierandItineraryresources. - The reference to the itinerary in a
DepartureServiceis now a full-fledgedItineraryresource.
- Bug fix to correctly send
Content-Type: application/jsonin POST, PUT, or PATCH.
- Update
DepartureServiceobject to contain a reference to itsItinerary
- Normalize API request headers, to promote caching.
- Added
ActivityDossierandAccommodationDossierresources, as well as references to it fromActivityandAccommodation.
- Added
PlaceDossierresource, as well as reference to it fromPlace
- Added
advertised_departurestoTourDossier
- 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.
- Departure resource is now listable via filters.
- Fixed a bug with
RedisCache`.is_cached` where it would not use the set ``key_prefixwhen checking for existence in cache. Effectively, it would always return False
- When setting a
date_field, initiate it as adatetime.datetype.
- Deprecated
RedisHashCachefrom cache backends available by default. Was not well tested or reliable.
- Fixed a bug where if a model field received
nullas a value, it would fail. Now, if the result isnull, the model field will have an appropriateNonevalue.
- Fix a bug in the DepartureRoom model. The
price_bandsattribute is now properly set.
- Fixed a bug where AgencyDocument was not included in the code base.
- Add
latitude,longitude, anddocumentsto theAgencyresource.
date_createdon theAgencyresource is correctly parsed as a local time.
- Improve the performance of
Resource.fetchby handling cache get/set.
- Fix a bug in AccommodationRoom price bands. The
season_datesandblackout_datesattributes are now properly set.
- Add iso_639_3 and iso_639_1 to
Language
- Remove the
add_onsfield inDeparture, and addaddons.
- Fix a bug when initializing AccommodationRoom from cached data.
- Add Query.purge_cached
- Add
detailsfield to the list ofincomplete_requirementsin aDepartureService.
- Removed sending of header X-HTTP-Method-Override: PATCH when the update command is called. Now, when .save(partial=True) is called, the correct PATCH HTTP method will be sent with the request.
- Return
Noneinstead 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)- Added Query.is_cached
- Added cache options
- Use setuptools find_packages
- First release on PyPI.