Compare commits

..

No commits in common. "starter" and "bio" have entirely different histories.
starter ... bio

40 changed files with 17685 additions and 1336 deletions

View File

View File

View File

View File

@ -1,40 +0,0 @@
./script/__
./src/__build
./src/__n1
./src/__run
./src/__run2
./src/__uvicorn
./src/_confs
./src/_confs/.vimrc
./src/_confs/.tmux.conf
./src/app/database.py
./src/app/main.py
./src/app/models.py
./src/app/schemas.py
./src/entrypoint.py
./src/poetry.lock
./src/pyproject.toml
./src/static/index.html
./src/static/script.js
./src/static/style.css
./src/Dockerfile-kopia
./src/php/Dockerfile
./src/Dockerfile
./src/__incus-proxy
./src/__docker-portainer
./src/docker-compose.yaml
./tex/backend/main.pdf
./tex/backend/main.tex
./tex/devops/main.pdf
./tex/devops/main.tex
./tex/fronted/main.pdf
./tex/fronted/main.tex
./__tracked-files

34
__tracked_files Normal file
View File

@ -0,0 +1,34 @@
./Dockerfile
./php/Dockerfile
./docker-compose.yaml
./__build
./__n1
./__run
./__run2
./__uvicorn
./__docker-portainer
./__incus-proxy
./_confs/.tmux.conf
./_confs/.vimrc
./app/schemas.py
./app/models.py
./app/main.py
./app/database.py
./pyproject.toml
./static/script.js
./static/style.css
./static/index.html
./static/vue.global.js
./data/pET-28a(+).gb
./entrypoint.py
./__tracked_files

View File

@ -1,3 +1,4 @@
#%%
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
@ -18,3 +19,10 @@ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
#%%
from sqlalchemy import text
with engine.connect() as conn:
result = conn.execute(text("select 'hello world'"))
print(result.all())

35
app/main.py Normal file
View File

@ -0,0 +1,35 @@
from fastapi import FastAPI, Depends
from fastapi.staticfiles import StaticFiles
from sqlalchemy.orm import Session
from .database import SessionLocal, engine
from .models import Sequence, Feature
from .database import Base
app = FastAPI()
Base.metadata.create_all(bind=engine)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
# Serwowanie plików statycznych
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/sequences/")
def read_sequences(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
sequences = db.query(Sequence).offset(skip).limit(limit).all()
return sequences
@app.get("/features/")
def read_features(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
features = db.query(Feature).offset(skip).limit(limit).all()
return features
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=9999)

26
app/models.py Normal file
View File

@ -0,0 +1,26 @@
from sqlalchemy import Column, Integer, String, Text, ForeignKey
from sqlalchemy.orm import relationship
from app.database import Base
class Sequence(Base):
__tablename__ = "sequences"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(255), index=True)
description = Column(String(255))
sequence = Column(Text)
features = relationship("Feature", back_populates="sequence")
class Feature(Base):
__tablename__ = "features"
id = Column(Integer, primary_key=True, index=True)
type = Column(String(255), index=True)
location = Column(String(255))
sequence = Column(Text)
qualifiers = Column(Text)
sequence_id = Column(Integer, ForeignKey('sequences.id'))
sequence = relationship("Sequence", back_populates="features")

333
data/gfp2.py Normal file
View File

@ -0,0 +1,333 @@
#! /usr/bin/env python3
# vim:fenc=utf-8
#
# Copyright © 2024 user <user@penguin>
#
# Distributed under terms of the MIT license.
import os
from Bio import Entrez, SeqIO
from Bio.Seq import Seq
from Bio.SeqFeature import SeqFeature, FeatureLocation
from Bio.Restriction import RestrictionBatch, EcoRI, BamHI, HindIII, Bpu1102I
from Bio.Restriction import AllEnzymes, Analysis
from Bio.Graphics import GenomeDiagram
from reportlab.lib import colors
#%%
# Ustawienia Entrez
Entrez.email = "your_email@example.com" # Wpisz swój adres email
# Funkcja do pobierania sekwencji z NCBI i zapisywania jej lokalnie
def fetch_and_save_sequence(db, id, file_path):
handle = Entrez.efetch(db=db, id=id, rettype="gb", retmode="text")
record = SeqIO.read(handle, "genbank")
handle.close()
SeqIO.write(record, file_path, "genbank")
return record
# Funkcja do wczytywania sekwencji z lokalnego pliku
def load_local_sequence(file_path):
with open(file_path, 'r') as file:
record = SeqIO.read(file, "genbank")
return record
#%%
# ID dla sekwencji w NCBI
gfp_id = "U87974"
plasmid_id = "pET-28a(+)"
# Ścieżki do lokalnych plików
gfp_file_path = gfp_id+'.gb'
plasmid_file_path = plasmid_id+'.gb'
#%%
# Sprawdzanie i pobieranie sekwencji GFP
if not os.path.exists(gfp_file_path):
print(f"Plik {gfp_file_path} nie istnieje. Pobieranie z serwera NCBI...")
gfp_record = fetch_and_save_sequence("nuccore", gfp_id, gfp_file_path)
print(f"Pobrano i zapisano sekwencję GFP do pliku {gfp_file_path}.")
else:
print(f"Plik {gfp_file_path} istnieje. Wczytywanie danych z lokalnego pliku...")
gfp_record = load_local_sequence(gfp_file_path)
print(f"Wczytano dane z pliku {gfp_file_path}.")
gfp_seq = str(gfp_record.seq)
print(f"GFP Sequence: {gfp_seq[:60]}...")
#%%
# Sprawdzanie i pobieranie sekwencji plazmidu
if not os.path.exists(plasmid_file_path):
print(f"Plik {plasmid_file_path} nie istnieje. Pobieranie z serwera NCBI...")
record = fetch_and_save_sequence("nuccore", plasmid_id, plasmid_file_path)
print(f"Pobrano i zapisano sekwencję plazmidu do pliku {plasmid_file_path}.")
else:
print(f"Plik {plasmid_file_path} istnieje. Wczytywanie danych z lokalnego pliku...")
record = load_local_sequence(plasmid_file_path)
print(f"Wczytano dane z pliku {plasmid_file_path}.")
#%%
# Wyświetl etykiety (annotacje)
for feature in record.features:
print(f"Type: {feature.type}")
print(f"Location: {feature.location}")
if 'gene' in feature.qualifiers:
print(f"Gene: {feature.qualifiers['gene']}")
if 'product' in feature.qualifiers:
print(f"Product: {feature.qualifiers['product']}")
print()
#%%
#%%
# Przejdź przez wszystkie funkcje w rekordzie i wypisz ich szczegółowe informacje
for feature in record.features:
if feature.type in ["promoter", "RBS","CDS", "protein_bind", "misc_feature", "rep_origin", "terminator"]:
print(f"Type: {feature.type}")
print(f"Location: {feature.location}")
print(f"Strand: {'+' if feature.strand == 1 else '-'}")
# Szczegółowe opisy
if feature.type == "CDS":
gene_name = feature.qualifiers.get('gene', ['Unknown gene'])[0]
product = feature.qualifiers.get('product', ['Unknown product'])[0]
print(f"Gene Name: {gene_name}")
print(f"Product: {product}")
elif feature.type == "protein_bind":
binding_site = feature.qualifiers.get('bound_moiety', ['Unknown binding site'])[0]
print(f"Binding Site: {binding_site}")
elif feature.type == "misc_feature":
note = feature.qualifiers.get('note', ['No additional information'])[0]
print(f"Note: {note}")
elif feature.type == "rep_origin":
print("This is a replication origin.")
# Pobierz sekwencję funkcji
feature_seq = record.seq[feature.location.start:feature.location.end]
print(f"Sequence ( ): {feature_seq}\n")
# Uwzględnij orientację nici (strand)
if feature.strand == -1:
feature_seq = feature_seq.reverse_complement()
print(f"Sequence (^): {feature_seq}\n")
# Znajdź i wyświetl sekwencję terminatora T7
for feature in record.features:
if feature.type == "terminator" and "T7" in feature.qualifiers.get('note', [''])[0]:
print("Terminator T7 znaleziony:")
print(f"Type: {feature.type}")
print(f"Location: {feature.location}")
print(f"Sequence: {record.seq[feature.location.start:feature.location.end]}")
print()
#%%
# Znajdź i wyświetl sekwencję terminatora T7
for feature in record.features:
if feature.type == "terminator" and "T7" in feature.qualifiers.get('note', [''])[0]:
print("Terminator T7 znaleziony:")
print(f"Type: {feature.type}")
print(f"Location: {feature.location}")
# Pobierz sekwencję terminatora
terminator_seq = record.seq[feature.location.start:feature.location.end]
# Sprawdź orientację i odwróć/uzupełnij jeśli potrzebne
if feature.strand == -1:
terminator_seq = terminator_seq.reverse_complement()
print(f"(+) Sequence: {terminator_seq}")
print()
#%%
#%%
t=record[25:73].seq
#%%
a = str (t)
a
#%%
class Model:
complement = {'A': 'T', 'T': 'A', 'C': 'G', 'G': 'C'}
def __init__ (self, seq=None):
self.seq = seq
def complement_dna(self):
complementary_sequence = ''.join(self.complement[base] for base in self.seq)
return complementary_sequence
#%%
r = Model(a)
#%%
r.seq
#%%
r.seq[::-1]
#%%
r.complement_dna()
#%%
r.seq
#%%
complement = {'A': 'T', 'T': 'A', 'C': 'G', 'G': 'C'}
complementary_sequence = ''.join(complement[base] for base in r.seq)
complementary_sequence
#%%
#%%
# Sekwencja DNA
dna_seq = record.seq
# Znajdź miejsca cięcia dla NcoI i Bpu1102I
ncoI_sites = NcoI.search(dna_seq)
bpu1102I_sites = Bpu1102I.search(dna_seq)
# Przyjmij pierwsze miejsca cięcia
ncoI_site = ncoI_sites[0]
bpu1102I_site = bpu1102I_sites[0]
# Wyodrębnij fragmenty 20 zasad od miejsc cięcia
ncoI_fragment = dna_seq[ncoI_site-16:ncoI_site+4] # 16 zasad przed i 4 po cięciu
bpu1102I_fragment = dna_seq[bpu1102I_site:bpu1102I_site+20] # 20 zasad po cięciu
# Lepkie końce
ncoI_sticky_end = ncoI_fragment[-4:]
ncoI_sticky_end_comp = ncoI_sticky_end.complement()
bpu1102I_sticky_end = bpu1102I_fragment[:4]
bpu1102I_sticky_end_comp = bpu1102I_sticky_end.complement()
# Funkcja do wyświetlania dwuniciowego DNA z lepkimi końcami w formacie schodkowym z indeksami dla dłuższej nici
def print_sticky_ends(seq1, sticky_end1, seq2, sticky_end2, start1, start2):
# Convert sequences to strings
seq1_str = str(seq1)
sticky_end1_str = str(sticky_end1)
comp_seq1_str = str(seq1.complement())
sticky_end1_comp_str = str(sticky_end1.complement())
seq2_str = str(seq2)
sticky_end2_str = str(sticky_end2)
comp_seq2_str = str(seq2.complement())
sticky_end2_comp_str = str(sticky_end2.complement())
# Add indexes to the ends
seq1_with_index = f"{seq1_str[:-1]} -{start1+len(seq1_str)-1}"
comp_seq1_with_index = f"{comp_seq1_str[:-1]}"
seq2_with_index = f"{start2}- {seq2_str[1:]}"
comp_seq2_with_index = f"{comp_seq2_str[1:]}"
# Lustrzane odbicie sekwencji
comp_seq2_with_index = comp_seq2_with_index[::-1]
sticky_end2_comp_str = sticky_end2_comp_str[::-1]
# Format the output as requested
print(f"5'-{seq1_with_index} {sticky_end1_str}-3' (+)")
print(f"3'-{comp_seq1_with_index}{sticky_end1_comp_str}-5'")
print()
print(f"5'-{sticky_end2_str} {seq2_with_index}-3' (+)")
print(f" {sticky_end2_comp_str}{comp_seq2_with_index}-5'")
# Wyświetl lepkie końce fragmentów
print("Fragmenty po cięciu NcoI i Bpu1102I:")
print_sticky_ends(ncoI_fragment[:-4], ncoI_sticky_end, bpu1102I_fragment[4:], bpu1102I_sticky_end, ncoI_site-16, bpu1102I_site)
#%%
# Projektowanie starterów
forward_primer = gfp_seq[:20] # Pierwsze 20 nukleotydów sekwencji GFP
reverse_primer = str(Seq(gfp_seq_with_his6[-20:]).reverse_complement()) # Ostatnie 20 nukleotydów + His6
print(f"Forward Primer: {forward_primer}")
print(f"Reverse Primer: {reverse_primer}")
#%%
# Miejsca cięcia restryktazy
enzymes = RestrictionBatch([EcoRI, BamHI, HindIII])
#enzymes = RestrictionBatch([BamHI, ])
restriction_sites = enzymes.search(record.seq)
#%%
# Przeprowadzenie analizy restrykcyjnej
analysis = Analysis(AllEnzymes, record.seq)
# Wynik analizy
results = analysis.full()
# Wyświetlanie wyników
#for enzyme in results:
# if len(results[enzyme]) > 0:
# print(f"{enzyme}: {results[enzyme]}")
#%%
# Utwórz diagram plazmidu
diagram = GenomeDiagram.Diagram("PUC19 Plasmid Map")
track = diagram.new_track(1, name="Annotated Features", greytrack=True)
feature_set = track.new_set()
# Dodanie sekwencji kodującej GFP
feature_set.add_feature(
SeqFeature(FeatureLocation(0, len(gfp_seq)), strand=+1),
name="GFP Coding Sequence",
label=True,
color=colors.lightblue
)
# Dodanie His6 tagu
feature_set.add_feature(
SeqFeature(FeatureLocation(len(gfp_seq), len(gfp_seq_with_his6)), strand=+1),
name="His6 Tag",
label=True,
color=colors.lightgreen
)
# Dodanie forward primer
feature_set.add_feature(
SeqFeature(FeatureLocation(0, len(forward_primer)), strand=+1),
name="Forward Primer",
label=True,
color=colors.orange
)
# Dodanie reverse primer
feature_set.add_feature(
SeqFeature(FeatureLocation(len(gfp_seq_with_his6) - len(reverse_primer), len(gfp_seq_with_his6)), strand=-1),
name="Reverse Primer",
label=True,
color=colors.red
)
# Dodanie miejsc cięcia restryktazy
for enzyme, sites in restriction_sites.items():
for site in sites:
feature_set.add_feature(
SeqFeature(FeatureLocation(site, site + 1), strand=0),
name=enzyme,
label=True,
color=colors.purple
)
# Rysowanie diagramu
diagram.draw(format="circular", circular=True, pagesize='A4', start=0, end=len(record), circle_core=0.5)
diagram.write("pdf/plasmid_map.pdf", "PDF")
print("Zapisano diagram plazmidu do pliku 'plasmid_map.pdf'")

