Exception handling
You may want to consider reducing the try block to where the expected exception actually is raised.
try:
app = App.objects.get(id=app_id)
except App.DoesNotExist:
…
Possible bugs
This test does not consider the case, that only one of addr and secret is None. Is that permitted?
if addr is None and secret is None:
…
These response dicts are never used:
if wallet.pk is None and wallet.pk > 0:
response = {'status': 'OK', 'data': 'success'}
else:
response = {'status': 'FAIL', 'data': 'Messed up'}
Deduplication
Regarding your concern of duplicated dicts: I see none. Sure, they are similar, but there are notno duplicates, since the error messages differ. Of course, you can outsource the generation to a function like
def make_response(data: str, success: bool) -> dict:
"""Returns a response dict."""
return {'status': 'OK' if success else 'FAIL', 'data': data}
but it's up to you to decide if that's worth an extra function.