first commit

This commit is contained in:
2024-11-07 17:44:29 +03:00
commit 643d6d8f65
247 changed files with 420800 additions and 0 deletions

93
service_app/.dockerignore Normal file
View File

@@ -0,0 +1,93 @@
# Git
.git
.gitignore
.gitattributes
# CI
.codeclimate.yml
.travis.yml
.taskcluster.yml
# Docker
docker-compose.yml
service_app/Dockerfile
.docker
.dockerignore
# Byte-compiled / optimized / DLL files
**/__pycache__/
**/*.py[cod]
# C extensions
*.so
# Distribution / packaging
.Python
service_app/env/
build/
develop-eggs/
dist/
downloads/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Virtual environment
service_app/.env
.venv/
venv/
# PyCharm
.idea
# Python mode for VIM
.ropeproject
**/.ropeproject
# Vim swap files
**/*.swp
# VS Code
.vscode/
test_application/

162
service_app/.gitignore vendored Normal file
View File

@@ -0,0 +1,162 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.idea/
.Python
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
service_app/.env
.venv
service_app/env/
venv/
service_app/env/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

32
service_app/Dockerfile Normal file
View File

@@ -0,0 +1,32 @@
FROM python:3.12-slim-bookworm
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
COPY ../service_app/requirements.txt .
RUN uv venv
RUN uv pip install -r requirements.txt
COPY ../service_app ./service_app
COPY ../databases ./service_app/databases
COPY ../api_services ./service_app/api_services
COPY ../api_objects ./service_app/api_objects
COPY ../api_configs ./service_app/api_configs
COPY ../api_events ./service_app/api_events
COPY ../api_library ./service_app/api_library
COPY ../api_validations ./service_app_init/api_validations
WORKDIR /service_app
CMD ["uv", "run", "app.py"]
# Old File
#FROM python:3.10
#RUN pip install --upgrade pip
#RUN pip install --no-cache-dir --upgrade -r requirements.txt
#CMD ["python", "-m", "app"]

0
service_app/__init__.py Normal file
View File

51
service_app/app.py Normal file
View File

@@ -0,0 +1,51 @@
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
from fastapi.exceptions import HTTPException
from middlewares.token_middleware import AuthHeaderMiddleware
from application.create_file import create_app
from handlers_exception import (
exception_handler_http,
exception_handler_exception,
)
from prometheus_fastapi_instrumentator import Instrumentator
from prometheus_client import Counter, Histogram
app = create_app()
Instrumentator().instrument(app=app).expose(app=app)
app.add_middleware(
CORSMiddleware,
**{
"allow_origins": ["*"],
"allow_credentials": True,
"allow_methods": ["*"],
"allow_headers": ["*"],
}
)
app.add_middleware(AuthHeaderMiddleware)
app.add_exception_handler(HTTPException, exception_handler_http)
app.add_exception_handler(Exception, exception_handler_exception)
# # Define a counter metric
# REQUESTS_COUNT = Counter(
# "requests_total", "Total number of requests", ["method", "endpoint", "status_code"]
# )
# # Define a histogram metric
# REQUESTS_TIME = Histogram("requests_time", "Request processing time", ["method", "endpoint"])
# api_request_summary = Histogram("api_request_summary", "Request processing time", ["method", "endpoint"])
# api_request_counter = Counter("api_request_counter", "Request processing time", ["method", "endpoint", "http_status"])
if __name__ == "__main__":
uvicorn_config = {
"app": "app:app",
"host": "0.0.0.0",
"port": 41575,
"log_level": "info",
"reload": True,
}
uvicorn.Server(uvicorn.Config(**uvicorn_config)).run()

View File

View File

@@ -0,0 +1,66 @@
def create_app():
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.openapi.utils import get_openapi
from fastapi.responses import RedirectResponse
from api_configs import Config
import routers
api_app = FastAPI(title=str(Config.TITLE), default_response_class=JSONResponse)
@api_app.get("/", include_in_schema=False, summary=str(Config.DESCRIPTION))
async def home():
return RedirectResponse(url="/docs")
for router in list(
[
getattr(routers, router)
for router in routers.__all__
if getattr(routers, router)
]
):
api_app.include_router(router)
openapi_schema = get_openapi(
title=Config.TITLE,
description=Config.DESCRIPTION,
version="0.0.1",
routes=api_app.routes,
)
if "components" in openapi_schema:
openapi_schema["components"]["securitySchemes"] = {
"Bearer Auth": {
"type": "apiKey",
"in": "header",
"name": "evyos-session-key",
"description": "Enter: **'Bearer <JWT>'**, where JWT is the access token",
}
}
for route in api_app.routes:
path = str(getattr(route, "path"))
if route.include_in_schema:
methods = [method.lower() for method in getattr(route, "methods")]
for method in methods:
if path not in Config.INSECURE_PATHS:
openapi_schema["paths"][path][method]["security"] = [
{"Bearer Auth": []}
]
openapi_schema["paths"][path][method]["responses"]["403"] = {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Returned if user is unauthorized.",
}
api_app.openapi_schema = openapi_schema
return api_app

5
service_app/env Normal file
View File

@@ -0,0 +1,5 @@
DATABASE_URL=postgresql+psycopg2://berkay_wag_user:berkay_wag_user_password@postgres_commercial:5432/wag_database
REDIS_HOST=commercial_memory_service
REDIS_PASSWORD=commercial_redis_password
REDIS_PORT=6379
REDIS_DB=0

View File

@@ -0,0 +1,9 @@
from .api_exception_handlers.http_exception_handler import (
exception_handler_http,
exception_handler_exception,
)
__all__ = [
"exception_handler_http",
"exception_handler_exception",
]

View File

@@ -0,0 +1,27 @@
from json import loads
from fastapi import status
from fastapi.requests import Request
from fastapi.exceptions import HTTPException
from fastapi.responses import JSONResponse
def exception_handler_http(request: Request, exc: HTTPException):
print('headers', request.headers)
detail = loads(exc.detail)
return JSONResponse(
status_code=exc.status_code,
content={
"Data": detail.get('data', {}),
"Error": detail.get('error_case', 'UNKNOWN'),
"Message": detail.get('message', 'An error occurred while processing the request')
}
)
def exception_handler_exception(request: Request, exc: Exception):
print('headers', request.headers)
return JSONResponse(
status_code=status.HTTP_417_EXPECTATION_FAILED, content={"message": exc.__str__()}
)

View File

@@ -0,0 +1 @@
from .token_middleware import AuthHeaderMiddleware

View File

@@ -0,0 +1,115 @@
import json
from time import perf_counter
from api_configs import Config
from starlette import status
from starlette.exceptions import HTTPException
from starlette.middleware.base import BaseHTTPMiddleware
class MiddlewareLogs:
@staticmethod
def log_error(self, log_message):
print(log_message)
def log_middlewares_exception(endpoint, token_user, message, request):
MiddlewareLogs.log_error(
str(
{
"log_type": "Authentication",
"log_message": message,
"log_action": "User",
"log_data": json.dumps(
{
"endpoint": endpoint,
"user": str(token_user),
"request": str(request.headers),
}
),
}
)
)
class AuthHeaderMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
start_time, token_user, endpoint = perf_counter(), None, None
if check_if_path_secure(request=request, insecure_paths=Config.INSECURE_PATHS):
endpoint = str(getattr(getattr(request, "url", None), "path", None))
if un_auth := check_if_token_is_not_valid(
request=request, endpoint_name=endpoint
):
auth, token_user = un_auth
if not auth == "valid":
# log_middlewares_exception(endpoint, token_user, "auth", request)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail=auth
)
response = await call_next(request)
prepare_response_needs(response, start_time)
# if endpoint and token_user:
# log_middlewares_exception(endpoint, token_user, "Request is completed", request)
return response
def prepare_response_needs(response, start_time):
end_time = perf_counter()
response.headers["request-starts"], response.headers["request-ends"] = str(
start_time
), str(end_time)
response.headers["elapsed-Time"] = str(float(end_time) - float(start_time)) + " ms"
def check_if_path_secure(request, insecure_paths) -> bool:
return str(getattr(getattr(request, "url", None), "path", None)) not in insecure_paths
def check_if_token_is_not_valid(request, endpoint_name):
from api_services.redis.functions import get_object_via_access_key
token_user = get_object_via_access_key(request)
if not token_user:
return "Session geçerli değil. Lütfen tekrar giriş yapınız.", token_user
return "valid", token_user
# on_token_user: Users = Users.find_one(uu_id=token_user["uu_id"])
# on_token_people: People = on_token_user.person
# #
# # if on_token_people.priority == 78:
# # return "valid", token_user
#
# if not token_user.get("duty_id", None):
# return (
# "Kullanıcı hiçbir yetki tanımlanmamıştır. Supervisor ile iletişime geçiniz.",
# token_user,
# )
# CompanyDutyApp.session.commit()
# CompanyDutyApp.session.flush()
#
# if endpoint_name in release_endpoint:
# return "valid", token_user
#
# if company_duty_app := CompanyDutyApp.find_one(
# endpoint_name=str("".join(endpoint_name.split("/")[:-1])),
# company_duty_id=int(token_user.get("duty_id")),
# ):
# if not company_duty_app.is_access_valid(
# endpoint_ext=endpoint_name.split("/")[-1]
# ):
# return (
# "Kullanıcı yetkili değildir. Supervisor ile iletişime geçiniz.",
# token_user,
# )
# else:
# return (
# "Kullanıcıya yetki tanımlanmamıştır. Supervisor ile iletişime geçiniz.",
# token_user,
# )
# return "valid", token_user

View File

@@ -0,0 +1,18 @@
arrow
Deprecated
fastapi
python-dotenv
uvicorn
pydantic
sqlalchemy-mixins
redis
psycopg2-binary
pymongo
rsa
redmail
unidecode
textdistance
pandas
cryptography
prometheus-client
prometheus-fastapi-instrumentator

View File

@@ -0,0 +1,3 @@
__all__ = []

View File