Skip to content
This repository was archived by the owner on Feb 13, 2024. It is now read-only.

Commit fbe483b

Browse files
author
Julien Chomarat
committed
Initial commit
1 parent 797b693 commit fbe483b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1669
-33
lines changed

.devcontainer/Dockerfile

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
FROM ubuntu:21.04
2+
3+
ARG USERNAME=alex
4+
ARG USER_UID=1000
5+
ARG USER_GID=$USER_UID
6+
7+
# Create the user
8+
RUN groupadd --gid $USER_GID $USERNAME \
9+
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME
10+
11+
# Update packages list & install missing packages
12+
RUN apt-get update \
13+
&& export DEBIAN_FRONTEND=noninteractive \
14+
# install missing packages
15+
&& apt-get install -y sudo git curl wget make procps \
16+
python3-pip unzip nodejs npm vim dos2unix apt-transport-https ca-certificates \
17+
gnupg lsb-release
18+
19+
# Finish setting up $USERNAME (sudo, no password etc ...)
20+
RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
21+
&& chmod 0440 /etc/sudoers.d/$USERNAME
22+
23+
# Install Docker CLI
24+
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
25+
26+
RUN echo \
27+
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
28+
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
29+
30+
RUN apt-get update \
31+
&& apt-get install -y docker-ce-cli
32+
33+
# Python things: update pip
34+
RUN python3 -m pip install pip --upgrade
35+
36+
# Install required librairies
37+
COPY ./requirements.txt /home/$USERNAME/
38+
39+
RUN pip install -r /home/$USERNAME/requirements.txt
40+
41+
# Set $USERNAME as default user
42+
USER $USERNAME
43+
44+
# Add custom bashrc
45+
COPY --chown=$USERNAME:$USERNAME ./bashrc /home/$USERNAME/.bashrc_extension
46+
RUN echo "source ~/.bashrc_extension" >> ~/.bashrc && dos2unix ~/.bashrc_extension
47+
48+
# Back to default shell
49+
SHELL ["/bin/bash", "-c"]
50+
51+
CMD [ "sleep", "infinity" ]

.devcontainer/bashrc

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Add autocompletion to make targets (so that one can input > make [tab])
2+
complete -W "`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' /workspace/?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'`" make
3+
4+
# Add autocompletion to git commands
5+
source /usr/share/bash-completion/completions/git
6+
7+
# Add aliases
8+
alias ll='ls -halp'
9+
10+
# Add .local/bin to PATH (Python libraries)
11+
export PATH="$HOME/.local/bin:$PATH"
12+
13+
# Set permissions on docker.sock for docker cli in docker
14+
if [ -e /var/run/docker.sock ]; then
15+
sudo chown alex:alex /var/run/docker.sock;
16+
fi

.devcontainer/devcontainer.json

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* devcontainer.json files support JSON with Comments (jsonc)! */
2+
3+
{
4+
"name": "flask-reactize",
5+
"dockerComposeFile": "docker-compose.yml",
6+
"service": "workspace-flask-reactize",
7+
"context": ".",
8+
"workspaceFolder": "/workspace",
9+
// Install ESLint and Peacock extensions
10+
"extensions": [
11+
"ms-python.python",
12+
"ms-python.vscode-pylance",
13+
"ms-azuretools.vscode-docker",
14+
"irongeek.vscode-env"
15+
],
16+
"settings": {
17+
"python.pythonPath": "/usr/bin/python3",
18+
"python.envFile": "${workspaceFolder}/python-path.env",
19+
"python.formatting.provider": "black",
20+
"python.testing.nosetestsEnabled": false,
21+
"python.testing.pytestEnabled": true
22+
},
23+
"mounts": [
24+
"source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind"
25+
],
26+
"runArgs": [
27+
"--init"
28+
]
29+
}

