rest api python backend, web service programming

Building a Python API to Sell Your Services: The Freelancer’s Guide

|

Learn how to build a professional API using Python and the FastAPI framework, and turn your skills and tools into a service you can sell to developers and companies.

Word Count: ~1900 · Reading Time: 10 minutes

Building a Web API with Python to Sell Your Services

How to turn your tools and scripts into a software service you can sell to developers and companies


Note to the reader: This article is completely self-contained, and you can apply everything in it without reading previous articles. However, if you haven’t dealt with backend concepts in Python before, we recommend checking out our article: Converting Your Static HTML Website into a Dynamic One with Python and Flask.

You have a Python script that does something useful — maybe it analyzes text, converts currencies, generates reports, or scrapes data from websites. So far, this script only runs on your local machine, and no one else can use it unless they install Python and execute the code manually.

What if you could turn this script into a service that any developer or application in the world could use with a single request? What if you could charge fees per request or a monthly subscription? This is exactly what building a REST API with Python allows you to do. In this article from Zy Yazan Platform, we will build a complete, professional API using the FastAPI framework, and learn how to protect it with access keys and document it automatically.

What is an API and Why Does It Matter to You?

API stands for Application Programming Interface, which is simply a standard way that allows one program to talk to another program over the internet. When a weather app displays the temperature, it talks to an API. When a user pays with their credit card, the application sends a request to a payment gateway’s API.

The most common API architecture today is known as a REST API, short for Representational State Transfer, which relies on the same HTTP protocol that powers the web. Each request arrives via a specific URL route, carries data in JSON format (JavaScript Object Notation), and returns a clear response.

An API is the shared language between applications. Anyone who owns a useful API owns a service that can be sold to any developer, regardless of the programming language they use.

api developer laptop code

Why FastAPI and Not Flask or Django?

In previous articles of this series, we explored Flask and Django. Both are capable of building APIs, but FastAPI was designed specifically for this purpose and stands out with three advantages that make it the best choice for selling programming services:

  • Speed: FastAPI is one of the fastest Python frameworks in the world, competing with Go and Node.js in performance thanks to its native support for Asynchronous programming.
  • Automatic Documentation: FastAPI generates interactive API documentation automatically without writing a single extra line of code. Your client can test the API directly from the browser.
  • Automatic Data Validation: It validates incoming data before it even reaches your code, saving you dozens of lines of manual verification logic.
Feature Flask Django REST Framework FastAPI
Performance & Speed Medium Medium Excellent
Auto Documentation Manual Partial Fully Automatic
Data Validation Manual Via Django Serializers Automatic via Pydantic
Learning Curve Easy Relatively Complex Easy & Straightforward
Best Suited For Simple websites Full-stack applications APIs & Microservices

Installation and Setup: Up and Running in Two Minutes

Install FastAPI along with the Uvicorn web server that runs it:

pip install fastapi uvicorn

Create a file named main.py and write the simplest possible API:

from fastapi import FastAPI

app = FastAPI(
    title="Text Analysis Service",
    description="API for analyzing Arabic and English text",
    version="1.0.0"
)

@app.get("/")
def root():
    return {"message": "Welcome! The API is running successfully."}

@app.get("/health")
def health_check():
    return {"status": "ok"}

Start the server:

uvicorn main:app --reload

Open your browser at http://127.0.0.1:8000/docs and you will find complete, interactive documentation for your API, ready without writing a single extra character. This is the magic of FastAPI.

Building a Real API: Text Analysis Service

Let’s build a practical example — a text analysis API that can be sold to bloggers, translators, and content creators. It will accept a text and return useful statistics about it:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import re
from datetime import datetime

app = FastAPI(
    title="Text Analysis Service — The Yazan Platform",
    description="""
    Professional API for analyzing Arabic and English text.
    Provides accurate metrics that help translators and content creators.
    """,
    version="1.0.0"
)

# Request data model — FastAPI validates this automatically
class TextRequest(BaseModel):
    text: str
    language: str = "auto"  # auto, arabic, english

# Response data model
class TextAnalysis(BaseModel):
    word_count: int
    char_count: int
    char_no_spaces: int
    sentence_count: int
    paragraph_count: int
    avg_word_length: float
    reading_time_minutes: float
    language_detected: str
    timestamp: str

def detect_language(text: str) -> str:
    """Detect language based on the ratio of Arabic characters"""
    arabic_chars = len(re.findall(r'[\u0600-\u06FF]', text))
    total_chars = len(re.findall(r'[a-zA-Z\u0600-\u06FF]', text))
    if total_chars == 0:
        return "unknown"
    return "arabic" if arabic_chars / total_chars > 0.5 else "english"

