🚀 Welcome to apipie

Welcome to apipie!
the syntax is easy (it is just json)

Tip: Use the navigation on the left to explore topics.


to get started, download apipie somehow

installing apipie

Install it by running

pip install apipie

if you would prefer not to use a venv run

python3 -m pip install apipie

or, on windows

py -m pip install apipie

To use you can run

apipie config.json False

the first argument is the filename, or the json iteself, if you would rather just input it right into there, make the second value true, that tells the code you want to use a string not a file path

you can also run it inside a .py file

example.py

from apipie import Apipie

apipie=Apipie('config.json', False)

#or

apipie=Apipie('{"some":{"json":"here"}}',True)

if __name__ == "__main__":
    apipie.run(debug=True, port=8080, host = "127.0.0.1")

All you really have to do is configure it, and you do that with api_config.json

{}

In this guide we will walk you through how to configure it, all the parameters required, extra ones, and maybe even some planned ones later on.

Apis and Nicknames

Lets start with code that sends and receives our get/post request

to start lets define our api nickname.

{
    "apis":{
        "get_api":{
            "method": "get",
            "url": "https://httpbin.org/get"
        }
    }
}

In that code above, the first value ("apis") tells us that is where all the api declarations are kept, the second value ("get_api") can have any value, that is the api nickname, and the url is where the request is sent to

now that that is defined, you can run the code, but nothing will happen, that is because we need to define the url path. it is super simple, put this at the very beginning.

{
    "routes":{
        "get":"get_api"
    },

full code here

{
    "routes":{
        "get":"get_api"
    },

    "apis":{
        "get_api":{
            "method": "get",
            "url": "https://httpbin.org/get"
        }
    }
}

Go to http://localhost:8000/get, you should get a result similar to this.


{
  "args": {}, 
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", 
    "Accept-Encoding": "gzip, deflate, br, zstd", 
    "Accept-Language": "en-US,en;q=0.9", 
    "Host": "httpbin.org", 
    "Priority": "u=0, i", 
    "Sec-Ch-Ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"", 
    "Sec-Ch-Ua-Mobile": "?0", 
    "Sec-Ch-Ua-Platform": "\"Windows\"", 
    "Sec-Fetch-Dest": "document", 
    "Sec-Fetch-Mode": "navigate", 
    "Sec-Fetch-Site": "none", 
    "Sec-Fetch-User": "?1", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", 
    "X-Amzn-Trace-Id": "Root=1-6______4-________________"
  }, 
  "origin": "--.---.--.---", 
  "url": "https://httpbin.org/get"
}

If you want you can change it to a post requests, and send a post request to that address if you want.

{
    "routes":{
        "get":"get_api"
    },

    "apis":{
        "get_api":{
            "method": "post",
            "url": "https://httpbin.org/post"
        }
    }
}

Multiple routes is just as easy, just define them with a nickname, than expose that route to apipie via "routes".

{
    "routes":{
        "post":"post_api",
        "get":"get_api",
        "example/here":"example"
    },

    "apis":{
        "post_api":{
            "method": "post",
            "url": "https://httpbin.org/post"
        },
        "get_api":{
            "method": "get",
            "url": "https://httpbin.org/get"
        },
        "example":{
            "method": "get",
            "url":"api.example.com/enpoint"
        }
    }
}

Services API keys and rate limiting

You want to use a service that requires an api key, but can't expose it to the public (for obvious reasons) but want too, well here is the right place to go.

Api keys

It is really easy to add api keys to your apipie instance first define the api keys using the "keys" key.

