MoreRSS

site iconThe Practical DeveloperModify

A constructive and inclusive social network for software developers.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of The Practical Developer

AI Tools That Actually Pay You Back: A Developer's Guide to Monetizing AI

2026-03-30 07:12:16

AI Tools That Actually Pay You Back: A Developer's Guide to Monetizing AI

=====================================================================================

As a developer, you're likely no stranger to the world of artificial intelligence (AI) and its many applications. From chatbots to predictive analytics, AI has become an integral part of modern software development. But did you know that there are AI tools that can actually pay you back? In this article, we'll explore some of the most promising AI tools that can help you monetize your skills and earn a return on investment.

Introduction to AI Monetization

Before we dive into the tools themselves, let's talk about the concept of AI monetization. AI monetization refers to the process of using AI to generate revenue, either directly or indirectly. This can be achieved through a variety of means, including:

  • Building and selling AI-powered products or services
  • Offering AI-related consulting or training services
  • Creating and licensing AI-powered intellectual property
  • Participating in AI-related affiliate programs or partnerships

Tool 1: Google Cloud AI Platform

The Google Cloud AI Platform is a powerful tool that allows developers to build, deploy, and manage AI models at scale. With the AI Platform, you can create custom machine learning models using popular frameworks like TensorFlow and scikit-learn, and then deploy them to a cloud-based infrastructure.

To get started with the AI Platform, you'll need to create a Google Cloud account and install the Google Cloud SDK. From there, you can use the following code example to deploy a simple machine learning model:

import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from google.cloud import aiplatform

# Load the dataset
df = pd.read_csv('data.csv')

# Split the data into training and testing sets
train_df, test_df = df.split(test_size=0.2, random_state=42)

# Create a random forest classifier
clf = RandomForestClassifier(n_estimators=100)

# Train the model
clf.fit(train_df.drop('target', axis=1), train_df['target'])

# Deploy the model to the AI Platform
ai_platform = aiplatform.Model(
    display_name='My Model',
    description='A simple random forest classifier'
)
ai_platform.deploy(clf, 'gs://my-bucket/model.pkl')

With the AI Platform, you can monetize your AI models by offering them as a service to customers, or by using them to build and sell AI-powered products.

Tool 2: Amazon SageMaker

Amazon SageMaker is another popular AI tool that allows developers to build, train, and deploy machine learning models. With SageMaker, you can create custom models using popular frameworks like TensorFlow and PyTorch, and then deploy them to a cloud-based infrastructure.

To get started with SageMaker, you'll need to create an AWS account and install the AWS SDK. From there, you can use the following code example to deploy a simple machine learning model:


python
import pandas as pd
import torch
import torch.nn as nn
from sagemaker.pytorch import PyTorch

# Load the dataset
df = pd.read_csv('data.csv')

# Split the data into training and testing sets
train_df, test_df = df.split(test_size=0.2, random_state=42)

# Create a simple neural network
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(784, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# Train the model
model = Net()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
for epoch in range

Grafana k6 Has a Free API That Load Tests Your APIs With JavaScript

2026-03-30 07:11:51

k6 is a load testing tool that uses JavaScript for test scripts. Run locally, in CI/CD, or in the cloud. Write tests like you write code — not XML configs.

Quick Start

# Install
brew install k6           # macOS
sudo apt install k6       # Ubuntu

# Run a test
k6 run script.js

Basic Load Test

import http from 'k6/http'
import { check, sleep } from 'k6'

export const options = {
  vus: 50,             // 50 virtual users
  duration: '30s',     // for 30 seconds
}

export default function () {
  const res = http.get('https://api.example.com/posts')

  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
  })

  sleep(1)
}

Ramping (Realistic Traffic Patterns)

export const options = {
  stages: [
    { duration: '2m', target: 100 },   // ramp up to 100 users
    { duration: '5m', target: 100 },   // stay at 100
    { duration: '2m', target: 200 },   // spike to 200
    { duration: '5m', target: 200 },   // stay at 200
    { duration: '2m', target: 0 },     // ramp down
  ],
}

Thresholds (Pass/Fail Criteria)

