r/flask Jul 06 '24

Tutorials and Guides Build Your Own Pastebin Service using Flask

Thumbnail
youtube.com
8 Upvotes

r/flask Aug 24 '24

Tutorials and Guides Flask Full Tutorial For Beginners

Thumbnail
youtu.be
8 Upvotes

r/flask Jun 11 '24

Tutorials and Guides In case anyone would find it useful, I wrote up the steps I took when setting up a 'traditional' Linux server to host a new Flask app

Thumbnail
github.com
18 Upvotes

r/flask Jul 12 '24

Tutorials and Guides Sending Confirmation Emails with Flask, Redis Queue, and Amazon SES

Thumbnail
testdriven.io
6 Upvotes

r/flask Apr 12 '24

Tutorials and Guides How do I share my Flask website?

1 Upvotes

beginner here, my friend asked me to share a function webbsite to her so she can show some of my school juniors. however, i’m not quite certain on how to publicly host a website since my projects are generally private. do i upload my code on github and then send her the link? or do i ‘save as’ the webpage and send her the google html file? please help!

r/flask Jul 14 '24

Tutorials and Guides Tutorial Resource needed

2 Upvotes

I am trying to make a Event Management web app for my college project I am a complete newby in flask html and css So with your help provide me some resources link to achieve my goal

r/flask Aug 13 '24

Tutorials and Guides Insurance Portal Development: Key Features, Best Practices

Thumbnail
quickwayinfosystems.com
2 Upvotes

r/flask Jun 18 '24

Tutorials and Guides Flask SocketIO with Gunicorn

3 Upvotes

I'm at my wits end.

Basically, my flask webapp allows users to upload videos, then the DeepFace library processes the videos and detects the facial expressions of the people in the videos. I used ProcessPoolExecutor to run the facial recognition classes that I created for DeepFace. I use socketio to track the progress of video processing.

Now I'm at the deployment phase of the project using gunicorn and nginx, and I'm running into some issues with gunicorn. For some reason, a gunicorn timeout error causes my app to fail when processing the video, this never happens during development.

**Server:

OS - Ubuntu

CPU - Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz

RAM - 32GB

**Here are some gunicorn logs:

config: ./gunicorn.conf.py

wsgi_app: None

bind: ['0.0.0.0:8050']

backlog: 2048

workers: 1

worker_class: eventlet

threads: 1

worker_connections: 1000

max_requests: 0

max_requests_jitter: 0

timeout: 30

graceful_timeout: 30

keepalive: 2

limit_request_line: 4094

limit_request_fields: 100

limit_request_field_size: 8190

reload: False

reload_engine: auto

reload_extra_files: []

spew: False

check_config: False

print_config: False

preload_app: False

sendfile: None

reuse_port: False

chdir: /home/flaskuser/flask_webapp

daemon: False

raw_env: []

pidfile: None

worker_tmp_dir: None

user: 1002

group: 1003

umask: 0

initgroups: False

tmp_upload_dir: None

secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}

forwarded_allow_ips: ['127.0.0.1']

accesslog: None

disable_redirect_access_to_syslog: False

access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"

errorlog: /tmp/gunicorn_log

loglevel: debug

capture_output: False

logger_class: gunicorn.glogging.Logger

logconfig: None

logconfig_dict: {}

logconfig_json: None

syslog_addr: udp://localhost:514

syslog: False

syslog_prefix: None

syslog_facility: user

enable_stdio_inheritance: False

statsd_host: None

dogstatsd_tags:

statsd_prefix:

proc_name: None

default_proc_name: main:app

pythonpath: None

paste: None

on_starting: <function OnStarting.on_starting at 0x7f9871a3ba30>

on_reload: <function OnReload.on_reload at 0x7f9871a3bb50>

when_ready: <function WhenReady.when_ready at 0x7f9871a3bc70>

pre_fork: <function Prefork.pre_fork at 0x7f9871a3bd90>

post_fork: <function Postfork.post_fork at 0x7f9871a3beb0>

post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f9871a58040>

worker_int: <function WorkerInt.worker_int at 0x7f9871a58160>

worker_abort: <function WorkerAbort.worker_abort at 0x7f9871a58280>

