streamlit
/
Makefile
416 строк · 13.8 Кб
1# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2024)
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15# Make uses /bin/sh by default, but we are using some bash features. On Ubuntu
16# /bin/sh is POSIX compliant, ie it's not bash. So let's be explicit:
17SHELL=/bin/bash18
19INSTALL_DEV_REQS ?= true20INSTALL_TEST_REQS ?= true21USE_CONSTRAINTS_FILE ?= true22PYTHON_VERSION := $(shell python --version | cut -d " " -f 2 | cut -d "." -f 1-2)23GITHUB_REPOSITORY ?= streamlit/streamlit24CONSTRAINTS_BRANCH ?= constraints-develop25CONSTRAINTS_URL ?= https://raw.githubusercontent.com/${GITHUB_REPOSITORY}/${CONSTRAINTS_BRANCH}/constraints-${PYTHON_VERSION}.txt26
27# Black magic to get module directories
28PYTHON_MODULES := $(foreach initpy, $(foreach dir, $(wildcard lib/*), $(wildcard $(dir)/__init__.py)), $(realpath $(dir $(initpy))))29
30.PHONY: help31help:32@# Magic line used to create self-documenting makefiles.33@# See https://stackoverflow.com/a/3573092834@awk '/^#/{c=substr($$0,3);next}c&&/^[[:alpha:]][[:alnum:]_-]+:/{print substr($$1,1,index($$1,":")),c}1{c=0}' Makefile | column -s: -t35
36.PHONY: all37# Get dependencies, build frontend, install Streamlit into Python environment.
38all: init frontend install39
40.PHONY: all-devel41# Get dependencies and install Streamlit into Python environment -- but do not build the frontend.
42all-devel: init develop pre-commit-install43@echo ""44@echo " The frontend has *not* been rebuilt."45@echo " If you need to make a wheel file or test S3 sharing, run:"46@echo ""47@echo " make frontend"48@echo ""49
50.PHONY: mini-devel51# Get minimal dependencies for development and install Streamlit into Python
52# environment -- but do not build the frontend.
53mini-devel: mini-init develop pre-commit-install54
55.PHONY: build-deps56# An even smaller installation than mini-devel. Installs the bare minimum
57# necessary to build Streamlit (by leaving out some dependencies necessary for
58# the development process). Does not build the frontend.
59build-deps: mini-init develop60
61.PHONY: init62# Install all Python and JS dependencies.
63init: python-init-all react-init protobuf64
65.PHONY: mini-init66# Install minimal Python and JS dependencies for development.
67mini-init: python-init-dev-only react-init protobuf68
69.PHONY: frontend70# Build frontend into static files.
71frontend: react-build72
73.PHONY: install74# Install Streamlit into your Python environment.
75install:76cd lib ; python setup.py install77
78.PHONY: develop79# Install Streamlit as links in your Python environment, pointing to local workspace.
80develop:81INSTALL_DEV_REQS=false INSTALL_TEST_REQS=false make python-init82
83.PHONY: python-init-all84# Install Streamlit and all (test and dev) requirements
85python-init-all:86INSTALL_DEV_REQS=true INSTALL_TEST_REQS=true make python-init87
88.PHONY: python-init-dev-only89# Install Streamlit and dev requirements
90python-init-dev-only:91INSTALL_DEV_REQS=true INSTALL_TEST_REQS=false make python-init92
93.PHONY: python-init-test-only94# Install Streamlit and test requirements
95python-init-test-only: lib/test-requirements.txt96INSTALL_DEV_REQS=false INSTALL_TEST_REQS=true make python-init97
98.PHONY: python-init-test-min-deps99# Install Streamlit and test requirements, with minimum dependency versions
100python-init-test-min-deps:101INSTALL_DEV_REQS=false INSTALL_TEST_REQS=true USE_CONSTRAINTS_FILE=true CONSTRAINTS_URL="lib/min-constraints-gen.txt" make python-init102
103.PHONY: python-init104python-init:105pip_args=("--editable" "lib[snowflake]");\106if [ "${USE_CONSTRAINTS_FILE}" = "true" ] ; then\107pip_args+=(--constraint "${CONSTRAINTS_URL}"); \108fi;\109if [ "${INSTALL_DEV_REQS}" = "true" ] ; then\110pip_args+=("--requirement" "lib/dev-requirements.txt"); \111fi;\112if [ "${INSTALL_TEST_REQS}" = "true" ] ; then\113pip_args+=("--requirement" "lib/test-requirements.txt"); \114fi;\115echo "Running command: pip install $${pip_args[@]}";\116pip install $${pip_args[@]};117if [ "${INSTALL_TEST_REQS}" = "true" ] ; then\118python -m playwright install --with-deps; \119fi;\120
121.PHONY: pylint122# Verify that our Python files are properly formatted.
123pylint:124# Does not modify any files. Returns with a non-zero125# status if anything is not properly formatted. (This isn't really126# "linting"; we're not checking anything but code style.)127if command -v "black" > /dev/null; then \128$(BLACK) --diff --check examples/ && \129$(BLACK) --diff --check lib/streamlit/ --exclude=/*_pb2.py$/ && \130$(BLACK) --diff --check lib/tests/ && \131$(BLACK) --diff --check e2e/scripts/ ; \132fi
133
134.PHONY: pyformat135# Fix Python files that are not properly formatted.
136pyformat:137pre-commit run black --all-files --hook-stage manual
138pre-commit run isort --all-files --hook-stage manual
139
140.PHONY: pytest141# Run Python unit tests.
142pytest:143cd lib; \144PYTHONPATH=. \145pytest -v \
146--junitxml=test-reports/pytest/junit.xml \147-l tests/ \
148$(PYTHON_MODULES)149
150# Run Python integration tests for snowflake.
151pytest-snowflake:152cd lib; \153PYTHONPATH=. \154pytest -v \
155--junitxml=test-reports/pytest/junit.xml \156--require-snowflake \
157-l tests/ \
158$(PYTHON_MODULES)159
160.PHONY: mypy161# Run Mypy static type checker.
162mypy:163./scripts/mypy
164
165.PHONY: integration-tests166# Run all our e2e tests in "bare" mode and check for non-zero exit codes.
167integration-tests:168python3 scripts/run_bare_integration_tests.py
169
170.PHONY: cli-smoke-tests171# Verify that CLI boots as expected when called with `python -m streamlit`
172cli-smoke-tests:173python3 scripts/cli_smoke_tests.py
174
175.PHONY: cli-regression-tests176# Verify that CLI boots as expected when called with `python -m streamlit`
177cli-regression-tests: install178pytest scripts/cli_regression_tests.py
179
180.PHONY: distribution181# Create Python distribution files in dist/.
182distribution:183# Get rid of the old build and dist folders to make sure that we clean old js and css.184rm -rfv lib/build lib/dist
185cd lib ; python3 setup.py bdist_wheel --universal sdist186
187.PHONY: package188# Build lib and frontend, and then run 'distribution'.
189package: build-deps frontend distribution190
191.PHONY: conda-distribution192# Create conda distribution files in lib/conda-recipe/dist.
193conda-distribution:194rm -rf lib/conda-recipe/dist
195mkdir lib/conda-recipe/dist
196# This can take upwards of 20 minutes to complete in a fresh conda installation! (Dependency solving is slow.)197# NOTE: Running the following command requires both conda and conda-build to198# be installed.199GIT_HASH=$$(git rev-parse --short HEAD) conda build lib/conda-recipe --output-folder lib/conda-recipe/dist200
201.PHONY: conda-package202# Build lib and (maybe) frontend assets, and then run 'conda-distribution'
203conda-package: build-deps204if [ "${SNOWPARK_CONDA_BUILD}" = "1" ] ; then\205echo "Creating Snowpark conda build, so skipping building frontend assets."; \206else \207make frontend; \208fi
209make conda-distribution;210
211.PHONY: clean212# Remove all generated files.
213clean:214cd lib; rm -rf build dist .eggs *.egg-info215rm -rf lib/conda-recipe/dist
216find . -name '*.pyc' -type f -delete || true217find . -name __pycache__ -type d -delete || true218find . -name .pytest_cache -exec rm -rfv {} \; || true219rm -rf .mypy_cache
220rm -f lib/streamlit/proto/*_pb2.py*
221rm -rf lib/streamlit/static
222rm -f lib/Pipfile.lock
223rm -rf frontend/app/build
224rm -rf frontend/node_modules
225rm -rf frontend/app/node_modules
226rm -rf frontend/lib/node_modules
227rm -rf frontend/test_results
228rm -f frontend/lib/src/proto.js
229rm -f frontend/lib/src/proto.d.ts
230rm -rf frontend/public/reports
231rm -rf frontend/lib/dist
232rm -rf ~/.cache/pre-commit
233rm -rf e2e_playwright/test-results
234find . -name .streamlit -type d -exec rm -rfv {} \; || true235cd lib; rm -rf .coverage .coverage\.*236
237MIN_PROTOC_VERSION = 3.20238.PHONY: check-protoc239# Ensure protoc is installed and is >= MIN_PROTOC_VERSION.
240check-protoc:241@# We support Python protobuf 4.21, which is incompatible with code generated from242@# protoc < 3.20243@if ! command -v protoc &> /dev/null ; then \244echo "protoc not installed."; \245exit 1; \246fi; \247\
248PROTOC_VERSION=$$(protoc --version | cut -d ' ' -f 2); \249\
250if [[ $$(echo -e "$$PROTOC_VERSION\n$(MIN_PROTOC_VERSION)" | sort -V | head -n1) != $(MIN_PROTOC_VERSION) ]]; then \251echo "Error: protoc version $${PROTOC_VERSION} is < $(MIN_PROTOC_VERSION)"; \252exit 1; \253else \254echo "protoc version $${PROTOC_VERSION} is >= than $(MIN_PROTOC_VERSION)"; \255fi
256
257.PHONY: protobuf258# Recompile Protobufs for Python and the frontend.
259protobuf: check-protoc260protoc \
261--proto_path=proto \262--python_out=lib \263--mypy_out=lib \264proto/streamlit/proto/*.proto
265
266@# JS protobuf generation. The --es6 flag generates a proper es6 module.267cd frontend/ ; ( \268echo "/* eslint-disable */" ; \269echo ; \270yarn --silent pbjs \
271../proto/streamlit/proto/*.proto \
272--path=proto -t static-module --wrap es6 \273) > ./lib/src/proto.js274
275@# Typescript type declarations for our generated protobufs276cd frontend/ ; ( \277echo "/* eslint-disable */" ; \278echo ; \279yarn --silent pbts ./lib/src/proto.js \
280) > ./lib/src/proto.d.ts281
282.PHONY: react-init283react-init:284cd frontend/ ; yarn install --frozen-lockfile285
286.PHONY: react-build287react-build:288cd frontend/ ; yarn run build289rsync -av --delete --delete-excluded --exclude=reports \290frontend/app/build/ lib/streamlit/static/
291
292.PHONY: frontend-fast293# Build frontend into static files faster by setting BUILD_AS_FAST_AS_POSSIBLE=true flag, which disables eslint and typechecking.
294frontend-fast:295cd frontend/ ; yarn run buildFast296rsync -av --delete --delete-excluded --exclude=reports \297frontend/app/build/ lib/streamlit/static/
298
299.PHONY: frontend-lib300# Build the frontend library
301frontend-lib:302cd frontend/ ; yarn run buildLib;303
304.PHONY: frontend-app305# Build the frontend app. One must build the frontend lib first before building the app.
306frontend-app:307cd frontend/ ; yarn run buildApp308
309.PHONY: jslint310# Lint the JS code
311jslint:312cd frontend; \313yarn lint;314
315.PHONY: tstypecheck316# Type check the JS/TS code
317tstypecheck:318pre-commit run typecheck-lib --all-files --hook-stage manual && pre-commit run typecheck-app --all-files --hook-stage manual
319
320.PHONY: jsformat321# Fix formatting issues in our JavaScript & TypeScript files.
322jsformat:323pre-commit run prettier --all-files --hook-stage manual
324
325.PHONY: jstest326# Run JS unit tests.
327jstest:328cd frontend; TESTPATH=$(TESTPATH) yarn run test329
330.PHONY: jscoverage331# Run JS unit tests and generate a coverage report.
332jscoverage:333cd frontend; yarn run test --coverage --watchAll=false334
335.PHONY: e2etest336# Run E2E tests.
337e2etest:338./scripts/run_e2e_tests.py
339
340.PHONY: playwright341# Run playwright E2E tests.
342playwright:343cd e2e_playwright; \344rm -rf ./test-results; \345pytest --browser webkit --browser chromium --browser firefox --video retain-on-failure --screenshot only-on-failure --output ./test-results/ -n auto --reruns 1 --reruns-delay 1 --rerun-except "Missing snapshot" --durations=5 -r aR -v346
347.PHONY: loc348# Count the number of lines of code in the project.
349loc:350find . -iname '*.py' -or -iname '*.js' | \351egrep -v "(node_modules)|(_pb2)|(lib\/streamlit\/proto)|(dist\/)" | \352xargs wc
353
354.PHONY: distribute355# Upload the package to PyPI.
356distribute:357cd lib/dist; \358twine upload $$(ls -t *.whl | head -n 1); \359twine upload $$(ls -t *.tar.gz | head -n 1)360
361.PHONY: notices362# Rebuild the NOTICES file.
363notices:364cd frontend; \365yarn licenses generate-disclaimer --silent --production --ignore-platform > ../NOTICES
366
367@# When `yarn licenses` is run in a yarn workspace, it misnames the project as368@# "WORKSPACE AGGREGATOR 2B7C80A7 6734 4A68 BB93 8CC72B9A5DEA". We fix that here.369@# There also isn't a portable way to invoke `sed` to edit files in-place, so we have370@# sed create a NOTICES.bak backup file that we immediately delete afterwards.371sed -i'.bak' 's/PORTIONS OF THE .*PRODUCT/PORTIONS OF THE STREAMLIT PRODUCT/' NOTICES372rm -f NOTICES.bak
373
374./scripts/append_license.sh frontend/app/src/assets/fonts/Source_Code_Pro/Source-Code-Pro.LICENSE
375./scripts/append_license.sh frontend/app/src/assets/fonts/Source_Sans_Pro/Source-Sans-Pro.LICENSE
376./scripts/append_license.sh frontend/app/src/assets/fonts/Source_Serif_Pro/Source-Serif-Pro.LICENSE
377./scripts/append_license.sh frontend/app/src/assets/img/Material-Icons.LICENSE
378./scripts/append_license.sh frontend/app/src/assets/img/Open-Iconic.LICENSE
379./scripts/append_license.sh frontend/lib/src/vendor/bokeh/bokeh-LICENSE.txt
380./scripts/append_license.sh frontend/lib/src/vendor/twemoji-LICENSE.txt
381./scripts/append_license.sh frontend/app/src/vendor/Segment-LICENSE.txt
382./scripts/append_license.sh frontend/lib/src/vendor/react-bootstrap-LICENSE.txt
383./scripts/append_license.sh lib/streamlit/vendor/ipython/IPython-LICENSE.txt
384
385.PHONY: headers386# Update the license header on all source files.
387headers:388pre-commit run insert-license --all-files --hook-stage manual
389pre-commit run license-headers --all-files --hook-stage manual
390
391.PHONY: gen-min-dep-constraints392# Write the minimum versions of our dependencies to a constraints file.
393gen-min-dep-constraints:394make develop >/dev/null
395python scripts/get_min_versions.py >lib/min-constraints-gen.txt
396
397.PHONY: pre-commit-install398pre-commit-install:399pre-commit install
400
401.PHONY: ensure-relative-imports402# ensure relative imports exist within the lib/dist folder when doing yarn buildLibProd
403ensure-relative-imports:404./scripts/ensure_relative_imports.sh
405
406.PHONY frontend-lib-prod:407# build the production version for @streamlit/lib
408frontend-lib-prod:409cd frontend/ ; yarn run buildLibProd;410
411.PHONY streamlit-lib-prod:412# build the production version for @streamlit/lib
413# while also doing a make init so it's a single command
414streamlit-lib-prod:415make mini-init;416make frontend-lib-prod;417
418