New Pricing Disaster

Knowing when to write your own Python API to extend a Bubble app, for me that usually comes down to when doing compute heavy actions… Bubble’s greatest value proposition is “display stuff in a browser”… it’s not very good at “compute many things” to display in browser. For example, the cost calculator for one of my plugins is powered by a Python endpoint… could I have done that in Bubble? Probably. Is it way easier in Python - yes! Expand the hidden code below and think about how to do it in native Bubble… I probably could have baked this into an Expression element using javascript but… because I already have a Python API setup, just adding this endpoint was easy enough. Beyond that, if trying to fetch data from other APIs/was a longer running process, like I was here, then that’s even more reason to try to do it in Python.

Cost Calculator Endpoint Code
@app.get("/api/v1/get_search_provider_pricing")
def compute_search_provider_costs(
    search_provider: str = "algolia",
    average_record_kb: float = 0.6,
    number_of_records: int = 50000,
    monthly_searches: int = 50000,
    regions: int = 1,
    is_new_algolia_plan: bool = True,
):
    def select_typesense_cluster_base_cost(
        number_of_records=50000, average_record_kb=0.6, regions=1
    ):
        region_cluster_pricing = {
            1: {0.5: 14.40, 1: 21.60, 2: 36, 4: 64.80, 8: 122.40, 16: 180},
            3: {0.5: 64.80, 1: 86.40, 2: 129.60, 4: 216.00, 8: 432.00, 16: 669.60},
            5: {0.5: 108, 1: 144, 2: 252, 4: 432.00, 8: 828.00, 16: 1260},
        }
        cluster_pricing = region_cluster_pricing[regions]
        cluster_gb = average_record_kb * number_of_records / 1000000
        minimum_cluster_gb = cluster_gb * 2
        recommended_minimum_cluster_gb = [
            key for key in cluster_pricing.keys() if key > minimum_cluster_gb
        ][0]
        base_monthly_price = cluster_pricing[recommended_minimum_cluster_gb]
        return recommended_minimum_cluster_gb, base_monthly_price

    if search_provider == "algolia":
        if is_new_algolia_plan:
            if number_of_records <= 100000:
                cost_number_of_records = 0
            else:
                cost_number_of_records = (number_of_records - 100000) / 1000 * 0.4
            if monthly_searches <= 10000:
                cost_monthly_searches = 0
            else:
                cost_monthly_searches = (monthly_searches - 10000) / 1000 * 0.5
            cost = cost_monthly_searches + cost_number_of_records
        else:
            if number_of_records <= 10000:
                cost_number_of_records = 0
            else:
                cost_number_of_records = (number_of_records - 10000) / 1000 * 1.0
            if monthly_searches <= 10000:
                cost_monthly_searches = 0
            else:
                cost_monthly_searches = (monthly_searches - 10000) / 1000 * 1.0
            cost = cost_monthly_searches + cost_number_of_records
    elif search_provider == "typesense":
        recommended_minimum_cluster_gb, base_monthly_price = (
            select_typesense_cluster_base_cost(
                number_of_records=number_of_records,
                average_record_kb=average_record_kb,
                regions=regions,
            )
        )
        # works out to 720MB per day per node across a month multiplied by regions and 0.09 GB
        bandwidth_out_cost_base = 0.720 * 30.44 * regions * 0.09
        bandwidth_out_cost_searches = (
            monthly_searches * average_record_kb * 100 / 1000000 * 0.09
        )
        cost = (
            base_monthly_price + bandwidth_out_cost_base + bandwidth_out_cost_searches
        )
    return {"cost": cost}
2 Likes