pre_exec: <function PreExec.pre_exec at 0x7f9871a583a0>

pre_request: <function PreRequest.pre_request at 0x7f9871a584c0>

post_request: <function PostRequest.post_request at 0x7f9871a58550>

child_exit: <function ChildExit.child_exit at 0x7f9871a58670>

worker_exit: <function WorkerExit.worker_exit at 0x7f9871a58790>

nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f9871a588b0>

on_exit: <function OnExit.on_exit at 0x7f9871a589d0>

ssl_context: <function NewSSLContext.ssl_context at 0x7f9871a58af0>

proxy_protocol: False

proxy_allow_ips: ['127.0.0.1']

keyfile: None

certfile: None

ssl_version: 2

cert_reqs: 0

ca_certs: None

suppress_ragged_eofs: True

do_handshake_on_connect: False

ciphers: None

raw_paste_global_conf: []

strip_header_spaces: False

permit_unconventional_http_method: False

permit_unconventional_http_version: False

casefold_http_method: False

header_map: drop

tolerate_dangerous_framing: False

[2024-06-18 09:48:07 +0000] [3703188] [INFO] Starting gunicorn 22.0.0

[2024-06-18 09:48:07 +0000] [3703188] [DEBUG] Arbiter booted

[2024-06-18 09:48:07 +0000] [3703188] [INFO] Listening at: http://0.0.0.0:8050 (3703188)

[2024-06-18 09:48:07 +0000] [3703188] [INFO] Using worker: eventlet

[2024-06-18 09:48:07 +0000] [3703188] [DEBUG] 1 workers

[2024-06-18 09:48:07 +0000] [3703205] [INFO] Booting worker with pid: 3703205

[2024-06-18 09:50:19 +0000] [3703188] [CRITICAL] WORKER TIMEOUT (pid:3703205)

[2024-06-18 09:50:49 +0000] [3703188] [ERROR] Worker (pid:3703205) was sent SIGKILL! Perhaps out of memory?

[2024-06-18 09:50:49 +0000] [3730830] [INFO] Booting worker with pid: 3730830

[2024-06-18 09:57:08 +0000] [3703188] [INFO] Handling signal: term

[2024-06-18 09:57:38 +0000] [3703188] [INFO] Shutting down: Master

[2024-06-18 09:59:08 +0000] [3730934] [DEBUG] Current configuration:

config: ./gunicorn.conf.py

wsgi_app: None

bind: ['0.0.0.0:8050']

backlog: 2048

workers: 1

worker_class: gevent

threads: 1

worker_connections: 1000

max_requests: 0

max_requests_jitter: 0

timeout: 30

graceful_timeout: 30

keepalive: 2

limit_request_line: 4094

limit_request_fields: 100

limit_request_field_size: 8190

reload: False

reload_engine: auto

reload_extra_files: []

spew: False

check_config: False

print_config: False

preload_app: False

sendfile: None

reuse_port: False

chdir: /home/flaskuser/flask_webapp

daemon: False

raw_env: []

pidfile: None

worker_tmp_dir: None

user: 1002

group: 1003

umask: 0

initgroups: False

tmp_upload_dir: None

secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}

forwarded_allow_ips: ['127.0.0.1']

accesslog: None

disable_redirect_access_to_syslog: False

access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"

errorlog: /tmp/gunicorn_log

loglevel: debug

capture_output: False

logger_class: gunicorn.glogging.Logger

logconfig: None

logconfig_dict: {}

logconfig_json: None

syslog_addr: udp://localhost:514

syslog: False

syslog_prefix: None

syslog_facility: user

enable_stdio_inheritance: False

statsd_host: None

dogstatsd_tags:

statsd_prefix:

proc_name: None

default_proc_name: main:app

pythonpath: None

paste: None

on_starting: <function OnStarting.on_starting at 0x7f29f239fa30>

on_reload: <function OnReload.on_reload at 0x7f29f239fb50>

when_ready: <function WhenReady.when_ready at 0x7f29f239fc70>

pre_fork: <function Prefork.pre_fork at 0x7f29f239fd90>

post_fork: <function Postfork.post_fork at 0x7f29f239feb0>

post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f29f23bc040>

worker_int: <function WorkerInt.worker_int at 0x7f29f23bc160>

