Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get next election from state #15

Merged
merged 8 commits into from
Jun 12, 2021
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vscode/
**/.ipynb_checkpoints/
6 changes: 5 additions & 1 deletion api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ boto3>=1.17.72
requests>=2.22.0
werkzeug<2.0.0
# werkzeug>=2.0.0
pytest>=6.2.4
pytest>=6.2.4
requests>=2.25.1
beautifulsoup4>=4.9.3
pandas>=1.2.4
lxml>=4.6.3
2 changes: 1 addition & 1 deletion api/src/candidate.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from src import app
from flask import jsonify, request

@app.route('/getCandidatesFromElection', methods['GET', 'POST'])
@app.route('/getCandidatesFromElection', methods=['GET', 'POST'])
def getCandidatesFromElection():
# TODO: Implement the function
return jsonify({'error':'Function not implemented'})
Expand Down
2 changes: 1 addition & 1 deletion api/src/constituency.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def getConstituencyFromVoterId():
voter_id = request.json.get('voter_id') if request.method == 'POST' else request.args.get('voter_id')
if not voter_id:
return jsonify({'error':"request body must contain the field 'voter_id'"}), 400
elif not isinstance(lat, str):
elif not isinstance(voter_id, str):
return jsonify({'error':"field 'voter_id' must be of type str"}), 400

# TODO: Implement the function
Expand Down
86 changes: 81 additions & 5 deletions api/src/election.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,88 @@
from datetime import date
import traceback
from typing import Tuple

from werkzeug.exceptions import FailedDependency, Gone
from src import app
from flask import jsonify, request
import requests
import pandas as pd

@app.route('/getElectionsFromConstituency', methods['GET', 'POST'])
@app.route('/getElectionsFromConstituency', methods=['GET', 'POST'])
def getElectionsFromConstituency():
# TODO: Implement the function
# TODO: Implement the function
return jsonify({'error':'Function not implemented'})

@app.route('/getElectionsFromPartNo', methods['GET', 'POST'])
@app.route('/getElectionsFromPartNo', methods=['GET', 'POST'])
def getElectionsFromPartNo():
# TODO: Implement the function
return jsonify({'error':'Function not implemented'})
# TODO: Implement the function
return jsonify({'error':'Function not implemented'})

@app.route('/getElectionsFromState', methods=['GET', 'POST'])
def getElectionsFromState():
state_elections, exp = __getNextElectionForState(request.args.get('state', '', type=str))
if exp != None:
app.logger.error(''.join(traceback.format_exception(type(exp), exp, exp.__traceback__)))
return jsonify({'exception':exp.description}), exp.code
return jsonify(state_elections)

@app.route('/getAllFutureElections', methods=['GET'])
def getAllFutureElections():
r = requests.get('https://eci.gov.in/elections/future-elections/')
print("getAllFutureElections", r.status_code)
if r.status_code == 200:
table_val = __getTableInformationFromHTML(r.text)
data = [table.to_dict(orient='records') for table in table_val]
return jsonify(data)
else:
return jsonify({'error':'Could not reach Election Commission of India\'s website'})

def __getTableInformationFromHTML(html_text: str):
all_data = []
tables = pd.read_html(html_text)
for table in tables:
if len(table) > 0:
all_data.append(table)
return all_data

def __getNextElectionForState(stateName: str) -> Tuple[object, Exception]:
try:
r = requests.get('https://eci.gov.in/elections/term-of-houses/')
print("__getNextElectionForState", r.status_code)
if r.status_code != 200:
raise Gone("Failed to get Term-of-houses from ECI website", r.raw)
except Exception as e:
return None, e

next_elections = []
terms_of_houses = __getTableInformationFromHTML(r.text)
union_elections_terms = terms_of_houses[0]
state_elections_terms = terms_of_houses[1]

# extract the date for next lok sabha elections
try:
lok_sabha_elections = union_elections_terms[(union_elections_terms['OFFICE/STATE'] == "LOK SABHA") & (union_elections_terms['TO'].str.contains('^\d+\.\d+\.\d+$'))]
if lok_sabha_elections.shape[0] != 1:
# there should be only one end-date for lok sabha elections
raise FailedDependency("Found "+ str(lok_sabha_elections.shape[0]) +" end-dates for the term of lok sabha on ECI website")
except Exception as e:
return None, e
next_elections.append(lok_sabha_elections.to_dict(orient='records')[0])

# extract the date for next state elections
try:
state_elections = state_elections_terms[(state_elections_terms['HOUSE/STATE'] == stateName.upper()) & (state_elections_terms['TO'].str.contains('^\d+\.\d+\.\d+$'))]
if state_elections.shape[0] != 1:
# there should be only one end-date for any state's elections
raise FailedDependency("Found "+ str(state_elections.shape[0]) +" end-dates for the term of " + stateName.upper() + " State on ECI website")
except Exception as e:
return None, e
next_elections.append(state_elections.to_dict(orient='records')[0])

next_elections.sort(key=lambda df: __getDateFromDateString(df['TO']))

return next_elections, None

def __getDateFromDateString(date_string: str) -> date:
day, month, year = [int(k) for k in date_string.split('.')]
return date(year, month, day)
Loading