@@ -12,9 +12,12 @@ def project_cli(ctx):
1212
1313@project_cli .command ()
1414@click .argument ("name" , required = True , type = str )
15- @click .option ("--path" , "-p" , type = click .Path ())
15+ @click .option ("--path" , "-p" , type = click .Path (), help = "The path to create the project in." )
1616@click .pass_context
1717def create (ctx , name : str , path ):
18+ """
19+ Create a new FireFrame project scaffold.
20+ """
1821 click .echo (f"Creating new project { name } ..." )
1922 # create a new subdirectory to path if given,
2023 # otherwise create a new subdirectory to current working directory
@@ -25,10 +28,73 @@ def create(ctx, name: str, path):
2528 elif not os .path .exists (name ):
2629 os .makedirs (os .path .join (os .getcwd (), name ))
2730
31+ # NOTE: We should probably use proper templates for these files
32+ # create a file called main.py in the new project directory
33+ with open (os .path .join (os .getcwd (), name , "main.py" ), "w" ) as f :
34+ f .write (f"# Path: { name } /main.py\n \n " )
35+ f .write (f"from fireframe.core.api import FireFrameAPI\n " )
36+ f .write (f"from fireframe.core.viewsets import crud_viewset\n \n " )
37+ f .write (f"from serializers import Example{ name .capitalize ()} Serializer\n " )
38+ f .write (f"from views import Example{ name .capitalize ()} ListAPIView\n \n " )
39+ f .write (f'app = FireFrameAPI(name="{ name } ", version="0.0.0")\n \n ' )
40+ f .write (f"# TODO: Add your routes here\n " )
41+ f .write (f"app.include_router(crud_viewset(Example{ name .capitalize ()} Serializer))\n " )
42+ f .write (f"app.include_router(Example{ name .capitalize ()} ListAPIView())\n " )
43+
44+ # create a file called models.py in the new project directory
45+ with open (os .path .join (os .getcwd (), name , "models.py" ), "w" ) as f :
46+ f .write (f"# Path: { name } /models.py\n \n " )
47+ f .write (f"from fireframe.core.models import Model\n \n " )
48+ f .write (f"class Example{ name .capitalize ()} Model(Model):\n " )
49+ f .write (f" example: str\n \n " )
50+ f .write (f"# TODO: Add more models here\n " )
51+
52+ # create a file called serializers.py in the new project directory
53+ with open (os .path .join (os .getcwd (), name , "serializers.py" ), "w" ) as f :
54+ f .write (f"# Path: { name } /serializers.py\n \n " )
55+ f .write ("from fireframe.core.serializers import ModelSerializer\n \n " )
56+ f .write (f"from models import Example{ name .capitalize ()} Model\n \n " )
57+ f .write (f"class Example{ name .capitalize ()} Serializer(ModelSerializer):\n " )
58+ f .write (f" class Meta:\n " )
59+ f .write (f" model = Example{ name .capitalize ()} Model\n " )
60+ f .write (f' fields = ["example"]\n \n ' )
61+ f .write (f"# TODO: Add more serializers here\n " )
62+
63+ # create a file called views.py in the new project directory
64+ with open (os .path .join (os .getcwd (), name , "views.py" ), "w" ) as f :
65+ f .write (f"# Path: { name } /views.py\n \n " )
66+ f .write ("from fireframe.core.views import BaseListAPIView\n \n " )
67+ f .write (f"from serializers import Example{ name .capitalize ()} Serializer\n \n " )
68+ f .write (f"class Example{ name .capitalize ()} ListAPIView(BaseListAPIView):\n " )
69+ f .write (f" serializer_class = Example{ name .capitalize ()} Serializer\n \n " )
70+ f .write (f"# TODO: Add more views here\n " )
71+
2872
2973@project_cli .command ()
30- @click .argument ("name" , required = True , type = str )
74+ @click .option (
75+ "--entrypoint" , "-e" , type = str , default = "main:app" , help = "The entrypoint of the project as specified by uvicorn."
76+ )
77+ @click .option ("--port" , "-p" , type = int , default = 8000 , help = "The port to run the project on." )
3178@click .pass_context
32- def startapp (ctx , name : str ):
33- click .echo (f"Starting new app { name } ..." )
34- raise NotImplementedError ("Implement project startapp." )
79+ def serve (ctx , entrypoint : str , port : int ):
80+ """
81+ Run the FireFrame project.
82+ """
83+ click .echo (f"Running FireFrame project on port { port } ..." )
84+ # check if uvicorn is installed via pip
85+ try :
86+ import uvicorn
87+ except ImportError :
88+ click .echo ("Uvicorn is not installed. Installing it via pip." )
89+ os .system ("pip install uvicorn" )
90+
91+ # check if the project has a main.py file
92+ if not os .path .exists (os .path .join (os .getcwd (), f"{ entrypoint .split (':' )[0 ]} .py" )):
93+ click .echo ("No main.py file found. Please run this command from the root directory of your project." )
94+ click .echo (
95+ "If you have renamed your main.py file, please specify the new entrypoint with the --entrypoint flag."
96+ )
97+ return
98+
99+ # run the project with uvicorn in background
100+ os .system (f"uvicorn { entrypoint } --reload --port { port } --host '0.0.0.0'" )
0 commit comments