{
    "keys":{
        "api_key_identifier":"you_api_key_here"
    },

It is really easy to add them to your url or whatever else.


{
    "routes":{
        "get":"get_api"
    },
    "keys":{
        "api_key_identifier":"you_api_key_here"
    },
    "apis":{
        "get_api":{
            "method": "get",
            "url": "https://httpbin.org/get?api-key=[api_key_identifier]"
        }
    }
}

Works with post in the same why, you can do that with headers and all that, but we will cover post later.

rate limits

Rate limits have two arguments, first is how many requests, second is the period of time between each refresh.

{
    "rate_limit": {
         "limit": 3, 
        "window": 30 
    }
}

That code there has the rate limits set to 3 requests every half a minute, than it refreshes.

Example


{
    "routes":{
        "get":"get_api"
    },
    "keys":{
        "api_key_identifier":"you_api_key_here"
    },
    "apis":{
        "get_api":{
            "method": "get",
            "url": "https://httpbin.org/get?api-key=[api_key_identifier]",
            "rate_limit": { "limit": 3, "window": 30 }
        }
    }
}

Variables

There are two kinds of variables, preset ones, and path based ones.

Pre defined

Pre defined variables is a variable that is set when the code is executed and is often not edited.

{
    "open-vars":{
        "city": "toronto"
    },

Variables are easy to use time savers

like api keys, they can be placed almost anywhere easily, but use angle braces ( < and > ) instead of square braces ( [ and ] ), example.

{
    "apis":{
        "get_api":{
            "method": "get",
            "url": "https://httpbin.org/get?<city>",
            "rate_limit": { "limit": 3, "window": 30 }
        }
    }
}

easy as that

{
    "routes":{
        "get":"get_api"
    },
    "keys":{
        "api_key_identifier":"you_api_key_here"
    },
    "open-vars":{
        "city": "toronto"
    },
    "apis":{
        "get_api":{
            "method": "get",
            "url": "https://httpbin.org/get?<city>&api-key=[api_key_identifier]",
            "rate_limit": { "limit": 3, "window": 30 }
        }
    }
}

Now lets do path based variables

they are super easy, just put the variable into the routes path.

{
    "routes":{
        "city/<city>":"some_nickname"
    },

And that is it, the syntax on everything else is the same.

{
    "routes":{
        "city/<city>":"get_api"
    },
    "keys":{
        "api_key_identifier":"you_api_key_here"
    },
    "apis":{
        "get_api":{
            "method": "get",
            "url": "https://httpbin.org/get?<city>&api-key=[api_key_identifier]",
            "rate_limit": { "limit": 3, "window": 30 }
        }
    }
}

Now if you go to https://localhost:8000/city/toronto you should get

{
    "args": {
    "api-key": "you_api_key_here", 
    "toronto": ""
  },  
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", 
    "Accept-Encoding": "gzip, deflate, br, zstd", 
    "Accept-Language": "en-US,en;q=0.9", 
    "Host": "httpbin.org", 
    "Priority": "u=0, i", 
    "Sec-Ch-Ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"", 
    "Sec-Ch-Ua-Mobile": "?0", 
    "Sec-Ch-Ua-Platform": "\"Windows\"", 
    "Sec-Fetch-Dest": "document", 
    "Sec-Fetch-Mode": "navigate", 
    "Sec-Fetch-Site": "none", 
    "Sec-Fetch-User": "?1", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", 
    "X-Amzn-Trace-Id": "Root=1-6______4-________________"
  }, 
  "origin": "--.---.--.---", 
  "url": "https://httpbin.org/get"
}

environment variables

You can use environment variables

an example on how to set on it.

os.environ['SOMETHING'] = 'somevalue'

You can set it using {ENVVARIABLENAME}

like

{"url":"https://httpbin/get?{SONETHING}"}

That is it, very simple.

cors

You can set cors to true or false to block cors requests.

{"cors":"false"}

That is it.

Custom html responses

You don't have to be stuck with plain old api requests, why not set your own custom html requests and use html files as well.

example

{
    "apis"{
        "index": {
            "require_api_key": false,
            "method":"GET",
            "html": "<h1>Welcome to Apipie API Service</h1><p>Use /api/{api_name} to access APIs.</p>"
        },
    }
}

And you can also use just plain old files.

index.html

Hello World! this is an html file served with apipie

api_config.json

{
    "apis"{
        "index": {
            "require_api_key": false,
            "method":"GET",
            "html_file":"index.html" 
        },
    }
}

USERS

Users are used to authenticate requests (i.e api keys, secrets, etc) They are simple to use, and means not every api you use is not secure.

They can be used to set custom rate limits, set allowed apis and more.

To start, create a "users" key, and after that, put the name you want for your user, you can also have multiple.

{
    "users":{
        "user1":{},
        "user2":{}
    }

USERS

Users are used to authenticate requests (i.e api keys, secrets, etc) They are simple to use, and means not every api you use is not secure.

They can be used to set custom rate limits, set allowed apis and more.

To start, create a "users" key, and after that, put the name you want for your user, you can also have multiple.

{
    "users":{
        "user1":{},
        "user2":{}
    }

Custom API Keys

Custom api key

Now that you have users set, you can no set the api key, which at the moment is just a hash, you can generate a hash with software that supports sha256, you can have any text you want, but to be safe, just generate it, here is the code.

import secrets
import hashlib

def generate_api_key():
    # Generate a secure random API key
    key = secrets.token_hex(32)  # 64 characters, 256-bit
    return key

def hash_api_key(api_key):
    return hashlib.sha256(api_key.encode('utf-8')).hexdigest()

if __name__ == "__main__":
    api_key = generate_api_key()
    hashed = hash_api_key(api_key)

    print("Generated API Key (save this!):")
    print(api_key)
    print("/nStore this hash in config:")
    print(hashed)

then you put it as a value in like this

{"api_key_hash":"you_hash_here"}

full code

{
    "users":{
        "user1":{"api_key_hash":"you_hash_here",},
        "user2":{"api_key_hash":"other_hash_here",}
    }


{
    "users": {
        "user1": {
            "api_key_hash": "912f3c265c1876046e0f147413cc1189e28af1e8c1ebbad5c485b71cd8027840",
            "allowed_apis": ["httpbin", "github"],
            "rate_limit": {"limit": 5, "window": 60}
        },
        "user2": {
            "api_key_hash": "6f8705b12a8f69fd97cb0a3df5862b35be54161b7df8f5df0e8db1e2d7b317a3",
            "allowed_apis": ["weather","hia"],
            "rate_limit": {"limit": 3, "window": 30}
        }
    },

    "open-vars": {
        "usrnm": "kokos-lab",
        "api_key_github": "ghp_123456789",
        "api_key_weather": "abc_openweather_456"
    },

    "keys": {
        "api_key_github": "ghp_123456789",
        "api_key_weather": "abc_openweather_456"},

    "routes": {
        "hia": "httpbin",
        "aloha": "weather",
        "get/v2/run": "github",
        "test/<varname>/hia": "hia"
    },
    
    "apis": {
        "httpbin": {
            "cors": "True",
            "method": "POST",
            "url": "https://httpbin.org/post",
            "bearer_token": "<api_key_github>",
            "json": {
                "message": "Hello from <usrnm>"
            },
            "headers": {
                "X-Custom": "Header for <usrnm>"
            }
        },
        "weather": {
            "cors": "False",
            "method": "GET",
            "url": "https://api.openweathermap.org/data/2.5/weather?q=<city>&appid=[api_key_weather]"
        },
        "github": {
            "cors": "True",
            "method": "GET",
            "url": "https://api.github.com/users/<usrnm>"
        },
        "hia": {
            "script": "print(hello to my world)",
            "cors": "False",
            "method": "GET",
            "url": "https://api.github.com/users/<varname>"
        }
    }
}

Allowed APIs

you may not always want all you apis to be open, or authenticated with all api users, you can set multiple users, multiple apis, multiple allowed apis, etc


{"allowed_apis":["multiple","api","names","here"]}

full example

{
    "users": {
        "user1": {
            "api_key_hash": "912f3c265c1876046e0f147413cc1189e28af1e8c1ebbad5c485b71cd8027840",
            "allowed_apis": ["httpbin", "github"],
            "rate_limit": {"limit": 5, "window": 60}
        },
        "user2": {
            "api_key_hash": "6f8705b12a8f69fd97cb0a3df5862b35be54161b7df8f5df0e8db1e2d7b317a3",
            "allowed_apis": ["weather","hia"],
            "rate_limit": {"limit": 3, "window": 30}
        }
    },

note: the keys for each one is 35b1b4d5fdcccb5b7d1a7d7870f647002b370b18bc3d5f0b552c011ff07b0d9c and 33f63ece2c910df2959e0a870f9ef83cbdc09b1b6678d037a12c17ab5fedc51d

Rate Limiting

{"rate_limit": {"limit": 5, "window": 60}}

That is it, just put it into the user and you will be fine.

NO tips at the moment

NO tips at the moment

This is new, so i have no idea

Scripting

Adding scripts to apipie for request and data manipulation and is super easy.

Start with a basic apipie config.json example.

        "hia": {
            "require_api_key": false,
            "script": "hia",
            "cors": "False",
            "method": "GET",
            "url": "https://api.github.com/users/<varname>"
        }

Script has the name hia for referencing

now that the script has been defined lets get coding lets start with something easy, how about a calculator script to start, add the decorator in your apipie instance.

from apipie import Apipie

apipie = Apipie("api_config.json", is_string=False)

@apipie.script('hia')
def calculator(request):
    pass

Now to add the logic use request.args.get("some_value_here"), and do that twice.

And to return custom type (i.e. html, json, or text, use apipie.response.json)

@apipie.script('hia')
def calculator(request):
    return apipie.response.json({"result": int(request.args.get("a",1))+int(request.args.get("b",2))})

It is that easy, all of the data available from request variables inside a function, most of the functions available are found at flask here.

note: this app is built off of sanic, which is Flask but faster

It is easy to change predefined or path variables at runtime using api scripting


@apipie.script('somescriptnamehere')
def calculator(request):
    hia=apipie["somevariablename"]
    apipie["varname"]=hia

Scripting

Adding scripts to apipie for request and data manipulation and is super easy.

Start with a basic apipie config.json example.

        "hia": {
            "require_api_key": false,
            "script": "hia",
            "cors": "False",
            "method": "GET",
            "url": "https://api.github.com/users/<varname>"
        }

Script has the name hia for referencing

now that the script has been defined lets get coding lets start with something easy, how about a calculator script to start, add the decorator in your apipie instance.

from apipie import Apipie

apipie = Apipie("api_config.json", is_string=False)

@apipie.script('hia')
def calculator(request):
    pass

Now to add the logic use request.args.get("some_value_here"), and do that twice.

And to return custom type (i.e. html, json, or text, use apipie.response.json)

@apipie.script('hia')
def calculator(request):
    return apipie.response.json({"result": int(request.args.get("a",1))+int(request.args.get("b",2))})

It is that easy, all of the data available from request variables inside a function, most of the functions available are found at flask here.

note: this app is built off of sanic, which is Flask but faster

It is easy to change predefined or path variables at runtime using api scripting


@apipie.script('somescriptnamehere')
def calculator(request):
    hia=apipie["somevariablename"]
    apipie["varname"]=hia