blob: d85ea6caa242f24962fbf5424aedb3a845a03098 [file] [log] [blame]
#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from __future__ import annotations
import os
import shlex
import shutil
import subprocess
import sys
from pathlib import Path
if __name__ not in ("__main__", "__mp_main__"):
raise SystemExit(
"This file is intended to be executed as an executable program. You cannot use it as a module."
f"To run this script, run the ./{__file__} command"
)
def clean_up_airflow_home(airflow_home: Path):
if airflow_home.exists():
print(f"Removing {airflow_home}")
shutil.rmtree(airflow_home, ignore_errors=True)
def check_if_in_virtualenv() -> bool:
return hasattr(sys, "real_prefix") or (hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix)
def check_for_package_extras() -> str:
"""
check if the user provided any extra packages to install.
defaults to package 'devel'.
"""
if len(sys.argv) > 1:
if len(sys.argv) > 2:
print('Provide extras as 1 argument like: "devel,google,snowflake"')
sys.exit(1)
return sys.argv[1]
return "devel"
def pip_install_requirements() -> int:
"""
install the requirements of the current python version.
return 0 if success, anything else is an error.
"""
extras = check_for_package_extras()
print(
f"""
Installing requirements.
Airflow is installed with "{extras}" extra.
----------------------------------------------------------------------------------------
IMPORTANT NOTE ABOUT EXTRAS !!!
You can specify extras as single coma-separated parameter to install. For example
* google,amazon,microsoft.azure
* devel_all
Note that "devel_all" installs all possible dependencies and we have > 600 of them,
which might not be possible to install cleanly on your host because of lack of
system packages. It's easier to install extras one-by-one as needed.
----------------------------------------------------------------------------------------
"""
)
version = get_python_version()
constraint = (
f"https://raw.githubusercontent.com/apache/airflow/constraints-main/"
f"constraints-source-providers-{version}.txt"
)
pip_install_command = ["pip", "install", "-e", f".[{extras}]", "--constraint", constraint]
quoted_command = " ".join([shlex.quote(parameter) for parameter in pip_install_command])
print()
print(f"Running command: \n {quoted_command}\n")
e = subprocess.run(pip_install_command)
return e.returncode
def get_python_version() -> str:
"""
return the version of python we are running.
"""
major = sys.version_info[0]
minor = sys.version_info[1]
return f"{major}.{minor}"
def main():
"""
Setup local virtual environment.
"""
airflow_home_dir = Path(os.environ.get("AIRFLOW_HOME", Path.home() / "airflow"))
airflow_sources = Path(__file__).parents[2]
if not check_if_in_virtualenv():
print(
"Local virtual environment not activated.\nPlease create and activate it "
"first. (for example using 'python3 -m venv venv && source venv/bin/activate')"
)
sys.exit(1)
print("Initializing environment...")
print(f"This will remove the folder {airflow_home_dir} and reset all the databases!")
response = input("Are you sure? (y/N/q)")
if response != "y":
sys.exit(2)
print(f"\nWiping and recreating {airflow_home_dir}")
if airflow_home_dir == airflow_sources:
print("AIRFLOW_HOME and Source code are in the same path")
print(
f"When running this script it will delete all files in path {airflow_home_dir} "
"to clear dynamic files like config/logs/db"
)
print("Please move the airflow source code elsewhere to avoid deletion")
sys.exit(3)
clean_up_airflow_home(airflow_home_dir)
return_code = pip_install_requirements()
if return_code != 0:
print(
"To solve persisting issues with the installation, you might need the "
"prerequisites installed on your system.\n "
"Try running the command below and rerun virtualenv installation\n"
)
os_type = sys.platform
if os_type == "darwin":
print("brew install sqlite mysql postgresql openssl")
print('export LDFLAGS="-L/usr/local/opt/openssl/lib"')
print('export CPPFLAGS="-I/usr/local/opt/openssl/include"')
else:
print(
"sudo apt install build-essential python3-dev libsqlite3-dev openssl "
"sqlite default-libmysqlclient-dev libmysqlclient-dev postgresql"
)
sys.exit(4)
print("\nResetting AIRFLOW sqlite database...")
env = os.environ.copy()
env["AIRFLOW__CORE__LOAD_EXAMPLES"] = "False"
env["AIRFLOW__CORE__UNIT_TEST_MODE"] = "False"
env["AIRFLOW__DATABASE__SQL_ALCHEMY_POOL_ENABLED"] = "False"
env["AIRFLOW__CORE__DAGS_FOLDER"] = f"{airflow_sources}/empty"
env["AIRFLOW__CORE__PLUGINS_FOLDER"] = f"{airflow_sources}/empty"
subprocess.run(["airflow", "db", "reset", "--yes"], env=env)
print("\nResetting AIRFLOW sqlite unit test database...")
env = os.environ.copy()
env["AIRFLOW__CORE__LOAD_EXAMPLES"] = "True"
env["AIRFLOW__CORE__UNIT_TEST_MODE"] = "False"
env["AIRFLOW__DATABASE__SQL_ALCHEMY_POOL_ENABLED"] = "False"
env["AIRFLOW__CORE__DAGS_FOLDER"] = f"{airflow_sources}/empty"
env["AIRFLOW__CORE__PLUGINS_FOLDER"] = f"{airflow_sources}/empty"
subprocess.run(["airflow", "db", "reset", "--yes"], env=env)
print("\nInitialization of environment complete! Go ahead and develop Airflow!")
if __name__ == "__main__":
main()