export const options = {
  thresholds: {
    http_req_duration: ['p(95)<500'],      // 95% of requests < 500ms
    http_req_failed: ['rate<0.01'],        // <1% error rate
    'http_req_duration{status:200}': ['p(99)<1000'],
  },
}

Use in CI/CD: k6 exits with non-zero if thresholds fail.

API Testing

import http from 'k6/http'
import { check } from 'k6'

export default function () {
  // POST with JSON
  const payload = JSON.stringify({ name: 'test', email: '[email protected]' })
  const params = { headers: { 'Content-Type': 'application/json' } }

  const res = http.post('https://api.example.com/users', payload, params)

  check(res, {
    'created': (r) => r.status === 201,
    'has id': (r) => JSON.parse(r.body).id !== undefined,
  })
}

k6 vs JMeter vs Artillery

Feature k6 JMeter Artillery
Language JavaScript XML/GUI YAML
Resource usage Low (Go) High (Java) Medium (Node)
CI/CD Native Possible Native
Cloud option k6 Cloud BlazeMeter Artillery.io
Learning curve Easy Steep Easy

The Bottom Line

k6 is the developer-friendly load testing tool. JavaScript scripts, low resource usage, CI/CD native, and thresholds that fail your pipeline when performance degrades.

Need to automate data collection or build custom scrapers? Check out my Apify actors for ready-made tools, or email [email protected] for custom solutions.

GitHub Copilot Workspace Has a Free AI That Plans and Implements Code Changes Across Files

2026-03-30 07:11:45

GitHub Copilot Workspace goes beyond autocomplete. You describe a task in natural language, it creates a plan, shows you which files need changes, and implements them — across your entire repository.

How It Works

  1. Open an issue or describe a task
  2. Workspace analyzes your repo and creates a plan
  3. Review the plan: which files change, what changes
  4. Edit the plan if needed
  5. Click Implement — Workspace writes the code
  6. Review diffs, test, create PR

The Key Difference

Feature Copilot (autocomplete) Copilot Workspace
Scope Current line/function Entire repo
Input Code context Natural language task
Output Code suggestions Plan + implementation
Files Single file Multi-file changes
Review Inline Full diff view

Example: "Add dark mode to the settings page"

Workspace would:

  1. Identify settings.tsx, theme.ts, globals.css
  2. Plan: "Add theme toggle component, update CSS variables, persist preference"
  3. Show you the plan before writing code
  4. Implement across all 3 files
  5. Let you review each change

What It's Best At

  • Bug fixes from issue descriptions
  • Feature implementations across multiple files
  • Refactoring (rename, extract, reorganize)
  • Adding tests for existing code
  • Documentation updates

Limitations

  • Still in technical preview
  • Works best with well-described issues
  • Complex architectural changes need human guidance
  • May miss edge cases

The Bottom Line

Copilot Workspace is the future of AI-assisted development: task-level, not line-level. You describe what needs to change, review the plan, and let AI implement it.

Need to automate data collection or build custom scrapers? Check out my Apify actors for ready-made tools, or email [email protected] for custom solutions.

Reflective — AI journaling companion built with Notion MCP and Claude

2026-03-30 07:11:43

This is a submission for the Notion MCP Challenge

What I Built

Reflective is a Chrome extension + Node.js backend that adds an AI journaling companion to your browser sidebar while you write in Notion.

Most journaling tools are write-only. You pour thoughts in, they sit there. Reflective makes your Notion journal a two-way conversation — without leaving the page.

How it works:

You write in Notion
       ↓
Click "Analyze this entry" in the sidebar
       ↓
Claude reads your entry + your journal history from Notion
       ↓
Opens a conversation grounded in what you actually wrote
       ↓
Click "Mark session complete"
       ↓
Mood score, tags, themes, and AI summary written back to Notion

Key behaviors:

  • Sits in the Chrome side panel alongside Notion — no new tabs
  • Context-aware: on a database view it loads your last 50 entries; on a single entry it reads just that page
  • Temporal awareness: if you're reading an old entry, Claude knows — it frames responses as looking back, not as if it's today
  • One conversation across the whole session — navigating to a new entry appends to the chat with a — now reading: [title] — divider
  • Analysis is always user-initiated. The extension makes zero API calls on navigation.
  • Mood sparkline shows your last 14 days, pulled live from a Notion database

