Init
This commit is contained in:
+174
@@ -0,0 +1,174 @@
|
||||
from contextlib import asynccontextmanager
|
||||
from fastapi import FastAPI
|
||||
from .exceptions import ExceptionHandlerRoute
|
||||
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from sqlalchemy.orm import Session
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from .models import Users
|
||||
from .db.db import engine
|
||||
from .db.config import settings
|
||||
from .middlewares import app_middleware
|
||||
from .auth.views import get_password_hash
|
||||
from .routes import routers, docs
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def init_db(app: FastAPI):
|
||||
with Session(engine) as session:
|
||||
from sqlalchemy import select, insert
|
||||
user = session.execute(select(Users).where(Users.username == settings.FIRST_SUPERUSER)).first()
|
||||
if not user:
|
||||
session.execute(insert(Users).values(
|
||||
username = settings.FIRST_SUPERUSER,
|
||||
hashed_password = get_password_hash(settings.FIRST_SUPERUSER_PASSWORD),
|
||||
full_name = "admin",
|
||||
type = 'ADMIN',
|
||||
email = settings.FIRST_SUPERUSER_EMAIL
|
||||
))
|
||||
session.commit()
|
||||
yield
|
||||
|
||||
description = """
|
||||
# Description
|
||||
This part of the documentation includes overview of the backend, backend internals and common attributes shared by all the apis.
|
||||
|
||||
The backend is written using [FastAPI](https://fastapi.tiangolo.com/), [SQLAlchemy](https://www.sqlalchemy.org/) and [Postgresql](https://www.postgresql.org/).
|
||||
|
||||
## Documentation
|
||||
Redoc with openapi will serve as primary documentation, which will be available publicly in development and staging environment and not for production evnrionment for security reasons.
|
||||
|
||||
## Authorization
|
||||
Authorization is implemended using OAuth2 using password and username, logging with external providers like google, github etc. is not supported.
|
||||
|
||||
Each type of user i.e. doctor, patient, staff is required to create their own username and password while registering, so that will be able to login to the system.
|
||||
|
||||
The auth token expiry duration is 120 minutes currently
|
||||
|
||||
|
||||
## Common columns
|
||||
All tables in the backend shares some common columns, these columns will be described here and not in the respective API as it has the same meaning everywhere.
|
||||
|
||||
|
||||
1. __created_at, updated_at__ : represents the datetime when the row was added, updated respectively
|
||||
|
||||
2. __create_by_id, updated_by_id__ : foreign key to user's id, it's extracted from the logged in user who created or updated the row.
|
||||
|
||||
3. __is_archived__ : It represents if the row is deleted, allows us to implement soft delete.
|
||||
|
||||
|
||||
## Audit
|
||||
|
||||
Each table on the backend has it's respective audit table with suffix ___audit__. i.e __appointment__ table has __appointment_audit__.
|
||||
It stores all the changes done in each row including which operation it was, which columns were changed and what's it's old and new values.
|
||||
|
||||
APIs will be created to access the audit for each table.
|
||||
|
||||
It's implemented using sqlalchemy_declarative_extention library
|
||||
|
||||
## Internals
|
||||
|
||||
### Primary, Foreign Key
|
||||
|
||||
All primary keys are [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), which makes it possible to avoid alot of security risks and implement dynamic features.
|
||||
Due to this all the foreign keys are also UUIDs
|
||||
UUIDs can be generated in postgres or in python easy and fast
|
||||
|
||||
## Errors
|
||||
|
||||
Errors are implemented using [RFC9457](https://www.rfc-editor.org/rfc/rfc9457.html) with some slight modification. Here is a sample error response.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "UNIQUE_VALIDATION",
|
||||
"status": 422,
|
||||
"detail": "Key (username)=(banana) already exists.",
|
||||
"title": "Unique violation"
|
||||
}
|
||||
```
|
||||
|
||||
The type will always be a standard enum value. the status will always be the http status code.
|
||||
The type, status, title and detail will __always__ exist,
|
||||
|
||||
For now in case of pydantic validation error, the raw pydantic message will be set in details
|
||||
|
||||
In case of internal server error the type will be 'INTERNAL_SERVER_ERROR' and it's detail will contain the error message.
|
||||
|
||||
In this way all the errors will be well documented and handled in a central module, It will also make writing automated tests easier.
|
||||
|
||||
|
||||
# Testing
|
||||
This section covers the steps for testing and guidelines for reporting and verifying bugs for backend api.
|
||||
In the future the manual for QA for frontend will also be included here.
|
||||
|
||||
|
||||
## Automated testing
|
||||
Automated testing is done using fastapi's testclient, pytest and faker
|
||||
This test creates new database on startup, runs the tests and deletes everything, so the errors i can be reproduceable and deterministic.
|
||||
The test interacts to the backend only thru API
|
||||
|
||||
### Prerequisites
|
||||
1. Python
|
||||
2. Postgresql server with a clean database (You can avoid it by using test database on the server)
|
||||
|
||||
### Steps
|
||||
1. Clone the [repository](https://git.aayutech.dev/fourleaf/backend)
|
||||
2. Create .env file using .env.example as reference
|
||||
3. Create virtual environment and install packages from requirements.txt
|
||||
4. Run tests using pytest (lookup pytest's documentation for more information)
|
||||
5. Create a test inside the tests folder
|
||||
|
||||
|
||||
## Manual testing
|
||||
Manual testing is done using postman or similar api client.
|
||||
Url for testing in dev environment is `https://api-dev.aayutech.dev`
|
||||
|
||||
|
||||
### Steps
|
||||
1. Download postmand collection from the git server (optional)
|
||||
2. Create and run requests from postman
|
||||
|
||||
## Reporting bug
|
||||
All the bug reporting will be done using kanban `https://project.aayutech.dev`
|
||||
|
||||
### Bug criteria
|
||||
1. All __INTERNAL_SERVER_ERROR__
|
||||
2. All about:none errors
|
||||
3. All errors that consists of raw sql messages
|
||||
4. Errors that doesn't match the description of the api
|
||||
5. Bug should be able to be reproduced
|
||||
|
||||
### Bug reporting steps
|
||||
1. Create new task in the `Bug Report` column in kanboard
|
||||
2. Write short description about the bug and how it can be reproduced
|
||||
3. Optionally take screenshot of postman or terminal where the bug can be seen
|
||||
4. Add related user as assigne
|
||||
|
||||
### Bug resolve steps
|
||||
1. After a bug is reported a QA or Developer will approve the bug and put it in the `BUG` column.
|
||||
2. After the bug is verified, the respective developer will fix the bug and put it in the `Read for QA` column.
|
||||
3. A QA will reverify the bug and put it in the `DONE` column.
|
||||
|
||||
"""
|
||||
|
||||
app = FastAPI(
|
||||
version = "0.0.1",
|
||||
lifespan = init_db,
|
||||
title = "Fastapi template",
|
||||
openapi_tags = docs,
|
||||
description = description
|
||||
)
|
||||
|
||||
for router in routers: app.include_router(router)
|
||||
|
||||
app.middleware('http')(app_middleware)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware
|
||||
,allow_origins=["*"]
|
||||
,allow_credentials=True # Set to True if you need to support cookies/authorization headers
|
||||
,allow_methods=["*"] # Allows all methods (GET, POST, PUT, DELETE, OPTIONS, etc.)
|
||||
,allow_headers=["*"] # Allows all headers
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user