worker_abort: <function WorkerAbort.worker_abort at 0x7f29f23bc280>

pre_exec: <function PreExec.pre_exec at 0x7f29f23bc3a0>

pre_request: <function PreRequest.pre_request at 0x7f29f23bc4c0>

post_request: <function PostRequest.post_request at 0x7f29f23bc550>

child_exit: <function ChildExit.child_exit at 0x7f29f23bc670>

worker_exit: <function WorkerExit.worker_exit at 0x7f29f23bc790>

nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f29f23bc8b0>

on_exit: <function OnExit.on_exit at 0x7f29f23bc9d0>

ssl_context: <function NewSSLContext.ssl_context at 0x7f29f23bcaf0>

proxy_protocol: False

proxy_allow_ips: ['127.0.0.1']

keyfile: None

certfile: None

ssl_version: 2

cert_reqs: 0

ca_certs: None

suppress_ragged_eofs: True

do_handshake_on_connect: False

ciphers: None

raw_paste_global_conf: []

strip_header_spaces: False

permit_unconventional_http_method: False

permit_unconventional_http_version: False

casefold_http_method: False

header_map: drop

tolerate_dangerous_framing: False

[2024-06-18 09:59:08 +0000] [3730934] [INFO] Starting gunicorn 22.0.0

[2024-06-18 09:59:08 +0000] [3730934] [DEBUG] Arbiter booted

[2024-06-18 09:59:08 +0000] [3730934] [INFO] Listening at: http://0.0.0.0:8050 (3730934)

[2024-06-18 09:59:08 +0000] [3730934] [INFO] Using worker: gevent

[2024-06-18 09:59:08 +0000] [3730954] [INFO] Booting worker with pid: 3730954

[2024-06-18 09:59:08 +0000] [3730934] [DEBUG] 1 workers

[2024-06-18 10:02:51 +0000] [3730934] [CRITICAL] WORKER TIMEOUT (pid:3730954)

**main.py

import os
from website import create_app, socketio

from dotenv import load_dotenv
load_dotenv()

app = create_app()

if __name__ == '__main__':
    socketio.run(app, debug=os.getenv('DEBUG'), host=os.getenv('APP_HOST'), port=os.getenv('APP_PORT'))