One-click workspace setup. On first launch, it creates a Journal Entries database, Mood Log, Weekly Summaries database, a seeded starter entry, and a dashboard page — all via the Notion API. You paste your integration token, it does the rest in ~10 seconds.

Video Demo

Show Us the Code

Repo: https://github.com/neicore/notion-reflective

Stack:

  • Chrome Extension (Manifest V3, React + TypeScript, Vite, Tailwind)
  • Node.js + Express backend (TypeScript)
  • Anthropic Claude (claude-sonnet-4-5)
  • Notion API (@notionhq/client v2)
  • Server-Sent Events for streaming progress to the extension
  • pnpm workspaces

How I Used Notion MCP

Notion is where users read and write their data — and it's also the entire data model. Every piece of state lives there, accessed via @notionhq/client.

Reading: building context for Claude

When you click "Analyze this entry", the backend fetches in parallel:

const [rawHistory, recentMoods] = await Promise.all([
  fetchJournalEntries(journalDbId, 50, notionToken),  // last 50 entries
  queryMoodHistory(moodLogDbId, 14, notionToken),      // 14-day sparkline
])

Then reads the current page blocks directly:

const [pageObj, blocks] = await Promise.all([
  notion.pages.retrieve({ page_id: pageId }),
  notion.blocks.children.list({ block_id: pageId, page_size: 100 }),
])

The block content becomes the raw text fed to Claude alongside journal history. History is split into "before this date" and "after this date" relative to the entry you're viewing — that's what gives Claude correct temporal framing.

Writing: analysis flows back into Notion

When you mark a session complete:

await notion.pages.update({
  page_id: pageId,
  properties: {
    'Mood Score':       { number: result.moodScore },
    'Mood Tags':        { multi_select: result.moodTags.map(name => ({ name })) },
    'Themes':           { multi_select: result.themes.map(name => ({ name })) },
    'AI Summary':       { rich_text: [{ text: { content: result.aiSummary } }] },
    'Word Count':       { number: wordCount },
    'Session Complete': { checkbox: true },
  },
})

Your Notion database gets richer over time. On future analyses, entries with an AI Summary are used as-is (fast); entries without one get their blocks fetched (slower, shown in the loading progress bar). First load hydrates your journal — subsequent loads are instant.

The loading experience

Hydrating 50 entries takes a while the first time. The /api/init endpoint streams progress via Server-Sent Events:

data: {"type":"journal_count","total":47}
data: {"type":"hydrating","index":1,"total":47,"title":"March reflections"}
data: {"type":"hydrating","index":2,"total":47,"title":"A hard week"}
...
data: {"type":"done","entryContent":"...","openingMessage":"..."}

The extension consumes this with fetch + ReadableStream (more reliable than EventSource in extension contexts), updating the UI: Reading your journal — 3/47 — A hard week.

What Notion unlocks that a plain database wouldn't

Notion's multi-select properties for Mood Tags and Themes mean once entries are analyzed, you can filter, sort, and group your entire journal by mood or theme natively in Notion — no custom query interface needed. The AI populates the properties; Notion's built-in views do the rest.

The mood sparkline pulls from a separate Mood Log database that tracks daily mood independently from journal entries. You can log mood on days you don't write, and the chart reflects it. Two related databases — the kind of structure that's natural in Notion and would need real schema design anywhere else.

That's the part I keep coming back to: the AI populates the properties, Notion's built-in views do the rest. No custom query interface, no separate dashboard to maintain. Your journal just gets smarter over time.

Gas-Aware Trading: Execute Only When Gas Is Cheap

2026-03-30 07:11:28

Your trading bot spotted a perfect arbitrage opportunity between Uniswap and Balancer. The price difference is 2.5% — enough for solid profit. But gas is sitting at 80 gwei. By the time the transaction confirms, the opportunity vanishes and you're left holding the gas bill.

