I write status reports every Friday, and it is always the same busywork. Today we will wire up a small Python CLI that turns raw bullet points into a polished weekly update. It calls Oxlo.ai directly, and because Oxlo.ai charges per request instead of per token, I do not have to trim my commit history to save money. See https://oxlo.ai/pricing for current plan details.
What you'll need
- Python 3.10 or newer
- The OpenAI SDK:
pip install openai - An Oxlo.ai API key from https://portal.oxlo.ai
Step 1: Configure the Oxlo.ai client
Oxlo.ai exposes an OpenAI-compatible endpoint, so the official SDK drops right in. Replace the placeholder with your actual key before running the script.
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
Step 2: Define the system prompt
The system prompt locks the tone and structure. I treat this as the contract between my code and the model, and you can edit the sections to match your team's format.
SYSTEM_PROMPT = """You are a technical writing assistant that converts raw engineering bullet points into a concise weekly status report.
Rules:
- Output valid markdown.
- Include sections: Accomplishments, Blockers, Goals for Next Week.
- Keep each bullet to one or two sentences.
- Use a calm, professional tone.
- Do not invent facts that are not in the input."""
Step 3: Format the user input
I read bullet points from a text file and wrap them in a simple message. This keeps the CLI clean and lets me pipe data from other tools.
def load_bullets(path: str) -> str:
with open(path, "r", encoding="utf-8") as f:
return f.read().strip()
def build_user_message(bullets: str) -> str:
return f"Turn the following bullet points into a weekly status report.\n\nBullet points:\n{bullets}"
Step 4: Stream the report
We call Llama 3.3 70B, Oxlo.ai's general-purpose flagship. Streaming lets me watch the report appear in real time instead of waiting for the full response.
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
SYSTEM_PROMPT = """You are a technical writing assistant that converts raw engineering bullet points into a concise weekly status report.
Rules:
- Output valid markdown.
- Include sections: Accomplishments, Blockers, Goals for Next Week.
- Keep each bullet to one or two sentences.
- Use a calm, professional tone.
- Do not invent facts that are not in the input."""
def build_user_message(bullets: str) -> str:
return f"Turn the following bullet points into a weekly status report.\n\nBullet points:\n{bullets}"
def generate_report(bullets: str) -> None:
user_message = build_user_message(bullets)
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
stream=True,
temperature=0.4,
)
print("\n--- Generated Report ---\n")
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
print()
Step 5: Wire up the CLI
Argparse gives us a proper command-line interface. I also added a --model flag so you can try Qwen 3 32B or DeepSeek V3.2 on Oxlo.ai without changing code.
import argparse
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
SYSTEM_PROMPT = """You are a technical writing assistant that converts raw engineering bullet points into a concise weekly status report.
Rules:
- Output valid markdown.
- Include sections: Accomplishments, Blockers, Goals for Next Week.
- Keep each bullet to one or two sentences.
- Use a calm, professional tone.
- Do not invent facts that are not in the input."""
def load_bullets(path: str) -> str:
with open(path, "r", encoding="utf-8") as f:
return f.read().strip()
def build_user_message(bullets: str) -> str:
return f"Turn the following bullet points into a weekly status report.\n\nBullet points:\n{bullets}"
def main():
parser = argparse.ArgumentParser(description="Generate a weekly status report via Oxlo.ai")
parser.add_argument("--input", required=True, help="Path to a text file with bullet points")
parser.add_argument("--model", default="llama-3.3-70b", help="Oxlo.ai model ID")
args = parser.parse_args()
bullets = load_bullets(args.input)
user_message = build_user_message(bullets)
response = client.chat.completions.create(
model=args.model,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
stream=True,
temperature=0.4,
)
print("\n--- Generated Report ---\n")
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
print()
if __name__ == "__main__":
main()
Run it
Save your bullet points to bullets.txt:
- Fixed race condition in auth service causing intermittent 500s
- Migrated staging RDS instance to Graviton 4
- Drafted RFC for new caching layer
Then run the script:
python status_report.py --input bullets.txt --model llama-3.3-70b
You should see streamed markdown like this:
--- Generated Report ---
## Accomplishments
- Fixed a race condition in the auth service that was causing intermittent 500 errors.
- Migrated the staging RDS instance to Graviton 4 processors.
## Blockers
- None noted.
## Goals for Next Week
- Finalize the RFC for the new caching layer and circulate it for review.
Next steps
Add JSON mode to the Oxlo.ai call so you can pipe the structured sections straight into a Notion or Slack dashboard. If your team writes mostly code, swap in DeepSeek V3.2 on Oxlo.ai for tighter technical language. Both models sit on the same endpoint, so it is a one-line change.







