-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathmain.py
More file actions
154 lines (123 loc) · 4.61 KB
/
main.py
File metadata and controls
154 lines (123 loc) · 4.61 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from fastapi import FastAPI
from fastapi.concurrency import asynccontextmanager
from fastapi.routing import APIRoute
from fastapi.middleware.cors import CORSMiddleware
import database
from database import init_db, session_factory
from seed import seed_if_empty
from routes import main_router
from user.permission import Permission
import os
from fastapi.openapi.utils import get_openapi
import redis.asyncio as redis
def generate_unique_id(route: APIRoute):
if len(route.tags) > 0:
return f"{route.tags[0]}-{route.name}"
else:
return f"{route.path}{route.name}"
@asynccontextmanager
async def lifespan(app: FastAPI):
if not os.getenv("ENVIRONMENT") == "testing":
database.redis_client = redis.from_url(
os.getenv("REDIS_URL"),
decode_responses=True,
)
await database.redis_client.ping()
if os.getenv("ENVIRONMENT") == "development":
# Not needed if you setup a migration system like Alembic
init_db()
with session_factory() as db:
seed_if_empty(app, db)
elif os.getenv("ENVIRONMENT") == "testing":
init_db()
yield
# after yield comes shutdown logic
if os.getenv("ENVIRONMENT") != "testing":
if database.redis_client:
await database.redis_client.close()
database.redis_client = None
# No Swagger/OpenAPI page for production
no_docs = os.getenv("ENVIRONMENT") == "production"
dev_origins = [
"http://localhost:3000", # If we don't specify port, it defaults to 80
"http://127.0.0.1:3000",
"http://localhost:3001", # Sometimes VSCode thinks 3000 is used, so the frontend uses a higher port
"http://127.0.0.1:3001", # Wildcard ports don't work with cookies so we need this cursed mess :(
"http://localhost:3002",
"http://127.0.0.1:3002",
"http://localhost:3003",
"http://127.0.0.1:3003",
]
stage_origins = [
"https://stage.frontend.fsektionen.se",
"http://localhost:3000", # If we don't specify port, it defaults to 80
"http://127.0.0.1:3000",
"http://localhost:3001", # Sometimes VSCode thinks 3000 is used, so the frontend uses a higher port
"http://127.0.0.1:3001",
"http://localhost:3002",
"http://127.0.0.1:3002",
"http://localhost:3003",
"http://127.0.0.1:3003",
]
production_origins = ["https://fsektionen.se"]
app = FastAPI(
lifespan=lifespan,
redoc_url=None if no_docs else "/redoc",
docs_url=None if no_docs else "/docs",
generate_unique_id_function=generate_unique_id,
)
if os.getenv("ENVIRONMENT") == "development":
app.add_middleware(
CORSMiddleware,
allow_origins=dev_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
if os.getenv("ENVIRONMENT") == "stage":
app.add_middleware(
CORSMiddleware,
allow_origins=stage_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
if os.getenv("ENVIRONMENT") == "production":
app.add_middleware(
CORSMiddleware,
allow_origins=production_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(router=main_router)
def custom_openapi(): # type: ignore
if app.openapi_schema:
return app.openapi_schema
# Generate the default OpenAPI schema
openapi_schema = get_openapi(
title=app.title,
version=app.version,
description=app.description,
routes=app.routes,
)
# Override the servers list to include only http://localhost:8000
# Uncomment the line below when generating with openapi-generator in flutter app
# openapi_schema["servers"] = [{"url": "http://10.0.2.2:8000"}]
# Cache the schema for future calls
app.openapi_schema = openapi_schema
return app.openapi_schema
# Override FastAPI's default OpenAPI generation with our custom function
app.openapi = custom_openapi
@app.get("/")
def hello_route():
return {"message": "Välkommen till F-Sektionens bäckend"}
@app.get("/user-only", dependencies=[Permission.base()])
def user_only():
return {"message": "Hello, you are a user."}
@app.get("/member-only", dependencies=[Permission.member()])
def member_only():
return {"message": "Congratz! Only members can reach this route"}
@app.get("/manage-event-only", dependencies=[Permission.require("manage", "Event")])
def permission_route():
return {"message": "Congratz. You reached a manage:Event route"}