194
data/pET-28a(+).gb Normal file
View File

@ -0,0 +1,194 @@
LOCUS 40924_17796 5369 bp DNA circular SYN 14-OCT-2021
DEFINITION synthetic circular DNA.
ACCESSION .
VERSION .
KEYWORDS .
SOURCE synthetic DNA construct
ORGANISM synthetic DNA construct
REFERENCE 1 (bases 1 to 5369)
AUTHORS caoheibi
TITLE Direct Submission
REFERENCE 2 (bases 1 to 5369)
AUTHORS .
TITLE Direct Submission
COMMENT SGRef: number: 1; type: "Journal Article"
FEATURES Location/Qualifiers
source 1..5369
/mol_type="other DNA"
/organism="synthetic DNA construct"
terminator complement(26..73)
/label=T7 terminator
/note="transcription terminator for bacteriophage T7 RNA
polymerase"
CDS complement(140..157)
/codon_start=1
/label=6xHis
/note="6xHis affinity tag"
/translation="HHHHHH"
CDS complement(207..239)
/codon_start=1
/label=T7 tag (gene 10 leader)
/note="leader peptide from bacteriophage T7 gene 10"
/translation="MASMTGGQQMG"
CDS complement(243..260)
/codon_start=1
/label=thrombin site
/note="thrombin recognition and cleavage site"
/translation="LVPRGS"
CDS complement(270..287)
/codon_start=1
/label=6xHis
/note="6xHis affinity tag"
/translation="HHHHHH"
RBS complement(306..328)
/label=RBS
/note="efficient ribosome binding site from bacteriophage
T7 gene 10 (Olins and Rangwala, 1989)"
protein_bind complement(343..367)
/label=lac operator
/note="The lac repressor binds to the lac operator to
inhibit transcription in E. coli. This inhibition can be
relieved by adding lactose or
isopropyl-beta-D-thiogalactopyranoside (IPTG)."
promoter complement(368..386)
/label=T7 promoter
/note="promoter for bacteriophage T7 RNA polymerase"
promoter 695..772
/label=lacI promoter
CDS 773..1852
/codon_start=1
/label=lacI
/note="lac repressor"
/translation="VKPVTLYDVAEYAGVSYQTVSRVVNQASHVSAKTREKVEAAMAEL
NYIPNRVAQQLAGKQSLLIGVATSSLALHAPSQIVAAIKSRADQLGASVVVSMVERSGV
EACKAAVHNLLAQRVSGLIINYPLDDQDAIAVEAACTNVPALFLDVSDQTPINSIIFSH
EDGTRLGVEHLVALGHQQIALLAGPLSSVSARLRLAGWHKYLTRNQIQPIAEREGDWSA
MSGFQQTMQMLNEGIVPTAMLVANDQMALGAMRAITESGLRVGADISVVGYDDTEDSSC
YIPPLTTIKQDFRLLGQTSVDRLLQLSQGQAVKGNQLLPVSLVKRKTTLAPNTQTASPR
ALADSLMQLARQVSRLESGQ"
protein_bind 1868..1889
/label=CAP binding site
/note="CAP binding activates transcription in the presence
of cAMP."
CDS 2664..2852
/codon_start=1
/label=rop
/note="Rop protein, which maintains plasmids at low copy
number"
/translation="VTKQEKTALNMARFIRSQTLTLLEKLNELDADEQADICESLHDHA
DELYRSCLARFGDDGENL"
misc_feature 2957..3099
/label=bom
/note="basis of mobility region from pBR322"
rep_origin complement(3285..3873)
/direction=LEFT
/label=ori
/note="high-copy-number ColE1/pMB1/pBR322/pUC origin of
replication"
CDS 3995..4807
/codon_start=1
/label=KanR
/note="aminoglycoside phosphotransferase"
/translation="MSHIQRETSCSRPRLNSNMDADLYGYKWARDNVGQSGATIYRLYG
KPDAPELFLKHGKGSVANDVTDEMVRLNWLTEFMPLPTIKHFIRTPDDAWLLTTAIPGK
TAFQVLEEYPDSGENIVDALAVFLRRLHSIPVCNCPFNSDRVFRLAQAQSRMNNGLVDA
SDFDDERNGWPVEQVWKEMHKLLPFSPDSVVTHGDFSLDNLIFDEGKLIGCIDVGRVGI
ADRYQDLAILWNCLGEFSPSLQKRLFQKYGIDNPDMNKLQFHLMLDEFF"
rep_origin complement(4903..5358)
/direction=LEFT
/label=f1 ori
/note="f1 bacteriophage origin of replication; arrow
indicates direction of (+) strand synthesis"
ORIGIN
1 atccggatat agttcctcct ttcagcaaaa aacccctcaa gacccgttta gaggccccaa
61 ggggttatgc tagttattgc tcagcggtgg cagcagccaa ctcagcttcc tttcgggctt
121 tgttagcagc cggatctcag tggtggtggt ggtggtgctc gagtgcggcc gcaagcttgt
181 cgacggagct cgaattcgga tccgcgaccc atttgctgtc caccagtcat gctagccata
241 tggctgccgc gcggcaccag gccgctgctg tgatgatgat gatgatggct gctgcccatg
301 gtatatctcc ttcttaaagt taaacaaaat tatttctaga ggggaattgt tatccgctca
361 caattcccct atagtgagtc gtattaattt cgcgggatcg agatctcgat cctctacgcc
421 ggacgcatcg tggccggcat caccggcgcc acaggtgcgg ttgctggcgc ctatatcgcc
481 gacatcaccg atggggaaga tcgggctcgc cacttcgggc tcatgagcgc ttgtttcggc
541 gtgggtatgg tggcaggccc cgtggccggg ggactgttgg gcgccatctc cttgcatgca
601 ccattccttg cggcggcggt gctcaacggc ctcaacctac tactgggctg cttcctaatg
661 caggagtcgc ataagggaga gcgtcgagat cccggacacc atcgaatggc gcaaaacctt
721 tcgcggtatg gcatgatagc gcccggaaga gagtcaattc agggtggtga atgtgaaacc
781 agtaacgtta tacgatgtcg cagagtatgc cggtgtctct tatcagaccg tttcccgcgt
841 ggtgaaccag gccagccacg tttctgcgaa aacgcgggaa aaagtggaag cggcgatggc
901 ggagctgaat tacattccca accgcgtggc acaacaactg gcgggcaaac agtcgttgct
961 gattggcgtt gccacctcca gtctggccct gcacgcgccg tcgcaaattg tcgcggcgat
1021 taaatctcgc gccgatcaac tgggtgccag cgtggtggtg tcgatggtag aacgaagcgg
1081 cgtcgaagcc tgtaaagcgg cggtgcacaa tcttctcgcg caacgcgtca gtgggctgat
1141 cattaactat ccgctggatg accaggatgc cattgctgtg gaagctgcct gcactaatgt
1201 tccggcgtta tttcttgatg tctctgacca gacacccatc aacagtatta ttttctccca
1261 tgaagacggt acgcgactgg gcgtggagca tctggtcgca ttgggtcacc agcaaatcgc
1321 gctgttagcg ggcccattaa gttctgtctc ggcgcgtctg cgtctggctg gctggcataa
1381 atatctcact cgcaatcaaa ttcagccgat agcggaacgg gaaggcgact ggagtgccat
1441 gtccggtttt caacaaacca tgcaaatgct gaatgagggc atcgttccca ctgcgatgct
1501 ggttgccaac gatcagatgg cgctgggcgc aatgcgcgcc attaccgagt ccgggctgcg
1561 cgttggtgcg gatatctcgg tagtgggata cgacgatacc gaagacagct catgttatat
1621 cccgccgtta accaccatca aacaggattt tcgcctgctg gggcaaacca gcgtggaccg
1681 cttgctgcaa ctctctcagg gccaggcggt gaagggcaat cagctgttgc ccgtctcact
1741 ggtgaaaaga aaaaccaccc tggcgcccaa tacgcaaacc gcctctcccc gcgcgttggc
1801 cgattcatta atgcagctgg cacgacaggt ttcccgactg gaaagcgggc agtgagcgca
1861 acgcaattaa tgtaagttag ctcactcatt aggcaccggg atctcgaccg atgcccttga
1921 gagccttcaa cccagtcagc tccttccggt gggcgcgggg catgactatc gtcgccgcac
1981 ttatgactgt cttctttatc atgcaactcg taggacaggt gccggcagcg ctctgggtca
2041 ttttcggcga ggaccgcttt cgctggagcg cgacgatgat cggcctgtcg cttgcggtat
2101 tcggaatctt gcacgccctc gctcaagcct tcgtcactgg tcccgccacc aaacgtttcg
2161 gcgagaagca ggccattatc gccggcatgg cggccccacg ggtgcgcatg atcgtgctcc
2221 tgtcgttgag gacccggcta ggctggcggg gttgccttac tggttagcag aatgaatcac
2281 cgatacgcga gcgaacgtga agcgactgct gctgcaaaac gtctgcgacc tgagcaacaa
2341 catgaatggt cttcggtttc cgtgtttcgt aaagtctgga aacgcggaag tcagcgccct
2401 gcaccattat gttccggatc tgcatcgcag gatgctgctg gctaccctgt ggaacaccta
2461 catctgtatt aacgaagcgc tggcattgac cctgagtgat ttttctctgg tcccgccgca
2521 tccataccgc cagttgttta ccctcacaac gttccagtaa ccgggcatgt tcatcatcag
2581 taacccgtat cgtgagcatc ctctctcgtt tcatcggtat cattaccccc atgaacagaa
2641 atccccctta cacggaggca tcagtgacca aacaggaaaa aaccgccctt aacatggccc
2701 gctttatcag aagccagaca ttaacgcttc tggagaaact caacgagctg gacgcggatg
2761 aacaggcaga catctgtgaa tcgcttcacg accacgctga tgagctttac cgcagctgcc
2821 tcgcgcgttt cggtgatgac ggtgaaaacc tctgacacat gcagctcccg gagacggtca
2881 cagcttgtct gtaagcggat gccgggagca gacaagcccg tcagggcgcg tcagcgggtg
2941 ttggcgggtg tcggggcgca gccatgaccc agtcacgtag cgatagcgga gtgtatactg
3001 gcttaactat gcggcatcag agcagattgt actgagagtg caccatatat gcggtgtgaa
3061 ataccgcaca gatgcgtaag gagaaaatac cgcatcaggc gctcttccgc ttcctcgctc
3121 actgactcgc tgcgctcggt cgttcggctg cggcgagcgg tatcagctca ctcaaaggcg
3181 gtaatacggt tatccacaga atcaggggat aacgcaggaa agaacatgtg agcaaaaggc
3241 cagcaaaagg ccaggaaccg taaaaaggcc gcgttgctgg cgtttttcca taggctccgc
3301 ccccctgacg agcatcacaa aaatcgacgc tcaagtcaga ggtggcgaaa cccgacagga
3361 ctataaagat accaggcgtt tccccctgga agctccctcg tgcgctctcc tgttccgacc
3421 ctgccgctta ccggatacct gtccgccttt ctcccttcgg gaagcgtggc gctttctcat
3481 agctcacgct gtaggtatct cagttcggtg taggtcgttc gctccaagct gggctgtgtg
3541 cacgaacccc ccgttcagcc cgaccgctgc gccttatccg gtaactatcg tcttgagtcc
3601 aacccggtaa gacacgactt atcgccactg gcagcagcca ctggtaacag gattagcaga
3661 gcgaggtatg taggcggtgc tacagagttc ttgaagtggt ggcctaacta cggctacact
3721 agaaggacag tatttggtat ctgcgctctg ctgaagccag ttaccttcgg aaaaagagtt
3781 ggtagctctt gatccggcaa acaaaccacc gctggtagcg gtggtttttt tgtttgcaag
3841 cagcagatta cgcgcagaaa aaaaggatct caagaagatc ctttgatctt ttctacgggg
3901 tctgacgctc agtggaacga aaactcacgt taagggattt tggtcatgaa caataaaact
3961 gtctgcttac ataaacagta atacaagggg tgttatgagc catattcaac gggaaacgtc
4021 ttgctctagg ccgcgattaa attccaacat ggatgctgat ttatatgggt ataaatgggc
4081 tcgcgataat gtcgggcaat caggtgcgac aatctatcga ttgtatggga agcccgatgc
4141 gccagagttg tttctgaaac atggcaaagg tagcgttgcc aatgatgtta cagatgagat
4201 ggtcagacta aactggctga cggaatttat gcctcttccg accatcaagc attttatccg
4261 tactcctgat gatgcatggt tactcaccac tgcgatcccc gggaaaacag cattccaggt
4321 attagaagaa tatcctgatt caggtgaaaa tattgttgat gcgctggcag tgttcctgcg
4381 ccggttgcat tcgattcctg tttgtaattg tccttttaac agcgatcgcg tatttcgtct
4441 cgctcaggcg caatcacgaa tgaataacgg tttggttgat gcgagtgatt ttgatgacga
4501 gcgtaatggc tggcctgttg aacaagtctg gaaagaaatg cataaacttt tgccattctc
4561 accggattca gtcgtcactc atggtgattt ctcacttgat aaccttattt ttgacgaggg
4621 gaaattaata ggttgtattg atgttggacg agtcggaatc gcagaccgat accaggatct
4681 tgccatccta tggaactgcc tcggtgagtt ttctccttca ttacagaaac ggctttttca
4741 aaaatatggt attgataatc ctgatatgaa taaattgcag tttcatttga tgctcgatga
4801 gtttttctaa gaattaattc atgagcggat acatatttga atgtatttag aaaaataaac
4861 aaataggggt tccgcgcaca tttccccgaa aagtgccacc tgaaattgta aacgttaata
4921 ttttgttaaa attcgcgtta aatttttgtt aaatcagctc attttttaac caataggccg
4981 aaatcggcaa aatcccttat aaatcaaaag aatagaccga gatagggttg agtgttgttc
5041 cagtttggaa caagagtcca ctattaaaga acgtggactc caacgtcaaa gggcgaaaaa
5101 ccgtctatca gggcgatggc ccactacgtg aaccatcacc ctaatcaagt tttttggggt
5161 cgaggtgccg taaagcacta aatcggaacc ctaaagggag cccccgattt agagcttgac
5221 ggggaaagcc ggcgaacgtg gcgagaaagg aagggaagaa agcgaaagga gcgggcgcta
5281 gggcgctggc aagtgtagcg gtcacgctgc gcgtaaccac cacacccgcc gcgcttaatg
5341 cgccgctaca gggcgcgtcc cattcgcca
//

