From 8fdc80ea0732034968a732171af52e64bdbec2e7 Mon Sep 17 00:00:00 2001 From: jbcodeforce Date: Wed, 24 Apr 2024 08:49:44 -0700 Subject: [PATCH] add fast api web socker and streaming api --- docs/python/faq.md | 6 +++++- docs/python/pydantic.md | 2 ++ {web-server => web_server}/Dockerfile | 0 web_server/api_stream/client.py | 6 ++++++ web_server/api_stream/server.py | 21 +++++++++++++++++++ web_server/api_stream/start_server.sh | 1 + {web-server => web_server}/fastapi_main.py | 0 {web-server => web_server}/requirements.txt | 0 .../websocket_server/TestWSServer.py | 0 .../websocket_server/a_client.py | 0 .../websocket_server/main.py | 0 11 files changed, 35 insertions(+), 1 deletion(-) rename {web-server => web_server}/Dockerfile (100%) create mode 100644 web_server/api_stream/client.py create mode 100644 web_server/api_stream/server.py create mode 100644 web_server/api_stream/start_server.sh rename {web-server => web_server}/fastapi_main.py (100%) rename {web-server => web_server}/requirements.txt (100%) rename {web-server => web_server}/websocket_server/TestWSServer.py (100%) rename {web-server => web_server}/websocket_server/a_client.py (100%) rename {web-server => web_server}/websocket_server/main.py (100%) diff --git a/docs/python/faq.md b/docs/python/faq.md index bf07639..4a6a4ae 100644 --- a/docs/python/faq.md +++ b/docs/python/faq.md @@ -279,4 +279,8 @@ A scope is a textual region of a Python program, where a namespace is directly a ???- question "How to program web socket server" - See [FastAPI doc](https://fastapi.tiangolo.com/advanced/websockets/) with [testing](https://fastapi.tiangolo.com/advanced/testing-websockets/) and matching code in [](https://github.com/jbcodeforce/python-code/tree/master/web-server/websocket_server) \ No newline at end of file + See [FastAPI doc](https://fastapi.tiangolo.com/advanced/websockets/) with [testing](https://fastapi.tiangolo.com/advanced/testing-websockets/) and matching code in [websocket_server](https://github.com/jbcodeforce/python-code/tree/master/web_server/websocket_server) + +???- question "Using async IO?" + async IO is a single-threaded, single-process design: it uses cooperative multitasking. [See this tutorial](https://realpython.com/async-io-python/): concurrency encompasses both multiprocessing (ideal for CPU-bound tasks) and threading (suited for IO-bound tasks). Async io is supported by `async` and `await` language keywords. Asynchronous routines are able to “pause” while waiting on their ultimate result and let other routines run in the meantime. `await` passes function control back to the event loop + See code in [api_stream](https://github.com/jbcodeforce/python-code/tree/master/web_server/api_stream/) \ No newline at end of file diff --git a/docs/python/pydantic.md b/docs/python/pydantic.md index cef6007..8a4e571 100644 --- a/docs/python/pydantic.md +++ b/docs/python/pydantic.md @@ -1,2 +1,4 @@ # Pydantic +[]() + diff --git a/web-server/Dockerfile b/web_server/Dockerfile similarity index 100% rename from web-server/Dockerfile rename to web_server/Dockerfile diff --git a/web_server/api_stream/client.py b/web_server/api_stream/client.py new file mode 100644 index 0000000..82d8709 --- /dev/null +++ b/web_server/api_stream/client.py @@ -0,0 +1,6 @@ +import requests + + +with requests.get("http://localhost:8000", stream=True) as r: + for chunk in r.iter_content(100): + print(chunk) \ No newline at end of file diff --git a/web_server/api_stream/server.py b/web_server/api_stream/server.py new file mode 100644 index 0000000..cea1010 --- /dev/null +++ b/web_server/api_stream/server.py @@ -0,0 +1,21 @@ +from fastapi import FastAPI +from typing import Generator +from fastapi.responses import StreamingResponse + +app = FastAPI() + +# coroutine which will suspend the execution if there is await or yield +# yield creates an asynchronous generator, which we iterate over with async for. +async def fake_video_streamer(): + for i in range(10): + yield b"some fake video bytes" + +# another example +# A simple method to open the file and get the data +async def get_data_from_file(file_path: str) -> Generator: + with open(file=file_path, mode="rb") as file_like: + yield file_like.read() + +@app.get("/") +async def main(): + return StreamingResponse(content=fake_video_streamer(),media_type="text/media") \ No newline at end of file diff --git a/web_server/api_stream/start_server.sh b/web_server/api_stream/start_server.sh new file mode 100644 index 0000000..573977f --- /dev/null +++ b/web_server/api_stream/start_server.sh @@ -0,0 +1 @@ +uvicorn server:app --port 8000 \ No newline at end of file diff --git a/web-server/fastapi_main.py b/web_server/fastapi_main.py similarity index 100% rename from web-server/fastapi_main.py rename to web_server/fastapi_main.py diff --git a/web-server/requirements.txt b/web_server/requirements.txt similarity index 100% rename from web-server/requirements.txt rename to web_server/requirements.txt diff --git a/web-server/websocket_server/TestWSServer.py b/web_server/websocket_server/TestWSServer.py similarity index 100% rename from web-server/websocket_server/TestWSServer.py rename to web_server/websocket_server/TestWSServer.py diff --git a/web-server/websocket_server/a_client.py b/web_server/websocket_server/a_client.py similarity index 100% rename from web-server/websocket_server/a_client.py rename to web_server/websocket_server/a_client.py diff --git a/web-server/websocket_server/main.py b/web_server/websocket_server/main.py similarity index 100% rename from web-server/websocket_server/main.py rename to web_server/websocket_server/main.py