forked from JSv4/Python-Redlines
    
        
        - 
                Notifications
    You must be signed in to change notification settings 
- Fork 0
Add FastAPI redlining API, token auth, tests, Docker, and tooling #2
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
          
     Open
      
      
            arthrod
  wants to merge
  1
  commit into
  main
  
    
      
        
          
  
    
      Choose a base branch
      
     
    
      
        
      
      
        
          
          
        
        
          
            
              
              
              
  
           
        
        
          
            
              
              
           
        
       
     
  
        
          
            
          
            
          
        
       
    
      
from
feat/fastapi-redline-service
  
      
      
   
  
    
  
  
  
 
  
      
    base: main
Could not load branches
            
              
  
    Branch not found: {{ refName }}
  
            
                
      Loading
              
            Could not load tags
            
            
              Nothing to show
            
              
  
            
                
      Loading
              
            Are you sure you want to change the base?
            Some commits from the old base branch may be removed from the timeline,
            and old review comments may become outdated.
          
          
  
     Open
                    Changes from all commits
      Commits
    
    
  File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # Generate a secure secret token, for example, by running: | ||
| # python -c 'import secrets; print(secrets.token_hex(32))' | ||
| API_TOKEN=your_secret_api_token_here | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,236 +1,33 @@ | ||
| # Byte-compiled / optimized / DLL files | ||
| __pycache__/ | ||
| *.py[cod] | ||
| *$py.class | ||
|  | ||
| # C# Build Dirs | ||
| csproj/bin/* | ||
| csproj/obj/* | ||
| # Environment variables | ||
| .env | ||
|  | ||
| # C extensions | ||
| *.so | ||
| # Python cache | ||
| __pycache__/ | ||
| *.pyc | ||
| *.pyo | ||
| *.pyd | ||
|  | ||
| # Distribution / packaging | ||
| .Python | ||
| build/ | ||
| develop-eggs/ | ||
| src/python_redlines/data/ | ||
| downloads/ | ||
| eggs/ | ||
| .eggs/ | ||
| lib/ | ||
| lib64/ | ||
| parts/ | ||
| sdist/ | ||
| var/ | ||
| wheels/ | ||
| share/python-wheels/ | ||
| # Build artifacts | ||
| /dist/ | ||
| /build/ | ||
| *.egg-info/ | ||
| .installed.cfg | ||
| *.egg | ||
| MANIFEST | ||
|  | ||
| # PyInstaller | ||
| # Usually these files are written by a python script from a template | ||
| # before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
| *.manifest | ||
| *.spec | ||
|  | ||
| # Installer logs | ||
| pip-log.txt | ||
| pip-delete-this-directory.txt | ||
|  | ||
| # Unit test / coverage reports | ||
| htmlcov/ | ||
| .tox/ | ||
| .nox/ | ||
| .coverage | ||
| .coverage.* | ||
| .cache | ||
| nosetests.xml | ||
| coverage.xml | ||
| *.cover | ||
| *.py,cover | ||
| .hypothesis/ | ||
| .pytest_cache/ | ||
| cover/ | ||
|  | ||
| # Translations | ||
| *.mo | ||
| *.pot | ||
|  | ||
| # Django stuff: | ||
| *.log | ||
| local_settings.py | ||
| db.sqlite3 | ||
| db.sqlite3-journal | ||
|  | ||
| # Flask stuff: | ||
| instance/ | ||
| .webassets-cache | ||
|  | ||
| # Scrapy stuff: | ||
| .scrapy | ||
|  | ||
| # Sphinx documentation | ||
| docs/_build/ | ||
|  | ||
| # PyBuilder | ||
| .pybuilder/ | ||
| target/ | ||
|  | ||
| # Jupyter Notebook | ||
| .ipynb_checkpoints | ||
|  | ||
| # IPython | ||
| profile_default/ | ||
| ipython_config.py | ||
|  | ||
| # pyenv | ||
| # For a library or package, you might want to ignore these files since the code is | ||
| # intended to run in multiple environments; otherwise, check them in: | ||
| # .python-version | ||
|  | ||
| # pipenv | ||
| # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
| # However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
| # having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
| # install all needed dependencies. | ||
| #Pipfile.lock | ||
|  | ||
| # poetry | ||
| # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. | ||
| # This is especially recommended for binary packages to ensure reproducibility, and is more | ||
| # commonly ignored for libraries. | ||
| # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control | ||
| #poetry.lock | ||
|  | ||
| # pdm | ||
| # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. | ||
| #pdm.lock | ||
| # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it | ||
| # in version control. | ||
| # https://pdm.fming.dev/#use-with-ide | ||
| .pdm.toml | ||
|  | ||
| # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm | ||
| __pypackages__/ | ||
|  | ||
| # Celery stuff | ||
| celerybeat-schedule | ||
| celerybeat.pid | ||
|  | ||
| # SageMath parsed files | ||
| *.sage.py | ||
|  | ||
| # Environments | ||
| .env | ||
| .venv | ||
| env/ | ||
| # Virtual environment | ||
| .venv/ | ||
| venv/ | ||
| ENV/ | ||
| env.bak/ | ||
| venv.bak/ | ||
|  | ||
| # Spyder project settings | ||
| .spyderproject | ||
| .spyproject | ||
|  | ||
| # Rope project settings | ||
| .ropeproject | ||
|  | ||
| # mkdocs documentation | ||
| /site | ||
|  | ||
| # mypy | ||
| .mypy_cache/ | ||
| .dmypy.json | ||
| dmypy.json | ||
|  | ||
| # Pyre type checker | ||
| .pyre/ | ||
|  | ||
| # pytype static type analyzer | ||
| .pytype/ | ||
|  | ||
| # Cython debug symbols | ||
| cython_debug/ | ||
|  | ||
| # PyCharm | ||
| # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider | ||
| # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
|  | ||
| # User-specific stuff | ||
| .idea/**/workspace.xml | ||
| .idea/**/tasks.xml | ||
| .idea/**/usage.statistics.xml | ||
| .idea/**/dictionaries | ||
| .idea/**/shelf | ||
|  | ||
| # AWS User-specific | ||
| .idea/**/aws.xml | ||
|  | ||
| # Generated files | ||
| .idea/**/contentModel.xml | ||
|  | ||
| # Sensitive or high-churn files | ||
| .idea/**/dataSources/ | ||
| .idea/**/dataSources.ids | ||
| .idea/**/dataSources.local.xml | ||
| .idea/**/sqlDataSources.xml | ||
| .idea/**/dynamic.xml | ||
| .idea/**/uiDesigner.xml | ||
| .idea/**/dbnavigator.xml | ||
|  | ||
| # Gradle | ||
| .idea/**/gradle.xml | ||
| .idea/**/libraries | ||
|  | ||
| # Gradle and Maven with auto-import | ||
| # When using Gradle or Maven with auto-import, you should exclude module files, | ||
| # since they will be recreated, and may cause churn. Uncomment if using | ||
| # auto-import. | ||
| # .idea/artifacts | ||
| # .idea/compiler.xml | ||
| # .idea/jarRepositories.xml | ||
| # .idea/modules.xml | ||
| # .idea/*.iml | ||
| # .idea/modules | ||
| # *.iml | ||
| # *.ipr | ||
|  | ||
| # CMake | ||
| cmake-build-*/ | ||
|  | ||
| # Mongo Explorer plugin | ||
| .idea/**/mongoSettings.xml | ||
|  | ||
| # File-based project format | ||
| *.iws | ||
|  | ||
| # IntelliJ | ||
| out/ | ||
|  | ||
| # mpeltonen/sbt-idea plugin | ||
| .idea_modules/ | ||
|  | ||
| # JIRA plugin | ||
| atlassian-ide-plugin.xml | ||
|  | ||
| # Cursive Clojure plugin | ||
| .idea/replstate.xml | ||
|  | ||
| # SonarLint plugin | ||
| .idea/sonarlint/ | ||
| env/ | ||
|  | ||
| # Crashlytics plugin (for Android Studio and IntelliJ) | ||
| com_crashlytics_export_strings.xml | ||
| crashlytics.properties | ||
| crashlytics-build.properties | ||
| fabric.properties | ||
| # IDE and editor files | ||
| .idea/ | ||
| .vscode/ | ||
| *.swp | ||
| *.swo | ||
|  | ||
| # Editor-based Rest Client | ||
| .idea/httpRequests | ||
| # Hatch | ||
| /.hatch/ | ||
| /src/python_redlines/bin | ||
| /src/python_redlines/dist | ||
|  | ||
| # Android studio 3.1+ serialized cache file | ||
| .idea/caches/build_file_checksums.ser | ||
| # C# build artifacts | ||
| /csproj/bin/ | ||
| /csproj/obj/ | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Use an official Python runtime as a parent image | ||
| FROM python:3.11-slim | ||
|  | ||
| # Set the working directory in the container | ||
| WORKDIR /app | ||
|  | ||
| # Install .NET SDK and other dependencies | ||
| RUN apt-get update && \ | ||
| apt-get install -y wget && \ | ||
| wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh && \ | ||
| chmod +x ./dotnet-install.sh && \ | ||
| ./dotnet-install.sh --version 8.0.100 && \ | ||
| rm dotnet-install.sh | ||
|  | ||
| # Add .dotnet to the PATH | ||
| ENV PATH="/root/.dotnet:$PATH" | ||
|  | ||
| # Copy files required for build | ||
| COPY pyproject.toml . | ||
| COPY hatch_run_build_hook.py . | ||
| COPY build_differ.py . | ||
| COPY src/python_redlines/__about__.py src/python_redlines/__about__.py | ||
| COPY csproj/ csproj/ | ||
|  | ||
| # Install hatch | ||
| RUN pip install hatch | ||
|  | ||
| # Build the project (which includes running build_differ.py) | ||
| RUN hatch run default:build | ||
|  | ||
| # Copy the rest of the application code | ||
| COPY . . | ||
|  | ||
| # Expose the port the app runs on | ||
| EXPOSE 8000 | ||
|  | ||
| # Start the API server | ||
| CMD ["hatch", "run", "api:start"] | ||
| 
      Comment on lines
    
      +1
     to 
      +38
    
   There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical security issues: running as root and no multi-stage build. The Dockerfile has several security and optimization issues: 
 Apply this diff to create a secure multi-stage build: -# Use an official Python runtime as a parent image
