{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-02-29-python-image-classification","result":{"data":{"currentBlog":{"id":"b1f620aa-5c24-5aa7-8b35-feadca3b91c7","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/202034/1583317036981-video3.png","authors":["Anycodes"],"categories":["user-stories"],"date":"2020-02-29T00:00:00.000Z","title":"20 行代码：Serverless 架构下用 Python 轻松搞定图像分类","description":"如何快速搭建一个图像分类/识别 API","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["Serverless","Python"],"keywords":"Serverless 图像分类,Serverless 识别 API,Serverless Python","outdated":true},"wordCount":{"words":115,"sentences":34,"paragraphs":34},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-02-29-python-image-classification.md","fields":{"slug":"/blog/2020-02-29-python-image-classification/","keywords":["python","serverless","云函数","editor","baboon","Irish","cost","cheetah"]},"html":"<p>「图像分类」是人工智能领域的一个热门话题，我们在实际生活中甚至业务的生产环境里，也经常遇到图像分类相似的需求，如何能快速搭建一个图像分类或者内容识别的 API 呢？</p>\n<p>我们考虑使用 <a href=\"https://github.com/serverless/serverless/blob/master/README_CN.md\">Serverless Framework</a> 将图像识别模块部署到腾讯云云函数 SCF 上。</p>\n<p>这里我们会用到一个图像相关的库：<code class=\"language-text\">ImageAI</code>，官方给了一个简单的 demo：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"2767882560073276000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`from imageai.Prediction import ImagePrediction\nimport os\nexecution_path = os.getcwd()\n\nprediction = ImagePrediction()\nprediction.setModelTypeAsResNet()\nprediction.setModelPath(os.path.join(execution_path, &quot;resnet50_weights_tf_dim_ordering_tf_kernels.h5&quot;))\nprediction.loadModel()\n\npredictions, probabilities = prediction.predictImage(os.path.join(execution_path, &quot;1.jpg&quot;), result_count=5 )\nfor eachPrediction, eachProbability in zip(predictions, probabilities):\n    print(eachPrediction + &quot; : &quot; + eachProbability)`, `2767882560073276000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> imageai<span class=\"token punctuation\">.</span>Prediction <span class=\"token keyword\">import</span> ImagePrediction\n<span class=\"token keyword\">import</span> os\nexecution_path <span class=\"token operator\">=</span> os<span class=\"token punctuation\">.</span>getcwd<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\nprediction <span class=\"token operator\">=</span> ImagePrediction<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nprediction<span class=\"token punctuation\">.</span>setModelTypeAsResNet<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nprediction<span class=\"token punctuation\">.</span>setModelPath<span class=\"token punctuation\">(</span>os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>join<span class=\"token punctuation\">(</span>execution_path<span class=\"token punctuation\">,</span> <span class=\"token string\">\"resnet50_weights_tf_dim_ordering_tf_kernels.h5\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\nprediction<span class=\"token punctuation\">.</span>loadModel<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\npredictions<span class=\"token punctuation\">,</span> probabilities <span class=\"token operator\">=</span> prediction<span class=\"token punctuation\">.</span>predictImage<span class=\"token punctuation\">(</span>os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>join<span class=\"token punctuation\">(</span>execution_path<span class=\"token punctuation\">,</span> <span class=\"token string\">\"1.jpg\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> result_count<span class=\"token operator\">=</span><span class=\"token number\">5</span> <span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">for</span> eachPrediction<span class=\"token punctuation\">,</span> eachProbability <span class=\"token keyword\">in</span> <span class=\"token builtin\">zip</span><span class=\"token punctuation\">(</span>predictions<span class=\"token punctuation\">,</span> probabilities<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>eachPrediction <span class=\"token operator\">+</span> <span class=\"token string\">\" : \"</span> <span class=\"token operator\">+</span> eachProbability<span class=\"token punctuation\">)</span></code></pre></div>\n<p>接下来分四步进行：<strong>创建项目 → 安装依赖 → 配置 yml 文件 → 部署</strong></p>\n<h3 id=\"本地创建-python-项目\"><a href=\"#%E6%9C%AC%E5%9C%B0%E5%88%9B%E5%BB%BA-python-%E9%A1%B9%E7%9B%AE\" aria-label=\"本地创建 python 项目 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>本地创建 Python 项目</h3>\n<p>首先，我们在本地创建一个 Python 的项目：mkdir imageDemo`</p>\n<p>然后新建文件：<code class=\"language-text\"></code>vim index.py`</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"16945474311483455000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`from imageai.Prediction import ImagePrediction\nimport os, base64, random\n\nexecution_path = os.getcwd()\n\nprediction = ImagePrediction()\nprediction.setModelTypeAsSqueezeNet()\nprediction.setModelPath(os.path.join(execution_path, &quot;squeezenet_weights_tf_dim_ordering_tf_kernels.h5&quot;))\nprediction.loadModel()\n\n\ndef main_handler(event, context):\n    imgData = base64.b64decode(event[&quot;body&quot;])\n    fileName = '/tmp/' + &quot;&quot;.join(random.sample('zyxwvutsrqponmlkjihgfedcba', 5))\n    with open(fileName, 'wb') as f:\n        f.write(imgData)\n    resultData = {}\n    predictions, probabilities = prediction.predictImage(fileName, result_count=5)\n    for eachPrediction, eachProbability in zip(predictions, probabilities):\n        resultData[eachPrediction] =  eachProbability\n    return resultData`, `16945474311483455000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> imageai<span class=\"token punctuation\">.</span>Prediction <span class=\"token keyword\">import</span> ImagePrediction\n<span class=\"token keyword\">import</span> os<span class=\"token punctuation\">,</span> base64<span class=\"token punctuation\">,</span> random\n\nexecution_path <span class=\"token operator\">=</span> os<span class=\"token punctuation\">.</span>getcwd<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\nprediction <span class=\"token operator\">=</span> ImagePrediction<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nprediction<span class=\"token punctuation\">.</span>setModelTypeAsSqueezeNet<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nprediction<span class=\"token punctuation\">.</span>setModelPath<span class=\"token punctuation\">(</span>os<span class=\"token punctuation\">.</span>path<span class=\"token punctuation\">.</span>join<span class=\"token punctuation\">(</span>execution_path<span class=\"token punctuation\">,</span> <span class=\"token string\">\"squeezenet_weights_tf_dim_ordering_tf_kernels.h5\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\nprediction<span class=\"token punctuation\">.</span>loadModel<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">main_handler</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    imgData <span class=\"token operator\">=</span> base64<span class=\"token punctuation\">.</span>b64decode<span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">[</span><span class=\"token string\">\"body\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    fileName <span class=\"token operator\">=</span> <span class=\"token string\">'/tmp/'</span> <span class=\"token operator\">+</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">.</span>join<span class=\"token punctuation\">(</span>random<span class=\"token punctuation\">.</span>sample<span class=\"token punctuation\">(</span><span class=\"token string\">'zyxwvutsrqponmlkjihgfedcba'</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">with</span> <span class=\"token builtin\">open</span><span class=\"token punctuation\">(</span>fileName<span class=\"token punctuation\">,</span> <span class=\"token string\">'wb'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">as</span> f<span class=\"token punctuation\">:</span>\n        f<span class=\"token punctuation\">.</span>write<span class=\"token punctuation\">(</span>imgData<span class=\"token punctuation\">)</span>\n    resultData <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n    predictions<span class=\"token punctuation\">,</span> probabilities <span class=\"token operator\">=</span> prediction<span class=\"token punctuation\">.</span>predictImage<span class=\"token punctuation\">(</span>fileName<span class=\"token punctuation\">,</span> result_count<span class=\"token operator\">=</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">for</span> eachPrediction<span class=\"token punctuation\">,</span> eachProbability <span class=\"token keyword\">in</span> <span class=\"token builtin\">zip</span><span class=\"token punctuation\">(</span>predictions<span class=\"token punctuation\">,</span> probabilities<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        resultData<span class=\"token punctuation\">[</span>eachPrediction<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span>  eachProbability\n    <span class=\"token keyword\">return</span> resultData</code></pre></div>\n<h3 id=\"下载安装依赖\"><a href=\"#%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85%E4%BE%9D%E8%B5%96\" aria-label=\"下载安装依赖 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>下载安装依赖</h3>\n<p>项目创建完成之后，下载所依赖的模型：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">- SqueezeNet（文件大小：4.82 MB，预测时间最短，精准度适中）\n- ResNet50 by Microsoft Research （文件大小：98 MB，预测时间较快，精准度高）\n- InceptionV3 by Google Brain team （文件大小：91.6 MB，预测时间慢，精度更高）\n- DenseNet121 by Facebook AI Research （文件大小：31.6 MB，预测时间较慢，精度最高）</code></pre></div>\n<p>我们先用第一个 <code class=\"language-text\">SqueezeNet</code> 来做测试：</p>\n<p>在官方文档复制模型文件地址：</p>\n<p><img src=\"http://editor.0duzhan.com/media/editor/WX20200302-144924_20200302064946149139.png\"></p>\n<p>使用 <code class=\"language-text\">wget</code> 直接安装：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">wget https://github.com/OlafenwaMoses/ImageAI/releases/download/1.0/squeezenet_weights_tf_dim_ordering_tf_kernels.h5</code></pre></div>\n<p><img src=\"http://editor.0duzhan.com/media/editor/WX20200302-145253@2x_20200302065305405982.png\"></p>\n<p>接下来安装依赖，这里面貌似安装的内容蛮多的：</p>\n<p><img src=\"http://editor.0duzhan.com/media/editor/WX20200302-145535_20200302065546714569.png\"></p>\n<p>这里需要注意：其中一些依赖需要编译，因此要在 centos + python2.7/3.6 的版本下打包才可以，这很复杂，尤其对于 mac/windows 用户，伤不起。</p>\n<p>这时候可以直接用我之前的打包网址：</p>\n<p><img src=\"http://editor.0duzhan.com/media/editor/WX20200302-145832_20200302065910362439.png\"></p>\n<p><img src=\"http://editor.0duzhan.com/media/editor/WX20200302-145859_20200302065917936649.png\"></p>\n<p>下载解压后，直接放到自己的项目中即可：</p>\n<p><img src=\"http://editor.0duzhan.com/media/editor/WX20200302-150100@2x_20200302070110872303.png\"></p>\n<h3 id=\"创建-yml-文件\"><a href=\"#%E5%88%9B%E5%BB%BA-yml-%E6%96%87%E4%BB%B6\" aria-label=\"创建 yml 文件 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>创建 yml 文件</h3>\n<p>接着创建 <code class=\"language-text\">serverless.yaml</code> 配置文件</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">imageDemo:\n  component: &quot;@serverless/tencent-scf&quot;\n  inputs:\n    name: imageDemo\n    codeUri: ./\n    handler: index.main_handler\n    runtime: Python3.6\n    region: ap-guangzhou\n    description: 图像识别/分类Demo\n    memorySize: 256\n    timeout: 10\n    events:\n      - apigw:\n          name: imageDemo_apigw_service\n          parameters:\n            protocols:\n              - http\n            serviceName: serverless\n            description: 图像识别/分类DemoAPI\n            environment: release\n            endpoints:\n              - path: /image\n                method: ANY</code></pre></div>\n<h3 id=\"部署\"><a href=\"#%E9%83%A8%E7%BD%B2\" aria-label=\"部署 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>部署</h3>\n<p>通过 <code class=\"language-text\">serverless</code> 命令（可使用命令缩写 <code class=\"language-text\">sls</code> ）进行部署，添加 <code class=\"language-text\">--debug</code> 参数查看部署详情：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"65128201539320440000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`\\$ sls --debug`, `65128201539320440000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ sls --debug</code></pre></div>\n<p>如果你的账号未 <a href=\"https://cloud.tencent.com/login\">登陆</a> 或 <a href=\"https://cloud.tencent.com/register\">注册</a> 腾讯云，可以直接通过微信扫描命令行中的二维码，从而进行授权登陆和注册。</p>\n<p><img src=\"http://editor.0duzhan.com/media/editor/WX20200302-150814@2x_20200302070827866955.png\"></p>\n<p>访问命令行输出的 URL，URL 就是我们刚才复制的 +<code class=\"language-text\">/image</code>，通过 Python 语言进行测试：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"10612161214710890000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import urllib.request\nimport base64\n\nwith open(&quot;1.jpg&quot;, 'rb') as f:\n    base64_data = base64.b64encode(f.read())\n    s = base64_data.decode()\n\nurl = 'http://service-9p7hbgvg-1256773370.gz.apigw.tencentcs.com/release/image'\n\nprint(urllib.request.urlopen(urllib.request.Request(\n    url = url,\n    data=s.encode(&quot;utf-8&quot;)\n)).read().decode(&quot;utf-8&quot;))`, `10612161214710890000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> urllib<span class=\"token punctuation\">.</span>request\n<span class=\"token keyword\">import</span> base64\n\n<span class=\"token keyword\">with</span> <span class=\"token builtin\">open</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"1.jpg\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'rb'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">as</span> f<span class=\"token punctuation\">:</span>\n    base64_data <span class=\"token operator\">=</span> base64<span class=\"token punctuation\">.</span>b64encode<span class=\"token punctuation\">(</span>f<span class=\"token punctuation\">.</span>read<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    s <span class=\"token operator\">=</span> base64_data<span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\nurl <span class=\"token operator\">=</span> <span class=\"token string\">'http://service-9p7hbgvg-1256773370.gz.apigw.tencentcs.com/release/image'</span>\n\n<span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>urllib<span class=\"token punctuation\">.</span>request<span class=\"token punctuation\">.</span>urlopen<span class=\"token punctuation\">(</span>urllib<span class=\"token punctuation\">.</span>request<span class=\"token punctuation\">.</span>Request<span class=\"token punctuation\">(</span>\n    url <span class=\"token operator\">=</span> url<span class=\"token punctuation\">,</span>\n    data<span class=\"token operator\">=</span>s<span class=\"token punctuation\">.</span>encode<span class=\"token punctuation\">(</span><span class=\"token string\">\"utf-8\"</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>read<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token string\">\"utf-8\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>例如我们用这张图进行测试：</p>\n<p><img src=\"http://editor.0duzhan.com/media/editor/1_20200302070800203686.jpg\"></p>\n<p>得到运行结果：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"59527613089730404000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}`, `59527613089730404000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token punctuation\">{</span><span class=\"token string\">\"cheetah\"</span><span class=\"token punctuation\">:</span> <span class=\"token number\">83.12643766403198</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Irish_terrier\"</span><span class=\"token punctuation\">:</span> <span class=\"token number\">2.315458096563816</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"lion\"</span><span class=\"token punctuation\">:</span> <span class=\"token number\">1.8476998433470726</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"teddy\"</span><span class=\"token punctuation\">:</span> <span class=\"token number\">1.6655176877975464</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"baboon\"</span><span class=\"token punctuation\">:</span> <span class=\"token number\">1.5562783926725388</span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>将代码修改一下，进行一下简单的耗时测试：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"10146971020535323000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import urllib.request\nimport base64, time\n\nfor i in range(0,10):\n    start_time = time.time()\n    with open(&quot;1.jpg&quot;, 'rb') as f:\n        base64_data = base64.b64encode(f.read())\n        s = base64_data.decode()\n\n    url = 'http://service-hh53d8yz-1256773370.bj.apigw.tencentcs.com/release/test'\n\n    print(urllib.request.urlopen(urllib.request.Request(\n        url = url,\n        data=s.encode(&quot;utf-8&quot;)\n    )).read().decode(&quot;utf-8&quot;))\n    print(&quot;cost: &quot;, time.time() - start_time)`, `10146971020535323000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> urllib<span class=\"token punctuation\">.</span>request\n<span class=\"token keyword\">import</span> base64<span class=\"token punctuation\">,</span> time\n\n<span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    start_time <span class=\"token operator\">=</span> time<span class=\"token punctuation\">.</span>time<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">with</span> <span class=\"token builtin\">open</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"1.jpg\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'rb'</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">as</span> f<span class=\"token punctuation\">:</span>\n        base64_data <span class=\"token operator\">=</span> base64<span class=\"token punctuation\">.</span>b64encode<span class=\"token punctuation\">(</span>f<span class=\"token punctuation\">.</span>read<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        s <span class=\"token operator\">=</span> base64_data<span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    url <span class=\"token operator\">=</span> <span class=\"token string\">'http://service-hh53d8yz-1256773370.bj.apigw.tencentcs.com/release/test'</span>\n\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>urllib<span class=\"token punctuation\">.</span>request<span class=\"token punctuation\">.</span>urlopen<span class=\"token punctuation\">(</span>urllib<span class=\"token punctuation\">.</span>request<span class=\"token punctuation\">.</span>Request<span class=\"token punctuation\">(</span>\n        url <span class=\"token operator\">=</span> url<span class=\"token punctuation\">,</span>\n        data<span class=\"token operator\">=</span>s<span class=\"token punctuation\">.</span>encode<span class=\"token punctuation\">(</span><span class=\"token string\">\"utf-8\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>read<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token string\">\"utf-8\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"cost: \"</span><span class=\"token punctuation\">,</span> time<span class=\"token punctuation\">.</span>time<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-</span> start_time<span class=\"token punctuation\">)</span></code></pre></div>\n<p>输出结果：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  2.1161561012268066\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  1.1259253025054932\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  1.3322770595550537\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  1.3562259674072266\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  1.0180821418762207\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  1.4290671348571777\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  1.5917718410491943\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  1.1727900505065918\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  2.962592840194702\n{&quot;cheetah&quot;: 83.12643766403198, &quot;Irish_terrier&quot;: 2.315458096563816, &quot;lion&quot;: 1.8476998433470726, &quot;teddy&quot;: 1.6655176877975464, &quot;baboon&quot;: 1.5562783926725388}\ncost:  1.2248001098632812</code></pre></div>\n<p>这个数据，整体性能基本在可接受范围内。</p>\n<p>基于 Serverless 架构搭建的 Python 图像识别/分类 小工具就大功告成啦！</p>\n<hr>\n<blockquote>\n<p><strong>传送门：</strong></p>\n<ul>\n<li>GitHub: <a href=\"https://github.com/serverless/serverless/blob/master/README_CN.md\">github.com/serverless</a></li>\n<li>官网：<a href=\"https://serverless.com/\">serverless.com</a></li>\n</ul>\n</blockquote>\n<p>欢迎访问：<a href=\"https://serverlesscloud.cn/\">Serverless 中文网</a>，您可以在 <a href=\"https://serverlesscloud.cn/best-practice\">最佳实践</a> 里体验更多关于 Serverless 应用的开发！</p>","tableOfContents":"<ul>\n<li><a href=\"/blog/2020-02-29-python-image-classification/#%E6%9C%AC%E5%9C%B0%E5%88%9B%E5%BB%BA-python-%E9%A1%B9%E7%9B%AE\">本地创建 Python 项目</a></li>\n<li><a href=\"/blog/2020-02-29-python-image-classification/#%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85%E4%BE%9D%E8%B5%96\">下载安装依赖</a></li>\n<li><a href=\"/blog/2020-02-29-python-image-classification/#%E5%88%9B%E5%BB%BA-yml-%E6%96%87%E4%BB%B6\">创建 yml 文件</a></li>\n<li><a href=\"/blog/2020-02-29-python-image-classification/#%E9%83%A8%E7%BD%B2\">部署</a></li>\n</ul>"},"previousBlog":{"id":"fa9a27f0-ada1-513b-8b49-7a2b4085b2f1","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020327/1585306882234-9.jpg","authors":["serverless 社区"],"categories":["meetup"],"date":"2020-02-29T00:00:00.000Z","title":"国产 Serverless Identity 开源组件工作坊 - 在线分享","description":"Authing 联合腾讯云、Serverless 中文社区专家分享 Serverless Framework 组件的开发及应用","authorslink":["https://serverlesscloud.cn"],"translators":null,"translatorslink":null,"tags":["Serverless","Identity"],"keywords":"Serverless 全局变量组件,Serverless 单独部署组件,Serverless Component","outdated":null},"wordCount":{"words":290,"sentences":31,"paragraphs":31},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-02-29-identity-meetup.md","fields":{"slug":"/blog/2020-02-29-identity-meetup/","keywords":["serverless","Serverless","serverless","Authing","Framework","Component","开发","github"]}},"nextBlog":{"id":"73489f86-2e06-57e0-833d-040c31733016","frontmatter":{"thumbnail":"https://serverlessimg-1253970226.cos.ap-chengdu.myqcloud.com/qianyi/images/0%20%281%29.jpg","authors":["liujiang"],"categories":["news"],"date":"2020-02-28T00:00:00.000Z","title":"Serverless 架构揭秘与静态网站部署实战（附实战源码）","description":"Serverless被誉为下一代云计算技术，因为其能带来研发交付速度提升与成本的降低在业内异常火爆。本文主要为大家分享 Serverless Framework 的架构演进、技术解析以及应用发展，并通过 Serverless+Hexo 实战案例，分享如何快速基于 Serverless Framework 进行业务开发部署。","authorslink":["https://github.com/jiangliu5267"],"translators":null,"translatorslink":null,"tags":["Serverless","Meetup"],"keywords":"Serverless,Serverless开发实战,Serverless架构,","outdated":true},"wordCount":{"words":450,"sentences":83,"paragraphs":83},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-02-28-serverless-website-development.md","fields":{"slug":"/blog/2020-02-28-serverless-website-development/","keywords":["go","java","serverless","website","无服务器","云函数","组件化开发","Serverless","serverless","bucket","架构","serverlesscloud"]}},"recommendBlogs":{"edges":[{"node":{"id":"4300b21c-7209-5256-86ff-0d38e3daec9b","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/14f1c8eed372e76c1b139703b2f6d0fa.jpg","authors":["KieranMcCarthy"],"categories":["user-stories","engineering-culture"],"date":"2018-01-09T00:00:00.000Z","title":"我是如何在四年时间里，从厨师转行为 Serverless 应用开发者","description":"我是厨师出身，现在成为了一名 Serverless 应用开发者。","authorslink":["https://serverless.com/author/kieranmccarthy/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["应用开发","Serverless"],"keywords":"Serverless 应用开发,Serverless 管理,厨师转行为 Serverless 应用开发者","outdated":null},"wordCount":{"words":285,"sentences":38,"paragraphs":36},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years.md","fields":{"slug":"/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years/","keywords":["无服务器","无服务器开发","云函数","学习","Serverless","构建","Framework","开发者","服务器","应用","学位","简历"]}}},{"node":{"id":"713a0563-4bf9-5721-bacb-3b4ef609fe4a","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/camp-fire/camp-fire-housing-thumb.jpg","authors":["EricWyne"],"categories":["guides-and-tutorials","user-stories"],"date":"2018-12-05T00:00:00.000Z","title":"Serverless Twitter 机器人帮助为坎普山火受灾者安置住房","description":"加利福尼亚州的坎普山火致使数千人流离失所，为此，我构建了一个简单的 Serverless Twitter 机器人来帮助将受灾者安置在临时住房！","authorslink":["https://serverless.com/author/ericwyne/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":157,"sentences":26,"paragraphs":26},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-05-serverless-twitter-camp-fire.md","fields":{"slug":"/blog/2018-12-05-serverless-twitter-camp-fire/","keywords":["serverless","无服务器","云函数","Serverless","org","住房","Twitter","函数","受灾","机器人","山火"]}}},{"node":{"id":"98602143-b837-5f50-a24f-3b1ec76044d7","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/sqquid/sqquid-serverless-thumb.jpg","authors":["RonPeled"],"categories":["user-stories"],"date":"2018-12-17T00:00:00.000Z","title":"SQQUID：100% 无服务器初创公司","description":"SQQUID 将 AWS Lambda 和无服务器框架用于其核心产品和营销网站。我们来看看一个完全无服务器的初创公司是怎样的。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":266,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-17-sqquid-one-hundred-percent-serverless.md","fields":{"slug":"/blog/2018-12-17-sqquid-one-hundred-percent-serverless/","keywords":["go","serverless","无服务器","无服务器架构","服务器","架构","Lambda","集成","FaaS","串行","系统"]}}},{"node":{"id":"29dc2e58-d2ba-56f9-aee1-d21b0bc62e0e","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/ao-com-story/ao-serverless-thumbnail.png","authors":["NickGottlieb"],"categories":["user-stories"],"date":"2019-04-24T00:00:00.000Z","title":"AO.com：逐渐转向无服务器优先","description":"AO.com 的 SCV 团队率先尝试无服务器服务。折服于无服务器框架的快速周转时间和低维护成本，整个团队逐渐转向无服务器优先。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":236,"sentences":42,"paragraphs":35},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-04-24-ao-serverless-first.md","fields":{"slug":"/blog/2019-04-24-ao-serverless-first/","keywords":["serverless","无服务器","服务器","团队","Lambda","功能","构建"]}}},{"node":{"id":"752d08d1-387a-5bde-acf3-98141baab294","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020414/1586871710979-%E5%85%AC%E5%85%B1%E7%94%A8.png","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-06-20T00:00:00.000Z","title":"如何用 Serverless 为 Python 云函数打包依赖","description":"在使用无服务器云函数SCF时通常会遇到导入第三方库的问题，很多小伙伴比较头疼是：应该如何打包进去？这里，推荐几个不错的方法。","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["云函数","Serverless"],"keywords":"Serverless,Serverless应用,无服务器云函数","outdated":null},"wordCount":{"words":81,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-06-20-for-python-cloud-functions.md","fields":{"slug":"/blog/2019-06-20-for-python-cloud-functions/","keywords":["java","serverless","无服务器","无服务器云函数","云函数","serverlesscloud","安装","serverless","pillowtest"]}}},{"node":{"id":"2dc78814-9d77-555b-a1bb-ad202c8ec2d1","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/cloudforecast/thumbnail.png","authors":["FrancoisLagier"],"categories":["user-stories"],"date":"2019-08-07T00:00:00.000Z","title":"Serverless：初创企业的理想选择？（CloudForecast 案例分析）","description":"CloudForecast 是 2018 年成立的一家独立初创企业，本文将介绍他们决定选择 Serverless 的原因。","authorslink":["https://serverless.com/author/francoislagier/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":211,"sentences":29,"paragraphs":29},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-08-07-serverless-for-startups.md","fields":{"slug":"/blog/2019-08-07-serverless-for-startups/","keywords":["serverless","云函数","serverless","函数","Serverless","utm","Framework","blog","CloudForecast","cloudforecast"]}}},{"node":{"id":"97450b07-658b-5207-8216-1c7b9b51b115","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578988490344-v2-8b2cd2c5275aa2c5a3c5083a148a7a9f_1200x500.jpg","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-09-01T00:00:00.000Z","title":"如何通过 Serverless 与自然语言处理，让搜索引擎「看」到你的博客","description":"Serverless 与自然语言处理结合的一个小应用","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["个人博客","serverless"],"keywords":"Serverless 自然语言处理","outdated":null},"wordCount":{"words":106,"sentences":34,"paragraphs":34},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-01-search-engine-blog.md","fields":{"slug":"/blog/2019-09-01-search-engine-blog/","keywords":["serverless","云函数","keywords","serverlesscloud","summary"]}}},{"node":{"id":"ae4fd2f8-515c-5aec-b584-38427ef33f7e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578989800047-part-00492-780.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials","user-stories"],"date":"2019-09-16T00:00:00.000Z","title":"突破传统 OJ 瓶颈，「判题姬」接入云函数","description":"通过 Serverless 实现在线编程","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["在线编程","云函数"],"keywords":"Serverless 在线编程,Serverless OJ","outdated":null},"wordCount":{"words":169,"sentences":30,"paragraphs":30},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-16-online-Judge.md","fields":{"slug":"/blog/2019-09-16-online-Judge/","keywords":["python","serverless","云函数","代码","函数","serverless"]}}}],"totalCount":64}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"b1f620aa-5c24-5aa7-8b35-feadca3b91c7","previousBlogId":"fa9a27f0-ada1-513b-8b49-7a2b4085b2f1","nextBlogId":"73489f86-2e06-57e0-833d-040c31733016","categories":["user-stories"]}}}