Compare commits

..

5 Commits
api ... step3

Author SHA1 Message Date
mpabi 0b77052943 Added images 2024-06-24 18:56:27 +00:00
mpabi ef2db25b0b vue tab fetch/post v0.01 2024-06-24 18:37:36 +00:00
mpabi 0363e941b1 solved API 2024-06-24 17:30:53 +00:00
mpabi 5a45abc524 added debug to endpoint get{id}, still not solved 2024-06-24 17:18:57 +00:00
mpabi 2ed560f13a upgraded entrypoint 2024-06-24 14:03:44 +00:00
14 changed files with 172 additions and 184 deletions

View File

@ -1,21 +1,28 @@
# app/main.py
# ---
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session
from app.database import SessionLocal, engine
from app import models, schemas
from app.database import SessionLocal
from app.models import PassportData
from typing import List, Optional
# ddfrom starlette.middleware.base import BaseHTTPMiddleware
# from starlette.responses import Response
# class CustomMIMEMiddleware(BaseHTTPMiddleware):
# async def dispatch(self, request, call_next):
# response = await call_next(request)
# if request.url.path.endswith('.vue'):
# response.headers['Content-Type'] = 'application/javascript'
# return response
from fastapi.staticfiles import StaticFiles
from typing import List, Optional
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
# Dependency to get DB session
models.Base.metadata.create_all(bind=engine)
def get_db():
db = SessionLocal()
try:
@ -23,24 +30,18 @@ def get_db():
finally:
db.close()
class PassportDataRequest(BaseModel):
number: str
name: str
surname: str
gender: str
@app.post("/passport_data/")
def create_passport_data(request: PassportDataRequest, db: Session = Depends(get_db)):
db_passport = PassportData(number=request.number, name=request.name, surname=request.surname, gender=request.gender)
db.add(db_passport)
@app.post("/passport/", response_model=schemas.PassportData)
def create_passport_data(passport_data: schemas.PassportDataCreate, db: Session = Depends(get_db)):
db_passport_data = models.PassportData(**passport_data.dict())
db.add(db_passport_data)
db.commit()
db.refresh(db_passport)
return db_passport
db.refresh(db_passport_data)
return db_passport_data
@app.get("/passport_data/{passport_number}")
@app.get("/passport/{passport_number}", response_model=schemas.PassportData)
def read_passport_data(passport_number: str, db: Session = Depends(get_db)):
db_passport = db.query(PassportData).filter(PassportData.number == passport_number).first()
if db_passport is None:
db_passport_data = db.query(models.PassportData).filter(models.PassportData.number == passport_number).first()
if db_passport_data is None:
raise HTTPException(status_code=404, detail="Passport data not found")
return db_passport
return schemas.PassportData.from_orm(db_passport_data)

View File

@ -1,13 +1,13 @@
# app/models.py
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy import Column, Integer, String
from app.database import Base
class PassportData(Base):
__tablename__ = 'passport_data'
id = Column(Integer, primary_key=True, autoincrement=True)
number = Column(String(255), unique=True, nullable=False)
name = Column(String(255), nullable=False)
surname = Column(String(255), nullable=False)
gender = Column(String(255), nullable=False)
name = Column(String(255), nullable=True)
surname = Column(String(255), nullable=True)
gender = Column(String(255), nullable=True)
fingerprint_url = Column(String(255), nullable=True) # New field for fingerprint image URL
photo_url = Column(String(255), nullable=True) # New field for photo image URL

View File

@ -0,0 +1,21 @@
# app/schemas.py
from pydantic import BaseModel
from typing import Optional
class PassportDataBase(BaseModel):
number: str
name: Optional[str] = None
surname: Optional[str] = None
gender: Optional[str] = None
fingerprint_url: Optional[str] = None
photo_url: Optional[str] = None
class PassportDataCreate(PassportDataBase):
pass
class PassportData(PassportDataBase):
id: int
class Config:
orm_mode = True # Poprawne przypisanie

View File

@ -1,25 +1,76 @@
from app.database import engine
from app.models import Base
# entrypoint.py
#%%
from app.database import engine, SessionLocal
from app.models import Base, PassportData
import argparse
import uvicorn
import os
def main(port):
# Create the database
#%%
def load_data_from_directory(directory_path: str, db_session):
files = os.listdir(directory_path)
passport_data = {}
for file in files:
file_parts = file.split('-')
if len(file_parts) != 2:
continue
passport_number = file_parts[0]
file_type = file_parts[1].split('.')[0]
if passport_number not in passport_data:
passport_data[passport_number] = {
"fingerprint_url": None,
"photo_url": None
}
file_path = os.path.join(directory_path, file)
if file_type == 'odcisk':
passport_data[passport_number]["fingerprint_url"] = file_path
elif file_type == 'zdjecie':
passport_data[passport_number]["photo_url"] = file_path
for number, data in passport_data.items():
passport_entry = PassportData(
number=number,
name=None,
surname=None,
gender=None,
fingerprint_url=data["fingerprint_url"],
photo_url=data["photo_url"]
)
db_session.add(passport_entry)
print (passport_entry)
db_session.commit()
#%%
def main(port, data_dir):
print("Creating database tables...")
Base.metadata.create_all(bind=engine)
print("Database tables created.")
# Run the FastAPI app using uvicorn
# uvicorn.run("app.main:app", host="0.0.0.0", port=port, reload=True)
db_session = SessionLocal()
try:
print(f"Loading data from directory: {data_dir}")
load_data_from_directory(data_dir, db_session)
print("Data loaded into database.")
finally:
db_session.close()
# uvicorn.run("app.main:app", host="0.0.0.0", port=port, reload=True)
#%% main(9999,"data")
#%%
if __name__ == "__main__":
# Create argument parser
parser = argparse.ArgumentParser(description="Run the FastAPI app")
# Add port argument, default is 9999
parser.add_argument("--port", type=int, default=9999, help="Port to run the FastAPI app on")
# Parse arguments
parser.add_argument("--data-dir", type=str, default="data", help="Directory containing passport data files")
args = parser.parse_args()
main(args.port)
main(args.port, args.data_dir)

