FDA Recalls Application
Overview
Food Recalls
A review of the U.S. Food and Drug Administration’s safety site shows that since the beginning of 2015, product recalls, withdrawals and safety alerts are almost a daily occurrence in America. With the frequency of recalls increasing every year, consumers need more transparency when it comes to recalls. By placing recall data on an immutable ledger such as Algorand, an environment of accountability and transparency is created for consumers, the FDA, and businesses.
By encoding the FDA’s API results in a transaction notefield using Python, we are able to successfully store critical pieces of information such as the UPC codes for recalled consumer drug products. After the recall data is encoded and stored on Algorand, a specific prefix is used to index the recall information.
This application focuses on the dates of 12/01/20 to 12/02/20 for food recalls specifically; the prefix ‘FDAF’ is used for the indexer portion. This application can encompass other date timelines and incorporate food, drug, or medical device recalls.
Requirements
- Python 3.0 or above
- Python Algorand SDK module
- Python requests module
- Dockerized Algorand sandbox environment
Additional Resources of Use
- Link to Algorand Python SDK
- Link to Python Requests Module Installation
- Link to Read and Write to the Transaction Note Field with Python Algorand Tutorial
- Link to Indexer Algorand Documentation Note Field Searching
- Link to Developer Office Hours, How to set up your Algorand Sandbox Environment
- Link to Algorand Sandbox
Steps
Step 0
- Get the code:
$ git clone https://github.com/huntpie/FDA_Recalls_App
$ cd FDA_Recalls_App`
Step 1
- Install
algosdk
module:$ pip install py-algorand-sdk
- Install
requests
module:$ pip install requests
Step 2
- Locate
parse_into_json()
function fromMain.py
file - Set
date1
to desired year, month and date as follows YYYYMMDD - Set
date2
to a later date with same format, YYYYMMDD - Set
recall_type
to either"food"
,"drug"
or"device"
def parse_into_json():
# dates (YYYYMMDD) and recall type(food, device, drug)
date1 = 20201201
date2 = 20201202
recall_type = "food"
Step 3
- Load Dockerized sandbox environment
- Run
$ ./sandbox up
in the command line of your terminal within your installed sandbox folder - Once sandbox nightly is loaded, find the three listed private accounts or simply run command
$ ./sandbox goal account list
in the terminal
- Copy the first account address, which will resemble a 58 character address like
VAJPCCDYERNMNJC6VDLAR5FCDD3OCFRBRETRTOBIG3YTBCMUG4JZXQ7J3U
- Run command
$ ./sandbox goal account export -a <paste 58 character address here>
- After running the
$ ./sandbox goal account export -a <paste 58 character address here>
command, copy the 25 word passphrase/key for the first account
Step 4
- Locate
send_note()
function fromMain.py
file
def send_note():
algod_address = "http://localhost:4001"
algod_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
algod_client = algod.AlgodClient(algod_token, algod_address)
passphrase = ""
private_key = mnemonic.to_private_key(passphrase)
my_address = mnemonic.to_public_key(passphrase)
print(f'My address: {my_address}')
params = algod_client.suggested_params()
# comment out the next two (2) lines to use suggested fees
params.flat_fee = True
params.fee = 1000
json_note = parse_into_json()
note = json_note.encode()
receiver = ""
- Set
passphrase = "<paste 25 word passphrase/ key here>"
- Go back to sandbox account list and copy the second or third 58 character account address,
- Set
receiver = "<second or third account address from sandbox account list here>"
Step 5
- Return to
parse_into_json()
function fromMain.py
file - Make a debugger break for line 69 which contains
parse_final_value = int(url_Number) - 1
# find number of results with index starting at 0
parse_final_value = int(url_Number) - 1
- Debug to find
url_Number
value
- Scroll down to
results_location
and set this value equal to0
or any number less than or equal toint(url_Number) - 1
# Add prefix FDAF to specified set of results, 0 to parse_final_value
results_location = 0
result = results_only[results_location]
json_note = json.dumps(result)
json_note = "FDAF" + json_note
return json_note
- Based on what
recall_type
is set in Step 2, change prefix from"FDAF"
, which represents FDA Food Recalls, to a prefix suited for the other recall types such as"FDADR"
for drug recalls or"FDADE"
for medical devices recalls
json_note = "<prefix here>" + json_note`
Step 6
- Run
Main.py
file - Verify transaction is sent by seeing the decoded note in the terminal
- If more transactions are to be sent, simply change the
results_location
value inparse_into_json()
to another number equal to or less thanint(url_Number) - 1
and runMain.py
file again
# Add prefix FDAF to specified set of results, 0 to parse_final_value
results_location = 10
result = results_only[results_location]
json_note = json.dumps(result)
json_note = "FDAF" + json_note
return json_note
Step 7
- Locate
Indexer.py
file - Referring to the prefix set in Step 5, change
note_prefix = 'FDAF'.encode()
tonote_prefix = '<your prefix>'.encode()
- Run
Indexer.py
file
import base64
import json
from algosdk.v2client import indexer
myindexer = indexer.IndexerClient(
indexer_token="", indexer_address="http://localhost:8980")
note_prefix = 'FDAF'.encode()
response = myindexer.search_transactions(note_prefix=note_prefix)
print("note_prefix = " + json.dumps(response, indent=2, sort_keys=True))
Final Step
- Indexer should now have successfully indexed all sent transactions with a notefield encoded with
'<your prefix>'
and the FDA recall data
Video Overview
Conclusion/ Future Improvements
Please contribute your ideas about this application on GitHub or reach out to me on the Dev Forums with any questions or about working with Algorand. My goal for this application is to bring more transparency for FDA recalls. Some improvement ideas are listed as follows:
- FDA could send transaction with data encoded in notefield to an FDA receiver account
- Build front-end interface for customers to create an Algorand account and scan receipts looking for recalls
- Customer locates recall item and scans/inputs UPC(or UDI for Medical Recalls)
- Indexer finds customer’s recall item and confirms customer’s recall item is Ongoing
- Customer’s recall item’s UPC/UDI code is verified through third-party oracle
- Companies can send refund transactions with a notefield containing the recall item and it’s UPC/UDI code
- Companies can track all their recalls on Algorand’s blockchain
- Companies could also track recall refunds using their own indexer