Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support reflex app creation from templates from github #2490

Merged
merged 17 commits into from
Apr 4, 2024

Conversation

martinxu9
Copy link
Contributor

@martinxu9 martinxu9 commented Jan 31, 2024

Summary

  • Support reflex app creation from templates from github
    • When reflex init: fetch from reflex backend server: the list of Reflex apps that can be used as a starting template (name and their URL). When no internet or backend is unreachable, only blank is shown to user.
    • Prompt user for template selection: default is blank.
    • Upon valid selection, download the source files as a zip. The Zip structure must contain a top level directory, which contains the rxconfig. This is the standard structure downloaded from github repos.
    • Extract all files from zip, copy files into current directory
    • Prompt for name change, by default the name is the valid reflex app name constructed by current directory name (e.g. no dashes allowed).
    • Rename folders/files, fix imports
  • Not supported:
    • Download a sub-directory in a github repo as standalone zip.

Usage:
reflex init --template https://github.com/reflex-dev/reflex-chat

Tests

@martinxu9 martinxu9 force-pushed the martinxu9/from-template branch from 798e47d to 2c62bfe Compare January 31, 2024 00:16
@martinxu9 martinxu9 requested a review from picklelo January 31, 2024 00:32
@martinxu9 martinxu9 marked this pull request as ready for review February 1, 2024 02:58
Copy link
Contributor

@picklelo picklelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well for me (though I wasn't able to connect to get the list of templates). Maybe for now we can leave out the interactive init and support initialization with the --template flag only. I think I they do --template without any args, that's where we could show all the templates we offer through the CLI.

reflex/reflex.py Outdated
template = prerequisites.prompt_for_template()
prerequisites.create_config(app_name)
prerequisites.initialize_app_directory(app_name, template)
# Fetch App templates from the backend server
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move all of this to a function in prerequisites.py to keep this function clean

def initialize_app_directory(
app_name: str,
template_name: str = constants.Templates.Kind.BLANK.value,
template_code_dir_name: Optional[str] = None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can do | None instead of Optional outside of Pydantic use cases

except OSError as ose:
console.error(f"Failed to create temp directory for download: {ose}")
raise typer.Exit(1) from ose
# Use httpx GET with redirects to download the zip file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we put blank lines before each comment to make the code more readable

A valid template name.
"""
if template is not None:
# If user selects a template, it needs to exist
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: end comments with periods for consistency

# the source code repo name on github
template_name = new_config.app_name

# Prompt for Reflex App name change
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this section to its own function? I think this may in the future be useful as its own subcommand reflex init --rename <new_name>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this section for now. Let me do that when we add --rename. The rename is slightly differently I suppose. Here, we basically generate a new rxconfig file instead regex replace any strings. I suspect we might have to do string substitution when it a generic app. There might be other attributes added in the template app.

@martinxu9
Copy link
Contributor Author

Works well for me (though I wasn't able to connect to get the list of templates). Maybe for now we can leave out the interactive init and support initialization with the --template flag only. I think I they do --template without any args, that's where we could show all the templates we offer through the CLI.

do you know how to achieve that in typer option? From what I experimented, if it's not a boolean flag, it'll expect something set for that flag or no flag at all for None.

@picklelo picklelo force-pushed the martinxu9/from-template branch from cfa5db2 to 07ea15b Compare April 2, 2024 20:13
templates = fetch_app_templates() or {}
if template is None:
template = prompt_for_template(templates)
templates: dict[str, Template] = fetch_app_templates() or {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: fetch_app_templates always return a dict, no need for or {}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, fixed

@picklelo picklelo force-pushed the martinxu9/from-template branch from a034a8a to d190d64 Compare April 4, 2024 21:37
template_url = templates[template].code_url
else:
# Check if the template is a github repo.
if "github.com" not in template:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be a more strict check something like it must start with https://github.com/ or something?

console.error(f"Template `{template}` not found.")
raise typer.Exit(1)
repo = template.split("github.com/")[1].strip("/")
template_url = f"https://github.com/{repo}/archive/main.zip"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like we expect the template_url to be of https://github.com/owner/repo/ format, do we want to just right strip / then append main.zip which also means we can't specify a branch for now. Likely ok

@picklelo picklelo merged commit 7d36610 into main Apr 4, 2024
46 checks passed
@masenf masenf deleted the martinxu9/from-template branch April 24, 2024 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants