{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Hello docker (for Data Scientists & Developers)\n", "\n", "source : https://docs.docker.com/get-started/\n", "\n", "---\n", "### Docker 개념과 장점\n", "\n", "Docker 컨테이너는 독립적으로 애플리케이션이나 프로세스를 실행할 수 있는 경량화된 컴퓨팅환경입니다. Docker를 이용할 때 다음과 같은 장점을 가질 수 있으며 이런 점 때문에 최근 가장 주목받는 컴퓨팅 실행환경으로 선택받고 있습니다.\n", "\n", "- 유연성(Flexible): Even the most complex applications can be containerized.\n", "- 경량(Lightweight): Containers leverage and share the host kernel, making them much more efficient in terms of system resources than virtual machines.\n", "- 이식성(Portable): You can build locally, deploy to the cloud, and run anywhere.\n", "- 느슨한 결합(Loosely coupled): Containers are highly self sufficient and encapsulated, allowing you to replace or upgrade one without disrupting others.\n", "- 확장성(Scalable): You can increase and automatically distribute container replicas across a datacenter.\n", "- 보안(Secure): Containers apply aggressive constraints and isolations to processes without any configuration required on the part of the user.\n", "\n", "이런 장점들은 특히 머신러닝의 실행환경에서 더욱 가치를 발휘합니다. 왜냐하면,\n", "\n", "- 머신러닝 코드에서 사용하게 되는 복잡한 dependency 관계를 자연스럽게 코드로 정의하게 되며, 동일한 실행환경을 언제든 반복적으로 재생성할 수 있습니다.\n", "- 일반적으로 학습단계에 대규묘 병렬 컴퓨팅을 필요로 하지만 그 필요량과 시점을 예측하기 어렵습니다. 머신러닝과 같이 동적으로 리소스를 배정해야 하는 환경에서 보다 효율적으로 리소스를 관리할 수 있습니다. \n", "- 머신러닝의 배포단계에서 추가 작업량이 현저히 줄어들게 됩니다. 머신러닝의 응용환경 적용대상은 클라우드 서버에서부터 모바일, IoT Edge에 이르기까지 다양합니다. 이런 다양한 환경에 모델을 배포할 때 환경설정으로 위한 시행착오를 줄일 수 있습니다.\n", "- 자동화된 재학습과 자동화된 배포구성시 더욱 용이하게 구성할 수 있습니다.\n", "\n", "### Docker 구조\n", "\n", "![](https://docs.docker.com/engine/images/architecture.svg)\n", "\n", "\n", "### Docker 기본 명령\n", "\n", "Docker는 많은 복잡하고 다양한 명령과 설정을 포함하고 있지만 인프라 운영자가 아닌 Data Scientist 또는 Developer의 관점에서 알아야 할 Docker 명령은 그리 많지 않습니다. 본 노트북에서는 예제를 통해 다음 기본 명령들이 어떤 기능을 하는지 이해하고 활용할 수 있는 것을 목적으로 합니다.\n", "\n", "- docker build\n", "- docker run\n", "- docker pull/push\n", "- docker image\n", "- docker ps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "### Docker 환경 점검\n", "\n", "SageMaker 노트북 환경에는 이미 도커가 설치되어 있습니다." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Docker version 19.03.6-ce, build 369ce74\n" ] } ], "source": [ "!docker --version" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`docker images` 명령을 통해 docker image repository를 확인할 수 있습니다." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "REPOSITORY TAG IMAGE ID CREATED SIZE\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/rmars latest 61ea9cc60ed1 3 days ago 779MB\n", "rmars latest 61ea9cc60ed1 3 days ago 779MB\n", " a0948009e757 3 days ago 779MB\n", "ubuntu 16.04 dfeff22e96ae 3 weeks ago 131MB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/hwlife latest 67ba4376c4ec 2 months ago 3.58GB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/hwlife 7d4aedb40ec3 2 months ago 3.58GB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training 2.2.0-cpu-py37 7a8906b92f39 2 months ago 2.95GB\n", "tensorflow/tensorflow latest-gpu-jupyter f0b0261fec71 3 months ago 3.3GB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/torchserve v1 e8118c508b9d 3 months ago 2.75GB\n", "torchserve v1 e8118c508b9d 3 months ago 2.75GB\n", "ubuntu 18.04 2eb2d388e1a2 3 months ago 64.2MB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training 2.1-cpu-py3 eaca4ea179b1 4 months ago 2.11GB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference 2.1-cpu a24d00bf4158 4 months ago 916MB\n" ] } ], "source": [ "!docker images" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`docker ps` 명령을 통해 컨터이너 실행환경의 프로세스를 확인할 수 있습니다." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n" ] } ], "source": [ "!docker ps -a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "다음 셀의 명령은 도커 레지스트리에서 아래 이미지를 로컬로 복사하여 가져옵니다. \n", "- https://hub.docker.com/_/busybox" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using default tag: latest\n", "latest: Pulling from library/busybox\n", "\n", "\u001b[1BDigest: sha256:a9286defaba7b3a519d585ba0e37d0b2cbee74ebfe590960b0b1d6a5e97d1e1d\n", "Status: Downloaded newer image for busybox:latest\n", "docker.io/library/busybox:latest\n" ] } ], "source": [ "!docker pull busybox" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "REPOSITORY TAG IMAGE ID CREATED SIZE\n", "hello_docker latest 0ce2e15a7669 18 minutes ago 444MB\n", " 299cdfc7a02d 3 hours ago 444MB\n", " 954bb26bbc65 3 hours ago 444MB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/rmars latest 61ea9cc60ed1 3 days ago 779MB\n", "rmars latest 61ea9cc60ed1 3 days ago 779MB\n", " a0948009e757 3 days ago 779MB\n", "ubuntu 16.04 dfeff22e96ae 3 weeks ago 131MB\n", "busybox latest f0b02e9d092d 4 weeks ago 1.23MB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/hwlife latest 67ba4376c4ec 2 months ago 3.58GB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/hwlife 7d4aedb40ec3 2 months ago 3.58GB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training 2.2.0-cpu-py37 7a8906b92f39 2 months ago 2.95GB\n", "tensorflow/tensorflow latest-gpu-jupyter f0b0261fec71 3 months ago 3.3GB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/torchserve v1 e8118c508b9d 3 months ago 2.75GB\n", "torchserve v1 e8118c508b9d 3 months ago 2.75GB\n", "ubuntu 18.04 2eb2d388e1a2 3 months ago 64.2MB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training 2.1-cpu-py3 eaca4ea179b1 4 months ago 2.11GB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference 2.1-cpu a24d00bf4158 4 months ago 916MB\n" ] } ], "source": [ "!docker images" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello docker!!\n" ] } ], "source": [ "!docker run busybox echo \"hello docker!!\"" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", "e001d10ddebf busybox \"echo 'hello docker!…\" 12 seconds ago Exited (0) 11 seconds ago tender_maxwell\n", "e49c9e1147bc busybox \"sh\" 51 seconds ago Exited (0) 50 seconds ago hardcore_hawking\n", "1fe657c2326a hello_docker \"python hello_docker…\" 19 minutes ago Exited (0) 19 minutes ago determined_leakey\n", "61536dd1b3c4 719c1148fe65 \"python hello_docker…\" 3 hours ago Exited (0) 3 hours ago kind_meninsky\n", "70bd5030457b 719c1148fe65 \"/bin/bash\" 3 hours ago Exited (0) 3 hours ago friendly_lumiere\n", "b6b2693318f1 299cdfc7a02d \"/bin/bash\" 3 hours ago Exited (0) 3 hours ago musing_rubin\n", "a83b0b6d4ae3 719c1148fe65 \"/bin/bash\" 3 hours ago Exited (126) 3 hours ago hopeful_saha\n", "4c9959a1e1d1 719c1148fe65 \"/bin/bash\" 3 hours ago Exited (130) 3 hours ago hopeful_shockley\n", "0d5af16e7512 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training:2.2.0-cpu-py37 \"train\" 2 months ago Exited (0) 2 months ago tmp1eoweitw_algo-1-cnr6r_1\n", "7019aa611b4d 308961792850.dkr.ecr.us-east-1.amazonaws.com/hwlife \"/bin/bash\" 2 months ago Exited (0) 2 months ago zen_hypatia\n", "7e38990c7e6d 7d4aedb40ec3 \"/bin/bash\" 2 months ago Exited (0) 2 months ago infallible_margulis\n", "806886fd0b1b 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference:2.1-cpu \"serve\" 3 months ago Exited (137) 2 months ago tmpwxryezk4_algo-1-s3axm_1\n", "23194d3ce1a6 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference:2.1-cpu \"serve\" 3 months ago Exited (137) 3 months ago tmpfpnkqqf3_algo-1-prg2v_1\n", "3088b4217f7e 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training:2.1-cpu-py3 \"train\" 3 months ago Exited (0) 3 months ago tmpbphyjgkh_algo-1-wl4rk_1\n" ] } ], "source": [ "!docker ps -a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "### Docker build " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dcokerfile을 이용하여 실행환경을 정의합니다.\n", "- ubuntu 16.04 를 base image로 사용합니다.\n", "- wget, python, nginx 등 추가 필요한 필요한 도구와 서비스를 정의합니다.\n", "- 사용자 프로그램에서 실행할 dependency library를 정의합니다.\n", "- 환경변수와 working directory 등을 구성합니다.\n", "- 맨 아래줄에 사용자 정의 테스트 프로그램 파일을 복사하고 있습니다." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting Dockerfile\n" ] } ], "source": [ "%%writefile Dockerfile\n", "# Use the official image as a parent image.\n", "FROM ubuntu:16.04\n", "\n", "# Install tools and utilities \n", "RUN apt-get -y update && apt-get install -y --no-install-recommends \\\n", " wget \\\n", " python \\\n", " nginx \\\n", " ca-certificates \\\n", "&& rm -rf /var/lib/apt/lists/*\n", "\n", "# install python dependencies\n", "RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && \\\n", " pip install numpy==1.16.2 scipy==1.2.1 scikit-learn==0.20.2 pandas flask gevent gunicorn && \\\n", " (cd /usr/local/lib/python2.7/dist-packages/scipy/.libs; rm *; ln ../../numpy/.libs/* .) && \\\n", " rm -rf /root/.cache\n", "\n", "# set env variables \n", "ENV PYTHONUNBUFFERED=TRUE\n", "ENV PYTHONDONTWRITEBYTECODE=TRUE\n", "ENV PATH=\"/opt/program:${PATH}\"\n", "\n", "# Set the working directory.\n", "WORKDIR /opt/program\n", "\n", "# Copy the file from your host to your current location.\n", "COPY hello_docker.py .\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "테스트용으로 사용할 간단한 파이썬 실행코드를 생성합니다. (Dockerfile에서 컨테이너 내부로 copy하여 실행할 파일)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting hello_docker.py\n" ] } ], "source": [ "%%writefile hello_docker.py\n", "import numpy as np\n", "import pandas as pd\n", "\n", "x = [1,2,3]\n", "pd.DataFrame(x)\n", "print(x)\n", "print('pandas library was installed and runs well!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "방금 정의한 Dockerfile을 이용하여 도커이미지를 빌드합니다." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sending build context to Docker daemon 241.7kB\n", "Step 1/8 : FROM ubuntu:16.04\n", " ---> dfeff22e96ae\n", "Step 2/8 : RUN apt-get -y update && apt-get install -y --no-install-recommends wget python nginx ca-certificates && rm -rf /var/lib/apt/lists/*\n", " ---> Using cache\n", " ---> 65f40e9b009e\n", "Step 3/8 : RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && pip install numpy==1.16.2 scipy==1.2.1 scikit-learn==0.20.2 pandas flask gevent gunicorn && (cd /usr/local/lib/python2.7/dist-packages/scipy/.libs; rm *; ln ../../numpy/.libs/* .) && rm -rf /root/.cache\n", " ---> Using cache\n", " ---> d01b9b443467\n", "Step 4/8 : ENV PYTHONUNBUFFERED=TRUE\n", " ---> Using cache\n", " ---> 9608f2802fef\n", "Step 5/8 : ENV PYTHONDONTWRITEBYTECODE=TRUE\n", " ---> Using cache\n", " ---> 80240e5319f9\n", "Step 6/8 : ENV PATH=\"/opt/program:${PATH}\"\n", " ---> Using cache\n", " ---> 0c2ba8be566e\n", "Step 7/8 : WORKDIR /opt/program\n", " ---> Using cache\n", " ---> dc21030805a7\n", "Step 8/8 : COPY hello_docker.py .\n", " ---> 0ce2e15a7669\n", "Successfully built 0ce2e15a7669\n", "Successfully tagged hello_docker:latest\n" ] } ], "source": [ "!docker build -t hello_docker ." ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "REPOSITORY TAG IMAGE ID CREATED SIZE\n", "hello_docker latest 0ce2e15a7669 1 second ago 444MB\n", " 299cdfc7a02d 3 hours ago 444MB\n", " 954bb26bbc65 3 hours ago 444MB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/rmars latest 61ea9cc60ed1 3 days ago 779MB\n", "rmars latest 61ea9cc60ed1 3 days ago 779MB\n", " a0948009e757 3 days ago 779MB\n", "ubuntu 16.04 dfeff22e96ae 3 weeks ago 131MB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/hwlife latest 67ba4376c4ec 2 months ago 3.58GB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/hwlife 7d4aedb40ec3 2 months ago 3.58GB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training 2.2.0-cpu-py37 7a8906b92f39 2 months ago 2.95GB\n", "tensorflow/tensorflow latest-gpu-jupyter f0b0261fec71 3 months ago 3.3GB\n", "torchserve v1 e8118c508b9d 3 months ago 2.75GB\n", "308961792850.dkr.ecr.us-east-1.amazonaws.com/torchserve v1 e8118c508b9d 3 months ago 2.75GB\n", "ubuntu 18.04 2eb2d388e1a2 3 months ago 64.2MB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training 2.1-cpu-py3 eaca4ea179b1 4 months ago 2.11GB\n", "763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference 2.1-cpu a24d00bf4158 4 months ago 916MB\n" ] } ], "source": [ "!docker images" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "### Docker 실행" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`docker run` 명령을 이용하여 방금 빌드한 이미지를 실행합니다.\n", "- `hello_docker` 이미지를 실행하면서 `python hello_docker.py`명령을 실행하고 있습니다." ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3]\n", "pandas library was installed and runs well!\n" ] } ], "source": [ "!docker run hello_docker python hello_docker.py" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", "61536dd1b3c4 hello_docker \"python hello_docker…\" 2 hours ago Exited (0) 2 hours ago kind_meninsky\n", "70bd5030457b hello_docker \"/bin/bash\" 2 hours ago Exited (0) 2 hours ago friendly_lumiere\n", "b6b2693318f1 299cdfc7a02d \"/bin/bash\" 2 hours ago Exited (0) 2 hours ago musing_rubin\n", "a83b0b6d4ae3 hello_docker \"/bin/bash\" 2 hours ago Exited (126) 2 hours ago hopeful_saha\n", "4c9959a1e1d1 hello_docker \"/bin/bash\" 2 hours ago Exited (130) 2 hours ago hopeful_shockley\n", "0d5af16e7512 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training:2.2.0-cpu-py37 \"train\" 2 months ago Exited (0) 2 months ago tmp1eoweitw_algo-1-cnr6r_1\n", "7019aa611b4d 308961792850.dkr.ecr.us-east-1.amazonaws.com/hwlife \"/bin/bash\" 2 months ago Exited (0) 2 months ago zen_hypatia\n", "7e38990c7e6d 7d4aedb40ec3 \"/bin/bash\" 2 months ago Exited (0) 2 months ago infallible_margulis\n", "806886fd0b1b 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference:2.1-cpu \"serve\" 3 months ago Exited (137) 2 months ago tmpwxryezk4_algo-1-s3axm_1\n", "23194d3ce1a6 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference:2.1-cpu \"serve\" 3 months ago Exited (137) 3 months ago tmpfpnkqqf3_algo-1-prg2v_1\n", "3088b4217f7e 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-training:2.1-cpu-py3 \"train\" 3 months ago Exited (0) 3 months ago tmpbphyjgkh_algo-1-wl4rk_1\n" ] } ], "source": [ "!docker ps -a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "### AWS ECR 연결\n", "\n", "다음 shell script 코드는 AWS ECR에 \"hello-docker\"라는 이름의 레포지토리를 만들고 접속한 후 조금 전 생성한 이미지를 레포지토리에 push합니다. " ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "308961792850.dkr.ecr.us-east-1.amazonaws.com/hello-docker:latest\n", "Login Succeeded\n", "The push refers to repository [308961792850.dkr.ecr.us-east-1.amazonaws.com/hello-docker]\n", "b22e671e4096: Preparing\n", "65975c96572d: Preparing\n", "8c48a68852f0: Preparing\n", "12597f08af5b: Preparing\n", "9edaa71ce233: Preparing\n", "62fdddf6a67c: Preparing\n", "eff16de3ff64: Preparing\n", "61727f5e6796: Preparing\n", "62fdddf6a67c: Waiting\n", "61727f5e6796: Waiting\n", "b22e671e4096: Pushed\n", "9edaa71ce233: Pushed\n", "65975c96572d: Pushed\n", "62fdddf6a67c: Pushed\n", "eff16de3ff64: Pushed\n", "12597f08af5b: Pushed\n", "61727f5e6796: Pushed\n", "8c48a68852f0: Pushed\n", "latest: digest: sha256:650c378f5d2ac0548506eb645f6e73f6287ae3cbdfc1006f1b1cf1f680e188d2 size: 1988\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.\n", "Configure a credential helper to remove this warning. See\n", "https://docs.docker.com/engine/reference/commandline/login/#credentials-store\n", "\n" ] } ], "source": [ "%%sh\n", "# Get the account number associated with the current IAM credentials\n", "account=$(aws sts get-caller-identity --query Account --output text)\n", "region=$(aws configure get region)\n", "image=\"hello-docker\"\n", "\n", "fullname=\"${account}.dkr.ecr.${region}.amazonaws.com/${image}:latest\"\n", "echo ${fullname}\n", "\n", "# 1) If the repository doesn't exist in ECR, create it.\n", "aws ecr describe-repositories --repository-names \"${image}\" > /dev/null 2>&1\n", "if [ $? -ne 0 ]\n", "then\n", " aws ecr create-repository --repository-name \"${image}\" > /dev/null\n", "fi\n", "\n", "# 2) login to ecr\n", "aws ecr get-login-password --region \"${region}\" | docker login --username AWS --password-stdin \"${account}\".dkr.ecr.\"${region}\".amazonaws.com\n", "\n", "# 3) docker push\n", "docker push ${fullname}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "실행이 완료되면 AWS 콘솔의 [ECR](https://console.aws.amazon.com/ecr/repositories)로 이동하여 생성된 레포지토리와 push된 이미지를 확인합니다. \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "conda_python3", "language": "python", "name": "conda_python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.10" } }, "nbformat": 4, "nbformat_minor": 4 }