A PDS blogpost today - Accessing semantic data with OData web interface- announced a new RESTful JSON web API to the PDS OData service under OData v4.
I've dabbled with this before in OData2 land (Calling an OData Service From Python – UK Parliament Members Data Platform) but I think the package that I used then has rotted a bit, so here's another attempt, this time using the odata
package from tuomur/python-odata.
#!pip3 install git+https://github.com/tuomur/python-odata.git
from odata import ODataService
url = 'http://services.odata.org/V4/Northwind/Northwind.svc/'
Service = ODataService(url, reflect_entities=True)
Supplier = Service.entities['Supplier']
query = Service.query(Supplier)
query = query.limit(2)
query = query.order_by(Supplier.CompanyName.asc())
for supplier in query:
print('Company:', supplier.CompanyName)
for product in supplier.Products:
print('- Product:', product.ProductName)
Company: Aux joyeux ecclésiastiques - Product: Côte de Blaye - Product: Chartreuse verte Company: Bigfoot Breweries - Product: Sasquatch Ale - Product: Steeleye Stout - Product: Laughing Lumberjack Lager
url='https://api.parliament.uk/Staging/odata/'
Service = ODataService(url, reflect_entities=True)
', '.join(sorted(list(Service.entities.keys())))
'AlternateMembership, Approval, ApprovedEPetition, Candidacy, CandidacyResult, Candidate, Concept, ConceptualisedThing, ConstituencyArea, ConstituencyGroup, ContactPoint, ContactableThing, Country, Debate, DeceasedPerson, DodsPerson, DodsThing, EPetition, Election, ElectionType, ElectoralIncumbency, Electorate, ExOfficioMembership, ExternalThing, FormalBody, FormalBodyMembership, Gender, GenderIdentity, GeographicalThing, GovRegisterCountry, GovRegisterTerritory, GovRegisterThing, GovernmentDepartment, GovernmentIncumbency, GovernmentPerson, GovernmentPosition, GovernmentResponse, House, HouseSeat, HouseSeatType, Image, ImageSubject, Incumbency, LocatedSignatureCount, Logo, LogoImage, Member, MemberImage, MnisConstituencyGroup, MnisContactPoint, MnisElectionType, MnisFormalBody, MnisFormalBodyMembership, MnisGender, MnisGovernmentDepartment, MnisGovernmentIncumbency, MnisGovernmentPosition, MnisHouseSeatType, MnisOppositionIncumbency, MnisOppositionPosition, MnisParty, MnisPartyMembership, MnisPerson, MnisSeatIncumbency, MnisThing, Moderation, NamedThing, OnsConstituencyGroup, OnsThing, OppositionIncumbency, OppositionPerson, OppositionPosition, ParliamentPeriod, ParliamentaryIncumbency, Party, PartyMember, PartyMembership, PastConstituencyGroup, PastFormalBody, PastFormalBodyMembership, PastIncumbency, PastParliamentPeriod, PastParliamentaryIncumbency, PastPartyMembership, PastThing, Person, PersonImage, PersonWebLink, PimsPerson, PimsThing, Place, Position, PostalAddress, RejectedEPetition, Rejection, RejectionCode, SeatIncumbency, SkosConcept, SubjectTaggedThing, TemporalThing, Territory, ThingWithLogo, Threshold, ThresholdAttainment, UkgapEPetition, UkgapThing, WebLink, WebLinkedThing, WikidataParliamentPeriod, WikidataThing'
def get_attributes(entity):
return [i for i in dir(entity) if not i.startswith('_')]
House = Service.entities['House']
get_attributes(House)
['HouseHasFormalBody', 'HouseHasHouseSeat', 'HouseName', 'Id']
query = Service.query(House)
query = query.limit(5)
for q in query:
print(q.HouseName)
House of Commons House of Lords
get_attributes(b)
['FormalBodyHasFormalBodyMembership', 'FormalBodyHasHouse', 'FormalBodyName', 'FormalBodyStartDate', 'Id']
query = Service.query(House)
query = query.limit(5)
for q in query:
print(q.HouseName,'\n')
for b in q.HouseHasFormalBody[:3]:
print(b.FormalBodyName)
print(b.FormalBodyStartDate)
print('\n')
House of Commons Culture, Media and Sport Committee 1997-07-28 00:00:00+00:00 Public Service 1995-01-01 00:00:00+00:00 Members' Expenses Committee 2011-07-18 00:00:00+00:00 House of Lords Procedure Committee (Lords) 1974-11-12 00:00:00+00:00 Relations between Central and Local Government, Committee on 1995-11-27 00:00:00+00:00 BBC Charter Review Committee 2005-03-01 00:00:00+00:00
Member = Service.entities['Member']
get_attributes(Member)
['ContactableThingHasContactPoint', 'Id', 'MemberHasAlternateMembership', 'MemberHasExOfficioMembership', 'MemberHasMemberImage', 'MemberHasParliamentaryIncumbency', 'PersonDateOfBirth', 'PersonFamilyName', 'PersonGivenName', 'PersonHasContactPoint', 'PersonHasFormalBodyMembership', 'PersonHasGenderIdentity', 'PersonHasPersonImage', 'PersonHasPersonWebLink', 'PersonOtherNames']
query = Service.query(Member)
query = query.limit(5)
for q in query:
print(q.PersonGivenName,q.PersonFamilyName )
for i in (q.MemberHasParliamentaryIncumbency):
print(i.ParliamentaryIncumbencyStartDate)
Dawn Primarolo 1987-06-11 00:00:00+00:00 2001-06-07 00:00:00+00:00 1997-05-01 00:00:00+00:00 2010-05-06 00:00:00+00:00 1992-04-09 00:00:00+00:00 2005-05-05 00:00:00+00:00 2015-10-26 00:00:00+00:00 Lyn Brown 2017-06-08 00:00:00+00:00 2015-05-07 00:00:00+00:00 2005-05-05 00:00:00+00:00 2010-05-06 00:00:00+00:00 Margaret Hodge 2015-05-07 00:00:00+00:00 2005-05-05 00:00:00+00:00 2001-06-07 00:00:00+00:00 1997-05-01 00:00:00+00:00 2010-05-06 00:00:00+00:00 1994-06-09 00:00:00+00:00 2017-06-08 00:00:00+00:00 Sandip Verma 2006-06-02 00:00:00+00:00 Jennifer Randerson 2011-01-27 00:00:00+00:00