# Python Script to scaffold project

Python script to generate the files needed for our user authentication with github along with initial file content:

```python
import os
import json

def create_files_and_dirs(config):
    """
    Creates directories and files based on the provided configuration.

    Args:
        config (dict): A dictionary defining the directory structure and file content.
    """

    for item_name, item_details in config.items():
        if isinstance(item_details, dict): # It's a directory
            print(f"Creating Directory: {item_name}")
            os.makedirs(item_name, exist_ok=True) # Create the dir if not exists
            create_files_and_dirs(item_details) # Recursively create in the dir
        elif isinstance(item_details, str): # Its a file, write content
            print(f"Creating file: {item_name}")
            with open(item_name, 'w') as f:
                f.write(item_details) # write file contents

        else:
          raise ValueError("Invalid config")

def read_config_from_json(file_path):
    """
    Reads the configuration from a json file
    """
    with open(file_path) as json_file:
      return json.load(json_file)


if __name__ == "__main__":

    json_config_path = "config.json"
    config = read_config_from_json(json_config_path)

    create_files_and_dirs(config)
    print("Directory and file structure created successfully!")
```

`config.json` file:

```json
{
  "backend": {
    "code_inspector": {
      "__init__.py": "",
      "models.py": "from django.db import models\n# Create your models here.",
      "serializers.py": "from rest_framework import serializers\n# Create your serializers here.",
      "urls.py": "from django.urls import path\nfrom .views import GithubCallback, GitHubLogin\n\nurlpatterns = [\n    path('auth/github/login/', GitHubLogin.as_view(), name='github_login'),\n    path('auth/github/callback/', GithubCallback.as_view(), name='github_callback'),\n]",
      "views.py": "from allauth.socialaccount.providers.github.views import GitHubOAuth2Adapter\nfrom allauth.socialaccount.providers.oauth2.client import OAuth2Client\nfrom rest_framework import generics\nfrom rest_framework.permissions import AllowAny\nfrom rest_framework.response import Response\nfrom rest_framework import status\nfrom allauth.socialaccount.models import SocialAccount\nfrom django.contrib.auth.models import User\n\nclass GitHubLogin(generics.GenericAPIView):\n    permission_classes = [AllowAny]\n    def post(self, request):\n        adapter = GitHubOAuth2Adapter(request)\n        client = OAuth2Client(request, adapter)\n        login_url = client.get_redirect_url()\n        return Response({\"login_url\": login_url}, status=status.HTTP_200_OK)\n\n\nclass GithubCallback(generics.GenericAPIView):\n  permission_classes = [AllowAny]\n  def get(self, request):\n    code = request.GET.get(\"code\")\n    try:\n        adapter = GitHubOAuth2Adapter(request)\n        client = OAuth2Client(request, adapter)\n        token = client.get_access_token(code)\n        user_data = client.get_user(token)\n        try:\n          user = User.objects.get(username=user_data[\"login\"])\n        except User.DoesNotExist:\n            user = User.objects.create_user(username=user_data[\"login\"], password=\"securepassword\")\n        social_account = SocialAccount.objects.filter(user_id=user.id, provider=\"github\").first()\n        if not social_account:\n           SocialAccount.objects.create(user=user, provider=\"github\", uid=str(user_data[\"id\"]), extra_data=user_data)\n        \n        return Response({\"message\": \"Github Logged In\", \"username\": user.username}, status=status.HTTP_200_OK)\n    except Exception as e:\n        return Response({\"message\": f\"Error logging with github: {e}\"}, status=status.HTTP_400_BAD_REQUEST)"
    },
    "backend": {
        "__init__.py": "",
        "urls.py": "from django.contrib import admin\nfrom django.urls import path, include\n\nurlpatterns = [\n    path('admin/', admin.site.urls),\n    path('api/', include('code_inspector.urls')),\n    path('accounts/', include('allauth.urls')),\n]\n",
        "settings.py": "INSTALLED_APPS = [\n    ...\n    'django.contrib.sites',\n    'allauth',\n    'allauth.account',\n    'allauth.socialaccount',\n    'allauth.socialaccount.providers.github',\n    'rest_framework'\n]\n\nSITE_ID = 1\n\nAUTHENTICATION_BACKENDS = [\n    'django.contrib.auth.backends.ModelBackend',\n    'allauth.account.auth_backends.AuthenticationBackend',\n]\n"
      }
    },
  "frontend": {
    "src": {
      "routes": {
          "+page.svelte": "<script>\n    let loginUrl;\n    let username = \"\";\n    async function handleGithubLogin(){\n        const response = await fetch(`http://localhost:8000/api/auth/github/login/`,{\n            method: \"POST\"\n        });\n        const data = await response.json();\n        window.location.href = data.login_url;\n    }\n\n    const urlParams = new URLSearchParams(window.location.search);\n    const code = urlParams.get('code');\n    async function fetchCallback(){\n        if (code){\n            const callbackResponse = await fetch(`http://localhost:8000/api/auth/github/callback/?code=${code}`)\n            const callbackData = await callbackResponse.json();\n            username = callbackData.username\n        }\n    }\n    fetchCallback()\n</script>\n{#if username != \"\"}\n  <h1> Logged in as {username} </h1>\n{:else}\n  <button on:click={handleGithubLogin}> Login With Github</button>\n{/if}"
        }
    }
  },
   "config.json": "{}"
}
```

**How to Use This Script**

1. **Save the Python Script:** Save the code above as a Python file (e.g., `create_`[`project.py`](http://project.py)).
    
2. **Create a** `config.json` file: Create a JSON file name `config.json` in the same directory where you saved your `create_`[`project.py`](http://project.py) file. Copy paste the `config.json` above.
    
3. **Run the Script:** Open a terminal, navigate to the directory where you saved the script, and execute it:
    
    ```bash
    python create_project.py
    ```
    

**Explanation:**

* The script will create a `backend` and `frontend` directory.
    
* The `backend/code_inspector` directory contains django app related file structure
    
* The `backend/backend` contains main django related files.
    
* The `frontend/src/routes` contains sveltekit project page file.
    
* All the related content is also created in the files for the corresponding auth functionality.
    

**Important Notes:**

* This script only creates the basic files with the code related to github login functionality. You still need to run commands like `django-admin startproject backend .`, `python` [`manage.py`](http://manage.py) `startapp code_inspector`, `npm create svelte@latest frontend`, `pip install django-allauth requests`, and install dependencies in your respective projects.
    
* You'll also need to configure your [`settings.py`](http://settings.py) and [`urls.py`](http://urls.py) files in your Django project, configure environment variables for your github client id and client secret etc.
    
* The `frontend` structure is simplified. You would need to adjust the content or use `npm create svelte@latest` to create a proper sveltekit project
    

This will get you started with a basic folder structure with initial code to use for your github authentication implementation. Let me know if you have any other questions!