11
src/script/__post Normal file
View File

@ -0,0 +1,11 @@
curl -X POST "http://localhost:9999/passport/" \
-H "Content-Type: application/json" \
-d '{
"number": "444",
"name": null,
"surname": null,
"gender": null,
"fingerprint_url": "data/444-odcisk.jpg",
"photo_url": "data/444-zdjecie.jpg"
}'

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -3,38 +3,14 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Library Management</title>
<link rel="stylesheet" href="style.css">
<title>Passport Form App</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<header>Library Management</header>
<div class="container">
<aside class="sidebar">
<h2>Add Author</h2>
<form id="addAuthorForm">
<input type="text" id="authorName" placeholder="Author Name" required>
<button type="submit">Add Author</button>
</form>
<h2>Add Book</h2>
<form id="addBookForm">
<input type="text" id="bookTitle" placeholder="Book Title" required>
<select id="bookAuthorId">
<!-- Autorzy będą dodawani tutaj dynamicznie -->
</select>
<button type="submit">Add Book</button>
</form>
</aside>
<main class="content">
<h2>Authors</h2>
<ul id="authorsList"></ul>
<h2>Books</h2>
<ul id="booksList"></ul>
<button id="loadBooksWithAuthors">Load Books with Authors</button>
<ul id="booksWithAuthorsList"></ul>
</main>
</div>
<footer>2024 Library Management System</footer>
<script src="script.js"></script>
<div id="app"></div>
<script src="./js/axios.min.js"></script>
<script type="module" src="./script.js"></script>
</body>
</html>

View File

@ -1,69 +1,16 @@
const BASE_URL = 'http://qstack.pl:1111'; // Zaktualizuj zgodnie z konfiguracją Twojego serwera
import { createApp } from './js/vue.esm-browser.js';
import PassportForm from './components/Tabs.js';
document.addEventListener('DOMContentLoaded', function() {
loadAuthors();
loadBooks();
});
document.getElementById('addAuthorForm').addEventListener('submit', function(e) {
e.preventDefault();
const authorName = document.getElementById('authorName').value;
fetch(`${BASE_URL}/authors/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: authorName }),
})
.then(response => response.json())
.then(() => {
loadAuthors(); // Ponowne ładowanie listy autorów po dodaniu nowego autora
})
.catch(error => console.error('Error:', error));
});
document.getElementById('addBookForm').addEventListener('submit', function(e) {
e.preventDefault();
const bookTitle = document.getElementById('bookTitle').value;
const bookAuthorId = document.getElementById('bookAuthorId').value;
fetch(`${BASE_URL}/books/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: bookTitle, author_id: parseInt(bookAuthorId, 10) }),
})
.then(response => response.json())
.then(() => {
loadBooks(); // Ponowne ładowanie listy książek po dodaniu nowej książki
})
.catch(error => console.error('Error:', error));
});
function loadAuthors() {
fetch(`${BASE_URL}/authors/`)
.then(response => response.json())
.then(data => {
const authorsSelect = document.getElementById('bookAuthorId');
authorsSelect.innerHTML = '<option value="">Select an Author</option>'; // Dodaj domyślną opcję
data.forEach(author => {
const option = document.createElement('option');
option.value = author.id;
option.textContent = author.name;
authorsSelect.appendChild(option);
});
})
.catch(error => console.error('Error:', error));
}
function loadBooks() {
fetch(`${BASE_URL}/books/`)
.then(response => response.json())
.then(data => {
const booksList = document.getElementById('booksList');
booksList.innerHTML = '';
data.forEach(book => {
const listItem = document.createElement('li');
listItem.textContent = `${book.title} - Author ID: ${book.author_id}`;
booksList.appendChild(listItem);
});
})
.catch(error => console.error('Error:', error));
}
const App = {
name: 'App',
components: {
PassportForm
},
template: `
<div id="app">
<PassportForm />
</div>
`,
};
createApp(App).mount('#app');

View File

@ -1,43 +1,24 @@
body, html {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
header, footer {
background-color: #333;
color: #fff;
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
padding: 1rem 0;
}
color: #2c3e50;
margin-top: 60px;
}
.container {
display: flex;
min-height: calc(100vh - 100px); /* Adjust based on header/footer height */
}
nav {
margin-bottom: 20px;
}
.sidebar {
width: 30%;
padding: 20px;
background-color: #f4f4f4;
}
.content {
flex-grow: 1;
padding: 20px;
}
form > * {
display: block;
margin-bottom: 10px;
}
button {
button {
padding: 10px 20px;
margin: 5px;
cursor: pointer;
}
}
ul {
list-style-type: none;
padding-left: 0;
}
button.active {
background-color: #2c3e50;
color: white;
}