.devcontainer/docker-compose.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: '3'
2+
services:
3+
workspace-flask-reactize:
4+
build:
5+
context: .
6+
dockerfile: Dockerfile
7+
volumes:
8+
- "..:/workspace"
9+
- "~/.ssh:/home/alex/.ssh"
10+
- "/var/run/docker.sock:/var/run/docker.sock"
11+
ports:
12+
- "127.0.0.1:8888:8888"
13+
command: sleep infinity

.devcontainer/requirements.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
setuptools==59.4.0
2+
wheel==0.37.0
3+
pytest==6.2.5
4+
pytest-cov==3.0.0
5+
twine
6+
requests-mock==1.9.3
7+
black==21.11b1
8+
flake8==4.0.1
9+
isort==5.10.1

.flake8

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[flake8]
2+
# Recommend matching the black line length (default 88),
3+
# rather than using the flake8 default of 79:
4+
max-line-length = 128
5+
exclude =
6+
.git,
7+
__pycache__,
8+
build,
9+
dist,
10+
extend-ignore =
11+
# See https://github.com/PyCQA/pycodestyle/issues/373
12+
E203,

.gitignore

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
### Developer ###
2+
.vscode/
3+
.idea/
4+
local.env
5+
.env
6+
.DS_Store
7+
.deployment
8+
9+
# a developer can copy his/her own files in a me/ folder without having them in git
10+
**/me/
11+
12+
13+
### Python ###
14+
# Byte-compiled / optimized / DLL files
15+
__pycache__/
16+
*.whl
17+
*.py[cod]
18+
*$py.class
19+
20+
# C extensions
21+
*.so
22+
23+
# Distribution / packaging
24+
.Python
25+
build/
26+
develop-eggs/
27+
dist/
28+
downloads/
29+
eggs/
30+
.eggs/
31+
parts/
32+
sdist/
33+
var/
34+
wheels/
35+
pip-wheel-metadata/
36+
share/python-wheels/
37+
*.egg-info/
38+
.installed.cfg
39+
*.egg
40+
MANIFEST
41+
42+
# PyTest
43+
.pytest_cache/
44+
.coverage
45+
coverage.xml
46+
pytest-results.xml
47+
pytest-integration-results.xml
48+
pytest-e2e-results.xml
49+
50+
# flask session folder
51+
flask_session/
52+
tests-report.md
53+
54+
55+
### reactjs ###
56+
node_modules/
57+
package-lock.json
58+
59+
.pypirc