This scenario plays out thousands of times daily in DeFi. Trading bots either miss opportunities waiting for cheap gas or burn through profits on expensive transactions. What if your bot could automatically execute trades only when gas prices meet your profitability threshold?

Why Gas-Aware Execution Matters for Trading Bots

Gas costs can make or break trading strategies. A profitable arbitrage at 20 gwei becomes a loss at 100 gwei. MEV bots competing for the same opportunities often end up in gas wars, driving costs through the roof. Manual gas monitoring doesn't scale when you're running strategies across multiple chains and protocols.

The challenge isn't just gas prices — it's coordination. Your bot needs to:

  • Monitor gas prices across networks in real-time
  • Queue transactions with conditional execution
  • Cancel outdated opportunities before they become losses
  • Maintain execution across 14 DeFi protocols simultaneously
  • Handle cross-chain arbitrage where timing matters

Building this infrastructure from scratch means maintaining gas price feeds, transaction queuing systems, and integrations with dozens of protocols. That's months of development before you even start on your actual trading logic.

Gas Conditional Execution: Your Bot Trades Smarter

WAIaaS solves this with gas conditional execution built into its 7-stage transaction pipeline. Your bot submits trades with gas price thresholds, and the system automatically executes only when conditions are met.

Here's how it works in practice. Your arbitrage bot spots an opportunity and submits a conditional trade:

curl -X POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000",
    "gasCondition": {
      "maxGasPrice": "50000000",
      "timeout": 300
    }
  }'

The transaction enters the pipeline and waits at stage 4 (wait) until gas drops below 50 lamports. If gas stays high for 300 seconds, the transaction expires automatically. No manual cancellation, no wasted gas on unprofitable trades.

Multi-Protocol Trading Through One API

Trading bots need access to liquidity across protocols. WAIaaS integrates 14 DeFi protocols through a unified API, so your bot can execute complex strategies without managing separate SDKs.

Execute a cross-protocol arbitrage in three API calls:

# 1. Swap on Jupiter (Solana)
curl -X POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{"inputMint": "SOL", "outputMint": "USDC", "amount": "10000000000"}'

# 2. Bridge to Ethereum via LI.FI
curl -X POST http://127.0.0.1:3100/v1/actions/lifi/bridge \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{"fromChain": "solana", "toChain": "ethereum", "token": "USDC", "amount": "1000"}'

# 3. Lend on Aave v3
curl -X POST http://127.0.0.1:3100/v1/actions/aave-v3/supply \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{"asset": "USDC", "amount": "1000"}'

Each action goes through the same gas-aware pipeline. Your bot submits the strategy, and WAIaaS handles execution timing across all three protocols.

Risk Controls That Scale

Trading bots need guardrails to prevent runaway losses. WAIaaS provides a 21-policy risk management system that operates at the wallet level, not per-strategy.

Set up automatic risk limits:

curl -X POST http://127.0.0.1:3100/v1/policies \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: my-secret-password" \
  -d '{
    "walletId": "<wallet-uuid>",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 1000,
      "notify_max_usd": 5000,
      "delay_max_usd": 20000,
      "delay_seconds": 300,
      "daily_limit_usd": 50000
    }
  }'

Trades under $1000 execute instantly. Trades between $1000-$5000 send notifications but still execute. Trades between $5000-$20000 wait 5 minutes (cancellable if your bot detects the opportunity expired). Trades over $20000 require manual approval.

You can also restrict protocols, tokens, and trading venues:

# Only allow trading on whitelisted protocols
curl -X POST http://127.0.0.1:3100/v1/policies \
  -H "X-Master-Password: my-secret-password" \
  -d '{
    "type": "CONTRACT_WHITELIST",
    "rules": {
      "contracts": [
        {"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4", "name": "Jupiter"},
        {"address": "0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9", "name": "Aave"}
      ]
    }
  }'

Simulation and Backtesting

Before risking capital, test strategies with the dry-run API. Submit any transaction with "dryRun": true to see exactly what would happen:

curl -X POST http://127.0.0.1:3100/v1/transactions/send \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wai_sess_<token>" \
  -d '{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'

The response shows gas estimates, policy decisions, and potential errors without executing the transaction. Essential for backtesting strategies against historical gas prices.

