{"id":122,"date":"2025-03-14T18:11:11","date_gmt":"2025-03-14T18:11:11","guid":{"rendered":"https:\/\/database.victorzsantos.com\/?page_id=122"},"modified":"2025-04-25T15:19:20","modified_gmt":"2025-04-25T15:19:20","slug":"apps","status":"publish","type":"page","link":"https:\/\/database.victorzsantos.com\/?page_id=122","title":{"rendered":"Apps"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"122\" class=\"elementor elementor-122\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f71326e e-flex e-con-boxed e-con e-parent\" data-id=\"f71326e\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-445ebb4 elementor-widget elementor-widget-text-editor\" data-id=\"445ebb4\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p class=\"p1\">Below is a <span class=\"s1\"><b>step-by-step<\/b><\/span> tutorial on how to start your <span class=\"s1\"><b>database_app_2.0<\/b><\/span> project, which includes both the <span class=\"s1\"><b>backend<\/b><\/span> (FastAPI) and the <span class=\"s1\"><b>frontend<\/b><\/span> (React). We\u2019ll assume your folder structure looks like this:<\/p><pre><code>~\/Desktop\/database_app_2.0\/\n    \u251c\u2500\u2500 backend\/\n    \u2502    \u251c\u2500\u2500 main.py  (Your FastAPI code)\n    \u2502    \u251c\u2500\u2500 database.csv  (Optional original CSV)\n    \u2502    \u251c\u2500\u2500 ... other backend files ...\n    \u251c\u2500\u2500 frontend\/\n    \u2502    \u251c\u2500\u2500 src\/\n    \u2502    \u2502    \u251c\u2500\u2500 App.js  (Your React code)\n    \u2502    \u2502    \u251c\u2500\u2500 uploadcsv.js (Optional upload component)\n    \u2502    \u251c\u2500\u2500 package.json\n    \u2502    \u251c\u2500\u2500 ... other frontend files ...\n    \u2514\u2500\u2500 ...<\/code><\/pre><p class=\"p1\">If your paths differ, just adjust them accordingly.<\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>1. Start the Backend<\/b><b><\/b><\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>1.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Open a Terminal<\/b><\/span> (on Mac, you can use Spotlight or Launchpad).<\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>2.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Navigate<\/b><\/span> to your <span class=\"s3\">backend<\/span> folder:<\/p><pre><code>cd ~\/Desktop\/database_app_2.0\/backend<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><span class=\"Apple-tab-span\">\t<\/span>3.<span class=\"Apple-tab-span\">\t<\/span>(Optional) <\/span><b>Activate your virtual environment<\/b><span class=\"s1\"> if you have one:<\/span><\/p><pre><code>source venv\/bin\/activate<\/code><\/pre><p class=\"p1\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span>You\u2019ll see <span class=\"s1\">(venv)<\/span> in your prompt if it\u2019s activated.<\/p><p class=\"p2\"><br><\/p><p class=\"p3\"><span class=\"Apple-tab-span\">\t<\/span>4.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Run<\/b><\/span> the FastAPI server with uvicorn:<\/p><pre><code>uvicorn main:app --reload --host 0.0.0.0 --port 3000<\/code><\/pre><p class=\"p1\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span>This starts your backend on <a href=\"http:\/\/localhost:3000\">http:\/\/localhost:3000<\/a>.<\/p><p class=\"p1\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span>You should see logs like:<\/p><pre><code>INFO:     Uvicorn running on http:\/\/0.0.0.0:3000 (Press CTRL+C to quit)<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>5.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Check<\/b><\/span> <a href=\"http:\/\/localhost:3000\/properties\/\">http:\/\/localhost:3000\/properties\/<\/a> in your browser. If you see JSON (like <span class=\"s2\">[]<\/span> or a list of objects), the backend is running fine.<\/p><p class=\"p1\"><br><\/p><p class=\"p3\"><span class=\"s1\"><b>Leave this Terminal open<\/b><\/span> so the server keeps running. To stop it, press <span class=\"s1\"><b>Ctrl + C<\/b><\/span>.<\/p><p class=\"p4\"><span class=\"s3\"><\/span><\/p><hr><p><\/p><p class=\"p5\"><b>2. Start the Frontend<\/b><b><\/b><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>1.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Open a New Terminal<\/b><\/span> window or tab (so the backend continues to run in the first one).<\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>2.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Navigate<\/b><\/span> to your <span class=\"s2\">frontend<\/span> folder:<\/p><pre><code>cd ~\/Desktop\/database_app_2.0\/frontend<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>3.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Install dependencies<\/b><\/span> if you haven\u2019t already:<\/p><pre><code>npm install<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>4.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Start<\/b><\/span> the React development server:<\/p><pre><code>npm start<\/code><\/pre><p class=\"p1\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span>If your backend is on port 3000, Create React App usually picks port 3001 for the frontend.<\/p><p class=\"p1\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span>If everything is correct, your default browser will open <a href=\"http:\/\/localhost:3000\">http:\/\/localhost:3000<\/a> or <a href=\"http:\/\/localhost:3001\">http:\/\/localhost:3001<\/a>.<\/p><p class=\"p1\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span>If you see a prompt like \u201cSomething is running on port 3000, run on port 3001 instead?\u201d press <span class=\"s1\"><b>Y<\/b><\/span>.<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>3. Verify the App<\/b><b><\/b><\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Backend<\/b><\/span>: <a href=\"http:\/\/localhost:3000\/properties\/\">http:\/\/localhost:3000\/properties\/<\/a> returns JSON data from FastAPI.<\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Frontend<\/b><\/span>: Usually <a href=\"http:\/\/localhost:3001\">http:\/\/localhost:3001<\/a> if React had to pick a different port. You\u2019ll see your React UI with tabs like \u201cSystem,\u201d \u201cK\/B,\u201d etc.<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>4. Uploading Data &amp; Checking Results<\/b><b><\/b><\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>1.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>In your React UI<\/b><\/span>, you\u2019ll see a button or component (UploadCSV) to upload a new CSV.<\/p><p class=\"p6\"><span class=\"s3\"><span class=\"Apple-tab-span\">\t<\/span>2.<span class=\"Apple-tab-span\">\t<\/span><\/span><span class=\"s1\"><b>Choose<\/b><\/span><span class=\"s3\"> a CSV file (like <\/span>TexasData.csv<span class=\"s3\"> or <\/span>database.csv<span class=\"s3\">).<\/span><\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>3.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>After upload<\/b><\/span>, open your backend logs (the Terminal where uvicorn runs) to see debug prints.<\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>4.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Go to<\/b><\/span> your React app again, select the tab you want (enter the correct password if needed), and your new data should appear if it passes all filters.<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>5. Stopping the App<\/b><b><\/b><\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Frontend<\/b><\/span>: In the Terminal where you ran <span class=\"s4\">npm start<\/span>, press <span class=\"s1\"><b>Ctrl + C<\/b><\/span>.<\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Backend<\/b><\/span>: In the Terminal where you ran <span class=\"s4\">uvicorn main:app &#8211;reload<\/span>, press <span class=\"s1\"><b>Ctrl + C<\/b><\/span>.<\/p><p class=\"p7\"><br><\/p><p class=\"p8\">Everything will shut down.<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>6. Summary<\/b><b><\/b><\/p><p class=\"p9\"><span class=\"s3\"><span class=\"Apple-tab-span\">\t<\/span>1.<span class=\"Apple-tab-span\">\t<\/span><\/span><b>Backend<\/b><span class=\"s3\">:<\/span><\/p><pre><code>cd ~\/Desktop\/database_app_2.0\/backend\nuvicorn main:app --reload --port 3000<\/code><\/pre><p class=\"p1\">(Activate your virtualenv if needed.)<\/p><p class=\"p2\"><br><\/p><p class=\"p3\"><span class=\"Apple-tab-span\">\t<\/span>2.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Frontend<\/b><\/span> (in a separate Terminal):<\/p><pre><code>cd ~\/Desktop\/database_app_2.0\/frontend\nnpm install\nnpm start<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>3.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Open<\/b><\/span> your browser to <a href=\"http:\/\/localhost:3001\">http:\/\/localhost:3001<\/a> (or whichever port React chooses) to see your UI.<\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>4.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Password-protected<\/b><\/span> tabs, filters, and the new CSV upload should all work now.<\/p><p class=\"p1\"><br><\/p><p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<\/p><p class=\"p3\">That\u2019s it! Let me know if you need any more details.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-96e9643 e-flex e-con-boxed e-con e-parent\" data-id=\"96e9643\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-64061a2 elementor-widget elementor-widget-heading\" data-id=\"64061a2\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Database_app_2.0 Online<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-f33e53e e-flex e-con-boxed e-con e-parent\" data-id=\"f33e53e\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8f5d2af elementor-widget elementor-widget-text-editor\" data-id=\"8f5d2af\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p class=\"p1\">Below is a <span class=\"s1\"><b>concise<\/b><\/span> tutorial on how to run <span class=\"s1\"><b>both<\/b><\/span> your <span class=\"s1\"><b>FastAPI backend<\/b><\/span> and <span class=\"s1\"><b>React frontend<\/b><\/span> on a DigitalOcean droplet <span class=\"s1\"><b>non-stop<\/b><\/span>, so they continue running when you close your terminal or even reboot the server. We\u2019ll use <span class=\"s1\"><b>PM2<\/b><\/span> to manage both processes.<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>1. Prerequisites<\/b><b><\/b><\/p><p class=\"p4\"><span class=\"s3\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><\/span><span class=\"s1\"><b>You have<\/b><\/span><span class=\"s3\"> your code on the droplet (e.g., <\/span>database_app_2.0\/backend<span class=\"s3\"> and <\/span>database_app_2.0\/frontend<span class=\"s3\">).<\/span><\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Python<\/b><\/span> is installed, along with your virtual environment for the backend.<\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Node.js<\/b><\/span> is installed for the frontend.<\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>PM2<\/b><\/span> is installed globally:<\/p><pre><code>npm install -g pm2<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>2. Run the FastAPI Backend with PM2<\/b><b><\/b><\/p><p class=\"p1\"><br><\/p><p class=\"p4\"><b>A) Create a Start Script (Optional but Recommended)<\/b><b><\/b><\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>1.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Go<\/b><\/span> to your backend folder:<\/p><pre><code>cd ~\/database_app_2.0\/backend<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><span class=\"Apple-tab-span\">\t<\/span>2.<span class=\"Apple-tab-span\">\t<\/span><\/span><span class=\"s2\"><b>Create<\/b><\/span><span class=\"s1\"> a script <\/span>start_backend.sh<span class=\"s1\">:<\/span><\/p><pre><code>nano start_backend.sh<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><span class=\"Apple-tab-span\">\t<\/span>3.<span class=\"Apple-tab-span\">\t<\/span><\/span><b>Paste<\/b><span class=\"s1\">:<\/span><\/p><pre><code>#!\/usr\/bin\/env bash\n# Activate the Python venv\nsource venv\/bin\/activate\n# Run FastAPI on port 8000\nuvicorn main:app --host 0.0.0.0 --port 8000<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>4.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Make<\/b><\/span> it executable:<\/p><pre><code>chmod +x start_backend.sh<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p1\"><br><\/p><p class=\"p2\"><b>B) Start with PM2<\/b><\/p><pre><code>pm2 start .\/start_backend.sh --name my-backend<\/code><\/pre><p class=\"p1\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>&#8211;name my-backend<\/b><\/span> helps you identify the process.<\/p><p class=\"p2\"><br><\/p><p class=\"p3\"><b>C) Verify &amp; Save<\/b><\/p><pre><code>pm2 status           # See if 'my-backend' is online\npm2 logs my-backend  # View logs if needed\npm2 save             # Save process list so it restarts on reboot<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>3. Run the React Frontend with PM2<\/b><b><\/b><\/p><p class=\"p1\"><br><\/p><p class=\"p4\"><b>A) Production Build (Recommended)<\/b><b><\/b><\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>1.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Go<\/b><\/span> to your frontend folder:<\/p><pre><code>cd ~\/database_app_2.0\/frontend<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>2.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Install<\/b><\/span> dependencies:<\/p><pre><code>npm install<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>3.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Build<\/b><\/span> the app:<\/p><pre><code>npm run build<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>4.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Install<\/b><\/span> <span class=\"s2\">serve<\/span> (if not already):<\/p><pre><code>npm install -g serve<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>5.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Create<\/b><\/span> <span class=\"s2\">start_frontend.sh<\/span> (optional but cleaner):<\/p><pre><code>nano start_frontend.sh<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><span class=\"Apple-tab-span\">\t<\/span>6.<span class=\"Apple-tab-span\">\t<\/span><\/span><b>Paste<\/b><span class=\"s1\">:<\/span><\/p><pre><code>#!\/usr\/bin\/env bash\ncd \/root\/database_app_2.0\/frontend\nserve -s build -l 3000<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>7.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Make<\/b><\/span> it executable:<\/p><pre><code>chmod +x start_frontend.sh<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p1\"><br><\/p><p class=\"p2\"><b>B) Start with PM2<\/b><\/p><pre><code>pm2 start .\/start_frontend.sh --name my-frontend<\/code><\/pre><p class=\"p1\"><b>C) Verify &amp; Save<\/b><\/p><pre><code>pm2 status           # Should see my-backend &amp; my-frontend\npm2 logs my-frontend # If you want to see logs\npm2 save<\/code><\/pre><p class=\"p1\"><span class=\"s1\">Now your <\/span><span class=\"s2\"><b>frontend<\/b><\/span><span class=\"s1\"> is served at <\/span>http:\/\/YOUR_DROPLET_IP:3000<span class=\"s1\">.<\/span><\/p><p class=\"p2\"><span class=\"s3\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>4. Keep Everything Running on Reboot<\/b><b><\/b><\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>PM2<\/b><\/span> auto-start:<\/p><pre><code>pm2 startup systemd<\/code><\/pre><p class=\"p1\">Copy\/paste the suggested command.<\/p><p class=\"p2\"><br><\/p><p class=\"p3\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Save<\/b><\/span> your processes:<\/p><pre><code>pm2 save<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p1\"><br><\/p><p class=\"p2\">If you <span class=\"s1\"><b>reboot<\/b><\/span> the droplet:<\/p><pre><code>reboot<\/code><\/pre><p class=\"p1\">When it comes back up, run:<\/p><pre><code>pm2 status<\/code><\/pre><p class=\"p1\">Both <span class=\"s1\">my-backend<\/span> and <span class=\"s1\">my-frontend<\/span> should show \u201conline.\u201d<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>5. Test in Your Browser<\/b><b><\/b><\/p><p class=\"p4\"><span class=\"s3\"><span class=\"Apple-tab-span\">\t<\/span>1.<span class=\"Apple-tab-span\">\t<\/span><\/span><span class=\"s4\"><b>Backend<\/b><\/span><span class=\"s3\">: <\/span>http:\/\/YOUR_DROPLET_IP:8000<span class=\"s3\"> (or <\/span>\/properties\/<span class=\"s3\"> etc.).<\/span><\/p><p class=\"p4\"><span class=\"s3\"><span class=\"Apple-tab-span\">\t<\/span>2.<span class=\"Apple-tab-span\">\t<\/span><\/span><span class=\"s4\"><b>Frontend<\/b><\/span><span class=\"s3\">: <\/span>http:\/\/YOUR_DROPLET_IP:3000<span class=\"s3\">.<\/span><\/p><p class=\"p5\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span>Make sure your React app fetches from <span class=\"s1\">http:\/\/YOUR_DROPLET_IP:8000<\/span>.<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>6. Useful PM2 Commands<\/b><b><\/b><\/p><p class=\"p6\"><span class=\"s3\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><\/span><b>List processes<\/b><span class=\"s3\">:<\/span><\/p><pre><code>pm2 status<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><\/span><b>View logs<\/b><span class=\"s1\">:<\/span><\/p><pre><code>pm2 logs my-backend\npm2 logs my-frontend<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Restart<\/b><\/span> a process:<\/p><pre><code>pm2 restart my-backend<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Stop<\/b><\/span> a process:<\/p><pre><code>pm2 stop my-frontend<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"Apple-tab-span\">\t<\/span>\u2022<span class=\"Apple-tab-span\">\t<\/span><span class=\"s1\"><b>Delete<\/b><\/span> a process from PM2:<\/p><pre><code>pm2 delete my-backend<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><hr><p><\/p><p class=\"p3\"><b>Summary<\/b><b><\/b><\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>1.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Install<\/b><\/span> PM2 globally.<\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>2.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Create<\/b><\/span> small start scripts for backend (<span class=\"s3\">start_backend.sh<\/span>) and frontend (<span class=\"s3\">start_frontend.sh<\/span>).<\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>3.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Run<\/b><\/span> them with <span class=\"s3\">pm2 start<\/span> and give them names.<\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>4.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Save<\/b><\/span> PM2 (<span class=\"s3\">pm2 save<\/span>) and set up auto-start (<span class=\"s3\">pm2 startup systemd<\/span>).<\/p><p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<\/p><p class=\"p4\"><span class=\"Apple-tab-span\">\t<\/span>5.<span class=\"Apple-tab-span\">\t<\/span><span class=\"s2\"><b>Done<\/b><\/span>: Both the FastAPI backend (port 8000) and React frontend (port 3000) will keep running, even after you close the terminal or reboot. Enjoy!<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5d52e0f e-flex e-con-boxed e-con e-parent\" data-id=\"5d52e0f\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-919c9f9 e-n-tabs-mobile elementor-widget elementor-widget-n-tabs\" data-id=\"919c9f9\" data-element_type=\"widget\" data-settings=\"{&quot;horizontal_scroll&quot;:&quot;disable&quot;}\" data-widget_type=\"nested-tabs.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"e-n-tabs\" data-widget-number=\"152685049\" aria-label=\"Tabs. Open items with Enter or Space, close with Escape and navigate using the Arrow keys.\">\n\t\t\t<div class=\"e-n-tabs-heading\" role=\"tablist\">\n\t\t\t\t\t<button id=\"e-n-tab-title-1526850491\" class=\"e-n-tab-title\" aria-selected=\"true\" data-tab-index=\"1\" role=\"tab\" tabindex=\"0\" aria-controls=\"e-n-tab-content-1526850491\" style=\"--n-tabs-title-order: 1;\">\n\t\t\t\t\t\t<span class=\"e-n-tab-title-text\">\n\t\t\t\tDatamerge_app2\t\t\t<\/span>\n\t\t<\/button>\n\t\t\t\t<button id=\"e-n-tab-title-1526850492\" class=\"e-n-tab-title\" aria-selected=\"false\" data-tab-index=\"2\" role=\"tab\" tabindex=\"-1\" aria-controls=\"e-n-tab-content-1526850492\" style=\"--n-tabs-title-order: 2;\">\n\t\t\t\t\t\t<span class=\"e-n-tab-title-text\">\n\t\t\t\tAddress_matcher\t\t\t<\/span>\n\t\t<\/button>\n\t\t\t\t<button id=\"e-n-tab-title-1526850493\" class=\"e-n-tab-title\" aria-selected=\"false\" data-tab-index=\"3\" role=\"tab\" tabindex=\"-1\" aria-controls=\"e-n-tab-content-1526850493\" style=\"--n-tabs-title-order: 3;\">\n\t\t\t\t\t\t<span class=\"e-n-tab-title-text\">\n\t\t\t\tTab #3\t\t\t<\/span>\n\t\t<\/button>\n\t\t\t\t\t<\/div>\n\t\t\t<div class=\"e-n-tabs-content\">\n\t\t\t\t<div id=\"e-n-tab-content-1526850491\" role=\"tabpanel\" aria-labelledby=\"e-n-tab-title-1526850491\" data-tab-index=\"1\" style=\"--n-tabs-title-order: 1;\" class=\"e-active elementor-element elementor-element-dad75c2 e-con-full e-flex e-con e-child\" data-id=\"dad75c2\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6cbea8e elementor-widget elementor-widget-text-editor\" data-id=\"6cbea8e\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p class=\"p1\">Here\u2019s how you can start your <span class=\"s1\">datamerge_app2<\/span> project located inside the <span class=\"s1\">Apps<\/span> folder on your <span class=\"s2\"><b>Desktop<\/b><\/span>:<\/p><p class=\"p2\">\u00a0<\/p><hr \/><p class=\"p2\">\u00a0<\/p><h3><b>\u2705 Step-by-Step Instructions (Mac)<\/b><\/h3><p class=\"p2\">\u00a0<\/p><ol start=\"1\"><li><p class=\"p1\"><b>Open Terminal<\/b><span class=\"s1\">.<\/span><\/p><\/li><li><p class=\"p1\"><b>Navigate to the project folder<\/b><span class=\"s1\">:<\/span><\/p><\/li><\/ol><pre><code>cd ~\/Desktop\/Apps\/datamerge_app2<\/code><\/pre><p class=\"p1\">\u00a0<\/p><ol start=\"2\"><li><p class=\"p1\">\u00a0<\/p><\/li><li><p class=\"p1\"><b>Activate the virtual environment<\/b><span class=\"s1\">:<\/span><\/p><p class=\"p2\">Assuming your virtual environment is named <span class=\"s2\">venv<\/span> and is inside <span class=\"s2\">datamerge_app2<\/span>, run:<\/p><\/li><\/ol><pre><code>source venv\/bin\/activate<\/code><\/pre><p class=\"p1\">\u00a0<\/p><ol start=\"3\"><li><p class=\"p1\">You should see the prompt change to something like <span class=\"s1\">(venv)<\/span>.<\/p><\/li><li><p class=\"p1\"><b>Start the app<\/b><span class=\"s1\">:<\/span><\/p><p class=\"p2\">If you\u2019re using <span class=\"s2\">app.py<\/span> as your main Flask file:<\/p><\/li><\/ol><pre><code>python app.py<\/code><\/pre><p class=\"p1\">\u00a0<\/p><ol start=\"4\"><li><p class=\"p1\">OR (alternative if you\u2019re using Flask CLI):<\/p><\/li><\/ol><pre><code>export FLASK_APP=app.py\nexport FLASK_DEBUG=1\nflask run<\/code><\/pre><p class=\"p1\">\u00a0<\/p><ol start=\"4\"><li><p class=\"p1\">\u00a0<\/p><\/li><li><p class=\"p1\"><b>Access the app<\/b><span class=\"s1\">:<\/span><\/p><p class=\"p2\">Once running, open your browser and go to:<\/p><\/li><\/ol><pre><code>http:\/\/127.0.0.1:5000<\/code><\/pre><p class=\"p1\">\u00a0<\/p><p class=\"p2\">\u00a0<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div id=\"e-n-tab-content-1526850492\" role=\"tabpanel\" aria-labelledby=\"e-n-tab-title-1526850492\" data-tab-index=\"2\" style=\"--n-tabs-title-order: 2;\" class=\" elementor-element elementor-element-7924826 e-con-full e-flex e-con e-child\" data-id=\"7924826\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-11a0b0e elementor-widget elementor-widget-text-editor\" data-id=\"11a0b0e\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p class=\"p1\">Absolutely \u2014 now that we\u2019re doing it right, here\u2019s your <span class=\"s1\"><b>full path<\/b><\/span> every time you want to activate and run your app:<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><h1><b>\u2705<span class=\"Apple-converted-space\">&nbsp;<\/span><\/b><\/h1><h1><b>FULL PATH TO START YOUR APP<\/b><\/h1><p><\/p><p class=\"p3\"><br><\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><h3><b>1. Open Terminal<\/b><\/h3><p><\/p><p class=\"p3\"><br><\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><h3><b>2. Go to your app folder:<\/b><\/h3><p><\/p><pre><code>cd ~\/Desktop\/Apps\/address_matcher<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><hr><p><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><h3><b>3. Activate the virtual environment:<\/b><\/h3><p><\/p><pre><code>source venv\/bin\/activate<\/code><\/pre><p class=\"p1\">(You\u2019ll see <span class=\"s1\">(venv)<\/span> appear at the start of your terminal prompt.)<\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><hr><p><\/p><p class=\"p2\"><span class=\"s2\"><\/span><\/p><h3><b>4. Run the app:<\/b><\/h3><p><\/p><pre><code>python3 app.py<\/code><\/pre><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><hr><p><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><h3><b>5. Open it in your browser:<\/b><\/h3><p><\/p><p class=\"p1\"><br><\/p><p class=\"p3\">Go to:<\/p><pre><code>http:\/\/127.0.0.1:5000<\/code><\/pre><p class=\"p1\">\u2705 You\u2019ll see the file upload screen, ready to match addresses.<\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><hr><p><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><h1><b>\ud83d\udd25 Quick Recap<\/b><\/h1><p><\/p><table><thead><tr><th>\n<p class=\"p1\"><b>Step<\/b><\/p>\n<\/th><th>\n<p class=\"p1\"><b>Command<\/b><\/p>\n<\/th><th>\n<p class=\"p1\"><b>Purpose<\/b><\/p>\n<\/th><\/tr><\/thead><tbody><tr><td>\n<p class=\"p1\">1<\/p>\n<\/td><td>\n<p class=\"p1\">cd ~\/Desktop\/Apps\/address_matcher<\/p>\n<\/td><td>\n<p class=\"p1\">Go to your project<\/p>\n<\/td><\/tr><tr><td>\n<p class=\"p1\">2<\/p>\n<\/td><td>\n<p class=\"p1\">source venv\/bin\/activate<\/p>\n<\/td><td>\n<p class=\"p1\">Activate your virtual environment<\/p>\n<\/td><\/tr><tr><td>\n<p class=\"p1\">3<\/p>\n<\/td><td>\n<p class=\"p1\">python3 app.py<\/p>\n<\/td><td>\n<p class=\"p1\">Run your app<\/p>\n<\/td><\/tr><\/tbody><\/table><p class=\"p1\"><br><\/p><p class=\"p2\"><span class=\"s1\"><\/span><\/p><hr><p><\/p><p class=\"p3\">Would you like me to also create a <span class=\"s2\"><b>start.sh<\/b><\/span> script (one single command) so you can just type <span class=\"s3\">.\/start.sh<\/span> and it does all 3 steps automatically? \ud83d\ude80<\/p><p class=\"p1\"><br><\/p><p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<\/p><p class=\"p3\">It\u2019s super easy if you want it.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div id=\"e-n-tab-content-1526850493\" role=\"tabpanel\" aria-labelledby=\"e-n-tab-title-1526850493\" data-tab-index=\"3\" style=\"--n-tabs-title-order: 3;\" class=\" elementor-element elementor-element-1ad9157 e-con-full e-flex e-con e-child\" data-id=\"1ad9157\" data-element_type=\"container\">\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Below is a step-by-step tutorial on how to start your database_app_2.0 project, which includes both the backend (FastAPI) and the frontend (React). We\u2019ll assume your folder structure looks like this: ~\/Desktop\/database_app_2.0\/ \u251c\u2500\u2500 backend\/ \u2502 \u251c\u2500\u2500 main.py (Your FastAPI code) \u2502 \u251c\u2500\u2500 database.csv (Optional original CSV) \u2502 \u251c\u2500\u2500 &#8230; other backend files &#8230; \u251c\u2500\u2500 frontend\/ \u2502 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-122","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/database.victorzsantos.com\/index.php?rest_route=\/wp\/v2\/pages\/122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/database.victorzsantos.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/database.victorzsantos.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/database.victorzsantos.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/database.victorzsantos.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=122"}],"version-history":[{"count":26,"href":"https:\/\/database.victorzsantos.com\/index.php?rest_route=\/wp\/v2\/pages\/122\/revisions"}],"predecessor-version":[{"id":154,"href":"https:\/\/database.victorzsantos.com\/index.php?rest_route=\/wp\/v2\/pages\/122\/revisions\/154"}],"wp:attachment":[{"href":"https:\/\/database.victorzsantos.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}