Skip to content

Commit

Permalink
Introducing new endpoint for getting amendments.
Browse files Browse the repository at this point in the history
It appears either the contract from ProPublica either changed recently or it was just always documented incorrectly.  Amendments are not returned from the specific bill endpoint like subjects and related bills are.
  • Loading branch information
lafritay committed Aug 11, 2017
1 parent 2f0f4aa commit 474d895
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 36 deletions.
34 changes: 34 additions & 0 deletions ProPublicaCongressAPI.Contracts/Amendment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace ProPublicaCongressAPI.Contracts
{
public class Amendment
{
public string Number { get; set; }

public string Slug { get; set; }

public string SponsorTitle { get; set; }

public string Sponsor { get; set; }

public string SponsorId { get; set; }

public string SponsorUrl { get; set; }

public string SponsorParty { get; set; }

public string SponsorState { get; set; }

public DateTime DateIntroduced { get; set; }

public string Title { get; set; }

public DateTime DateLatestMajorAction { get; set; }

public string LatestMajorAction { get; set; }
}
}
18 changes: 18 additions & 0 deletions ProPublicaCongressAPI.Contracts/AmendmentsContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Newtonsoft.Json;
using System.Collections.Generic;

namespace ProPublicaCongressAPI.Contracts
{
public class AmendmentsContainer
{
public int Congress { get; set; }

public string BillId { get; set; }

public int NumberOfResults { get; set; }

public int Offset { get; set; }

public IReadOnlyCollection<Amendment> Amendments { get; set; }
}
}
1 change: 0 additions & 1 deletion ProPublicaCongressAPI.Contracts/SpecificBillDetail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public class SpecificBillDetail
public DateTime? DateHousePassageVote { get; set; }
public DateTime? DateSenatePassageVote { get; set; }
public IReadOnlyCollection<SpecificBillDetailSubject> Subjects { get; set; }
public IReadOnlyCollection<SpecificBillDetailAmendment> Amendments { get; set; }
public IReadOnlyCollection<SpecificBillDetailRelated> RelatedBills { get; set; }
}
}
1 change: 0 additions & 1 deletion ProPublicaCongressAPI.Contracts/SpecificBillDetailType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ public enum SpecificBillDetailType
{
Unknown,
Subjects,
Amendments,
Related
}
}
12 changes: 7 additions & 5 deletions ProPublicaCongressAPI/AutoMapperConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,6 @@ public static void Initialize()
.ForMember(dest => dest.DateLatestMajorAction,
opts => opts.ResolveUsing<DateTimeResolver, string>(s => s.DateLatestMajorAction));
x.CreateMap<InternalModels.SpecificBillDetailSubject, Contracts.SpecificBillDetailSubject>();
x.CreateMap<InternalModels.SpecificBillDetailAmendment, Contracts.SpecificBillDetailAmendment>()
.ForMember(dest => dest.DateIntroduced,
opts => opts.ResolveUsing<DateTimeResolver, string>(s => s.DateIntroduced))
.ForMember(dest => dest.DateLatestMajorAction,
opts => opts.ResolveUsing<DateTimeResolver, string>(s => s.DateLatestMajorAction));
x.CreateMap<InternalModels.SpecificBillDetail, Contracts.SpecificBillDetail>()
.ForMember(dest => dest.DateIntroduced,
opts => opts.ResolveUsing<DateTimeResolver, string>(s => s.DateIntroduced))
Expand All @@ -157,6 +152,13 @@ public static void Initialize()
.ForMember(dest => dest.DateSenatePassageVote,
opts => opts.ResolveUsing<NullableDateTimeResolver, string>(s => s.DateSenatePassageVote));
x.CreateMap<InternalModels.AmendmentsContainer, Contracts.AmendmentsContainer>();
x.CreateMap<InternalModels.Amendment, Contracts.Amendment>()
.ForMember(dest => dest.DateIntroduced,
opts => opts.ResolveUsing<DateTimeResolver, string>(s => s.DateIntroduced))
.ForMember(dest => dest.DateLatestMajorAction,
opts => opts.ResolveUsing<DateTimeResolver, string>(s => s.DateLatestMajorAction));
x.CreateMap<InternalModels.BillCosponsor, Contracts.BillCosponsor>()
.ForMember(dest => dest.DateCosponsored,
opts => opts.ResolveUsing<DateTimeResolver, string>(s => s.DateCosponsored));
Expand Down
1 change: 1 addition & 0 deletions ProPublicaCongressAPI/IProPublicaCongressApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public interface IProPublicaCongressApiClient
{
Task<MemberBillSponsorshipComparisonContainer> CompareMemberBillSponsorships(string firstMemberId, string secondMemberId, int congress, Chamber chamber);
Task<IReadOnlyCollection<MemberVoteComparison>> CompareMemberVotes(string firstMemberId, string secondMemberId, int congress, Chamber chamber);
Task<Contracts.AmendmentsContainer> GetAmendments(int congress, string billId, int? offset);
Task<BillCosponsorContainer> GetBillCosponsors(int congress, string billId);
Task<MemberBillsCosponsoredContainer> GetBillsCosponsoredByMember(string memberId, CosponsorBillType type);
Task<CommitteesContainer> GetCommitttees(int congress, Chamber chamber);
Expand Down
46 changes: 46 additions & 0 deletions ProPublicaCongressAPI/InternalModels/Amendment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace ProPublicaCongressAPI.InternalModels
{
internal class Amendment
{
[JsonProperty("amendment_number")]
public string Number { get; set; }

[JsonProperty("slug")]
public string Slug { get; set; }

[JsonProperty("sponsor_title")]
public string SponsorTitle { get; set; }

[JsonProperty("sponsor")]
public string Sponsor { get; set; }

[JsonProperty("sponsor_id")]
public string SponsorId { get; set; }

[JsonProperty("sponsor_uri")]
public string SponsorUrl { get; set; }

[JsonProperty("sponsor_party")]
public string SponsorParty { get; set; }

[JsonProperty("sponsor_state")]
public string SponsorState { get; set; }

[JsonProperty("introduced_date")]
public string DateIntroduced { get; set; }

[JsonProperty("title")]
public string Title { get; set; }

[JsonProperty("latest_major_action_date")]
public string DateLatestMajorAction { get; set; }

[JsonProperty("latest_major_action")]
public string LatestMajorAction { get; set; }
}
}
23 changes: 23 additions & 0 deletions ProPublicaCongressAPI/InternalModels/AmendmentsContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Newtonsoft.Json;
using System.Collections.Generic;

namespace ProPublicaCongressAPI.InternalModels
{
internal class AmendmentsContainer
{
[JsonProperty("congress")]
public int Congress { get; set; }

[JsonProperty("bill_id")]
public string BillId { get; set; }

[JsonProperty("num_results")]
public int NumberOfResults { get; set; }

[JsonProperty("offset")]
public int Offset { get; set; }

[JsonProperty("amendments")]
public IReadOnlyCollection<Amendment> Amendments { get; set; }
}
}
3 changes: 0 additions & 3 deletions ProPublicaCongressAPI/InternalModels/SpecificBillDetail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ internal class SpecificBillDetail
[JsonProperty("subjects")]
public IReadOnlyCollection<SpecificBillDetailSubject> Subjects { get; set; }

[JsonProperty("amendments")]
public IReadOnlyCollection<SpecificBillDetailAmendment> Amendments { get; set; }

[JsonProperty("related_bills")]
public IReadOnlyCollection<SpecificBillDetailRelated> RelatedBills { get; set; }
}
Expand Down

