The FastAPI REST API is working great when checked in the local browser and with the Advanced REST client Chrome plugin (only while using the XHR enabled).
But in no way are the same API accessible via the Android App running inside an emulator.
The info message in FastAPI console when accessed via Android App
127.0.0.1:57083 - "POST /v1/login HTTP/1.1" 307 Temporary Redirect
This is what is configured while loading the FastAPI
api = FastAPI(title=PROJECT_NAME)
if not ALLOWED_HOSTS:
ALLOWED_HOSTS = ["*"]
api.add_middleware(
CORSMiddleware,
allow_origins=ALLOWED_HOSTS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Any help would be greatly appreciated.
Hard to say exactly what鈥檚 going on here without more detail (eg, what are the raw 307 http response contents? what is the redirect url? what do the server request logs contain?) but my guess is something is going on with a trailing slash. Possibly your android client is modifying the url to add a trailing slash? Or maybe performing some other url modification starlette is able to handle via redirect?
Sorry about that. Here are the details via CURL
sushil@Sushils-MacBook % curl -v -X POST -H "Origin: http://aws.indonis.com" http://localhost:8000/v1/login
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 8000 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> POST /v1/login HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.64.1
> Accept: */*
> Origin: http://aws.indonis.com
>
< HTTP/1.1 307 Temporary Redirect
< date: Mon, 25 Nov 2019 03:22:56 GMT
< server: uvicorn
< location: http://localhost:8000/v1/login/
< access-control-allow-origin: *
< transfer-encoding: chunked
<
* Connection #0 to host localhost left intact
* Closing connection 0
sushil@Sushils-MacBook-Pro indonis_api %
Below is how the FastAPI server has been setup
# Read settings for API project
api_settings = get_api_settings()
api = FastAPI(title=PROJECT_NAME)
# Attach the Sync API router
api.include_router(sync_api, prefix=api_settings.api_v1_route)
# Set the GzipRoute
api.router.route_class = GzipRoute
# Allow cross origin for Dev purpose
if not ALLOWED_HOSTS:
ALLOWED_HOSTS = ["http://aws.indonis.com"]
api.add_middleware(
CORSMiddleware,
allow_credentials=False,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"]
)
api.add_exception_handler(HTTPException, http_error_handler)
api.add_exception_handler(HTTP_422_UNPROCESSABLE_ENTITY, http_422_error_handler)
uvicorn.run("app.main:api", host="0.0.0.0", port=8080, reload=True)
Quite curious to know what's being missed out.
Yeah, you can see it is trying to redirect you to the endpoint with a trailing slash:
< HTTP/1.1 307 Temporary Redirect
< date: Mon, 25 Nov 2019 03:22:56 GMT
< server: uvicorn
< location: http://localhost:8000/v1/login/
The problem is in code you didn't share -- wherever you've defined your endpoint, the path you are providing is ending with a "/"
. If you remove that trailing slash (or put a ?
after it, if you want it to work both ways), this issue should go away.
It works in a browser just fine because the browser is just following the redirect automatically.
Wow, that really was the cause of the issue, indeed. After removing the trailing "/" now both the REST API Client and the Android Emulator are able to connect to the REST API.
Thank you very much. This was really really helpful. Much appreciated :-)
Thanks for the help here @dmontagu ! :clap: :bow:
Thanks for reporting back and closing the issue @sushaeel :+1:
Unfortunately, "/?" no longer works in the versions since April @tiangolo as reported in #1787 and #1648
Most helpful comment
Yeah, you can see it is trying to redirect you to the endpoint with a trailing slash:
The problem is in code you didn't share -- wherever you've defined your endpoint, the path you are providing is ending with a
"/"
. If you remove that trailing slash (or put a?
after it, if you want it to work both ways), this issue should go away.It works in a browser just fine because the browser is just following the redirect automatically.