** code that processes the video (I'm using ProcessPoolExecutor to call the classes I created with DeepFace)

import os
import pathlib
import cv2
import numpy as np
import threading
from threading import Thread
from concurrent.futures import ProcessPoolExecutor
from concurrent.futures import as_completed
from typing import List, Tuple, Dict

from .. import app
from ..utility import write_to_log
from .processing.utility import timeit
from .processing.process_image import ProcessImage
from .processing.process_lighting import ProcessLighting


def prepare_audit_directories(directory_name: str) -> None:
    
    directory_path = os.path.join(app.config['SNAPSHOTS_DIR'], directory_name)
    pathlib.Path(app.config['SNAPSHOTS_DIR'], directory_name).mkdir(exist_ok=True)
    pathlib.Path(directory_path, 'bad_lighting').mkdir(exist_ok=True)
    pathlib.Path(directory_path, 'emotions').mkdir(exist_ok=True)
    pathlib.Path(os.path.join(directory_path, 'emotions'), 'happy').mkdir(exist_ok=True)
    pathlib.Path(os.path.join(directory_path, 'emotions'), 'surprise').mkdir(exist_ok=True)
    pathlib.Path(os.path.join(directory_path, 'emotions'), 'neutral').mkdir(exist_ok=True)
    pathlib.Path(os.path.join(directory_path, 'emotions'), 'sad').mkdir(exist_ok=True)
    pathlib.Path(os.path.join(directory_path, 'emotions'), 'fear').mkdir(exist_ok=True)
    pathlib.Path(os.path.join(directory_path, 'emotions'), 'disgust').mkdir(exist_ok=True)
    pathlib.Path(os.path.join(directory_path, 'emotions'), 'angry').mkdir(exist_ok=True)
    pathlib.Path(os.path.join(directory_path, 'emotions'), 'None').mkdir(exist_ok=True)


def convert_ms_to_timestamp(ms: float) -> str:
    total_sec: float = ms / 1000
    min: int = int(total_sec // 60)
    sec: int = int(total_sec % 60)
    
    min_str: str = f"0{min}" if min < 10 else min
    sec_str: str = f"0{sec}" if sec < 10 else sec
    
    return f"{min_str}_{sec_str}"


def get_video_duration(duration: float) -> str:
    minutes = round(duration/60)
    seconds = round(duration%60)
    return f'{minutes}_{seconds}'
    
    
def get_percentage(part: float, whole: int) -> float:
        return round((part/whole) * 100,2)
    
    
def get_weights(dict: Dict[str, float | int], snapshot_counter: int) -> Dict[str, float]:
    for key, value in dict.items():
        dict[key] = get_percentage(value, snapshot_counter)
        
    return dict
    

async def start(video_filename: str, file_extension: str, crop_video: bool, detector_backend: str, frame_iteration: int, dark_pixel_threshold: int, dark_percentage_threshold: int) -> Dict[str, Dict[str, int | float | Dict[str, float]]]:
    # create a directory named "input" in root and place the video to process
    input_video_path: str = os.path.join(app.config['UPLOADS_DIR'], f"{video_filename}{file_extension}")
    # Open the video file
    video: cv2.VideoCapture = cv2.VideoCapture(input_video_path)
    
    # setting video metadata
    frame_counter: int = 0 # counts total frame interations
    snapshot_counter: int = 0 # total snapshots from video (rate is based on frames_per_snapshot)
    total_frames: float = video.get(cv2.CAP_PROP_FRAME_COUNT)
    total_frames_counter: float = total_frames # used for while loop condition, decrementing
    fps: int = round(video.get(cv2.CAP_PROP_FPS))
    video_duration: str = get_video_duration(total_frames/fps)
    video_dimensions: str | None = None

    # value is 999999 for only 1 snapshot
    if frame_iteration != 999999:
        frames_per_snapshot = round(frame_iteration*fps)
    else:
        frames_per_snapshot = round(total_frames / 2)+1 # adding 1 to make sure it only takes one snapshot
    
    # initializing process classes in audit app
    process_img: ProcessImage = ProcessImage(detector_backend, video_filename)
    process_lighting: ProcessLighting = ProcessLighting(dark_pixel_threshold, dark_percentage_threshold, video_filename)
    
    # lighting report
    dark_snapshot_counter: int = 0
    
    emotion_counter: Dict[str, float] = {'happy':0,'surprise':0,'neutral':0,'fear':0,'sad':0,'disgust':0,'angry':0,'None':0}
    
    # setting max workers of cpu count
    max_workers: int = round(int(os.cpu_count())/2)
    with ProcessPoolExecutor(max_workers) as executor:
        futures = [] # will contain the data for each process in pool
        
        while total_frames_counter > 0:
            
            # Read a frame from the video
            ret: bool = False
            frame: np.ndarray | None = None
            ret, frame = video.read()

            # If the frame was not read correctly, we have reached the end of the video
            if not ret:
                break
            
            frame_counter +=1
            
            #  get dimension of frame (width, height)
            if video_dimensions == None:
                video_dimensions = f"{frame.shape[1::-1][0]}x{frame.shape[1::-1][1]}"

            if frame_counter % frames_per_snapshot == 0:
                
                # Crop the frame to the specified ROI
                if crop_video == True:
                    # Region of Interest (ROI) coordinates (x, y, width, height) for cropping
                    roi: Tuple[int, int, int, int] = (694, 50, 319, 235)
                    frame = frame[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2]]
                
                timestamp: str = convert_ms_to_timestamp(video.get(cv2.CAP_PROP_POS_MSEC))
                
                futures.append(executor.submit(process_lighting.analyse_lighting, frame, frame_counter, timestamp))
                futures.append(executor.submit(process_img.analyse_emotion, frame, frame_counter, timestamp))
                snapshot_counter+=1
                
            total_frames_counter-=1
        
        # wait for all processes to finish and compile return values
        for future in as_completed(futures):
            try:
                # retrieve the result of current future
                result = future.result()
                
                if 'dark' in result and result['dark']:
                    dark_snapshot_counter+=1
                elif 'emotion' in result:
                    key = result['emotion']
                    emotion_counter[key] += 1
                
            except Exception as e:
                write_to_log(video_filename, e)
                app.logger.error(f'{video_filename} -> {e}')
        
    # Release the video file
    video.release()
        
    dark_percentage = get_percentage(dark_snapshot_counter, snapshot_counter)    
    weights: Dict[str, float] = get_weights(emotion_counter, snapshot_counter)
    
    return {
        'metadata':{
            'file_name': video_filename,
            'file_extension': file_extension,
            'total_frames': total_frames,
            'fps': fps,
            'duration': video_duration,
            'dimensions': video_dimensions,
            'total_snapshots': snapshot_counter,
            'snapshot_directory': process_lighting.get_snapshot_directory(),
        },
        'options': {
            'crop_video': crop_video,
            'detector_backend': detector_backend,
            'dark_pixel_threshold': dark_pixel_threshold,
            'dark_percentage_threshold': dark_percentage_threshold,
            'frame_iteration': frame_iteration,
        },
        'bad_lighting': {
            'dark_percentage': dark_percentage,
            'dark_snapshot_count': dark_snapshot_counter,
            'total_lighting_snapshots': snapshot_counter,
        },
        'emotion': {
            'weights': weights,
        },
    } 

** Solutions I tried:

setting --timeout to 0 or 2100 seconds, didn't work.

I was using eventlet then switched to gevent, didn't work.

I specified the max workers for my ProcessPoolExecutor to half of my cpu count, didn't work.

Any advice is appreciated. TIA!

r/flask Jul 07 '24

Tutorials and Guides Flask authentication and clean architecture

5 Upvotes

I am a beginner with flask. I am receiving auth token from a flutter firebase setup using google sso login. How to get the data encrypted using secret key in flask app. I am actually looking for good coding practices (clean architecture) developer uses generally on flask apps.

r/flask Jun 02 '24

Tutorials and Guides Need help with Industry Standard Project structure

7 Upvotes

Hi All,

I need some help regarding any course or blogs out there that tells how the Flask projects are structured according to industry standard.

Does anyone know about it? I am already a dev, but I feel the mentors I work with doesn't know much stuff on structuring larger projects. Also the standard patterns are rarely followed.

Please let me know if I can refer to some good course or blog!

Thanks

r/flask Jul 28 '24

Tutorials and Guides system design mock interviews

2 Upvotes

Where should i take mock interviews on system design so i can learn more and improve myself

r/flask Jul 23 '24

Tutorials and Guides Implementing Instant Search with Flask and HTMX

Thumbnail
differ.blog
1 Upvotes

r/flask Jul 11 '24

Tutorials and Guides A Guide to Front-End vs. Back-End vs. Full-Stack Development

Thumbnail
quickwayinfosystems.com
0 Upvotes

r/flask Jul 06 '24

Tutorials and Guides Ultimate SQL Learning Resource: Case Studies, Projects, and Platform Solutions in One Place!

2 Upvotes

Hi everyone !!

Check out Faizan's SQL Portfolio on GitHub! 🚀

This comprehensive resource includes:

  • Case Studies: Real-world scenarios from Danny Ma's 8 Week SQL Challenge.
  • Platform Solutions: SQL problems & solutions from 7 different platforms including DataLemur, Leetcode, Hackerrank, Stratascratch and more.
  • Projects: Detailed SQL projects with data analysis techniques.
  • Resources: List of compiled SQL resources from different channels like YT, Books, Tutorials etc.

and much more!!

Perfect for students and professionals to enhance their SQL skills through practical applications. Explore, learn, and improve your SQL expertise!

🔗 https://github.com/faizanxmulla/sql-portfolio

Thank you so much for considering! If you would like to connect, feel free to reach out to me on LinkedIn.

Happy learning! 

r/flask Mar 23 '24

Tutorials and Guides Refresh Jinja HTML Without Reloading the Page | Flask Tutorial

Thumbnail
youtu.be
10 Upvotes

r/flask Jul 05 '24

Tutorials and Guides Geolocate an IP address and perform WHOIS domain lookup in Flask

Thumbnail
blog.ip2location.com
0 Upvotes

r/flask Mar 24 '24

Tutorials and Guides Google authorization and Google Drive

5 Upvotes

Hello everyone. I need some help in creating a website that allows users to log in using their Google account. Once they are logged in, I want to provide them with the ability to upload files to their Google Drive. Can anyone provide some guidance on how to do this? Thank you in advance.

r/flask Jun 01 '24

Tutorials and Guides Is a directory called "instance" supposed to be generated?

2 Upvotes

*update* I'm following the Flask Application Factory tutorial. It runs correctly, but it generates a folder literally called "myapp/instance" after running the file myapp/myapp/__init__.py.

I'm using the app.instance_path variable in the tutorial, but my configs are from an object with defined env vars, so should I be testing for AppConfig.SRCPATH (myapp/myapp) or a made up instance (myapp/myapp/madupname ). Some clarification would be great, thanks!

def create_app(test_config=False):
    # create and configure the app
    # I also tried Flask(__name__, ...). Still uses the name "instance"
    app = Flask("archive_tool", instance_relative_config=True)

    app.config.update(
        DEBUG=test_config,
        SQLALCHEMY_DATABASE_URI = AppConfig.DBURI,
        SECRET_KEY=AppConfig.SECRET_KEY,
        DATABASE=DBPATH,
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_object(AppConfig, silent=True)

    # ensure the instance folder exists
    try:
        WindowsPath.mkdir(WindowsPath(app.instance_path), exist_ok=True)
    except WindowsError as e:
        print(f"instance_path failed: {e}")

r/flask Jun 17 '24

Tutorials and Guides Flask Master Class For Beginners To Pro | Free Udemy Coupons

Thumbnail
webhelperapp.com
0 Upvotes

r/flask May 01 '24

Tutorials and Guides Reading / viewing suggestions on the inner workings of Flask

7 Upvotes

Sorry if this is a dumb question or if it doesn't make sense. When I run into issues with my flask application and struggle to find a solution, I think a big part of it is I lack a lot of fundamental understanding of what flask is actually doing "mechanically", and what my server is doing with it. I'm not looking for tutorial #30 on how to make a storefront or what terminal commands in what sequence I need to spin up a server. But rather a general overview of how the software itself behaves beneath the surface. The goal here is to set myself up to better troubleshoot my own issues as they arise, or at least become more efficient in seeking answers.

I've been reading the docs for Flask, gunicorn, and nginx (these are what I'm using), but I find a lot of it dense and maybe presumptive of some beforehand knowledge. Is there anything out there gives a basic primer on how all of this works?

r/flask Jun 11 '24

Tutorials and Guides Best UI/UX Practices in Web App Development - Enhance User Experience

Thumbnail
quickwayinfosystems.com
1 Upvotes

r/flask May 18 '24

Tutorials and Guides Python,Flask Framework And Django Course For Beginners | Free Udemy Coupons

Thumbnail
webhelperapp.com
0 Upvotes

r/flask May 29 '24

Tutorials and Guides Python And Flask Demonstrations Practice Course | Free Udemy Coupons

Thumbnail
webhelperapp.com
0 Upvotes

r/flask May 22 '24

Tutorials and Guides Flask Stripe Tutorial

Thumbnail
testdriven.io
14 Upvotes

r/flask Nov 05 '23

Tutorials and Guides Flask coding challenge without blueprints and marshmallow

0 Upvotes

I have an upcoming coding assessment at work for flask. I'm not a flask developer(only have knowledge from self preparation from YouTube). The coding challenge has the project structure With route.py, model.py, serialisation.py, url.py and other files (including main.py, tests.py) I'm only allowed to modify the files i named(main not included) Not allowed to install external libraries other than the ones already provided as the validation with be done on a sanbox that is already configured.(marshmallow is not provided)

Not allowed to modify the import section also.(i don't see blueprints used in any file)

The question is to solve an API that performs CRUD operations with SQL alchemy (context can be ecommerce app or hospital patient management systems ... Similar to that)

Some of the endpoints need to output JSON with atleast 5 nested level (from the joining and group by on the db.tables)

The test is only 2 hrs(need to create all the models and endpoints at least 10 will be there).

What is the best approach to solve this type of problems(considering the time constraint). ?

p.s, All the tutorials were using marshmallow and blueprints to achieve this. ( I only have basic knowledge in flask , is there a different approach?)