@app.post("/analyze", response_model=TextAnalysis)
def analyze_text(request: TextRequest):
    """
    Analyze text and return detailed metrics.
    - **text**: The text to be analyzed (required)
    - **language**: Text language (optional — auto for auto-detection)
    """
    text = request.text.strip()

    if not text:
        raise HTTPException(
            status_code=400,
            detail="Text is empty. Please provide valid text."
        )

    if len(text) > 50000:
        raise HTTPException(
            status_code=413,
            detail="Text exceeds the maximum allowed limit (50,000 characters)."
        )

    # Metrics
    words = text.split()
    word_count = len(words)
    char_count = len(text)
    char_no_spaces = len(text.replace(" ", ""))
    sentences = re.split(r'[.!?؟،\n]+', text)
    sentence_count = len([s for s in sentences if s.strip()])
    paragraphs = [p for p in text.split('\n\n') if p.strip()]
    paragraph_count = max(len(paragraphs), 1)
    avg_word_length = round(
        sum(len(w) for w in words) / word_count, 2
    ) if word_count > 0 else 0

    # Reading time: 200 wpm for English, 150 wpm for Arabic
    lang = request.language if request.language != "auto" else detect_language(text)
    wpm = 150 if lang == "arabic" else 200
    reading_time = round(word_count / wpm, 2)

    return TextAnalysis(
        word_count=word_count,
        char_count=char_count,
        char_no_spaces=char_no_spaces,
        sentence_count=sentence_count,
        paragraph_count=paragraph_count,
        avg_word_length=avg_word_length,
        reading_time_minutes=reading_time,
        language_detected=lang,
        timestamp=datetime.now().isoformat()
    )

Try sending a request to this API using Python:

import requests

response = requests.post(
    "http://127.0.0.1:8000/analyze",
    json={
        "text": "Python is a wonderful programming language. It is characterized by readability and clean syntax.",
        "language": "auto"
    }
)

print(response.json())
# Result:
# {
#   "word_count": 13,
#   "char_count": 94,
#   "reading_time_minutes": 0.07,
#   "language_detected": "english",
#   ...
# }

Protecting the API with Access Keys (API Keys)

An open API cannot be sold — it must be protected with access keys that each client receives after subscribing. Here is the simplest and most common approach:

from fastapi import FastAPI, HTTPException, Security
from fastapi.security.api_key import APIKeyHeader
import secrets

app = FastAPI()

# Define where to look for the key — in the request header
API_KEY_HEADER = APIKeyHeader(name="X-API-Key", auto_error=False)

# In real production projects, these are stored in a database
VALID_API_KEYS = {
    "key_abc123xyz": {"client": "Ahmed Mohamed", "plan": "basic", "requests_limit": 1000},
    "key_def456uvw": {"client": "Tech Company", "plan": "pro", "requests_limit": 10000},
}

def verify_api_key(api_key: str = Security(API_KEY_HEADER)):
    """Validate the access token"""
    if api_key is None:
        raise HTTPException(
            status_code=401,
            detail="API access key missing. Add it to the header: X-API-Key"
        )
    if api_key not in VALID_API_KEYS:
        raise HTTPException(
            status_code=403,
            detail="The access key is invalid or expired."
        )
    return VALID_API_KEYS[api_key]

# Using authentication within endpoints
@app.post("/analyze")
def analyze_text(
    request: TextRequest,
    client_info: dict = Security(verify_api_key)
):
    # client_info contains authenticated client records
    print(f"Request from client: {client_info['client']} — Plan: {client_info['plan']}")
    # ... remaining processing logic

Now, every request arriving without a valid key is turned back with a explicit error message. A developer wishing to consume your service sends their token like this:

import requests

response = requests.post(
    "https://api.yourdomain.com/analyze",
    headers={"X-API-Key": "key_abc123xyz"},
    json={"text": "Text to be analyzed..."}
)

print(response.json())

HTTP Method Types: GET, POST, PUT, and DELETE

Every operation on API data utilizes a different type of HTTP request. This is not arbitrary but rather a convention followed by all developers globally:

Request Type Functionality Practical Example
GET Retrieve Data GET /clients — Get the list of clients
POST Create a New Record POST /analyze — Submit text for analysis
PUT Update an Existing Record PUT /clients/5 — Update a client’s information
DELETE Delete a Record DELETE /clients/5 — Delete a client

Here is an example of a complete CRUD API for managing a To-Do task list illustrating all four methods:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

# Temporary in-memory storage — use a real database for live products
tasks_db = {}
next_id = 1