.isort.cfg

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[settings]
2+
profile = black
3+
multi_line_output = 3
4+
src_paths = ./src/*/src

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Contributing to [project-title]
1+
# Contributing to flask-reactize
22

33
This project welcomes contributions and suggestions. Most contributions require you to agree to a
44
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us

DockerFile-py310

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM python:3.10-slim-buster
2+
3+
EXPOSE 80
4+
5+
ENV MODE="prod"
6+
7+
WORKDIR /app
8+
9+
COPY ./sample/main.py /app
10+
COPY ./sample/static /app/static
11+
12+
RUN python3 -m pip install pip --upgrade
13+
14+
RUN python -m pip install gunicorn==20.1.0 flask-reactize
15+
16+
CMD ["gunicorn", "--bind", "0.0.0.0:80", "--log-level", "debug", "main:app"]

DockerFile-py38

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM python:3.8-slim-buster
2+
3+
EXPOSE 80
4+
5+
ENV MODE="prod"
6+
7+
WORKDIR /app
8+
9+
COPY ./sample/main.py /app
10+
COPY ./sample/static /app/static
11+
12+
RUN python3 -m pip install pip --upgrade
13+
14+
RUN python -m pip install gunicorn==20.1.0 flask-reactize
15+
16+
CMD ["gunicorn", "--bind", "0.0.0.0:80", "--log-level", "debug", "main:app"]

README.md

+65-32
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,90 @@
1-
# Project Name
1+
# flask-reactize
22

3-
(short, 1-3 sentenced, description of the project)
3+
[![PyPI version](https://badge.fury.io/py/flask-reactize.svg)](https://badge.fury.io/py/flask-reactize)
4+
5+
Developing a ReactJS application requires to use nodejs as back end server.
6+
What if you want to consume external APIs: how are you going to handle cross origin calls?
7+
What if you want to secure your application and APIs easily?
8+
9+
In modern days, as we are now, [React JS](https://reactjs.org/) offers many nice functionalities to develop an application easily, from any IDE.
10+
11+
In development mode, [React JS](https://reactjs.org/) requires [NodeJS](https://nodejs.org/en/) as a back end server. [NodeJS](https://nodejs.org/en/) maintains a connection between your development environment and your browser where the application is loaded so that:
12+
13+
* it refreshes automatically when an update is made,
14+
* it sends in real time any error, warning that may have, in both the console and the developers toolbar of your browser of choice.
15+
16+
For production, you can compile your [React JS](https://reactjs.org/) application into static assets - you can then use any technology to serve those static files.
17+
18+
However, if your [React JS](https://reactjs.org/) calls external APIs (whether there are customs, or public) you will face security issues.
19+
20+
In addition, if your APIs require to be logged in, this is not going to be easy to implement.
421

522
## Features
623

7-
This project framework provides the following features:
24+
*flask-reactize* is a boostrap to serve any [React JS](https://reactjs.org/) via a Python back-end, using [Flask](https://flask.palletsprojects.com/en/2.0.x/) as web framework.
825

9-
* Feature 1
10-
* Feature 2
11-
* ...
26+
Your back-end web server can be anything: [Flask](https://flask.palletsprojects.com/en/2.0.x/) itself (Although not recommended for production), [Uvicorn](https://www.uvicorn.org/), [Gunicorn](https://gunicorn.org/) etc.
27+
28+
In a nutshell, *flask-reactize* is a proxy for your [React JS](https://reactjs.org/) application and for your APIs.
29+
30+
* It has a development mode: a nodejs server is transparently started by the Python back-end,
31+
* It supports production mode: this back-end can also serve your static assets,
32+
* It supports hot reload while developing: changing the Python code or the React code will trigger a browser refresh,
33+
* It supports proxying multiple APIs via a specific route name.
1234

1335
## Getting Started
1436

37+
Here is what you are going to find in this repo:
38+
39+
* Under *src/flask-reactize* you will find the Python module (also available via [PyPi](https://pypi.org/project/flask-reactize/)). [More info](./src/flask-reactize/README.md),
40+
* Under *sample/* you will find a simple demo site built with [React JS](https://reactjs.org/) using *flask-reactize*. [More info on how to use it](./sample/README.md),
41+
* Two *DockerFile* for Python 3.8 and Python 3.10. To run them.
42+
1543
### Prerequisites
1644

17-
(ideally very short, if any)
45+
* [vscode](https://code.visualstudio.com/) installed because you are going to use [DevContainers](https://code.visualstudio.com/docs/remote/containers) to have all prerequisites without any hassle,
46+
* [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) extension,
47+
* [docker](https://www.docker.com/)
48+
49+
### Quickstart with Docker
50+
51+
To experiment in a minimum of effort what this library is doing, follow the steps below:
52+
53+
1. git clone https://github.com/Azure-samples/flask-reactize
54+
2. cd flask-reactize
55+
3. code .
1856

19-
- OS
20-
- Library version
21-
- ...
57+
Once [vscode](https://code.visualstudio.com/) is opened, build the development container:
2258

23-
### Installation
59+
1. open the Palette (Ctrl+Shift+P / Cmd+Shift+P)
60+
2. select *Remote-Containers: Reopen in container*
2461

25-
(ideally very short)
62+
Once the container is built, your [vscode](https://code.visualstudio.com/) is fully operational. If you open the terminal built in [vscode](https://code.visualstudio.com/), you will be prompted directly inside the container, as a "dummy" user called *alex*.
2663

27-
- npm install [package name]
28-
- mvn install
29-
- ...
64+
You can now build the *flask-reactize* container to test *flask-reactize* in either Python 3.8 or 3.10 version
3065

31-
### Quickstart
32-
(Add steps to get up and running quickly)
66+
1. run `make docker-build-sample-py38` in the terminal for Python 3.8
67+
2. OR run `make docker-build-sample-py310` in the terminal for Python 3.10
68+
3. then run `make docker-run-sample` to start the sample demo site
3369

34-
1. git clone [repository clone url]
35-
2. cd [respository name]
36-
3. ...
70+
> If running the commands above result in an access is denied for the file `/var/run/docker.sock`, ensure that your user is the owner of this file. If it is not the case, run `sudo chown alex:alex /var/run/docker.sock` in the terminal.
3771
72+
You can now open your browser and load the url [http://localhost:8080](http://localhost:8080)
3873

39-
## Demo
74+
## Use this library in your project
4075

41-
A demo app is included to show how to use the project.
76+
**Please note** that you need to be on a *nix system for that, whether you are on Linux, Mac or Windows with [WSL](https://docs.microsoft.com/en-us/windows/wsl/about).
4277

43-
To run the demo, follow these steps:
78+
Instructions to follow can be found [here](./src/flask-reactize/README.md).
4479

45-
(Add steps to start up the demo)
80+
## Deploy to Azure
4681

47-
1.
48-
2.
49-
3.
82+
You can deploy your web application on Azure following one of the following methods (non exhaustive list):
5083

51-
## Resources
84+
1. Using [Web App for Containers](https://docs.microsoft.com/en-us/azure/app-service/quickstart-custom-container?tabs=dotnet&pivots=container-linux),
85+
2. Using a [Web App](https://docs.microsoft.com/en-US/azure/app-service/quickstart-python?tabs=flask%2Cwindows%2Cazure-portal%2Cterminal-bash%2Cvscode-deploy%2Cdeploy-instructions-azportal%2Cdeploy-instructions-zip-azcli),
86+
3. Using [Azure Kubernetes Service](https://azure.microsoft.com/en-us/services/kubernetes-service/#overview) in a multi-scalable containers scenario.
5287

53-
(Any additional resources or related projects)
88+
## Contributing
5489

55-
- Link to supporting information
56-
- Link to similar sample
57-
- ...
90+
If you want to contribute to *flask-reactize*, [follow this guide](./CONTRIBUTING.md).

makefile

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
SHELL=/bin/bash
2+
3+
clean:
4+
@find . -name '__pycache__' -exec rm -fr {} +
5+
@find . -name '.pytest_cache' -exec rm -fr {} +
6+
@find . -name 'build' ! -path '*/node_modules/*' -exec rm -fr {} +
7+
@find . -name 'dist' ! -path '*/node_modules/*' -exec rm -fr {} +
8+
@find . -name 'flask_reactize.egg-info' -exec rm -fr {} +
9+
@find . -name '.coverage' -exec rm -f {} +
10+
@find . -name 'coverage.xml' -exec rm -f {} +
11+
@find . -name 'pytest-results.xml' -exec rm -f {} +
12+
13+
install-deps:
14+
@make install-deps --directory src/flask-reactize
15+
16+
docker-build-sample-py38:
17+
@test -d ./sample/static || (echo "You need to compile your React application first"; exit 1)
18+
19+
@echo "Build docker image"
20+
@docker build --no-cache -t flask-reactize-sample:latest -f DockerFile-py38 .
21+
22+
docker-build-sample-py310:
23+
@test -d ./sample/static || (echo "You need to compile your React application first"; exit 1)
24+
25+
@echo "Build docker image"
26+
@docker build -t flask-reactize-sample:latest -f DockerFile-py310 .
27+
28+
docker-run-sample:
29+
@test -z "$(shell docker images -q flask-reactize-sample:latest)" || \
30+
docker run -p 8080:80 flask-reactize-sample:latest

python-path.env

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Set path of all Python modules here, separated by semicolon
2+
PYTHONPATH=./src/flask-reactize/src

0 commit comments

Comments
 (0)