Skip to content

Commit 4cca4b5

Browse files
author
cris_gk
committed
Merge branch 'master' into 393-foster-import
2 parents e9273ce + 5c224e1 commit 4cca4b5

File tree

17 files changed

+607
-150
lines changed

17 files changed

+607
-150
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ start_env.sh
2222
/src/server/local_files/
2323
.mypy_cache/
2424
*secrets*
25-
*kustomization*
25+
*kustomization*

src/client/src/pages/DataView360/View/View360.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,14 @@ class View360 extends Component {
6868
});
6969
response = await response.json();
7070

71-
let shelterluvInfo = await fetch(`/api/person/${this.state.matchId}/animals`);
71+
let shelterluvInfo = await fetch(`/api/person/${this.state.matchId}/animals`,
72+
{
73+
method: 'GET',
74+
headers: {
75+
'Content-Type': 'application/json',
76+
'Authorization': 'Bearer ' + this.props.access_token
77+
}
78+
});
7279
shelterluvInfo = await shelterluvInfo.json()
7380
const shelterluvShortId = shelterluvInfo["person_details"]["shelterluv_short_id"]
7481
let animalInfo = shelterluvInfo["animal_details"]
@@ -89,7 +96,14 @@ class View360 extends Component {
8996
});
9097
}
9198

92-
let supportOverviewData = await fetch(`/api/person/${this.state.matchId}/support`);
99+
let supportOverviewData = await fetch(`/api/person/${this.state.matchId}/support`,
100+
{
101+
method: 'GET',
102+
headers: {
103+
'Content-Type': 'application/json',
104+
'Authorization': 'Bearer ' + this.props.access_token
105+
}
106+
});
93107
supportOverviewData = await supportOverviewData.json()
94108

95109
this.setState({
@@ -104,7 +118,14 @@ class View360 extends Component {
104118
}
105119

106120
async getAnimalEvents(animalId, matchId) {
107-
let response = await fetch(`/api/person/${matchId}/animal/${animalId}/events`);
121+
let response = await fetch(`/api/person/${matchId}/animal/${animalId}/events`,
122+
{
123+
method: 'GET',
124+
headers: {
125+
'Content-Type': 'application/json',
126+
'Authorization': 'Bearer ' + this.props.access_token
127+
}
128+
});
108129
return await response.json()
109130
}
110131

src/helm-chart/templates/deployment.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ spec:
88
{{- if not .Values.autoscaling.enabled }}
99
replicas: {{ .Values.replicaCount }}
1010
{{- end }}
11+
strategy:
12+
type: Recreate
1113
selector:
1214
matchLabels:
1315
{{- include "helm-chart.selectorLabels" . | nindent 6 }}

src/server/alembic/versions/783cabf889d9_inital_schema_setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
Create Date: 2020-12-16 01:47:43.686881
66
77
"""
8+
from sqlalchemy.sql.expression import null
89
from alembic import op
910
import sqlalchemy as sa
1011

1112

13+
1214
# revision identifiers, used by Alembic.
1315
revision = '783cabf889d9'
1416
down_revision = None
@@ -33,6 +35,5 @@ def upgrade():
3335
sa.Column('created', sa.DateTime,nullable=False, server_default='now()')
3436
)
3537

36-
3738
def downgrade():
3839
pass
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""Merges heads '8f4, '28b
2+
3+
Revision ID: fc7325372396
4+
Revises: a3ba63dee8f4, fd187937528b
5+
Create Date: 2022-01-17 22:05:05.824901
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = 'fc7325372396'
14+
down_revision = ('a3ba63dee8f4', 'fd187937528b')
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
pass
21+
22+
23+
def downgrade():
24+
pass
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""create pdp_contacts table
2+
3+
Revision ID: fd187937528b
4+
Revises: 57b547e9b464
5+
Create Date: 2021-08-10 20:16:54.169168
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
from sqlalchemy.dialects.postgresql import JSONB
11+
import datetime
12+
13+
# revision identifiers, used by Alembic.
14+
revision = 'fd187937528b'
15+
down_revision = '57b547e9b464'
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
22+
op.create_table('pdp_contacts',
23+
sa.Column('_id', sa.Integer, primary_key=True, autoincrement=True),
24+
sa.Column('matching_id', sa.Integer, primary_key=True),
25+
sa.Column('source_type', sa.String, nullable=False),
26+
sa.Column('source_id', sa.String, nullable=False),
27+
sa.Column('is_organization', sa.Boolean),
28+
sa.Column('first_name', sa.String),
29+
sa.Column('last_name', sa.String),
30+
sa.Column('email', sa.String),
31+
sa.Column('mobile', sa.String),
32+
sa.Column('street_and_number', sa.String),
33+
sa.Column('apartment', sa.String),
34+
sa.Column('city', sa.String),
35+
sa.Column('state', sa.String),
36+
sa.Column('zip', sa.String),
37+
sa.Column('json', JSONB),
38+
sa.Column('created_date', sa.DateTime, default=datetime.datetime.utcnow),
39+
sa.Column('archived_date', sa.DateTime, default=None)
40+
)
41+
42+
def downgrade():
43+
44+
op.drop_table("pdp_contacts")
45+
op.drop_table("pdp_contact_types")

src/server/api/common_api.py

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,22 @@
66
import time
77
from datetime import datetime
88

9+
from api.fake_data import sl_mock_data
10+
911
try:
1012
from secrets_dict import SHELTERLUV_SECRET_TOKEN
1113
except ImportError:
1214
# Not running locally
1315
print("Couldn't get SHELTERLUV_SECRET_TOKEN from file, trying environment **********")
14-
from os import environ
15-
16-
try:
17-
SHELTERLUV_SECRET_TOKEN = environ['SHELTERLUV_SECRET_TOKEN']
18-
except KeyError:
19-
# Nor in environment
20-
# You're SOL for now
21-
print("Couldn't get secrets from file or environment")
22-
16+
from os import getenv
2317

18+
SHELTERLUV_SECRET_TOKEN = getenv('SHELTERLUV_SECRET_TOKEN')
19+
if not SHELTERLUV_SECRET_TOKEN:
20+
print("Couldn't get secrets from file or environment",
21+
"Defaulting to Fake Data")
2422

2523
from api import jwt_ops
2624

27-
2825
@common_api.route('/api/timeout_test/<duration>', methods=['GET'])
2926
def get_timeout(duration):
3027
start = datetime.now().strftime("%H:%M:%S");
@@ -178,14 +175,17 @@ def get_360(matching_id):
178175

179176
return jsonify({'result': result})
180177

181-
182178
@common_api.route('/api/person/<matching_id>/animals', methods=['GET'])
179+
@jwt_ops.jwt_required()
183180
def get_animals(matching_id):
184181
result = {
185182
"person_details": {},
186183
"animal_details": {}
187184
}
188185

186+
if not SHELTERLUV_SECRET_TOKEN:
187+
return jsonify(sl_mock_data('animals'))
188+
189189
with engine.connect() as connection:
190190
query = text("select * from pdp_contacts where matching_id = :matching_id and source_type = 'shelterluvpeople' and archived_date is null")
191191
query_result = connection.execute(query, matching_id=matching_id)
@@ -206,19 +206,15 @@ def get_animals(matching_id):
206206
return result
207207

208208

209-
@common_api.route('/api/animal/<animal_id>/events', methods=['GET'])
210-
def get_animal_events(animal_id):
211-
result = {}
212-
animal_url = f"http://shelterluv.com/api/v1/animals/{animal_id}/events"
213-
event_details = requests.get(animal_url, headers={"x-api-key": SHELTERLUV_SECRET_TOKEN}).json()
214-
result[animal_id] = event_details["events"]
215-
return result
216-
217-
218209
@common_api.route('/api/person/<matching_id>/animal/<animal_id>/events', methods=['GET'])
210+
@jwt_ops.jwt_required()
219211
def get_person_animal_events(matching_id, animal_id):
220212
result = {}
221213
events = []
214+
215+
if not SHELTERLUV_SECRET_TOKEN:
216+
return jsonify(sl_mock_data('events'))
217+
222218
with engine.connect() as connection:
223219
query = text("select * from pdp_contacts where matching_id = :matching_id and source_type = 'shelterluvpeople' and archived_date is null")
224220
query_result = connection.execute(query, matching_id=matching_id)
@@ -237,6 +233,7 @@ def get_person_animal_events(matching_id, animal_id):
237233
return result
238234

239235
@common_api.route('/api/person/<matching_id>/support', methods=['GET'])
236+
@jwt_ops.jwt_required()
240237
def get_support_oview(matching_id):
241238
"""Return these values for the specified match_id:
242239
largest gift, date for first donation, total giving, number of gifts,
@@ -385,3 +382,31 @@ def get_support_oview(matching_id):
385382
current_app.logger.debug('No SF contact IDs found for matching_id ' + str(matching_id))
386383
oview_fields['number_of_gifts'] = 0 # Marker for no data
387384
return jsonify(oview_fields)
385+
386+
387+
@common_api.route('/api/last_analysis', methods=['GET'])
388+
@jwt_ops.jwt_required()
389+
def get_last_analysis():
390+
""" Return the UTC string (e.g., '2021-12-11T02:29:14.830371') representing
391+
when the last analysis run succesfully completed.
392+
Returns an empty string if no results.
393+
"""
394+
395+
last_run = ''
396+
397+
last_stamp = """
398+
select update_stamp
399+
from execution_status
400+
where stage = 'flow' and status = 'complete'
401+
order by update_stamp desc
402+
limit 1;
403+
"""
404+
405+
with engine.connect() as connection:
406+
result = connection.execute(last_stamp)
407+
if result.rowcount:
408+
row = result.fetchone()
409+
last_run_dt = row[0] # We get as a datetime object
410+
last_run = last_run_dt.isoformat()
411+
412+
return last_run

src/server/api/fake_data.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
""" Fake data that can be returned when an API token is missing for local
2+
development, or for running pytest
3+
4+
Shelterluv Data contains:
5+
Matched: Animal & Event End point
6+
"""
7+
8+
shelterluv_data = {
9+
'animals': {
10+
"animal_details": {
11+
'12345': {
12+
"Age": 24,
13+
"DOBUnixTime": 1568480456,
14+
"Name": "Lola aka Fake Cat",
15+
"Type": "Cat",
16+
"Photos":
17+
["https://images.unsplash.com/photo-1456926631375-92c8ce872def?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8OHx8YW5pbWFsfGVufDB8fDB8fA%3D%3D&w=1000&q=80"],
18+
"Status": "Healthy In Home",
19+
},
20+
},
21+
"person_details": {
22+
"shelterluv_short_id": 2,
23+
},
24+
},
25+
'events': {
26+
'12345':[
27+
{
28+
'AssociatedRecords': [
29+
{'Id': 12345, 'Type': 'Animal' },
30+
{'Id': 12345, 'Type': 'Person'},
31+
],
32+
'Subtype': 'Foster Home',
33+
'Time': '1602694822',
34+
'Type': 'Outcome.Adoption',
35+
'User': 'Fake User',
36+
},
37+
]
38+
},
39+
}
40+
41+
42+
def sl_mock_data(end_point: str)-> dict:
43+
""" Shelterluv mock data.
44+
Takes the end_point as a str of `animals` or `events` and returns
45+
a dict representing a test data for that end_point.
46+
"""
47+
48+
return shelterluv_data.get(end_point)

src/server/bin/export_secrets.sh

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
set -o allexport
2-
while read k _ v;
3-
do
4-
eval $k=$v;
5-
export k;
6-
done < 'secrets_dict.py'
7-
set +o allexport
2+
source secrets_dict.py
3+
set +o allexport

src/server/config.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@
3131

3232
engine = db.create_engine(DB)
3333

34-
with engine.connect() as connection:
35-
models.Base.metadata.create_all(connection)
36-
# This is safe: by default, will check first to ensure tables don't already exist
37-
3834
# Run Alembic to create managed tables
3935
# from alembic.config import Config
4036
# from alembic import command

0 commit comments

Comments
 (0)