class Task(BaseModel):
    title: str
    description: Optional[str] = None
    is_done: bool = False

@app.get("/tasks")
def get_all_tasks():
    """Retrieve all tasks"""
    return list(tasks_db.values())

@app.get("/tasks/{task_id}")
def get_task(task_id: int):
    """Retrieve a single task by its identifier"""
    if task_id not in tasks_db:
        raise HTTPException(status_code=404, detail="Task not found")
    return tasks_db[task_id]

@app.post("/tasks", status_code=201)
def create_task(task: Task):
    """Create a new task"""
    global next_id
    task_data = {"id": next_id, **task.dict()}
    tasks_db[next_id] = task_data
    next_id += 1
    return task_data

@app.put("/tasks/{task_id}")
def update_task(task_id: int, task: Task):
    """Update an existing task"""
    if task_id not in tasks_db:
        raise HTTPException(status_code=404, detail="Task not found")
    tasks_db[task_id].update(task.dict())
    return tasks_db[task_id]

@app.delete("/tasks/{task_id}")
def delete_task(task_id: int):
    """Delete a task"""
    if task_id not in tasks_db:
        raise HTTPException(status_code=404, detail="Task not found")
    del tasks_db[task_id]
    return {"message": f"Task {task_id} has been deleted successfully"}

Automatic Documentation: Your Free Gift from FastAPI

When you run a FastAPI application, you immediately gain access to two interactive documentation dashboards out of the box:

  • Swagger UI at route /docs — Allows trying out the endpoints directly from the browser with a single click.
  • ReDoc at route /redoc — An elegant, clean, and printable specification layout, ideal for sharing with enterprise clients.

These endpoints speak professionally for your service. Instead of writing a manual PDF document to explain how to integrate your API, you simply send your client the /docs URL and let them discover it interactively. This alone saves hours of consulting with each consumer.

How Do You Sell Your API? Practical Pricing Frameworks

Once your API is built and locked down, the vital business question remains: how do you monetize it? There are three common pricing strategies used by independent developers:

Strategy 1 — Usage-Based Pricing (Pay Per Use): Every transaction triggers a microscopic charge. For instance, $0.001 per text analysis execution. Perfect for customers with irregular workload spikes.

Strategy 2 — Monthly Subscription Tiers: Static monthly brackets with hard consumption limits. The starter tier offers 1,000 monthly calls for $9. Ideal if you want steady, predictable recurring income.

Strategy 3 — Enterprise Licensing: Selling your API through flat annual contract frameworks to enterprises who need to self-host the deployment within their isolated infrastructure. Higher ticket prices, smaller target volumes.

Marketplaces like RapidAPI and API Layer let you publish your endpoints, configure tiers, and manage customer subscriptions and payouts seamlessly, saving you from building billing infrastructure early on.

A clever freelancer does not merely sell hours; they engineer digital assets that yield dividends around the clock. APIs represent the closest embodiment of this strategy in software engineering.

rest api python backend, web service programming

Deploying Your API to Production

To publish your FastAPI instance onto public web ecosystems, add a requirements.txt file containing your project’s dependencies:

fastapi==0.111.0
uvicorn==0.30.0
pydantic==2.7.0

And a Procfile specifying runtime configurations for cloud platforms:

web: uvicorn main:app --host 0.0.0.0 --port $PORT

Ecosystems like Render and Railway swallow this setup seamlessly. Push your project folder to a GitHub repository, map it inside your hosting dashboard, and your live production routes will be available to public traffic within moments.


Summary and Next Steps

Today, we discovered how to construct a professional, industry-grade REST API utilizing Python and FastAPI. We handled security walls via custom client keys, inherited integrated documentation interfaces effortlessly, and explored practical monetization business strategies. An API isn’t just an engineering protocol — it’s an end-to-end commercial paradigm allowing you to productize algorithms into scalable cash flow assets.

Recommended Next Step:

We built a solid API asset — but what if we injected artificial intelligence directly into its processing logic? What if your API calls leverage Large Language Models (LLMs) to parse, transform, and generate rich contextual text instead of standard hardcoded algorithms? In our upcoming article, we tackle how to merge core AI systems directly into our Python application architectures.

Join us in the thirteenth article: How to Integrate Artificial Intelligence Models Inside Your Python Projects.


References and Sources:

  1. Official FastAPI Framework Ecosystem Documentation: FastAPI Official Documentation
  2. Pydantic Core Schema Parsing Guide: Pydantic Documentation
  3. MDN Network HTTP Verb Specification Manual: MDN Web Docs — HTTP request methods
  4. RapidAPI Global API Aggregator and Vendor Marketplace: RapidAPI Marketplace

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *