maxmind / minfraud-api-python

Python API for minFraud Score, Insights, and Factors
https://minfraud.readthedocs.org/
Apache License 2.0
27 stars 12 forks source link

How to get json instead of object easily? #26

Open prince-tanapong opened 6 years ago

prince-tanapong commented 6 years ago

I want to store response from our end, what is the easily way to do that? now the return data is objects

oschwald commented 6 years ago

Unfortunately, I don't think there is an easy way to do this currently.

prince-tanapong commented 6 years ago

No worries, I just override your Client class to return json body also.

vsalvino commented 7 months ago

This is would be very useful for serializing to logs or storing results in a database for further human review.

Normally I would use __dict__ in a pinch, but it looks like the classes are technically NamedTuples which are a bit more complicated to serialize.

antigenius commented 5 months ago

Leaving this here in case it helps someone in the future. The use case I'm trying to tackle is storing Insights responses from the client as JSON for analysis. It hasn't been tested in production and assumes that this test (where I got the test request from) would mimic what would be returned by the clients.

You can leverage the orjson library to correctly serialize a namedtuple. Further, it appears that types that aren't namedtupled do have __dict__.

from minfraud.models import Insights
import orjson

req = {
    "id": "b643d445-18b2-4b9d-bad4-c9c4366e402a",
    "disposition": {"action": "reject"},
    "ip_address": {"country": {"iso_code": "US"}},
    "credit_card": {
        "is_business": True,
        "is_prepaid": True,
        "brand": "Visa",
        "type": "debit",
    },
    "device": {"id": "b643d445-18b2-4b9d-bad4-c9c4366e402a"},
    "email": {"domain": {"first_seen": "2014-02-23"}, "is_free": True},
    "shipping_address": {"is_in_ip_country": True},
    "billing_address": {"is_in_ip_country": True},
    "funds_remaining": 10.01,
    "queries_remaining": 123,
    "risk_score": 0.01,
    "warnings": [{"code": "INVALID_INPUT"}],
}
insights = Insights(req)
insights = orjson.dumps(insights, default=lambda o: o._asdict() if hasattr(o, '_asdict') else o.__dict__)
print(insights.decode('utf-8'))
{
  "billing_address": {
    "distance_to_ip_location": null,
    "is_in_ip_country": true,
    "is_postal_in_city": null,
    "latitude": null,
    "longitude": null
  },
  "credit_card": {
    "brand": "Visa",
    "country": null,
    "is_business": true,
    "is_issued_in_billing_address_country": null,
    "is_prepaid": true,
    "is_virtual": null,
    "issuer": {
      "matches_provided_name": null,
      "matches_provided_phone_number": null,
      "name": null,
      "phone_number": null
    },
    "type": "debit"
  },
  "device": {
    "confidence": null,
    "id": "b643d445-18b2-4b9d-bad4-c9c4366e402a",
    "last_seen": null,
    "local_time": null
  },
  "disposition": {
    "action": "reject",
    "reason": null,
    "rule_label": null
  },
  "email": {
    "domain": {
      "first_seen": "2014-02-23"
    },
    "first_seen": null,
    "is_disposable": null,
    "is_free": true,
    "is_high_risk": null
  },
  "funds_remaining": 10.01,
  "id": "b643d445-18b2-4b9d-bad4-c9c4366e402a",
  "ip_address": {
    "_locales": [
      "en"
    ],
    "continent": {
      "code": null,
      "geoname_id": null,
      "_locales": [
        "en"
      ],
      "names": {}
    },
    "country": {
      "is_high_risk": false,
      "confidence": null,
      "geoname_id": null,
      "is_in_european_union": false,
      "iso_code": "US",
      "_locales": [
        "en"
      ],
      "names": {}
    },
    "registered_country": {
      "confidence": null,
      "geoname_id": null,
      "is_in_european_union": false,
      "iso_code": null,
      "_locales": [
        "en"
      ],
      "names": {}
    },
    "represented_country": {
      "type": null,
      "confidence": null,
      "geoname_id": null,
      "is_in_european_union": false,
      "iso_code": null,
      "_locales": [
        "en"
      ],
      "names": {}
    },
    "maxmind": {
      "queries_remaining": null
    },
    "traits": {
      "autonomous_system_number": null,
      "autonomous_system_organization": null,
      "connection_type": null,
      "domain": null,
      "is_anonymous": false,
      "is_anonymous_proxy": false,
      "is_anonymous_vpn": false,
      "is_anycast": false,
      "is_hosting_provider": false,
      "is_legitimate_proxy": false,
      "is_public_proxy": false,
      "is_residential_proxy": false,
      "is_satellite_provider": false,
      "is_tor_exit_node": false,
      "isp": null,
      "mobile_country_code": null,
      "mobile_network_code": null,
      "organization": null,
      "static_ip_score": null,
      "user_type": null,
      "user_count": null,
      "ip_address": null,
      "_network": null,
      "_prefix_len": null
    },
    "raw": {
      "country": {
        "iso_code": "US"
      }
    },
    "city": {
      "confidence": null,
      "geoname_id": null,
      "_locales": [
        "en"
      ],
      "names": {}
    },
    "location": {
      "local_time": null,
      "average_income": null,
      "accuracy_radius": null,
      "latitude": null,
      "longitude": null,
      "metro_code": null,
      "population_density": null,
      "time_zone": null
    },
    "postal": {
      "code": null,
      "confidence": null
    },
    "subdivisions": {
      "_locales": null
    },
    "risk": null,
    "risk_reasons": [],
    "_finalized": true
  },
  "queries_remaining": 123,
  "risk_score": 0.01,
  "shipping_address": {
    "distance_to_billing_address": null,
    "distance_to_ip_location": null,
    "is_high_risk": null,
    "is_in_ip_country": true,
    "is_postal_in_city": null,
    "latitude": null,
    "longitude": null
  },
  "warnings": [
    {
      "code": "INVALID_INPUT",
      "input_pointer": null,
      "warning": null
    }
  ]
}

EDIT Included JSON string.