-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
130 lines (103 loc) · 4.04 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import os
import logging
import uvicorn
import importlib.util
import time
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.openapi.utils import get_openapi
from starlette.middleware import Middleware
from starlette.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from slowapi import Limiter
from slowapi.util import get_ipaddr
from fastapi_cache import FastAPICache
from fastapi_cache.backends.inmemory import InMemoryBackend
from utils.utils import config
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
limiter = Limiter(key_func=get_ipaddr)
middleware = [
Middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
),
Middleware(
GZipMiddleware,
minimum_size=500
)
]
app = FastAPI(middleware=middleware)
app.mount("/static", StaticFiles(directory="static"), name="static")
def include_routers(app, directory):
for filename in os.listdir(directory):
if filename.endswith(".py") and not filename.startswith("__"):
module_name = filename[:-3]
file_path = os.path.join(directory, filename)
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
router = getattr(module, "router", None)
if router:
app.include_router(router)
# Include routers from public and private directories
include_routers(app, os.path.join(os.path.dirname(__file__), "routers", "public"))
include_routers(app, os.path.join(os.path.dirname(__file__), "routers", "v2"))
@app.on_event("startup")
async def startup_event():
FastAPICache.init(InMemoryBackend())
@app.get("/", include_in_schema=False, response_class=RedirectResponse)
async def docs():
if config.is_local:
return RedirectResponse(f"http://localhost/docs")
return RedirectResponse(f"https://api.clashk.ing/docs")
@app.get("/openapi/private", include_in_schema=False)
async def get_private_openapi():
from fastapi.openapi.utils import get_openapi
print(app.routes[0].__dict__)
routes = [route for route in app.routes if not route.__dict__.get('include_in_schema')]
for route in routes:
route.__dict__['include_in_schema'] = True
schema = get_openapi(
title="Private Endpoints",
version="1.0.0",
routes=routes,
)
for route in routes:
route.__dict__['include_in_schema'] = False
return schema
@app.get("/private/docs", include_in_schema=False)
async def get_private_docs():
return get_swagger_ui_html(openapi_url="/openapi/private", title="Private API Docs")
description = """
### Clash of Clans Based API 👑
- No Auth Required, Free to Use
- Please credit if using these stats in your project, Creator Code: ClashKing
- Ratelimit is largely 30 req/sec, 5 req/sec on post & large requests
- Largely 300 second cache
- Not perfect, stats are collected by polling the Official API
- [ClashKing Discord](https://discord.gg/clashking) | [API Developers](https://discord.gg/clashapi)
This content is not affiliated with, endorsed, sponsored, or specifically approved by Supercell and Supercell is not responsible for it.
For more information see [Supercell’s Fan Content Policy](https://supercell.com/fan-content-policy)
"""
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="ClashKingAPI",
version="0.1",
description=description,
routes=app.routes,
)
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
if __name__ == "__main__":
if config.is_local:
uvicorn.run("main:app", host="localhost", port=8000, reload=True)
else:
uvicorn.run("main:app", host="0.0.0.0", port=8010)