High-Performance Bot Integration

Trading bots need minimal latency overhead. WAIaaS provides both REST APIs and TypeScript/Python SDKs optimized for high-frequency strategies:

import { WAIaaSClient } from '@waiaas/sdk';

const client = new WAIaaSClient({
  baseUrl: 'http://127.0.0.1:3100',
  sessionToken: process.env.WAIAAS_SESSION_TOKEN,
});

// Check opportunity profitability
const balance = await client.getBalance();
const gasPrice = await client.getGasPrice();

if (gasPrice < profitabilityThreshold) {
  // Execute arbitrage
  const tx = await client.executeAction('jupiter-swap', {
    inputMint: 'SOL',
    outputMint: 'USDC',
    amount: balance.balance
  });
}

The SDK handles connection pooling, request retries, and error handling so your bot focuses on trading logic, not infrastructure.

Quick Start: Gas-Aware Trading Bot

Get started with gas conditional execution in 5 steps:

  1. Deploy WAIaaS daemon:
git clone https://github.com/minhoyoo-iotrust/WAIaaS.git
cd WAIaaS
docker compose up -d
  1. Create a trading wallet:
npm install -g @waiaas/cli
waiaas quickset --mode mainnet
  1. Set up risk policies (spending limits, protocol whitelist, gas thresholds)

  2. Install the SDK:

npm install @waiaas/sdk
  1. Submit your first gas-conditional trade using the Jupiter swap example above

Your bot now executes trades only when gas conditions are favorable, with automatic risk controls and multi-protocol access.

What's Next

This is just the beginning. WAIaaS supports perpetual futures on Hyperliquid, prediction markets on Polymarket, liquid staking, cross-chain bridging, and more. Each protocol integration includes gas-aware execution and risk controls out of the box.

Ready to build smarter trading bots? Check out the full documentation and examples at https://github.com/minhoyoo-iotrust/WAIaaS or visit https://waiaas.ai to get started.

Fresh 2 Has a Free API That Brings Zero-JS Pages to Deno With Island Architecture

2026-03-30 07:08:55

Fresh is Deno's web framework. Zero JavaScript shipped to the client by default. Interactive parts are "islands" that hydrate independently. Fresh 2 adds Preact Signals, better plugins, and faster builds.

Quick Start

deno run -A https://fresh.deno.dev my-app
cd my-app && deno task start

Zero JS by Default

Every Fresh page is server-rendered HTML. No JavaScript bundle. This page component ships 0 bytes of JS:

// routes/index.tsx
export default function Home() {
  return (
    <div>
      <h1>Hello Fresh</h1>
      <p>This page has zero client-side JavaScript.</p>
    </div>
  )
}

Islands (Interactive Components)

Only components in /islands/ get hydrated on the client:

// islands/Counter.tsx
import { useSignal } from "@preact/signals"

export default function Counter() {
  const count = useSignal(0)
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => count.value++}>+1</button>
    </div>
  )
}
// routes/index.tsx
import Counter from "../islands/Counter.tsx"

export default function Home() {
  return (
    <div>
      <h1>Static content (0 JS)</h1>
      <Counter />  {/* Only this hydrates */}
    </div>
  )
}

Data Loading with Handlers

// routes/posts/[id].tsx
import { Handlers, PageProps } from "$fresh/server.ts"

export const handler: Handlers = {
  async GET(_req, ctx) {
    const post = await fetchPost(ctx.params.id)
    if (!post) return ctx.renderNotFound()
    return ctx.render(post)
  }
}

export default function PostPage({ data }: PageProps) {
  return <article><h1>{data.title}</h1><p>{data.body}</p></article>
}

Fresh vs Next.js vs Remix

Feature Fresh Next.js Remix
Runtime Deno Node Node
Default JS 0 bytes Bundle Bundle
Hydration Islands Full/Partial Full
State Preact Signals React React

The Bottom Line

Fresh is perfect for content-heavy sites that need minimal interactivity. Zero JS default + island architecture = fastest possible page loads.

Need to automate data collection or build custom scrapers? Check out my Apify actors for ready-made tools, or email [email protected] for custom solutions.