diff --git a/README.md b/README.md
index 0fd648c..e49e379 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,17 @@ This is an API for anime-girls-and-computers [github repo](https://github.com/TH
How to host your own AGAC API instance
### π¬ Docker Method (recommended)
-Coming Soonβ’
+1. Pull the image
+```sh
+docker pull r3tr0ananas/agac-api:latest
+```
+2. Then launch a container with this command.
+> *you don't really need to mount a volume but it's recommended*
+```sh
+docker run -p 8000:8000/tcp -v ./cached_images:/app/assets/cache r3tr0ananas/agac-api:latest
+```
+3. Now visit ``localhost:8000`` in your browser and there you go! π
+> *if you wanna use docker-compose, [this file](./docker-compose.yml) might be useful to you*
### π Native Method (recommended for development)
@@ -41,8 +51,8 @@ make
```sh
make get-repo
```
-5. Run that sh#t.
+5. Run.
```sh
make run
```
-6. Visit ``localhost:8083`` in your browser, then all should be good! π
+6. Visit ``localhost:8083`` in your browser, then all should be good! π
\ No newline at end of file
diff --git a/api/__init__.py b/api/__init__.py
index 5da0b9a..f74f503 100644
--- a/api/__init__.py
+++ b/api/__init__.py
@@ -1 +1 @@
-__version__ = "1.1.2"
\ No newline at end of file
+__version__ = "1.1.3"
\ No newline at end of file
diff --git a/api/errors.py b/api/errors.py
index 8e1b3ba..e87e2ad 100644
--- a/api/errors.py
+++ b/api/errors.py
@@ -54,12 +54,27 @@ class ImageMetadataNotFound(BaseModel):
}
}
+class RateLimited(BaseModel):
+ error: str
+ message: str
+
+ model_config = {
+ "json_schema_extra": {
+ "examples": [
+ {
+ "error": "RateLimited",
+ "message": "Rate limit exceeded: 3 per 1 second (Follow the rates: https://github.com/r3tr0ananas/agac-api/wiki#-rate-limiting)"
+ }
+ ]
+ }
+ }
+
def rate_limit_handler(request: Request, exc: RateLimitExceeded):
response = JSONResponse(
status_code = 429,
content = {
"error": "RateLimited",
- "message": f"Rate limit exceeded: {exc.detail} (Follow the rates: https://github.com/r3tr0ananas/agac-api/wiki#rate-limiting)"
+ "message": f"Rate limit exceeded: {exc.detail} (Follow the rates: https://github.com/r3tr0ananas/agac-api/wiki#-rate-limiting)"
}
)
diff --git a/api/main.py b/api/main.py
index e9569c0..f717f92 100644
--- a/api/main.py
+++ b/api/main.py
@@ -19,16 +19,43 @@
ROOT_PATH = (lambda x: x if x is not None else "")(environ.get("ROOT_PATH"))
+TAGS_METADATA = [
+ {
+ "name": "image",
+ "description": "The main endpoints that allow you to get images."
+ },
+ {
+ "name": "other",
+ "description": "Other endpoints."
+ }
+]
+
+DESCRIPTION = """
+
+
+
+
+ The **anime-girls-and-computers** API!
+
+ This is an API for anime-girls-and-computers [github repo](https://github.com/THEGOLDENPRO/anime-girls-and-computers).
+
+ Report bugs [over here](https://github.com/r3tr0ananas/agac-api/issues).
+
+
+
+Rate limiting applies to the ``/random`` and ``/get`` endpoints. Check out the rate limits [over here](https://github.com/r3tr0ananas/agac-api/wiki#-rate-limiting).
+"""
+
+
limiter = Limiter(key_func=get_remote_address, headers_enabled = True)
app = FastAPI(
title = "AGAC-API",
- description = "",
+ description = DESCRIPTION,
license_info = {
- "name": "MIT",
+ "name": "License: MIT",
"identifier": "MIT",
- },
+ },
version = f"v{__version__}",
-
root_path = ROOT_PATH
)
app.state.limiter = limiter
@@ -38,9 +65,9 @@
@app.get(
"/",
- tags = ["misc"]
+ tags = ["other"]
)
-async def root(request: Request):
+async def root():
return RedirectResponse(f"{ROOT_PATH}/docs")
@app.get(
@@ -49,7 +76,7 @@ async def root(request: Request):
tags = ["other"]
)
async def info():
- """Returns repository information like image count and etc."""
+ """Returns repository information like image count and etc."""
return {
"version": __version__,
"image_count": len(agac.images)
@@ -67,7 +94,7 @@ async def info():
}
},
)
-async def all(request: Request):
+async def all():
return [
image.to_dict() for image in agac.images
]
@@ -89,6 +116,10 @@ async def all(request: Request):
"model": errors.ImageNotFound,
"description": "The image was not Found."
},
+ 429: {
+ "model": errors.RateLimited,
+ "description": "Rate Limit exceeded"
+ }
},
)
@limiter.limit(f"{RATE_LIMIT}/second")
@@ -122,7 +153,7 @@ async def get(request: Request, id: str, raw: bool = False):
},
},
)
-async def get_metadata(request: Request, id: str):
+async def get_metadata(id: str):
image = agac.get(id)
if image is not None:
@@ -140,6 +171,7 @@ async def get_metadata(request: Request, id: str):
"/random",
name = "Get a random image",
tags = ["image"],
+ description = "To retrieve metadata for a random image, check the `x-image-id` header for the search ID.",
response_class = FileResponse,
responses = {
200: {
@@ -149,6 +181,10 @@ async def get_metadata(request: Request, id: str):
},
"description": "Returned an image successfully. π",
},
+ 429: {
+ "model": errors.RateLimited,
+ "description": "Rate Limit exceeded"
+ }
},
)
@limiter.limit(f"{RATE_LIMIT}/second")
@@ -170,7 +206,6 @@ async def random_image(request: Request, category: str = None, raw: bool = False
},
)
async def search(
- request: Request,
query: str,
category: str = None,
limit: int = 10
@@ -199,7 +234,7 @@ async def search(
"/search/advanced",
name = "Advanced Search for images.",
tags = ["image"],
- description = "You add multiple tags by adding \",\" after each tag",
+ description = "You can add multiple tags by adding \",\" after each tag",
response_class = JSONResponse,
responses = {
200: {
@@ -209,7 +244,6 @@ async def search(
},
)
async def search_advanced(
- request: Request,
tags: str = "",
author: str = None,
limit: int = 10
@@ -247,7 +281,5 @@ async def search_advanced(
},
},
)
-async def categories(request: Request):
- return list(agac.categories.keys())
-
-
+async def categories():
+ return list(agac.categories.keys())
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..9893baa
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,8 @@
+services:
+ agac-api:
+ image: r3tr0ananas/agac-api:latest
+ volumes:
+ - ./cached_images:/app/assets/cache
+ environment:
+ ROOT_PATH: ""
+ restart: unless-stopped
\ No newline at end of file