FastApi and VueJS routing

I started building a hobby project with FastApi backend and VueJS frontend. The frontend should be served with the uvicorn service of the backend. But how to allow the vuejs-router to be used.

My solution for the moment is to use the 404-handler of FastApi to route all 404s to VueJS and let the vuejs-router handle the remaining requests.

The frontend is build this way:

vite build --outDir ../app/dist --emptyOutDir

The outDir is in the the FastApi app folder, is mounted as StaticFolder and in the 404-handler.

A minimal working main.py example:

from pathlib import Path

from fastapi import FastAPI, Request
from fastapi.exceptions import HTTPException
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles

app = FastAPI()

@app.get("/ping")
async def ping():
    return "pong"

@app.exception_handler(404)
async def redirect_all_requests_to_frontend(request: Request, exc: HTTPException):
    return HTMLResponse(open(Path(__file__).parent / "dist/index.html").read())

app.mount(
    "/assets",
    StaticFiles(directory=Path(__file__).parent / "dist/assets"),
    name="assets",
)

All routes of the FastApi app have precedence, everything else is handled by the 404-handler and routed to the VueJS app. Real 404s should be handled within the vuejs-router. For example like this:

{
  path: '/:catchAll(.*)',
  component: () => import('./components/notfound.vue')
}

The order in the vuejs-router matters, so putting the notfound route at the end should do the trick.

Use Google Text-to-Speech

For a project idea I want to see the quality of Google TTS as a reader of a longer story.

Again the most complicated thing is getting the correct key-file to be allowed to call the API. Thankfully the quickstart-guide helps here:

# replace YOUR_PROJECT with the correct value for your project

# create a service account named "tts-quickstart"
gcloud iam service-accounts create tts-quickstart --project YOUR_PROJECT

# give the new user the right "roles/viewer"
gcloud projects add-iam-policy-binding YOUR_PROJECT --member \
  serviceAccount:tts-quickstart@YOUR_PROJECT.iam.gserviceaccount.com \
  --role roles/viewer

# export the key as json file
gcloud iam service-accounts keys create tts-key.json \
  --iam-account tts-quickstart@YOUR_PROJECT.iam.gserviceaccount.com

# and now set it in the environment for the script below to actually use it
export GOOGLE_APPLICATION_CREDENTIALS=tts-key.json

Next the actual Python code that uses the API to generate an mp3 file for a given text.

from google.cloud import texttospeech_v1beta1 as tts

client = tts.TextToSpeechClient()

request = tts.SynthesizeSpeechRequest(
    input=tts.SynthesisInput(
        text="There was a stream at the foot of the hill. "
        "They filled their bottles and the small camping "
        "kettle at a little fall where the water fell a few "
        "feet over an outcrop of grey stone. "
        "It was icy cold; and they spluttered and puffed "
        "as they bathed their faces and hands."
    ),
    voice=tts.VoiceSelectionParams(
        language_code="en-GB", name="en-GB-Neural2-D"
    ),
    audio_config=tts.AudioConfig(
        audio_encoding=tts.AudioEncoding.MP3
  ),
)

response = client.synthesize_speech(request=request)
with open("output.mp3", "wb") as fp:
    fp.write(response.audio_content)

I selected the voice en-GB-Neural2-D on the demo website of Google TTS. The quality seems good enough for my usecase.

Resurrect an old smartphone Part 2

As a follow-up to my previous post, I did the same for a Pocophone F1. I already unlocked it years ago. Unlocking is really annoying here, because it needs Windows 7+, a sim-card and 3 days of waiting.

The Pocophone F1 was already on Android 9 (LineageOS 16) and I want to install Android 13 (LineageOS 20). The first thing I found out: bootloader and recovery have different keys to press. To get into the bootloader (to install the recovery) you have to press Volume-DOWN and Power. To get into the recovery you have to press Volume-UP and Power. And the second thing, I need of course a newer firmware.

So the newer firmware first. To install it the correct twrp is needed:

fastboot flash recovery twrp-3.7.0_9-0-beryllium.img

Boot into the twrp recovery, go to "advanced" / "ADB Sideload" and sideload the current firmware:

adb sideload fw_beryllium_miui_POCOF1Global_V12.0.3.0.QEJMIXM_cf3fccffce_10.0.zip

Then reboot into the bootloader.

Second step: install the current LineageOS recovery for the Pocophone F1.:

fastboot flash recovery lineage-20.0-20230218-recovery-beryllium.img

Disclaimer: The next step will erase everything on your phone!

Then Factory reset: Format data/factory. And install the new Android via "Apply Update" / "ADB sideload":

adb sideload lineage-20.0-20230218-nightly-beryllium-signed.zip

Finally install the matching GoogleApps which is the one for Android 13 arm64:

adb sideload MindTheGapps-13.0.0-arm64-20221025_100653.zip

Now reboot and enjoy Android 13 (LineageOS 20) on a Pocophone F1.