-FROM python:3.11-slim
+# Multi-stage build for smaller, more secure images
+FROM python:3.11-slim AS builder
 
 # Set the working directory in the container
 WORKDIR /app
 
 # Install .NET SDK and other dependencies
 RUN apt-get update && \
     apt-get install -y wget && \
     wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh && \
     chmod +x ./dotnet-install.sh && \
     ./dotnet-install.sh --version 8.0.100 && \
-    rm dotnet-install.sh
+    rm dotnet-install.sh && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/*
 
 # Add .dotnet to the PATH
 ENV PATH="/root/.dotnet:$PATH"
 
 # Copy files required for build
 COPY pyproject.toml .
 COPY hatch_run_build_hook.py .
 COPY build_differ.py .
 COPY src/python_redlines/__about__.py src/python_redlines/__about__.py
 COPY csproj/ csproj/
 
 # Install hatch
 RUN pip install hatch
 
 # Build the project (which includes running build_differ.py)
 RUN hatch run default:build
 
+# Final stage - runtime image
+FROM python:3.11-slim
+
+WORKDIR /app
+
+# Create non-root user
+RUN groupadd -r appuser && useradd -r -g appuser appuser && \
+    chown -R appuser:appuser /app
+
+# Copy built artifacts from builder
+COPY --from=builder --chown=appuser:appuser /app/dist ./dist
+COPY --from=builder --chown=appuser:appuser /app/src ./src
+
 # Copy the rest of the application code
-COPY . .
+COPY --chown=appuser:appuser pyproject.toml .
+COPY --chown=appuser:appuser README.md .
+
+# Install runtime dependencies only
+RUN pip install --no-cache-dir hatch && \
+    pip install --no-cache-dir -e .
+
+# Switch to non-root user
+USER appuser
 
 # Expose the port the app runs on
 EXPOSE 8000
 
+# Add health check
+HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
+    CMD python -c "import httpx; httpx.get('http://localhost:8000/health', timeout=2)" || exit 1
+
 # Start the API server
 CMD ["hatch", "run", "api:start"]🤖 Prompt for AI Agents | ||
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Dockerfile can be significantly optimized for a smaller image size and better security by using a multi-stage build. Currently, the final image includes the .NET SDK and other build-time dependencies, which are not required for running the application.
A multi-stage build would involve:
builderstage to install the .NET SDK, build the C# binaries, and then discard this environment.python:3.11-slimstage that copies only the necessary application code and the compiled binaries from thebuilderstage.This practice leads to smaller, more secure, and faster-deploying images. Additionally, it's a good practice to clean up the
aptcache within the sameRUNlayer to further reduce image size by adding&& rm -rf /var/lib/apt/lists/*.