Documentacao do cardisk
Esta documentacao foi organizada para web com base no pacote publicado no PyPI (cardisk 0.4.7, publicado em 4 de marco de 2026).
Introducao
cardisk e um framework Python para construir aplicacoes USSD, com API baseada em decoradores e fluxo de menu interativo.
- Simple API - Decorator-based routing for clean screen handlers
- Menu System - Built-in support for interactive menus with automatic navigation
- Session Management - Automatic session handling with in-memory or Redis storage
- Monitoring - Built-in Prometheus metrics endpoint
- Error Handling - Robust error handling middleware
- Type Safe - Full type hints support
- Fast - High-performance runtime with Uvicorn
Instalacao
Instalacao de producao
pip install cardisk
Instalacao para desenvolvimento
pip install -e .
Quick Start
Crie um ficheiro app.py:
from cardisk import Cardisk, ussd
app = Cardisk()
@app.route("/")
def main_menu():
ussd.menu("Welcome to Wolke Services", [
("Loans", "/loans"),
("Savings", "/savings"),
("Insurance", "/insurance")
])
@app.route("/loans")
def loans():
ussd.menu("Loans Menu", [
("Apply for loan", "/loan/apply"),
("Check loan status", "/loan/status"),
("Repay loan", "/loan/repay")
])
@app.route("/loan/apply")
def loan_apply():
ussd.screen(f"Enter loan amount for {ussd.msisdn}")
ussd.next("/loan/confirm")
@app.route("/loan/confirm")
def loan_confirm():
amount = ussd.input
ussd.screen(f"Loan of ${amount} submitted successfully for {ussd.msisdn}")
ussd.end()
Execute a aplicacao:
cardisk runserver app.py
Ou com Uvicorn:
uvicorn app:app.app --reload --port 8000
API
Setup da aplicacao
from cardisk import Cardisk, ussd
app = Cardisk()
Decorador de rota: @app.route()
@app.route("/path")
def handler():
pass
- As rotas devem iniciar com
/. -
Use
/como ponto de entrada do menu principal.
Objeto ussd
Propriedades:
ussd.msisdn: numero do utilizadorussd.session: ID da sessao atual-
ussd.input: entrada do utilizador no passo anterior
Metodos principais:
ussd.menu("Main Menu", [
("Option 1", "/route1"),
("Option 2", "/route2")
])
ussd.screen("Hello!")
ussd.next("/verify-pin")
ussd.end()
Protocolo XML USSD
Formato da requisicao
<ussd>
<type>1</type>
<msisdn>254712345678</msisdn>
<sessionid>unique-session-id</sessionid>
<msg>user-input</msg>
</ussd>
Formato da resposta
<ussd>
<type>2</type>
<msg>Response text</msg>
</ussd>
Testes
Com cURL
1. Iniciar nova sessao:
curl -X POST http://localhost:8000/ \
-H "Content-Type: application/xml" \
-d '<ussd><type>1</type><msisdn>254712345678</msisdn><sessionid>test123</sessionid><msg></msg></ussd>'
2. Selecionar opcao de menu (ex.: opcao 1):
curl -X POST http://localhost:8000/ \
-H "Content-Type: application/xml" \
-d '<ussd><type>2</type><msisdn>254712345678</msisdn><sessionid>test123</sessionid><msg>1</msg></ussd>'
3. Enviar um input:
curl -X POST http://localhost:8000/ \
-H "Content-Type: application/xml" \
-d '<ussd><type>2</type><msisdn>254712345678</msisdn><sessionid>test123</sessionid><msg>500</msg></ussd>'
Com Python
import httpx
client = httpx.Client(base_url="http://localhost:8000")
# Start session
response = client.post("/", content="""
<ussd>
<type>1</type>
<msisdn>254712345678</msisdn>
<sessionid>test123</sessionid>
<msg></msg>
</ussd>
""", headers={"Content-Type": "application/xml"})
print(response.text)
# Continue session
response = client.post("/", content="""
<ussd>
<type>2</type>
<msisdn>254712345678</msisdn>
<sessionid>test123</sessionid>
<msg>1</msg>
</ussd>
""", headers={"Content-Type": "application/xml"})
print(response.text)
Exemplo de aplicacao
Exemplo completo disponivel em
examples/mybank/main.py:
cd examples/mybank
cardisk runserver main.py
Ou com Uvicorn:
cd examples/mybank
uvicorn main:app.app --reload
Sessoes
Por padrao, cardisk usa armazenamento de sessao em memoria. Para producao com multiplas instancias, use Redis.
export CARDISK_USE_REDIS=true
export CARDISK_REDIS_URL=redis://localhost:6379/0
cardisk runserver app.py
Metricas
As metricas Prometheus estao disponiveis no endpoint
/metrics.
curl http://localhost:8000/metrics
Metrica disponivel: cardisk_requests_total.
Docker
Build
docker build -t cardisk-app .
Run
docker run -p 8000:8000 cardisk-app
Com Redis
docker run -p 8000:8000 \
-e CARDISK_USE_REDIS=true \
-e CARDISK_REDIS_URL=redis://redis:6379/0 \
cardisk-app
CLI
Criar novo projeto
cardisk new myproject
Executar servidor
cardisk runserver app.py --host 0.0.0.0 --port 8000
Uso avancado
Tratamento de erro personalizado
@app.route("/transfer")
def transfer():
try:
amount = float(ussd.input)
if amount <= 0:
ussd.screen("Invalid amount. Please try again.")
ussd.next("/transfer")
else:
ussd.screen(f"Transfer of ${amount} successful!")
ussd.end()
except ValueError:
ussd.screen("Invalid input. Please enter a number.")
ussd.next("/transfer")
Formulario multi-step
@app.route("/register")
def register_name():
ussd.screen("Enter your name:")
ussd.next("/register/age")
@app.route("/register/age")
def register_age():
name = ussd.input
ussd.screen(f"Hello {name}! Enter your age:")
ussd.next("/register/confirm")
@app.route("/register/confirm")
def register_confirm():
age = ussd.input
ussd.screen(f"Registration complete! Age: {age}")
ussd.end()
Testing
Run tests
pytest
Run with coverage
pytest --cov=cardisk --cov-report=html
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License.
Support
For issues and questions, please open an issue on GitHub.