194
data/plasmid.gb Normal file
View File

@ -0,0 +1,194 @@
LOCUS 40924_17796 5369 bp DNA circular SYN 14-OCT-2021
DEFINITION synthetic circular DNA.
ACCESSION .
VERSION .
KEYWORDS .
SOURCE synthetic DNA construct
ORGANISM synthetic DNA construct
REFERENCE 1 (bases 1 to 5369)
AUTHORS caoheibi
TITLE Direct Submission
REFERENCE 2 (bases 1 to 5369)
AUTHORS .
TITLE Direct Submission
COMMENT SGRef: number: 1; type: "Journal Article"
FEATURES Location/Qualifiers
source 1..5369
/mol_type="other DNA"
/organism="synthetic DNA construct"
terminator complement(26..73)
/label=T7 terminator
/note="transcription terminator for bacteriophage T7 RNA
polymerase"
CDS complement(140..157)
/codon_start=1
/label=6xHis
/note="6xHis affinity tag"
/translation="HHHHHH"
CDS complement(207..239)
/codon_start=1
/label=T7 tag (gene 10 leader)
/note="leader peptide from bacteriophage T7 gene 10"
/translation="MASMTGGQQMG"
CDS complement(243..260)
/codon_start=1
/label=thrombin site
/note="thrombin recognition and cleavage site"
/translation="LVPRGS"
CDS complement(270..287)
/codon_start=1
/label=6xHis
/note="6xHis affinity tag"
/translation="HHHHHH"
RBS complement(306..328)
/label=RBS
/note="efficient ribosome binding site from bacteriophage
T7 gene 10 (Olins and Rangwala, 1989)"
protein_bind complement(343..367)
/label=lac operator
/note="The lac repressor binds to the lac operator to
inhibit transcription in E. coli. This inhibition can be
relieved by adding lactose or
isopropyl-beta-D-thiogalactopyranoside (IPTG)."
promoter complement(368..386)
/label=T7 promoter
/note="promoter for bacteriophage T7 RNA polymerase"
promoter 695..772
/label=lacI promoter
CDS 773..1852
/codon_start=1
/label=lacI
/note="lac repressor"
/translation="VKPVTLYDVAEYAGVSYQTVSRVVNQASHVSAKTREKVEAAMAEL
NYIPNRVAQQLAGKQSLLIGVATSSLALHAPSQIVAAIKSRADQLGASVVVSMVERSGV
EACKAAVHNLLAQRVSGLIINYPLDDQDAIAVEAACTNVPALFLDVSDQTPINSIIFSH
EDGTRLGVEHLVALGHQQIALLAGPLSSVSARLRLAGWHKYLTRNQIQPIAEREGDWSA
MSGFQQTMQMLNEGIVPTAMLVANDQMALGAMRAITESGLRVGADISVVGYDDTEDSSC
YIPPLTTIKQDFRLLGQTSVDRLLQLSQGQAVKGNQLLPVSLVKRKTTLAPNTQTASPR
ALADSLMQLARQVSRLESGQ"
protein_bind 1868..1889
/label=CAP binding site
/note="CAP binding activates transcription in the presence
of cAMP."
CDS 2664..2852
/codon_start=1
/label=rop
/note="Rop protein, which maintains plasmids at low copy
number"
/translation="VTKQEKTALNMARFIRSQTLTLLEKLNELDADEQADICESLHDHA
DELYRSCLARFGDDGENL"
misc_feature 2957..3099
/label=bom
/note="basis of mobility region from pBR322"
rep_origin complement(3285..3873)
/direction=LEFT
/label=ori
/note="high-copy-number ColE1/pMB1/pBR322/pUC origin of
replication"
CDS 3995..4807
/codon_start=1
/label=KanR
/note="aminoglycoside phosphotransferase"
/translation="MSHIQRETSCSRPRLNSNMDADLYGYKWARDNVGQSGATIYRLYG
KPDAPELFLKHGKGSVANDVTDEMVRLNWLTEFMPLPTIKHFIRTPDDAWLLTTAIPGK
TAFQVLEEYPDSGENIVDALAVFLRRLHSIPVCNCPFNSDRVFRLAQAQSRMNNGLVDA
SDFDDERNGWPVEQVWKEMHKLLPFSPDSVVTHGDFSLDNLIFDEGKLIGCIDVGRVGI
ADRYQDLAILWNCLGEFSPSLQKRLFQKYGIDNPDMNKLQFHLMLDEFF"
rep_origin complement(4903..5358)
/direction=LEFT
/label=f1 ori
/note="f1 bacteriophage origin of replication; arrow
indicates direction of (+) strand synthesis"
ORIGIN
1 atccggatat agttcctcct ttcagcaaaa aacccctcaa gacccgttta gaggccccaa
61 ggggttatgc tagttattgc tcagcggtgg cagcagccaa ctcagcttcc tttcgggctt
121 tgttagcagc cggatctcag tggtggtggt ggtggtgctc gagtgcggcc gcaagcttgt
181 cgacggagct cgaattcgga tccgcgaccc atttgctgtc caccagtcat gctagccata
241 tggctgccgc gcggcaccag gccgctgctg tgatgatgat gatgatggct gctgcccatg
301 gtatatctcc ttcttaaagt taaacaaaat tatttctaga ggggaattgt tatccgctca
361 caattcccct atagtgagtc gtattaattt cgcgggatcg agatctcgat cctctacgcc
421 ggacgcatcg tggccggcat caccggcgcc acaggtgcgg ttgctggcgc ctatatcgcc
481 gacatcaccg atggggaaga tcgggctcgc cacttcgggc tcatgagcgc ttgtttcggc
541 gtgggtatgg tggcaggccc cgtggccggg ggactgttgg gcgccatctc cttgcatgca
601 ccattccttg cggcggcggt gctcaacggc ctcaacctac tactgggctg cttcctaatg
661 caggagtcgc ataagggaga gcgtcgagat cccggacacc atcgaatggc gcaaaacctt
721 tcgcggtatg gcatgatagc gcccggaaga gagtcaattc agggtggtga atgtgaaacc
781 agtaacgtta tacgatgtcg cagagtatgc cggtgtctct tatcagaccg tttcccgcgt
841 ggtgaaccag gccagccacg tttctgcgaa aacgcgggaa aaagtggaag cggcgatggc
901 ggagctgaat tacattccca accgcgtggc acaacaactg gcgggcaaac agtcgttgct
961 gattggcgtt gccacctcca gtctggccct gcacgcgccg tcgcaaattg tcgcggcgat
1021 taaatctcgc gccgatcaac tgggtgccag cgtggtggtg tcgatggtag aacgaagcgg
1081 cgtcgaagcc tgtaaagcgg cggtgcacaa tcttctcgcg caacgcgtca gtgggctgat
1141 cattaactat ccgctggatg accaggatgc cattgctgtg gaagctgcct gcactaatgt
1201 tccggcgtta tttcttgatg tctctgacca gacacccatc aacagtatta ttttctccca
1261 tgaagacggt acgcgactgg gcgtggagca tctggtcgca ttgggtcacc agcaaatcgc
1321 gctgttagcg ggcccattaa gttctgtctc ggcgcgtctg cgtctggctg gctggcataa
1381 atatctcact cgcaatcaaa ttcagccgat agcggaacgg gaaggcgact ggagtgccat
1441 gtccggtttt caacaaacca tgcaaatgct gaatgagggc atcgttccca ctgcgatgct
1501 ggttgccaac gatcagatgg cgctgggcgc aatgcgcgcc attaccgagt ccgggctgcg
1561 cgttggtgcg gatatctcgg tagtgggata cgacgatacc gaagacagct catgttatat
1621 cccgccgtta accaccatca aacaggattt tcgcctgctg gggcaaacca gcgtggaccg
1681 cttgctgcaa ctctctcagg gccaggcggt gaagggcaat cagctgttgc ccgtctcact
1741 ggtgaaaaga aaaaccaccc tggcgcccaa tacgcaaacc gcctctcccc gcgcgttggc
1801 cgattcatta atgcagctgg cacgacaggt ttcccgactg gaaagcgggc agtgagcgca
1861 acgcaattaa tgtaagttag ctcactcatt aggcaccggg atctcgaccg atgcccttga
1921 gagccttcaa cccagtcagc tccttccggt gggcgcgggg catgactatc gtcgccgcac
1981 ttatgactgt cttctttatc atgcaactcg taggacaggt gccggcagcg ctctgggtca
2041 ttttcggcga ggaccgcttt cgctggagcg cgacgatgat cggcctgtcg cttgcggtat
2101 tcggaatctt gcacgccctc gctcaagcct tcgtcactgg tcccgccacc aaacgtttcg
2161 gcgagaagca ggccattatc gccggcatgg cggccccacg ggtgcgcatg atcgtgctcc
2221 tgtcgttgag gacccggcta ggctggcggg gttgccttac tggttagcag aatgaatcac
2281 cgatacgcga gcgaacgtga agcgactgct gctgcaaaac gtctgcgacc tgagcaacaa
2341 catgaatggt cttcggtttc cgtgtttcgt aaagtctgga aacgcggaag tcagcgccct
2401 gcaccattat gttccggatc tgcatcgcag gatgctgctg gctaccctgt ggaacaccta
2461 catctgtatt aacgaagcgc tggcattgac cctgagtgat ttttctctgg tcccgccgca
2521 tccataccgc cagttgttta ccctcacaac gttccagtaa ccgggcatgt tcatcatcag
2581 taacccgtat cgtgagcatc ctctctcgtt tcatcggtat cattaccccc atgaacagaa
2641 atccccctta cacggaggca tcagtgacca aacaggaaaa aaccgccctt aacatggccc
2701 gctttatcag aagccagaca ttaacgcttc tggagaaact caacgagctg gacgcggatg
2761 aacaggcaga catctgtgaa tcgcttcacg accacgctga tgagctttac cgcagctgcc
2821 tcgcgcgttt cggtgatgac ggtgaaaacc tctgacacat gcagctcccg gagacggtca
2881 cagcttgtct gtaagcggat gccgggagca gacaagcccg tcagggcgcg tcagcgggtg
2941 ttggcgggtg tcggggcgca gccatgaccc agtcacgtag cgatagcgga gtgtatactg
3001 gcttaactat gcggcatcag agcagattgt actgagagtg caccatatat gcggtgtgaa
3061 ataccgcaca gatgcgtaag gagaaaatac cgcatcaggc gctcttccgc ttcctcgctc
3121 actgactcgc tgcgctcggt cgttcggctg cggcgagcgg tatcagctca ctcaaaggcg
3181 gtaatacggt tatccacaga atcaggggat aacgcaggaa agaacatgtg agcaaaaggc
3241 cagcaaaagg ccaggaaccg taaaaaggcc gcgttgctgg cgtttttcca taggctccgc
3301 ccccctgacg agcatcacaa aaatcgacgc tcaagtcaga ggtggcgaaa cccgacagga
3361 ctataaagat accaggcgtt tccccctgga agctccctcg tgcgctctcc tgttccgacc
3421 ctgccgctta ccggatacct gtccgccttt ctcccttcgg gaagcgtggc gctttctcat
3481 agctcacgct gtaggtatct cagttcggtg taggtcgttc gctccaagct gggctgtgtg
3541 cacgaacccc ccgttcagcc cgaccgctgc gccttatccg gtaactatcg tcttgagtcc
3601 aacccggtaa gacacgactt atcgccactg gcagcagcca ctggtaacag gattagcaga
3661 gcgaggtatg taggcggtgc tacagagttc ttgaagtggt ggcctaacta cggctacact
3721 agaaggacag tatttggtat ctgcgctctg ctgaagccag ttaccttcgg aaaaagagtt
3781 ggtagctctt gatccggcaa acaaaccacc gctggtagcg gtggtttttt tgtttgcaag
3841 cagcagatta cgcgcagaaa aaaaggatct caagaagatc ctttgatctt ttctacgggg
3901 tctgacgctc agtggaacga aaactcacgt taagggattt tggtcatgaa caataaaact
3961 gtctgcttac ataaacagta atacaagggg tgttatgagc catattcaac gggaaacgtc
4021 ttgctctagg ccgcgattaa attccaacat ggatgctgat ttatatgggt ataaatgggc
4081 tcgcgataat gtcgggcaat caggtgcgac aatctatcga ttgtatggga agcccgatgc
4141 gccagagttg tttctgaaac atggcaaagg tagcgttgcc aatgatgtta cagatgagat
4201 ggtcagacta aactggctga cggaatttat gcctcttccg accatcaagc attttatccg
4261 tactcctgat gatgcatggt tactcaccac tgcgatcccc gggaaaacag cattccaggt
4321 attagaagaa tatcctgatt caggtgaaaa tattgttgat gcgctggcag tgttcctgcg
4381 ccggttgcat tcgattcctg tttgtaattg tccttttaac agcgatcgcg tatttcgtct
4441 cgctcaggcg caatcacgaa tgaataacgg tttggttgat gcgagtgatt ttgatgacga
4501 gcgtaatggc tggcctgttg aacaagtctg gaaagaaatg cataaacttt tgccattctc
4561 accggattca gtcgtcactc atggtgattt ctcacttgat aaccttattt ttgacgaggg
4621 gaaattaata ggttgtattg atgttggacg agtcggaatc gcagaccgat accaggatct
4681 tgccatccta tggaactgcc tcggtgagtt ttctccttca ttacagaaac ggctttttca
4741 aaaatatggt attgataatc ctgatatgaa taaattgcag tttcatttga tgctcgatga
4801 gtttttctaa gaattaattc atgagcggat acatatttga atgtatttag aaaaataaac
4861 aaataggggt tccgcgcaca tttccccgaa aagtgccacc tgaaattgta aacgttaata
4921 ttttgttaaa attcgcgtta aatttttgtt aaatcagctc attttttaac caataggccg
4981 aaatcggcaa aatcccttat aaatcaaaag aatagaccga gatagggttg agtgttgttc
5041 cagtttggaa caagagtcca ctattaaaga acgtggactc caacgtcaaa gggcgaaaaa
5101 ccgtctatca gggcgatggc ccactacgtg aaccatcacc ctaatcaagt tttttggggt
5161 cgaggtgccg taaagcacta aatcggaacc ctaaagggag cccccgattt agagcttgac
5221 ggggaaagcc ggcgaacgtg gcgagaaagg aagggaagaa agcgaaagga gcgggcgcta
5281 gggcgctggc aagtgtagcg gtcacgctgc gcgtaaccac cacacccgcc gcgcttaatg
5341 cgccgctaca gggcgcgtcc cattcgcca
//

