{"id":20292713,"url":"https://github.com/hayabhay/megadetector-fastapi","last_synced_at":"2025-04-11T11:23:32.736Z","repository":{"id":65278760,"uuid":"530491265","full_name":"hayabhay/megadetector-fastapi","owner":"hayabhay","description":"MegaDetector models served over FastAPI \u0026 visualized with Streamlit","archived":false,"fork":false,"pushed_at":"2023-05-09T22:13:38.000Z","size":6368,"stargazers_count":10,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T07:41:42.052Z","etag":null,"topics":["fastapi","megadetector","object-detection","python","streamlit","yolov5"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hayabhay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-30T04:09:00.000Z","updated_at":"2024-11-29T22:02:18.000Z","dependencies_parsed_at":"2024-11-14T15:18:44.392Z","dependency_job_id":"9b5f692c-acaa-4ee0-bd60-0913c2c70534","html_url":"https://github.com/hayabhay/megadetector-fastapi","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabhay%2Fmegadetector-fastapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabhay%2Fmegadetector-fastapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabhay%2Fmegadetector-fastapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabhay%2Fmegadetector-fastapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hayabhay","download_url":"https://codeload.github.com/hayabhay/megadetector-fastapi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248382262,"owners_count":21094559,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastapi","megadetector","object-detection","python","streamlit","yolov5"],"created_at":"2024-11-14T15:18:33.809Z","updated_at":"2025-04-11T11:23:32.703Z","avatar_url":"https://github.com/hayabhay.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MegaDetector with FastAPI \u0026 Streamlit\n\nThis repo packages [MegaDetector](https://github.com/microsoft/CameraTraps/blob/main/megadetector.md) models and serves them over [FastAPI](https://fastapi.tiangolo.com/). Additionally, it comes with a simple [Streamlit](https://streamlit.io/) UI to visualize \u0026 compare annotations from different models.\n\nMost of the code is directly copied from MegaDetector's source repo. Any additional code form thin wrappers to streamline some interfaces \u0026 dependencies for the API.\n\n**Why FastAPI?** - FastAPI is async-first and also comes with nice things like Pydantic validation \u0026 Swagger UI out of the box. Async in the context of cloud endpoints and large batches of images is particularly useful since it allows images to be downloaded in parallel significantly lowering CPU-idle time and its associated cloud costs.\n\n**Why Streamlit** - Streamlit is an extremely simple, pure Python way to build web GUIs. While Swagger UI allows API interactions, the outputs are still raw JSON. Streamlit complements this with visualization of annotated images with trivial amounts of python code.\n\n![MegaDetector Streamlit demo](/assets/streamlit_demo.gif)\n\n## Getting Started\n\n**Pre-requisite**: A fresh `python-3.9` virtual environment ([Pyenv](https://realpython.com/intro-to-pyenv/)+[Virtualenv](https://virtualenv.pypa.io/en/latest/). [Conda](https://docs.conda.io/en/latest/) etc.). If you're using a GPU, this also assumes you have set up the necessary drivers.\n\n\u003e **Note**: This code is tested on `python 3.9` and will likely work on `python 3.7+` (untested for now).\n\n**Step 1**: Clone this repo.\n\n```\ngit clone https://github.com/abhay1/megadetector-fastapi.git\ncd megadetector-fastapi\n```\n\n**Step 2**: Install python dependencies.\n\n```\npip install -r requirements/requirements-dev.txt\n```\n\n\u003e **Note**: There are several requirements files to choose from. For local development purposes, we'll install the GPU enabled version of PyTorch \u0026 Tensorflow. Later, when dockerizing it, you can pick and choose from them depending on the model you wish to use.\n\n**Step 3**: Run the FastAPI app.\n```\ncd api\nuvicorn main:app --port 8000 --reload\n```\nYou should now be able to navigate to [http://127.0.0.1:8000](http://127.0.0.1:8000) and see a welcome message. FastAPI comes with [Swagger UI](https://swagger.io/tools/swagger-ui/) and [ReDoc](https://redocly.com/) out of the box that you can find at [/docs](http://127.0.0.1:8000/docs) \u0026 [/redoc](http://127.0.0.1:8000/redoc). You can use this to interact with the server and you'll see it's JSON responses.\n\n![MegaDetector FastAPI demo](/assets/api_demo.gif)\n\n**Step 4**: Run the Streamlit app.\n```\ncd ../ui/\nstreamlit run app.py\n```\nYou should now be able to navigate to [http://127.0.0.1:8501](http://127.0.0.1:8501) to see the Streamlit app live!\n`8501` is the default starting port and if you want to change it, you can pass it in like this\n`streamlit run app.py --server.port 8001` or [use other supported methods](https://docs.streamlit.io/library/advanced-features/configuration).\n\n\u003e **Note**: Streamlit reads the FastAPI server location from an environment variable `MEGADETECTOR_API_URL` and defaults to `http://127.0.0.1:8000/` if it is missing. If the server port is different, you can directly update it in the `config.py` file or put it in a `.env` file (like this `MEGADETECTOR_API_URL='http://127.0.0.1:8000'`) which might be preferrable if the URL is public and shouldn't be on git.\n\n## Deployment\n\nThere is a docker template to containerize the application and deploy it. Currently, the configuration is tailored to create containers that run on CPUs. This is primarily for Cloud based APIs, specifically, Google Cloud Run (soon to be tested).\n\nDeployment strategies like Google Cloud Run spin up instances on demand. In this setting, instead of downloading the MegaDetector model everytime,  it might be useful to create images with the MegaDetector models baked in the container images. However, to keep them light, it is best to only have a specific model in addition to its required dependencies installed (PyTorch \u0026 Tensorflow).\n\n## Batch of Images\n\nFastAPI, with uvicorn is async by default i.e. subsequent calls to the server aren't blocked by I/O from previous calls. For synchronous services like Flask, this is usually supported by adding threads/workers to gunicorn. Regardless, to leverage this, the calling application also needs to use an async client like `httpx` or `aiohttp` instead of sync clients like `requests`. Or, it needs to make requests in a threadpool. ([more details](https://www.twilio.com/blog/asynchronous-http-requests-in-python-with-httpx-and-asyncio))\n\nHere is an example of calling this API with `httpx` for a list of image urls (or base64 encoded strings).\n\n```\nimport asyncio\nimport httpx\n\n# List of image urls to call the API with\nimages = [...]\n\n# Async function to get annotation for an image\nasync def get_annotation(image, client):\n    response = await client.post(url,json={\"image\": image})\n    return response.json()[\"annotation\"]\n\n# Use asyncio to make concurrent requests with httpx\nasync with httpx.AsyncClient() as client:\n    # Create a list of tasks to run concurrently\n    tasks = [\n        get_annotation(\n            image=image,\n            url=\"http://127.0.0.1:8000/annotate/\",\n            client=client\n        )\n        for image in images\n    ]\n    # Run inference on each image in the list\n    # * operator here simply unpacks the list\n    results = await asyncio.gather(*tasks)\n```\nThat's it!\n\n## Issues, Comments \u0026 Feedback\n\n- For bugs \u0026 feature requests, please [open an issue](https://github.com/abhay1/megadetector-fastapi/issues/new/choose).\n- For feedback, suggestions \u0026 ideas, please leave a comment on the [discussion forum](https://github.com/abhay1/megadetector-fastapi/discussions).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhayabhay%2Fmegadetector-fastapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhayabhay%2Fmegadetector-fastapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhayabhay%2Fmegadetector-fastapi/lists"}