This file was deleted.

21 changes: 20 additions & 1 deletion ProPublicaCongressAPI/ProPublicaCongressApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public class ProPublicaCongressApiClient : IProPublicaCongressApiClient
private const string recentBillsUrl = "v1/{0}/{1}/bills/{2}.json"; // 0 = congress, 1 = chamber, 2 = bill-type
private const string recentBillsByMemberUrl = "v1/members/{0}/bills/{1}.json"; // 0 = member-id, 1 = bill-type
private const string specificBillUrl = "v1/{0}/bills/{1}.json"; // 0 = congress, 1 = bill-id
private const string specificBillDetailsUrl = "v1/{0}/bills/{1}/{2}.json"; // 0 = congress, 1 = details-type
private const string specificBillDetailsUrl = "v1/{0}/bills/{1}/{2}.json"; // 0 = congress, 1 = details-type, 2 = details-type
private const string amendmentsUrl = "v1/{0}/bills/{1}/amendments.json"; // 0 = congress, 1 = details-type
private const string billCosponsorsUrl = "v1/{0}/bills/{1}/cosponsors.json"; // 0 = congress, 1 = bill-id
private const string recentNominationsByTypeUrl = "v1/{0}/nominees/{1}.json"; // 0 = congress, 1 = nomination-type
private const string specificNominationUrl = "v1/{0}/nominees/{1}.json"; // 0 = congress, 1 = nominee-id
Expand Down Expand Up @@ -118,6 +119,24 @@ public ProPublicaCongressApiClient(string apiKey)
return contract;
}

public async Task<Contracts.AmendmentsContainer> GetAmendments(int congress, string billId, int? offset)
{
string url = apiBaseUrl + String.Format(amendmentsUrl, congress, billId);

// we can offset the results to page through them since this endpoint only returns 20 at a time
if (offset.HasValue && offset.Value > 0)
{
url += String.Format(offsetParameter, offset.Value);
}

var internalModel = await GetMultipleResultDataAsync<InternalModels.AmendmentsContainer>(url);
var contract = AutoMapperConfiguration.Mapper.Map<
InternalModels.AmendmentsContainer,
Contracts.AmendmentsContainer>(internalModel.Results.ElementAt(0));

return contract;
}

public async Task<Contracts.SpecificBillDetail> GetSpecificBillDetail(int congress, string billId, SpecificBillDetailType billDetailType)
{
string url = apiBaseUrl + String.Format(specificBillDetailsUrl, congress, billId, billDetailType.ToString().ToLower());
Expand Down

0 comments on commit 474d895

Please sign in to comment.