first backend steps
This commit is contained in:
parent
9cb67b692c
commit
0d5a5f3da8
22 changed files with 305 additions and 11 deletions
7
backend/README.md
Normal file
7
backend/README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Database
|
||||||
|
|
||||||
|
MySQL is used.
|
||||||
|
|
||||||
|
CREATE DATABASE noxiosdb;
|
||||||
|
CREATE USER 'noxios'@'localhost';
|
||||||
|
GRANT ALL PRIVILEGES ON noxiosdb.* To 'noxios'@'localhost' IDENTIFIED BY 'password';
|
||||||
BIN
backend/__pycache__/config.cpython-312.pyc
Normal file
BIN
backend/__pycache__/config.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/__pycache__/database.cpython-312.pyc
Normal file
BIN
backend/__pycache__/database.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
backend/__pycache__/models.cpython-312.pyc
Normal file
BIN
backend/__pycache__/models.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/__pycache__/user.cpython-312.pyc
Normal file
BIN
backend/__pycache__/user.cpython-312.pyc
Normal file
Binary file not shown.
1
backend/config.py
Normal file
1
backend/config.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
DATABASE_URL = 'mysql+aiomysql://noxios:@127.0.0.1:3306/nexiosdb'
|
||||||
BIN
backend/controller/__pycache__/comments.cpython-312.pyc
Normal file
BIN
backend/controller/__pycache__/comments.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/controller/__pycache__/newsletter.cpython-312.pyc
Normal file
BIN
backend/controller/__pycache__/newsletter.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/controller/__pycache__/user.cpython-312.pyc
Normal file
BIN
backend/controller/__pycache__/user.cpython-312.pyc
Normal file
Binary file not shown.
|
|
@ -0,0 +1,7 @@
|
||||||
|
def setup_comment_routes(app):
|
||||||
|
|
||||||
|
#get comments
|
||||||
|
@app.get("/comment/{id}")
|
||||||
|
async def get_comments_for_post(req, res):
|
||||||
|
return res.json(status_code=201)
|
||||||
|
#add comment
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
def setup_newsletter_routes(app):
|
||||||
|
|
||||||
|
# Create Mail Entry by Mail
|
||||||
|
@app.post("/newsletter")
|
||||||
|
async def create_mail_entry(request, response):
|
||||||
|
return response.json(status_code=201)
|
||||||
|
|
||||||
|
# Delete Mail Entry by UUID
|
||||||
|
@app.put("/newsletter/{id}")
|
||||||
|
async def create_mail_entry(request, response):
|
||||||
|
return response.json(status_code=201)
|
||||||
29
backend/controller/user.py
Normal file
29
backend/controller/user.py
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
from database import get_db
|
||||||
|
from nexios import Depend
|
||||||
|
from nexios.http import Request, Response
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from models import User
|
||||||
|
|
||||||
|
def setup_user_routes(app):
|
||||||
|
|
||||||
|
@app.get("/users")
|
||||||
|
async def list_users(
|
||||||
|
request: Request,
|
||||||
|
response: Response,
|
||||||
|
db: AsyncSession = Depend(get_db)
|
||||||
|
):
|
||||||
|
result = await db.execute("SELECT * FROM users")
|
||||||
|
users = result.fetchall()
|
||||||
|
return response.json(users)
|
||||||
|
|
||||||
|
@app.post("/users")
|
||||||
|
async def create_user(
|
||||||
|
request: Request,
|
||||||
|
response: Response,
|
||||||
|
db: AsyncSession = Depend(get_db)
|
||||||
|
):
|
||||||
|
data = await request.json
|
||||||
|
user = User(**data)
|
||||||
|
db.add(user)
|
||||||
|
await db.commit()
|
||||||
|
return response.json({"id": user.id})
|
||||||
29
backend/database.py
Normal file
29
backend/database.py
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
|
||||||
|
from sqlalchemy.orm import declarative_base
|
||||||
|
from config import DATABASE_URL
|
||||||
|
|
||||||
|
engine = create_async_engine(
|
||||||
|
DATABASE_URL,
|
||||||
|
echo=True,
|
||||||
|
pool_size=5,
|
||||||
|
max_overflow=10,
|
||||||
|
)
|
||||||
|
|
||||||
|
AsyncSessionLocal = async_sessionmaker(
|
||||||
|
engine,
|
||||||
|
class_=AsyncSession,
|
||||||
|
expire_on_commit=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
async def init_db():
|
||||||
|
async with engine.begin() as conn:
|
||||||
|
await conn.run_sync(Base.metadata.create_all)
|
||||||
|
|
||||||
|
async def get_db() -> AsyncSession:
|
||||||
|
async with AsyncSessionLocal() as session:
|
||||||
|
try:
|
||||||
|
yield session
|
||||||
|
finally:
|
||||||
|
await session.close()
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
|
from database import init_db
|
||||||
|
from controller.user import setup_user_routes
|
||||||
|
from controller.comments import setup_comment_routes
|
||||||
|
from controller.newsletter import setup_newsletter_routes
|
||||||
from nexios import NexiosApp
|
from nexios import NexiosApp
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
# Create a new Nexios application
|
|
||||||
app = NexiosApp()
|
app = NexiosApp()
|
||||||
|
|
||||||
# Define a simple route
|
@app.on_startup
|
||||||
@app.get("/")
|
async def startup():
|
||||||
async def hello_world(request, response):
|
await init_db()
|
||||||
return response.json({
|
|
||||||
"message": "Hello from Nexios!",
|
|
||||||
"status": "success"
|
|
||||||
})
|
|
||||||
|
|
||||||
# If you forget to use async def for your handler, Nexios will run the handler in a threadpool
|
setup_newsletter_routes(app)
|
||||||
|
setup_comment_routes(app)
|
||||||
# If you define two routes with the same path and method, Nexios will raise a conflict error at startup.
|
setup_user_routes(app)
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
14
backend/models.py
Normal file
14
backend/models.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
from sqlalchemy import Column, Integer, String, Boolean, DateTime
|
||||||
|
from sqlalchemy.orm import declarative_base
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
__tablename__ = "users"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String(100))
|
||||||
|
email = Column(String(100), unique=True)
|
||||||
|
is_active = Column(Boolean, default=True)
|
||||||
|
created_at = Column(DateTime, default=datetime.now)
|
||||||
6
backend/pyrefly.toml
Normal file
6
backend/pyrefly.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
project-includes = [
|
||||||
|
"venv/**/*.py*",
|
||||||
|
"venv/**/*.ipynb",
|
||||||
|
]
|
||||||
|
|
||||||
|
python-platform = "linux"
|
||||||
17
backend/user.py
Normal file
17
backend/user.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
from nexios.pagination import SyncDataHandler
|
||||||
|
from sqlalchemy import select
|
||||||
|
from models import User
|
||||||
|
|
||||||
|
class UserDataHandler(SyncDataHandler):
|
||||||
|
def __init__(self, session):
|
||||||
|
self.session = session
|
||||||
|
|
||||||
|
def get_total_items(self):
|
||||||
|
result = self.session.execute(select(User))
|
||||||
|
return len(result.scalars().all())
|
||||||
|
|
||||||
|
def get_items(self, offset, limit):
|
||||||
|
result = self.session.execute(
|
||||||
|
select(User).offset(offset).limit(limit)
|
||||||
|
)
|
||||||
|
return result.scalars().all()
|
||||||
BIN
backend/venv/bin/pyrefly
Executable file
BIN
backend/venv/bin/pyrefly
Executable file
Binary file not shown.
8
backend/venv/bin/tortoise
Executable file
8
backend/venv/bin/tortoise
Executable file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/home/ebby/Desktop/Bluewaterblog/backend/venv/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from tortoise.cli import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
||||||
164
backend/venv/include/site/python3.12/greenlet/greenlet.h
Normal file
164
backend/venv/include/site/python3.12/greenlet/greenlet.h
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
|
||||||
|
|
||||||
|
/* Greenlet object interface */
|
||||||
|
|
||||||
|
#ifndef Py_GREENLETOBJECT_H
|
||||||
|
#define Py_GREENLETOBJECT_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is deprecated and undocumented. It does not change. */
|
||||||
|
#define GREENLET_VERSION "1.0.0"
|
||||||
|
|
||||||
|
#ifndef GREENLET_MODULE
|
||||||
|
#define implementation_ptr_t void*
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _greenlet {
|
||||||
|
PyObject_HEAD
|
||||||
|
PyObject* weakreflist;
|
||||||
|
PyObject* dict;
|
||||||
|
implementation_ptr_t pimpl;
|
||||||
|
} PyGreenlet;
|
||||||
|
|
||||||
|
#define PyGreenlet_Check(op) (op && PyObject_TypeCheck(op, &PyGreenlet_Type))
|
||||||
|
|
||||||
|
|
||||||
|
/* C API functions */
|
||||||
|
|
||||||
|
/* Total number of symbols that are exported */
|
||||||
|
#define PyGreenlet_API_pointers 12
|
||||||
|
|
||||||
|
#define PyGreenlet_Type_NUM 0
|
||||||
|
#define PyExc_GreenletError_NUM 1
|
||||||
|
#define PyExc_GreenletExit_NUM 2
|
||||||
|
|
||||||
|
#define PyGreenlet_New_NUM 3
|
||||||
|
#define PyGreenlet_GetCurrent_NUM 4
|
||||||
|
#define PyGreenlet_Throw_NUM 5
|
||||||
|
#define PyGreenlet_Switch_NUM 6
|
||||||
|
#define PyGreenlet_SetParent_NUM 7
|
||||||
|
|
||||||
|
#define PyGreenlet_MAIN_NUM 8
|
||||||
|
#define PyGreenlet_STARTED_NUM 9
|
||||||
|
#define PyGreenlet_ACTIVE_NUM 10
|
||||||
|
#define PyGreenlet_GET_PARENT_NUM 11
|
||||||
|
|
||||||
|
#ifndef GREENLET_MODULE
|
||||||
|
/* This section is used by modules that uses the greenlet C API */
|
||||||
|
static void** _PyGreenlet_API = NULL;
|
||||||
|
|
||||||
|
# define PyGreenlet_Type \
|
||||||
|
(*(PyTypeObject*)_PyGreenlet_API[PyGreenlet_Type_NUM])
|
||||||
|
|
||||||
|
# define PyExc_GreenletError \
|
||||||
|
((PyObject*)_PyGreenlet_API[PyExc_GreenletError_NUM])
|
||||||
|
|
||||||
|
# define PyExc_GreenletExit \
|
||||||
|
((PyObject*)_PyGreenlet_API[PyExc_GreenletExit_NUM])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PyGreenlet_New(PyObject *args)
|
||||||
|
*
|
||||||
|
* greenlet.greenlet(run, parent=None)
|
||||||
|
*/
|
||||||
|
# define PyGreenlet_New \
|
||||||
|
(*(PyGreenlet * (*)(PyObject * run, PyGreenlet * parent)) \
|
||||||
|
_PyGreenlet_API[PyGreenlet_New_NUM])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PyGreenlet_GetCurrent(void)
|
||||||
|
*
|
||||||
|
* greenlet.getcurrent()
|
||||||
|
*/
|
||||||
|
# define PyGreenlet_GetCurrent \
|
||||||
|
(*(PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PyGreenlet_Throw(
|
||||||
|
* PyGreenlet *greenlet,
|
||||||
|
* PyObject *typ,
|
||||||
|
* PyObject *val,
|
||||||
|
* PyObject *tb)
|
||||||
|
*
|
||||||
|
* g.throw(...)
|
||||||
|
*/
|
||||||
|
# define PyGreenlet_Throw \
|
||||||
|
(*(PyObject * (*)(PyGreenlet * self, \
|
||||||
|
PyObject * typ, \
|
||||||
|
PyObject * val, \
|
||||||
|
PyObject * tb)) \
|
||||||
|
_PyGreenlet_API[PyGreenlet_Throw_NUM])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
|
||||||
|
*
|
||||||
|
* g.switch(*args, **kwargs)
|
||||||
|
*/
|
||||||
|
# define PyGreenlet_Switch \
|
||||||
|
(*(PyObject * \
|
||||||
|
(*)(PyGreenlet * greenlet, PyObject * args, PyObject * kwargs)) \
|
||||||
|
_PyGreenlet_API[PyGreenlet_Switch_NUM])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
|
||||||
|
*
|
||||||
|
* g.parent = new_parent
|
||||||
|
*/
|
||||||
|
# define PyGreenlet_SetParent \
|
||||||
|
(*(int (*)(PyGreenlet * greenlet, PyGreenlet * nparent)) \
|
||||||
|
_PyGreenlet_API[PyGreenlet_SetParent_NUM])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PyGreenlet_GetParent(PyObject* greenlet)
|
||||||
|
*
|
||||||
|
* return greenlet.parent;
|
||||||
|
*
|
||||||
|
* This could return NULL even if there is no exception active.
|
||||||
|
* If it does not return NULL, you are responsible for decrementing the
|
||||||
|
* reference count.
|
||||||
|
*/
|
||||||
|
# define PyGreenlet_GetParent \
|
||||||
|
(*(PyGreenlet* (*)(PyGreenlet*)) \
|
||||||
|
_PyGreenlet_API[PyGreenlet_GET_PARENT_NUM])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* deprecated, undocumented alias.
|
||||||
|
*/
|
||||||
|
# define PyGreenlet_GET_PARENT PyGreenlet_GetParent
|
||||||
|
|
||||||
|
# define PyGreenlet_MAIN \
|
||||||
|
(*(int (*)(PyGreenlet*)) \
|
||||||
|
_PyGreenlet_API[PyGreenlet_MAIN_NUM])
|
||||||
|
|
||||||
|
# define PyGreenlet_STARTED \
|
||||||
|
(*(int (*)(PyGreenlet*)) \
|
||||||
|
_PyGreenlet_API[PyGreenlet_STARTED_NUM])
|
||||||
|
|
||||||
|
# define PyGreenlet_ACTIVE \
|
||||||
|
(*(int (*)(PyGreenlet*)) \
|
||||||
|
_PyGreenlet_API[PyGreenlet_ACTIVE_NUM])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Macro that imports greenlet and initializes C API */
|
||||||
|
/* NOTE: This has actually moved to ``greenlet._greenlet._C_API``, but we
|
||||||
|
keep the older definition to be sure older code that might have a copy of
|
||||||
|
the header still works. */
|
||||||
|
# define PyGreenlet_Import() \
|
||||||
|
{ \
|
||||||
|
_PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GREENLET_MODULE */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* !Py_GREENLETOBJECT_H */
|
||||||
Loading…
Add table
Reference in a new issue