1+ import contextlib
12import json
23import logging
4+ import subprocess
35import tarfile
46import tempfile
57import time
1214import rignore
1315import typer
1416from httpx import Client
15- from pydantic import BaseModel
17+ from pydantic import BaseModel , EmailStr , TypeAdapter , ValidationError
1618from rich .text import Text
1719from rich_toolkit import RichToolkit
1820from rich_toolkit .menu import Option
@@ -385,6 +387,118 @@ def _setup_environment_variables(toolkit: RichToolkit, app_id: str) -> None:
385387 progress .log ("Environment variables set up successfully!" )
386388
387389
390+ class SignupToWaitingList (BaseModel ):
391+ email : EmailStr
392+ name : Optional [str ] = None
393+ organization : Optional [str ] = None
394+ role : Optional [str ] = None
395+ team_size : Optional [str ] = None
396+ location : Optional [str ] = None
397+ use_case : Optional [str ] = None
398+ secret_code : Optional [str ] = None
399+
400+
401+ def _send_waitlist_form (
402+ result : SignupToWaitingList ,
403+ toolkit : RichToolkit ,
404+ ) -> None :
405+ with toolkit .progress ("Sending your request..." ) as progress :
406+ with APIClient () as client :
407+ with handle_http_errors (progress ):
408+ response = client .post (
409+ "/users/waiting-list" , json = result .model_dump (mode = "json" )
410+ )
411+
412+ response .raise_for_status ()
413+
414+ progress .log ("Let's go! Thanks for your interest in FastAPI Cloud! 🚀" )
415+
416+
417+ def _waitlist_form (toolkit : RichToolkit ) -> None :
418+ from rich_toolkit .form import Form
419+
420+ toolkit .print (
421+ "We're currently in private beta. If you want to be notified when we launch, please fill out the form below." ,
422+ tag = "waitlist" ,
423+ )
424+
425+ toolkit .print_line ()
426+
427+ email = toolkit .input (
428+ "Enter your email:" ,
429+ required = True ,
430+ validator = TypeAdapter (EmailStr ),
431+ )
432+
433+ toolkit .print_line ()
434+
435+ result = SignupToWaitingList (email = email )
436+
437+ if toolkit .confirm (
438+ "Do you want to get access faster by giving us more information?" ,
439+ tag = "waitlist" ,
440+ ):
441+ toolkit .print_line ()
442+ form = Form ("Waitlist form" , style = toolkit .style )
443+
444+ form .add_input ("name" , label = "Name" , placeholder = "John Doe" )
445+ form .add_input ("organization" , label = "Organization" , placeholder = "Acme Inc." )
446+ form .add_input ("team" , label = "Team" , placeholder = "Team A" )
447+ form .add_input ("role" , label = "Role" , placeholder = "Developer" )
448+ form .add_input ("location" , label = "Location" , placeholder = "San Francisco" )
449+ form .add_input (
450+ "use_case" ,
451+ label = "How do you plan to use FastAPI Cloud?" ,
452+ placeholder = "I'm building a web app" ,
453+ )
454+ form .add_input ("secret_code" , label = "Secret code" , placeholder = "123456" )
455+
456+ result = form .run () # type: ignore
457+
458+ try :
459+ result = SignupToWaitingList .model_validate (
460+ {
461+ "email" : email ,
462+ ** result , # type: ignore
463+ }
464+ )
465+ except ValidationError :
466+ toolkit .print (
467+ "[error]Invalid form data. Please try again.[/]" ,
468+ )
469+
470+ return
471+
472+ toolkit .print_line ()
473+
474+ if toolkit .confirm (
475+ (
476+ "Do you agree to\n "
477+ "- Terms of Service: [link=https://fastapicloud.com/legal/terms]https://fastapicloud.com/legal/terms[/link]\n "
478+ "- Privacy Policy: [link=https://fastapicloud.com/legal/privacy-policy]https://fastapicloud.com/legal/privacy-policy[/link]\n "
479+ ),
480+ tag = "terms" ,
481+ ):
482+ toolkit .print_line ()
483+
484+ _send_waitlist_form (
485+ result ,
486+ toolkit ,
487+ )
488+
489+ with contextlib .suppress (Exception ):
490+ subprocess .run (
491+ ["open" , "raycast://confetti" ],
492+ stdout = subprocess .DEVNULL ,
493+ stderr = subprocess .DEVNULL ,
494+ check = False ,
495+ )
496+
497+ toolkit .print_line ()
498+
499+ toolkit .print ("Thank you for your interest in FastAPI Cloud! 🚀" )
500+
501+
388502def deploy (
389503 path : Annotated [
390504 Union [Path , None ],
@@ -401,17 +515,14 @@ def deploy(
401515 """
402516
403517 with get_rich_toolkit () as toolkit :
404- toolkit .print_title ("Starting deployment" , tag = "FastAPI" )
405- toolkit .print_line ()
406-
407518 if not is_logged_in ():
408- toolkit .print (
409- "No credentials found. Use [blue]`fastapi login`[/] to login." ,
410- tag = "auth" ,
411- )
519+ _waitlist_form (toolkit )
412520
413521 raise typer .Exit (1 )
414522
523+ toolkit .print_title ("Starting deployment" , tag = "FastAPI" )
524+ toolkit .print_line ()
525+
415526 path_to_deploy = path or Path .cwd ()
416527
417528 app_config = get_app_config (path_to_deploy )
0 commit comments