59
entrypoint.py Normal file
View File

@ -0,0 +1,59 @@
from Bio import SeqIO
from sqlalchemy.orm import Session
from app.database import engine, SessionLocal, Base
from app.models import Sequence, Feature
import json
# Tworzenie tabeli w bazie danych
Base.metadata.create_all(bind=engine)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def load_genbank_to_db(file_path: str):
db = next(get_db())
with open(file_path, 'r') as file:
record = SeqIO.read(file, "genbank")
# Zapisz sekwencję do bazy danych
sequence_data = Sequence(
name=record.name,
description=record.description if 'description' in record.annotations else 'No description',
sequence=str(record.seq)
)
db.add(sequence_data)
db.commit()
db.refresh(sequence_data) # Odśwież sekwencję, aby uzyskać jej ID
# Zapisz cechy (features) do bazy danych
for feature in record.features:
if feature.type in ["promoter", "RBS","CDS", "protein_bind", "misc_feature", "rep_origin", "terminator"]:
qualifiers = {}
if feature.type == "CDS":
qualifiers['gene_name'] = feature.qualifiers.get('gene', ['Unknown gene'])[0]
qualifiers['product'] = feature.qualifiers.get('product', ['Unknown product'])[0]
elif feature.type == "protein_bind":
qualifiers['binding_site'] = feature.qualifiers.get('bound_moiety', ['Unknown binding site'])[0]
elif feature.type == "misc_feature":
qualifiers['note'] = feature.qualifiers.get('note', ['No additional information'])[0]
elif feature.type == "rep_origin":
qualifiers['note'] = "This is a replication origin."
feature_data = Feature(
type=feature.type,
location=str(feature.location),
sequence=str(record.seq[feature.location.start:feature.location.end]),
qualifiers=json.dumps(qualifiers),
sequence_id=sequence_data.id # Ustawienie poprawnego ID
)
db.add(feature_data)
db.commit()
print(f"Loaded {file_path} to database.")
if __name__ == "__main__":
load_genbank_to_db("data/plasmid.gb")

View File

@ -1,18 +0,0 @@
#!/bin/bash
f() {
for i in {1..5}; do
curl -X 'POST' \
"http://$1:9999/api/" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"type": "Item",
"quantity": 1,
"address": "Example Address '"$i"'"
}'
done
}
f $1

View File

@ -1,71 +0,0 @@
# Choose a base image. Debian is a good choice due to pyenv
FROM debian:latest
# Update the package list and install necessary dependencies
RUN apt-get update && apt-get install -y \
aptitude \
tmux vim-nox nano mc git curl termshark procps \
sudo iproute2 iputils-ping bridge-utils \
ifupdown udev make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget llvm libncurses5-dev \
libncursesw5-dev xz-utils libffi-dev liblzma-dev \
sqlite3 default-libmysqlclient-dev pkg-config \
npm htop
# Set password for root user (optional, for configuration)
RUN echo 'root:rootpass' | chpasswd
# Add a new user `user` with password `pass` and prepare the environment
RUN useradd -m user && echo 'user:pass' | chpasswd && adduser user sudo
# Switch to user `user`
USER user
WORKDIR /home/user
# Install pyenv
RUN git clone https://github.com/pyenv/pyenv .pyenv
# Install pyenv-virtualenv
RUN git clone https://github.com/pyenv/pyenv-virtualenv .pyenv/plugins/pyenv-virtualenv
# Set environment variables
ENV HOME /home/user
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
# Add pyenv and pyenv-virtualenv configuration to .bashrc
RUN echo 'export PYENV_ROOT="$HOME/.pyenv"' >> .bashrc
RUN echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> .bashrc
RUN echo 'eval "$(pyenv init -)"' >> .bashrc
RUN echo 'eval "$(pyenv virtualenv-init -)"' >> .bashrc
# Install Python 3.11 with --enable-shared
RUN bash -i -c "source ~/.bashrc && env PYTHON_CONFIGURE_OPTS='--enable-shared' pyenv install 3.11"
# Create a virtual environment p3.11
RUN bash -i -c "source ~/.bashrc && pyenv virtualenv 3.11 p3.11"
# Set p3.11 as the default virtual environment, docker doesn't like ;)
RUN bash -i -c "source ~/.bashrc && pyenv local 3.11"
# Install Poetry
RUN curl -sSL https://install.python-poetry.org | python3 -
RUN curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
# Copy the project into the image
COPY --chown=user:user . /home/user/fapi
COPY --chown=user:user ./_confs/* ./
COPY --chown=user:user ./static/* ./
# Set the working directory for installing dependencies
WORKDIR /home/user/fapi
# Add Poetry path to PATH directly in the Dockerfile
ENV PATH="$HOME/.local/bin:$PATH"
RUN bash -i -c "source ~/.bashrc && poetry config virtualenvs.create false && poetry install"
# Run the application
CMD ["/bin/bash", "-c", "python entrypoint.py"]

View File

@ -1,50 +0,0 @@
# app/main.py
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from sqlalchemy.orm import joinedload
from app import models, database, schemas # Importuj schematy
from fastapi.staticfiles import StaticFiles
from typing import List, Optional
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
# Dependency
def get_db():
db = database.SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/authors/", response_model=schemas.AuthorModel)
def create_author(author: schemas.AuthorCreate, db: Session = Depends(get_db)):
db_author = models.Author(**author.dict())
db.add(db_author)
db.commit()
db.refresh(db_author)
return db_author
@app.get("/authors/", response_model=List[schemas.AuthorModel])
def read_authors(db: Session = Depends(get_db)):
authors = db.query(models.Author).all()
return authors
@app.post("/books/", response_model=schemas.BookModel)
def create_book(book: schemas.BookCreate, db: Session = Depends(get_db)):
db_book = models.Book(**book.dict())
db.add(db_book)
db.commit()
db.refresh(db_book)
return db_book
@app.get("/books/", response_model=List[schemas.BookModel])
def read_books(db: Session = Depends(get_db)):
books = db.query(models.Book).all()
return books
@app.get("/books-with-authors/", response_model=List[schemas.BookWithAuthor])
def read_books_with_authors(db: Session = Depends(get_db)):
books = db.query(models.Book).options(joinedload(models.Book.author)).all()
return books

View File

@ -1,21 +0,0 @@
# app/models.py
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from app.database import Base
class Author(Base):
__tablename__ = "authors"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(255), unique=True, index=True)
books = relationship("Book", back_populates="author")
class Book(Base):
__tablename__ = "books"
id = Column(Integer, primary_key=True, index=True)
title = Column(String(255), index=True)
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship("Author", back_populates="books")

View File

@ -1,23 +0,0 @@
from app.database import engine
from app.models import Base
import uvicorn
import argparse # Importuj argparse
def main(port):
# Create the database
print("Creating database tables...")
Base.metadata.create_all(bind=engine)
print("Database tables created.")
# Uruchomienie aplikacji FastAPI za pomocą uvicorn
uvicorn.run("app.main:app", host="0.0.0.0", port=port, reload=True)
if __name__ == "__main__":
# Utwórz parser argumentów
parser = argparse.ArgumentParser(description="Run the FastAPI app")
# Dodaj argument port, domyślnie 9999
parser.add_argument("--port", type=int, default=9999, help="Port to run the FastAPI app on")
# Parsuj argumenty
args = parser.parse_args()
main(args.port)

653
src/poetry.lock generated
View File

@ -1,653 +0,0 @@
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]]
name = "anyio"
version = "4.3.0"
description = "High level compatibility layer for multiple asynchronous event loop implementations"
optional = false
python-versions = ">=3.8"
files = [
{file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"},
{file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"},
]
[package.dependencies]
exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
idna = ">=2.8"
sniffio = ">=1.1"
typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
[package.extras]
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
trio = ["trio (>=0.23)"]
[[package]]
name = "asgiref"
version = "3.8.1"
description = "ASGI specs, helper code, and adapters"
optional = false
python-versions = ">=3.8"
files = [
{file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"},
{file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"},
]
[package.dependencies]
typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""}
[package.extras]
tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
[[package]]
name = "astunparse"
version = "1.6.3"
description = "An AST unparser for Python"
optional = false
python-versions = "*"
files = [
{file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"},
{file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"},
]
[package.dependencies]
six = ">=1.6.1,<2.0"
wheel = ">=0.23.0,<1.0"
[[package]]
name = "click"
version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "exceptiongroup"
version = "1.2.0"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
{file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]]
name = "fastapi"
version = "0.85.2"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
optional = false
python-versions = ">=3.7"
files = [
{file = "fastapi-0.85.2-py3-none-any.whl", hash = "sha256:6292db0edd4a11f0d938d6033ccec5f706e9d476958bf33b119e8ddb4e524bde"},
{file = "fastapi-0.85.2.tar.gz", hash = "sha256:3e10ea0992c700e0b17b6de8c2092d7b9cd763ce92c49ee8d4be10fee3b2f367"},
]
[package.dependencies]
pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0"
starlette = "0.20.4"
[package.extras]
all = ["email-validator (>=1.1.1,<2.0.0)", "itsdangerous (>=1.1.0,<3.0.0)", "jinja2 (>=2.11.2,<4.0.0)", "orjson (>=3.2.1,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "pyyaml (>=5.3.1,<7.0.0)", "requests (>=2.24.0,<3.0.0)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)", "uvicorn[standard] (>=0.12.0,<0.19.0)"]
dev = ["autoflake (>=1.4.0,<2.0.0)", "flake8 (>=3.8.3,<6.0.0)", "pre-commit (>=2.17.0,<3.0.0)", "uvicorn[standard] (>=0.12.0,<0.19.0)"]
doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer[all] (>=0.6.1,<0.7.0)"]
test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==22.8.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flake8 (>=3.8.3,<6.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "pytest-cov (>=2.12.0,<5.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "pyyaml (>=5.3.1,<7.0.0)", "requests (>=2.24.0,<3.0.0)", "sqlalchemy (>=1.3.18,<=1.4.41)", "types-orjson (==3.6.2)", "types-ujson (==5.5.0)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"]
[[package]]
name = "graphql-core"
version = "3.2.3"
description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL."
optional = false
python-versions = ">=3.6,<4"
files = [
{file = "graphql-core-3.2.3.tar.gz", hash = "sha256:06d2aad0ac723e35b1cb47885d3e5c45e956a53bc1b209a9fc5369007fe46676"},
{file = "graphql_core-3.2.3-py3-none-any.whl", hash = "sha256:5766780452bd5ec8ba133f8bf287dc92713e3868ddd83aee4faab9fc3e303dc3"},
]
[[package]]
name = "greenlet"
version = "3.0.3"
description = "Lightweight in-process concurrent programming"
optional = false
python-versions = ">=3.7"
files = [
{file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"},
{file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"},
{file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"},
{file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"},
{file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"},
{file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"},
{file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"},
{file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"},
{file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"},
{file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"},
{file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"},
{file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"},
{file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"},
{file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"},
{file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"},
{file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"},
{file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"},
{file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"},
{file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"},
{file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"},
{file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"},
{file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"},
{file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"},
{file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"},
{file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"},
{file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"},
{file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"},
{file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"},
{file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"},
{file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"},
{file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"},
{file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"},
{file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"},
{file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"},
{file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"},
{file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"},
{file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"},
{file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"},
{file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"},
{file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"},
{file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"},
{file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"},
{file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"},
{file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"},
{file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"},
{file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"},
{file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"},
{file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"},
{file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"},
{file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"},
{file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"},
{file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"},
{file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"},
{file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"},
]
[package.extras]
docs = ["Sphinx", "furo"]
test = ["objgraph", "psutil"]
[[package]]
name = "h11"
version = "0.14.0"
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
optional = false
python-versions = ">=3.7"
files = [
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
]
[[package]]
name = "idna"
version = "3.6"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.5"
files = [
{file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
]
[[package]]
name = "mysql-connector-python"
version = "8.3.0"
description = "MySQL driver written in Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "mysql-connector-python-8.3.0.tar.gz", hash = "sha256:e4ff23aa8036b4c5b6463fa81398bb5a528a29f99955de6ba937f0bba57a2fe3"},
{file = "mysql_connector_python-8.3.0-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:f4ee7e07cca6b744874d60d6b0b24817d9246eb4e8d7269b7ddbe68763a0bd13"},
{file = "mysql_connector_python-8.3.0-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:5718e426cf67f041772d4984f709052201883f74190ba6feaddce5cbd3b99e6f"},
{file = "mysql_connector_python-8.3.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:0deb38f05057e12af091a48e03a1ff00e213945880000f802879fae5665e7502"},
{file = "mysql_connector_python-8.3.0-cp310-cp310-manylinux_2_17_x86_64.whl", hash = "sha256:4be4165e4cd5acb4659261ddc74e9164d2dfa0d795d5695d52f2bf39ea0762fa"},
{file = "mysql_connector_python-8.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:51d97bf771519829797556718d81e8b9bdcd0a00427740ca57c085094c8bde17"},
{file = "mysql_connector_python-8.3.0-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:5e2c86c60be08c71bae755d811fe8b89ec4feb8117ec3440ebc6c042dd6f06bc"},
{file = "mysql_connector_python-8.3.0-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:de74055944b214bff56e1752ec213d705c421414c67a250fb695af0c5c214135"},
{file = "mysql_connector_python-8.3.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:b2901391b651d60dab3cc8985df94976fc1ea59fa7324c5b19d0a4177914c8dd"},
{file = "mysql_connector_python-8.3.0-cp311-cp311-manylinux_2_17_x86_64.whl", hash = "sha256:55cb57d8098c721abce20fdef23232663977c0e5c87a4d0f9f73466f32c7d168"},
{file = "mysql_connector_python-8.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:201e609159b84a247be87b76f5deb79e8c6b368e91f043790e62077f13f3fed8"},
{file = "mysql_connector_python-8.3.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:c57d02fd6c28be444487e7905ede09e3fecb18377cf82908ca262826369d3401"},
{file = "mysql_connector_python-8.3.0-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:9302d774025e76a0fac46bfeea8854b3d6819715a6a16ff23bfcda04218a76b7"},
{file = "mysql_connector_python-8.3.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:85fa878fdd6accaeb7d609bd2637c2cfa61592e7f9bdbdc0da18b2fa998d3d5a"},
{file = "mysql_connector_python-8.3.0-cp312-cp312-manylinux_2_17_x86_64.whl", hash = "sha256:de0f2f2baa9e091ca8bdc4a091f874f9cd0b84b256389596adb0e032a05fe9f9"},
{file = "mysql_connector_python-8.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:27f8be2087627366a44a6831ec68b568c98dbf0f4ceff24682d90c21db6e0f1f"},
{file = "mysql_connector_python-8.3.0-cp38-cp38-macosx_13_0_x86_64.whl", hash = "sha256:ec6dc3434a7deef74ab04e8978f6c5e181866a5423006c1b5aec5390a189d28d"},
{file = "mysql_connector_python-8.3.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:73ee8bc5f9626c42b37342a91a825cddb3461f6bfbbd6524d8ccfd3293aaa088"},
{file = "mysql_connector_python-8.3.0-cp38-cp38-manylinux_2_17_x86_64.whl", hash = "sha256:1db5b48b4ff7d24344217ed2418b162c7677eec86ab9766dc0e5feae39c90974"},
{file = "mysql_connector_python-8.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:77bae496566d3da77bb0e938d89243103d20ee41633f626a47785470451bf45c"},
{file = "mysql_connector_python-8.3.0-cp39-cp39-macosx_13_0_arm64.whl", hash = "sha256:f7acacdf9fd4260702f360c00952ad9a9cc73e8b7475e0d0c973c085a3dd7b7d"},
{file = "mysql_connector_python-8.3.0-cp39-cp39-macosx_13_0_x86_64.whl", hash = "sha256:5f707a9b040ad4700fc447ba955c78b08f2dd5affde37ac2401918f7b6daaba3"},
{file = "mysql_connector_python-8.3.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:125714c998a697592bc56cce918a1acc58fadc510a7f588dbef3e53a1920e086"},
{file = "mysql_connector_python-8.3.0-cp39-cp39-manylinux_2_17_x86_64.whl", hash = "sha256:7f4f5fa844c19ee3a78c4606f6e138b06829e75469592d90246a290c7befc322"},
{file = "mysql_connector_python-8.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:de5c3ee89d9276356f93df003949d3ba4c486f32fec9ec9fd7bc0caab124d89c"},
{file = "mysql_connector_python-8.3.0-py2.py3-none-any.whl", hash = "sha256:e868ccc7ad9fbc242546db04673d89cee87d12b8139affd114524553df4e5d6a"},
]
[package.extras]
dns-srv = ["dnspython (>=1.16.0,<=2.3.0)"]
fido2 = ["fido2 (==1.1.2)"]
gssapi = ["gssapi (>=1.6.9,<=1.8.2)"]
opentelemetry = ["Deprecated (>=1.2.6)", "typing-extensions (>=3.7.4)", "zipp (>=0.5)"]
[[package]]
name = "mysqlclient"
version = "2.2.4"
description = "Python interface to MySQL"
optional = false
python-versions = ">=3.8"
files = [
{file = "mysqlclient-2.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:ac44777eab0a66c14cb0d38965572f762e193ec2e5c0723bcd11319cc5b693c5"},
{file = "mysqlclient-2.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:329e4eec086a2336fe3541f1ce095d87a6f169d1cc8ba7b04ac68bcb234c9711"},
{file = "mysqlclient-2.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:e1ebe3f41d152d7cb7c265349fdb7f1eca86ccb0ca24a90036cde48e00ceb2ab"},
{file = "mysqlclient-2.2.4-cp38-cp38-win_amd64.whl", hash = "sha256:3c318755e06df599338dad7625f884b8a71fcf322a9939ef78c9b3db93e1de7a"},
{file = "mysqlclient-2.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:9d4c015480c4a6b2b1602eccd9846103fc70606244788d04aa14b31c4bd1f0e2"},
{file = "mysqlclient-2.2.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d43987bb9626096a302ca6ddcdd81feaeca65ced1d5fe892a6a66b808326aa54"},
{file = "mysqlclient-2.2.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4e80dcad884dd6e14949ac6daf769123223a52a6805345608bf49cdaf7bc8b3a"},
{file = "mysqlclient-2.2.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9d3310295cb682232cadc28abd172f406c718b9ada41d2371259098ae37779d3"},
{file = "mysqlclient-2.2.4.tar.gz", hash = "sha256:33bc9fb3464e7d7c10b1eaf7336c5ff8f2a3d3b88bab432116ad2490beb3bf41"},
]
[[package]]
name = "pydantic"
version = "1.10.14"
description = "Data validation and settings management using python type hints"
optional = false
python-versions = ">=3.7"
files = [
{file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"},
{file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"},
{file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"},
{file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"},
{file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"},
{file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"},
{file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"},
{file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"},
{file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"},
{file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"},
{file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"},
{file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"},
{file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"},
{file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"},
{file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"},
{file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"},
{file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"},
{file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"},
{file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"},
{file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"},
{file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"},
{file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"},
{file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"},
{file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"},
{file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"},
{file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"},
{file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"},
{file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"},
{file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"},
{file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"},
{file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"},
{file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"},
{file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"},
{file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"},
{file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"},
{file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"},
]
[package.dependencies]
typing-extensions = ">=4.2.0"
[package.extras]
dotenv = ["python-dotenv (>=0.10.4)"]
email = ["email-validator (>=1.0.3)"]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
description = "Extensions to the standard Python datetime module"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
files = [
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
]
[package.dependencies]
six = ">=1.5"
[[package]]
name = "python-multipart"
version = "0.0.9"
description = "A streaming multipart parser for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215"},
{file = "python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026"},
]
[package.extras]
dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatch", "invoke (==2.2.0)", "more-itertools (==10.2.0)", "pbr (==6.0.0)", "pluggy (==1.4.0)", "py (==1.11.0)", "pytest (==8.0.0)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.2.0)", "pyyaml (==6.0.1)", "ruff (==0.2.1)"]
[[package]]
name = "six"
version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
[[package]]
name = "sniffio"
version = "1.3.1"
description = "Sniff out which async library your code is running under"
optional = false
python-versions = ">=3.7"
files = [
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
]
[[package]]
name = "sqlalchemy"
version = "2.0.29"
description = "Database Abstraction Library"
optional = false
python-versions = ">=3.7"
files = [
{file = "SQLAlchemy-2.0.29-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c142852ae192e9fe5aad5c350ea6befe9db14370b34047e1f0f7cf99e63c63b"},
{file = "SQLAlchemy-2.0.29-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:99a1e69d4e26f71e750e9ad6fdc8614fbddb67cfe2173a3628a2566034e223c7"},
{file = "SQLAlchemy-2.0.29-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ef3fbccb4058355053c51b82fd3501a6e13dd808c8d8cd2561e610c5456013c"},
{file = "SQLAlchemy-2.0.29-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d6753305936eddc8ed190e006b7bb33a8f50b9854823485eed3a886857ab8d1"},
{file = "SQLAlchemy-2.0.29-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0f3ca96af060a5250a8ad5a63699180bc780c2edf8abf96c58af175921df847a"},
{file = "SQLAlchemy-2.0.29-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c4520047006b1d3f0d89e0532978c0688219857eb2fee7c48052560ae76aca1e"},
{file = "SQLAlchemy-2.0.29-cp310-cp310-win32.whl", hash = "sha256:b2a0e3cf0caac2085ff172c3faacd1e00c376e6884b5bc4dd5b6b84623e29e4f"},
{file = "SQLAlchemy-2.0.29-cp310-cp310-win_amd64.whl", hash = "sha256:01d10638a37460616708062a40c7b55f73e4d35eaa146781c683e0fa7f6c43fb"},
{file = "SQLAlchemy-2.0.29-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:308ef9cb41d099099fffc9d35781638986870b29f744382904bf9c7dadd08513"},
{file = "SQLAlchemy-2.0.29-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:296195df68326a48385e7a96e877bc19aa210e485fa381c5246bc0234c36c78e"},
{file = "SQLAlchemy-2.0.29-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a13b917b4ffe5a0a31b83d051d60477819ddf18276852ea68037a144a506efb9"},
{file = "SQLAlchemy-2.0.29-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f6d971255d9ddbd3189e2e79d743ff4845c07f0633adfd1de3f63d930dbe673"},
{file = "SQLAlchemy-2.0.29-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:61405ea2d563407d316c63a7b5271ae5d274a2a9fbcd01b0aa5503635699fa1e"},
{file = "SQLAlchemy-2.0.29-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de7202ffe4d4a8c1e3cde1c03e01c1a3772c92858837e8f3879b497158e4cb44"},
{file = "SQLAlchemy-2.0.29-cp311-cp311-win32.whl", hash = "sha256:b5d7ed79df55a731749ce65ec20d666d82b185fa4898430b17cb90c892741520"},
{file = "SQLAlchemy-2.0.29-cp311-cp311-win_amd64.whl", hash = "sha256:205f5a2b39d7c380cbc3b5dcc8f2762fb5bcb716838e2d26ccbc54330775b003"},
{file = "SQLAlchemy-2.0.29-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d96710d834a6fb31e21381c6d7b76ec729bd08c75a25a5184b1089141356171f"},
{file = "SQLAlchemy-2.0.29-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:52de4736404e53c5c6a91ef2698c01e52333988ebdc218f14c833237a0804f1b"},
{file = "SQLAlchemy-2.0.29-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c7b02525ede2a164c5fa5014915ba3591730f2cc831f5be9ff3b7fd3e30958e"},
{file = "SQLAlchemy-2.0.29-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dfefdb3e54cd15f5d56fd5ae32f1da2d95d78319c1f6dfb9bcd0eb15d603d5d"},
{file = "SQLAlchemy-2.0.29-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a88913000da9205b13f6f195f0813b6ffd8a0c0c2bd58d499e00a30eb508870c"},
{file = "SQLAlchemy-2.0.29-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fecd5089c4be1bcc37c35e9aa678938d2888845a134dd016de457b942cf5a758"},
{file = "SQLAlchemy-2.0.29-cp312-cp312-win32.whl", hash = "sha256:8197d6f7a3d2b468861ebb4c9f998b9df9e358d6e1cf9c2a01061cb9b6cf4e41"},
{file = "SQLAlchemy-2.0.29-cp312-cp312-win_amd64.whl", hash = "sha256:9b19836ccca0d321e237560e475fd99c3d8655d03da80c845c4da20dda31b6e1"},
{file = "SQLAlchemy-2.0.29-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:87a1d53a5382cdbbf4b7619f107cc862c1b0a4feb29000922db72e5a66a5ffc0"},
{file = "SQLAlchemy-2.0.29-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a0732dffe32333211801b28339d2a0babc1971bc90a983e3035e7b0d6f06b93"},
{file = "SQLAlchemy-2.0.29-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90453597a753322d6aa770c5935887ab1fc49cc4c4fdd436901308383d698b4b"},
{file = "SQLAlchemy-2.0.29-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ea311d4ee9a8fa67f139c088ae9f905fcf0277d6cd75c310a21a88bf85e130f5"},
{file = "SQLAlchemy-2.0.29-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5f20cb0a63a3e0ec4e169aa8890e32b949c8145983afa13a708bc4b0a1f30e03"},
{file = "SQLAlchemy-2.0.29-cp37-cp37m-win32.whl", hash = "sha256:e5bbe55e8552019c6463709b39634a5fc55e080d0827e2a3a11e18eb73f5cdbd"},
{file = "SQLAlchemy-2.0.29-cp37-cp37m-win_amd64.whl", hash = "sha256:c2f9c762a2735600654c654bf48dad388b888f8ce387b095806480e6e4ff6907"},
{file = "SQLAlchemy-2.0.29-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e614d7a25a43a9f54fcce4675c12761b248547f3d41b195e8010ca7297c369c"},
{file = "SQLAlchemy-2.0.29-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:471fcb39c6adf37f820350c28aac4a7df9d3940c6548b624a642852e727ea586"},
{file = "SQLAlchemy-2.0.29-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:988569c8732f54ad3234cf9c561364221a9e943b78dc7a4aaf35ccc2265f1930"},
{file = "SQLAlchemy-2.0.29-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dddaae9b81c88083e6437de95c41e86823d150f4ee94bf24e158a4526cbead01"},
{file = "SQLAlchemy-2.0.29-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:334184d1ab8f4c87f9652b048af3f7abea1c809dfe526fb0435348a6fef3d380"},
{file = "SQLAlchemy-2.0.29-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:38b624e5cf02a69b113c8047cf7f66b5dfe4a2ca07ff8b8716da4f1b3ae81567"},
{file = "SQLAlchemy-2.0.29-cp38-cp38-win32.whl", hash = "sha256:bab41acf151cd68bc2b466deae5deeb9e8ae9c50ad113444151ad965d5bf685b"},
{file = "SQLAlchemy-2.0.29-cp38-cp38-win_amd64.whl", hash = "sha256:52c8011088305476691b8750c60e03b87910a123cfd9ad48576d6414b6ec2a1d"},
{file = "SQLAlchemy-2.0.29-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3071ad498896907a5ef756206b9dc750f8e57352113c19272bdfdc429c7bd7de"},
{file = "SQLAlchemy-2.0.29-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dba622396a3170974f81bad49aacebd243455ec3cc70615aeaef9e9613b5bca5"},
{file = "SQLAlchemy-2.0.29-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b184e3de58009cc0bf32e20f137f1ec75a32470f5fede06c58f6c355ed42a72"},
{file = "SQLAlchemy-2.0.29-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c37f1050feb91f3d6c32f864d8e114ff5545a4a7afe56778d76a9aec62638ba"},
{file = "SQLAlchemy-2.0.29-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bda7ce59b06d0f09afe22c56714c65c957b1068dee3d5e74d743edec7daba552"},
{file = "SQLAlchemy-2.0.29-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:25664e18bef6dc45015b08f99c63952a53a0a61f61f2e48a9e70cec27e55f699"},
{file = "SQLAlchemy-2.0.29-cp39-cp39-win32.whl", hash = "sha256:77d29cb6c34b14af8a484e831ab530c0f7188f8efed1c6a833a2c674bf3c26ec"},
{file = "SQLAlchemy-2.0.29-cp39-cp39-win_amd64.whl", hash = "sha256:04c487305ab035a9548f573763915189fc0fe0824d9ba28433196f8436f1449c"},
{file = "SQLAlchemy-2.0.29-py3-none-any.whl", hash = "sha256:dc4ee2d4ee43251905f88637d5281a8d52e916a021384ec10758826f5cbae305"},
{file = "SQLAlchemy-2.0.29.tar.gz", hash = "sha256:bd9566b8e58cabd700bc367b60e90d9349cd16f0984973f98a9a09f9c64e86f0"},
]
[package.dependencies]
greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""}
typing-extensions = ">=4.6.0"
[package.extras]
aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"]
aioodbc = ["aioodbc", "greenlet (!=0.4.17)"]
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"]
asyncio = ["greenlet (!=0.4.17)"]
asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"]
mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"]
mssql = ["pyodbc"]
mssql-pymssql = ["pymssql"]
mssql-pyodbc = ["pyodbc"]
mypy = ["mypy (>=0.910)"]
mysql = ["mysqlclient (>=1.4.0)"]
mysql-connector = ["mysql-connector-python"]
oracle = ["cx_oracle (>=8)"]
oracle-oracledb = ["oracledb (>=1.0.1)"]
postgresql = ["psycopg2 (>=2.7)"]
postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"]
postgresql-pg8000 = ["pg8000 (>=1.29.1)"]
postgresql-psycopg = ["psycopg (>=3.0.7)"]
postgresql-psycopg2binary = ["psycopg2-binary"]
postgresql-psycopg2cffi = ["psycopg2cffi"]
postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"]
pymysql = ["pymysql"]
sqlcipher = ["sqlcipher3_binary"]
[[package]]
name = "starlette"
version = "0.20.4"
description = "The little ASGI library that shines."
optional = false
python-versions = ">=3.7"
files = [
{file = "starlette-0.20.4-py3-none-any.whl", hash = "sha256:c0414d5a56297d37f3db96a84034d61ce29889b9eaccf65eb98a0b39441fcaa3"},
{file = "starlette-0.20.4.tar.gz", hash = "sha256:42fcf3122f998fefce3e2c5ad7e5edbf0f02cf685d646a83a08d404726af5084"},
]
[package.dependencies]
anyio = ">=3.4.0,<5"
typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""}
[package.extras]
full = ["itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests"]
[[package]]
name = "strawberry-graphql"
version = "0.219.2"
description = "A library for creating GraphQL APIs"
optional = false
python-versions = ">=3.8,<4.0"
files = [
{file = "strawberry_graphql-0.219.2-py3-none-any.whl", hash = "sha256:6b26994bcf092714dbd6def4c69a36c279fbdbfdc2390fb6294728dd076ba863"},
{file = "strawberry_graphql-0.219.2.tar.gz", hash = "sha256:b7a9b3115398402ec04fceb76b0dd3908dd90009cf20d344071be985c039aac7"},
]
[package.dependencies]
astunparse = {version = ">=1.6.3,<2.0.0", markers = "python_version < \"3.9\""}
fastapi = {version = ">=0.65.2", optional = true, markers = "extra == \"fastapi\""}
graphql-core = ">=3.2.0,<3.3.0"
python-dateutil = ">=2.7.0,<3.0.0"
python-multipart = {version = ">=0.0.7", optional = true, markers = "extra == \"asgi\" or extra == \"debug-server\" or extra == \"fastapi\""}
typing-extensions = ">=4.5.0"
[package.extras]
aiohttp = ["aiohttp (>=3.7.4.post0,<4.0.0)"]
asgi = ["python-multipart (>=0.0.7)", "starlette (>=0.18.0)"]
chalice = ["chalice (>=1.22,<2.0)"]
channels = ["asgiref (>=3.2,<4.0)", "channels (>=3.0.5)"]
cli = ["libcst (>=0.4.7)", "pygments (>=2.3,<3.0)", "rich (>=12.0.0)", "typer (>=0.7.0)"]
debug = ["libcst (>=0.4.7)", "rich (>=12.0.0)"]
debug-server = ["libcst (>=0.4.7)", "pygments (>=2.3,<3.0)", "python-multipart (>=0.0.7)", "rich (>=12.0.0)", "starlette (>=0.18.0)", "typer (>=0.7.0)", "uvicorn (>=0.11.6)"]
django = ["Django (>=3.2)", "asgiref (>=3.2,<4.0)"]
fastapi = ["fastapi (>=0.65.2)", "python-multipart (>=0.0.7)"]
flask = ["flask (>=1.1)"]
litestar = ["litestar (>=2)"]
opentelemetry = ["opentelemetry-api (<2)", "opentelemetry-sdk (<2)"]
pydantic = ["pydantic (>1.6.1)"]
pyinstrument = ["pyinstrument (>=4.0.0)"]
quart = ["quart (>=0.19.3)"]
sanic = ["sanic (>=20.12.2)"]
starlite = ["starlite (>=1.48.0)"]
[[package]]
name = "typing-extensions"
version = "4.10.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
{file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
]
[[package]]
name = "uvicorn"
version = "0.17.6"
description = "The lightning-fast ASGI server."
optional = false
python-versions = ">=3.7"
files = [
{file = "uvicorn-0.17.6-py3-none-any.whl", hash = "sha256:19e2a0e96c9ac5581c01eb1a79a7d2f72bb479691acd2b8921fce48ed5b961a6"},
{file = "uvicorn-0.17.6.tar.gz", hash = "sha256:5180f9d059611747d841a4a4c4ab675edf54c8489e97f96d0583ee90ac3bfc23"},
]
[package.dependencies]
asgiref = ">=3.4.0"
click = ">=7.0"
h11 = ">=0.8"
[package.extras]
standard = ["PyYAML (>=5.1)", "colorama (>=0.4)", "httptools (>=0.4.0)", "python-dotenv (>=0.13)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchgod (>=0.6)", "websockets (>=10.0)"]
[[package]]
name = "websockets"
version = "12.0"
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
optional = false
python-versions = ">=3.8"
files = [
{file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
{file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"},
{file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"},
{file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"},
{file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"},
{file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"},
{file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"},
{file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"},
{file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"},
{file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"},
{file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"},
{file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"},
{file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"},
{file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"},
{file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"},
{file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"},
{file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"},
{file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"},
{file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"},
{file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"},
{file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"},
{file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"},
{file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"},
{file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"},
{file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"},
{file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"},
{file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"},
{file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"},
{file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"},
{file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"},
{file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"},
{file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"},
{file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"},
{file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"},
{file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"},
{file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"},
{file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"},
{file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"},
{file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"},
{file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"},
{file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"},
{file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"},
{file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"},
{file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"},
{file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"},
{file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"},
{file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"},
{file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"},
{file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"},
{file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"},
{file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"},
{file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"},
{file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"},
{file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"},
{file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"},
{file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"},
{file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"},
{file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"},
{file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"},
{file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"},
{file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"},
{file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"},
{file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"},
{file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"},
{file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"},
{file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"},
{file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"},
{file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"},
{file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"},
{file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"},
{file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
{file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
]
[[package]]
name = "wheel"
version = "0.43.0"
description = "A built-package format for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "wheel-0.43.0-py3-none-any.whl", hash = "sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81"},
{file = "wheel-0.43.0.tar.gz", hash = "sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85"},
]
[package.extras]
test = ["pytest (>=6.0.0)", "setuptools (>=65)"]
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
content-hash = "105119712865c66fa759fbc45c472ee9026535e6473b012bb5db3c4ecf73b0f3"

View File

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<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">
</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>
</body>
</html>

69
static/index.html Normal file
View File

@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Feature Viewer</title>
<script src="/static/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>Feature Viewer</h1>
<button @click="fetchSequences">Fetch Sequences</button>
<button @click="fetchFeatures">Fetch Features</button>
<div v-if="sequences.length">
<h2>Sequences:</h2>
<ul>
<li v-for="sequence in sequences" :key="sequence.id">
<p><strong>Name:</strong> {{ sequence.name }}</p>
<p><strong>Description:</strong> {{ sequence.description }}</p>
<p><strong>Sequence:</strong> {{ sequence.sequence }}</p>
</li>
</ul>
</div>
<div v-if="features.length">
<h2>Features:</h2>
<ul>
<li v-for="feature in features" :key="feature.id">
<p><strong>Type:</strong> {{ feature.type }}</p>
<p><strong>Location:</strong> {{ feature.location }}</p>
<p><strong>Sequence:</strong> {{ feature.sequence }}</p>
<p><strong>Qualifiers:</strong> {{ feature.qualifiers }}</p>
</li>
</ul>
</div>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
sequences: [],
features: []
}
},
methods: {
async fetchSequences() {
try {
const response = await fetch('/sequences/');
this.sequences = await response.json();
} catch (error) {
console.error("There was an error fetching the sequences:", error);
}
},
async fetchFeatures() {
try {
const response = await fetch('/features/');
this.features = await response.json();
} catch (error) {
console.error("There was an error fetching the features:", error);
}
}
}
}).mount('#app');
</script>
</body>
</html>

16733
static/vue.global.js Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,25 +0,0 @@
\documentclass{article}
\usepackage{hyperref} % Dodaje aktywne linki
\begin{document}
\section{Polecenia curl}
Poniżej znajdują się polecenia \texttt{curl} do wysyłania żądań POST do endpointu \texttt{/kebab\_orders/}:
\begin{verbatim}
for i in {1..5}; do \
curl -X 'POST' \
'http://qstack.pl:9999/kebab_orders/' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"type": "Kebab",
"quantity": 1,
"address": "Example Address '$i'"
}'; \
done
\end{verbatim}
\end{document}

Binary file not shown.

View File

@ -1,232 +0,0 @@
\documentclass{article}
\usepackage[margin=2cm]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc} % Support for Polish characters
\usepackage{polski} % Polish language settings
\usepackage[english]{babel} % Multilingual support, with Polish as default
\usepackage{listings}
\usepackage{xcolor}
\definecolor{vscodePurple}{rgb}{0.5, 0.0, 0.5} % Function names, keywords
\definecolor{vscodeBlue}{rgb}{0.16, 0.32, 0.75} % Comments
\definecolor{vscodeGreen}{rgb}{0, 0.6, 0} % Strings
% Configuration for the listings package
\lstset{
basicstyle=\ttfamily,
columns=fullflexible,
keywordstyle=\color{vscodePurple},
stringstyle=\color{vscodeGreen},
commentstyle=\color{vscodeBlue},
morecomment=[l][\color{magenta}]{\#},
frame=single,
language=Python,
showstringspaces=false,
breaklines=true, % Enables line breaking
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space}, % Marks where a line has been broken
}
\usepackage{graphicx} % Add the graphicx package for \reflectbox
\usepackage{hyperref}
\usepackage[
sortcites,
backend=biber,
hyperref=true,
firstinits=true,
maxbibnames=99,
]{biblatex}
\addbibresource{references.bib}
\title{Dockerfile for FastAPI Application using Pyenv and Poetry}
\author{M. Pabiszczak}
\date{\today}
\begin{document}
\maketitle
\section{Description of Dockerfile}
\subsection{Base Image}
\textbf{Dockerfile Instruction:}
\begin{verbatim}
FROM debian:latest
\end{verbatim}
Choose a base image. Debian is a good choice due to Pyenv.
\subsection{Installing Dependencies}
\textbf{Dockerfile Instruction:}
\begin{verbatim}
RUN apt-get update && apt-get install -y \
aptitude \
tmux vim-nox nano mc git curl termshark procps \
sudo iproute2 iputils-ping bridge-utils \
ifupdown udev make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget llvm libncurses5-dev \
libncursesw5-dev xz-utils libffi-dev liblzma-dev \
sqlite3 default-libmysqlclient-dev pkg-config
RUN echo 'root:pass' | chpasswd
RUN useradd -m user && echo 'user:pass' | chpasswd && adduser user sudo
\end{verbatim}
Update the package list and install necessary dependencies.
\subsection{Installing Pyenv}
\textbf{Dockerfile Instruction:}
\begin{verbatim}
RUN git clone https://github.com/pyenv/pyenv .pyenv
RUN git clone https://github.com/pyenv/pyenv-virtualenv .pyenv/plugins/pyenv-virtualenv
ENV HOME /home/user
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
RUN echo 'export PYENV_ROOT="$HOME/.pyenv"' >> .bashrc
RUN echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> .bashrc
RUN echo 'eval "$(pyenv init -)"' >> .bashrc
RUN echo 'eval "$(pyenv virtualenv-init -)"' >> .bashrc
\end{verbatim}
Install Pyenv and Pyenv-virtualenv.
\subsection{Installing Python 3.11}
\textbf{Dockerfile Instruction:}
\begin{verbatim}
RUN bash -i -c "source ~/.bashrc && env PYTHON_CONFIGURE_OPTS='--enable-shared' pyenv install 3.11"
RUN bash -i -c "source ~/.bashrc && pyenv virtualenv 3.11 p3.11"
RUN bash -i -c "source ~/.bashrc && pyenv local 3.11"
\end{verbatim}
Install Python 3.11 using Pyenv.
\subsection{Installing Poetry}
\textbf{Dockerfile Instruction:}
\begin{verbatim}
RUN curl -sSL https://install.python-poetry.org | python3 -
\end{verbatim}
Install Poetry.
\subsection{Project Configuration}
\textbf{Dockerfile Instruction:}
\begin{verbatim}
COPY --chown=user:user . /home/user/fapi
COPY ./_confs/* ./
WORKDIR /home/user/fapi
ENV PATH="$HOME/.local/bin:$PATH"
RUN bash -i -c "source ~/.bashrc && poetry config virtualenvs.create false && poetry install"
\end{verbatim}
Copy the project into the image, configure the Poetry path, and install dependencies.
\subsection{Running the Application}
\textbf{Dockerfile Instruction:}
\begin{verbatim}
CMD ["/bin/bash", "-c", "python entrypoint.py"]
\end{verbatim}
Run the application.
\section{Running the Container}
\subsection{Running with Default Command}
\textbf{Docker Command:}
\begin{verbatim}
docker run --rm -dit -p 9999:9999 fapi
\end{verbatim}
Run the container with the default command (CMD).
\subsection{Running with Bash Shell}
\textbf{Docker Command:}
\begin{verbatim}
docker run --rm -dit -p 9999:9999 --name cfapi fapi bash
\end{verbatim}
Run the container with a bash shell.
\subsection{Accessing Container Shell}
\textbf{Docker Command:}
\begin{verbatim}
docker exec -it cfapi bash
\end{verbatim}
Allows accessing the shell of the container named cfapi.
\appendix
\section{Complete Dockerfile with Database Creation}
\begin{verbatim}
# Choose a base image. Debian is a good choice due to pyenv
FROM debian:latest
# Update the package list and install necessary dependencies
RUN apt-get update && apt-get install -y \
aptitude \
tmux vim-nox nano mc git curl termshark procps \
sudo iproute2 iputils-ping bridge-utils \
ifupdown udev make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget llvm libncurses5-dev \
libncursesw5-dev xz-utils libffi-dev liblzma-dev \
sqlite3 default-libmysqlclient-dev pkg-config
# Set password for root user (optional, for configuration)
RUN echo 'root:rootpass' | chpasswd
# Add a new user `user` with password `pass` and prepare the environment
RUN useradd -m user && echo 'user:pass' | chpasswd && adduser user sudo
# Switch to user `user`
USER user
WORKDIR /home/user
# Install pyenv
RUN git clone https://github.com/pyenv/pyenv .pyenv
# Install pyenv-virtualenv
RUN git clone https://github.com/pyenv/pyenv-virtualenv .pyenv/plugins/pyenv-virtualenv
# Set environment variables
ENV HOME /home/user
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
# Add pyenv and pyenv-virtualenv configuration to .bashrc
RUN echo 'export PYENV_ROOT="$HOME/.pyenv"' >> .bashrc
RUN echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> .bashrc
RUN echo 'eval "$(pyenv init -)"' >> .bashrc
RUN echo 'eval "$(pyenv virtualenv-init -)"' >> .bashrc
# Install Python 3.11 with --enable-shared
RUN bash -i -c "source ~/.bashrc && env PYTHON_CONFIGURE_OPTS='--enable-shared' pyenv install 3.11"
# Create a virtual environment p3.11
RUN bash -i -c "source ~/.bashrc && pyenv virtualenv 3.11 p3.11"
# Set p3.11 as the default virtual environment, docker doesn't like ;)
RUN bash -i -c "source ~/.bashrc && pyenv local 3.11"
# Install Poetry
RUN curl -sSL https://install.python-poetry.org | python3 -
# Copy the project into the image
COPY --chown=user:user . /home/user/fapi
COPY ./_confs/* ./
# Set the working directory for installing dependencies
WORKDIR /home/user/fapi
# Add Poetry path to PATH directly in the Dockerfile
ENV PATH="$HOME/.local/bin:$PATH"
RUN bash -i -c "source ~/.bashrc && poetry config virtualenvs.create false && poetry install"
# Run the application
CMD ["/bin/bash", "-c", "python entrypoint.py"]
\end{verbatim}
\end{document}

Binary file not shown.

View File

@ -1,163 +0,0 @@
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
% \title{Exercise:
\title{Fetching Data from API with FastAPI and JavaScript and Inserting into a Table}
\author{Tomasz Zadworny}
\date{\today}
\begin{document}
\maketitle
\section{Introduction}
In this exercise, we will explore the process of fetching data from an API using FastAPI on the server side and displaying it on the client side using JavaScript with the \texttt{fetch} API.
\section{Server-side Implementation with FastAPI}
Create a FastAPI application that serves a simple API endpoint returning JSON data. The following Python code snippet demonstrates a basic FastAPI application:
\begin{verbatim}
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"http://localhost:8888",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins, # Dla wszystkich domen (uwaga: lepiej określić konkretne adresy)
allow_credentials=True,
# allow_origins=["*"], # Dla wszystkich domen (uwaga: lepiej określić konkretne adresy)
# allow_credentials=False,
allow_methods=["*"], # Dla wszystkich metod HTTP
allow_headers=["*"], # Dla wszystkich nagłówków HTTP
)
data = [
{"id": 1, "name": "Example 1"},
{"id": 2, "name": "Example 2"},
{"id": 3, "name": "Example 3"},
]
@app.get("/api/data")
def get_data():
return data
\end{verbatim}
\subsection{Poetry Configuration}
To configure your Python project using Poetry, follow these steps:
\begin{enumerate}
\item \textbf{Initialize Poetry:} Run the following command to initialize your project with Poetry.
\begin{verbatim}
poetry init
\end{verbatim}
This command will guide you through the project setup process, prompting for information such as the project name, version, and dependencies.
\item \textbf{Add FastAPI:} Use the following command to add FastAPI as a dependency to your project.
\begin{verbatim}
poetry add fastapi
\end{verbatim}
This will automatically update your \texttt{pyproject.toml} file with the FastAPI dependency.
\item \textbf{Add Uvicorn:} Similarly, add Uvicorn as a dependency.
\begin{verbatim}
poetry add uvicorn
\end{verbatim}
\item \textbf{Install Dependencies:} Execute the following command to install the dependencies.
\begin{verbatim}
poetry install
\end{verbatim}
This command installs the project dependencies, including FastAPI and Uvicorn.
\item \textbf{Install (No-Root):} For development purposes, it's recommended to use the following command to install dependencies without including the project itself.
\begin{verbatim}
poetry install --no-root
\end{verbatim}
This command installs dependencies without including the main project. It's useful when you're working in a virtual environment.
\item \textbf{Run Uvicorn:} To run your FastAPI application using Uvicorn, execute the following command:
\begin{verbatim}
poetry run uvicorn --reload app.main:app --host 0.0.0.0 --port 9999
\end{verbatim}
This command starts the FastAPI application with Uvicorn, enabling hot-reloading and specifying the host and port.
\end{enumerate}
These steps help you configure your Python project using Poetry, adding FastAPI and Uvicorn as dependencies and providing commands to install and run your application.
\section{Client-side Implementation with JavaScript}
Design an HTML page that uses JavaScript and the \texttt{fetch} API to retrieve data from the FastAPI endpoint and display it in a table. The following HTML and JavaScript code can serve as a starting point:
\begin{verbatim}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fetch Data Example</title>
</head>
<body>
<table id="data-table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody id="data-body"></tbody>
</table>
<script>
document.addEventListener("DOMContentLoaded", function () {
fetchData();
});
async function fetchData() {
try {
const response = await fetch('http://localhost:9999/api/data');
const data = await response.json();
populateTable(data);
} catch (error) {
console.error('Error fetching data:', error);
}
}
function populateTable(data) {
const tableBody = document.getElementById('data-body');
data.forEach(item => {
const row = document.createElement('tr');
row.innerHTML = `<td>${item.id}</td><td>${item.name}</td>`;
tableBody.appendChild(row);
});
}
</script>
</body>
</html>
\end{verbatim}
\section{Conclusion}
This exercise introduces the basics of using FastAPI to create a simple API and using JavaScript with the \texttt{fetch} API to retrieve and display data on the client side.
\end{document}