├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github └── workflows │ ├── docker_image.yml │ └── web_app.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── images ├── api-running.png ├── fast-api.png ├── try-it-out.png └── video-banner.gif ├── requirements.txt ├── translations ├── es │ └── README.md └── pt-BR │ └── README.md └── webapp ├── main.py └── static ├── bootstrap.min.css └── index.html /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/python-3/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster 4 | ARG VARIANT="3.10-bullseye" 5 | FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} 6 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/python-3 3 | { 4 | "name": "Python 3", 5 | "forwardPorts": [8000], 6 | "build": { 7 | "dockerfile": "Dockerfile", 8 | "context": "..", 9 | "args": { 10 | // Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6 11 | // Append -bullseye or -buster to pin to an OS version. 12 | // Use -bullseye variants on local on arm64/Apple Silicon. 13 | "VARIANT": "3.8-bullseye", 14 | // Options 15 | "NODE_VERSION": "none" 16 | } 17 | }, 18 | 19 | // Configure tool-specific properties. 20 | "customizations": { 21 | // Configure properties specific to VS Code. 22 | "vscode": { 23 | // Set *default* container specific settings.json values on container create. 24 | "settings": { 25 | "python.defaultInterpreterPath": "/usr/local/bin/python", 26 | "python.linting.enabled": true, 27 | "python.linting.pylintEnabled": true, 28 | "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", 29 | "python.formatting.blackPath": "/usr/local/py-utils/bin/black", 30 | "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", 31 | "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", 32 | "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", 33 | "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", 34 | "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", 35 | "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", 36 | "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" 37 | }, 38 | 39 | // Add the IDs of extensions you want installed when the container is created. 40 | "extensions": [ 41 | "ms-python.python", 42 | "ms-python.vscode-pylance", 43 | "GitHub.copilot" 44 | ] 45 | } 46 | }, 47 | 48 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 49 | // "forwardPorts": [], 50 | 51 | // Use 'postCreateCommand' to run commands after the container is created. 52 | "postCreateCommand": "pip3 install --user -r requirements.txt", 53 | 54 | // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 55 | "remoteUser": "vscode", 56 | "features": { 57 | "azure-cli": "latest" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.github/workflows/docker_image.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | # Using pattern as described in https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#using-filters 5 | pull_request: 6 | branches: 7 | - main 8 | push: 9 | branches: 10 | - main 11 | # Allow mannually trigger 12 | workflow_dispatch: 13 | 14 | jobs: 15 | 16 | build: 17 | 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | - run: echo "Job being triggered by ${{ github.event_name }} event" 23 | - name: Build the Codespaces container image 24 | run: docker build . --file .devcontainer/Dockerfile 25 | - run: echo "Job status is ${{ job.status }}." 26 | -------------------------------------------------------------------------------- /.github/workflows/web_app.yml: -------------------------------------------------------------------------------- 1 | name: Build and deploy Python app to Azure Web App 2 | 3 | env: 4 | AZURE_WEBAPP_NAME: your-app-name # set this to your application's name 5 | WORKING_DIRECTORY: '.' # set this to the path to your path of working directory inside github repository, defaults to the repository root 6 | PYTHON_VERSION: '3.9' 7 | STARTUP_COMMAND: 'gunicorn -w 2 -k uvicorn.workers.UvicornWorker webapp.main:app' # set this to the startup command required to start the gunicorn server. default it is empty 8 | 9 | on: 10 | # uncomment the next two lines to deploy on every push to main 11 | #push: 12 | # branches: [ "main" ] 13 | workflow_dispatch: 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | build-and-deploy: 20 | runs-on: ubuntu-latest 21 | environment: dev 22 | steps: 23 | # checkout the repo 24 | - uses: actions/checkout@master 25 | # setup python 26 | - name: Setup Python 27 | uses: actions/setup-python@v1 28 | with: 29 | python-version: ${{ env.PYTHON_VERSION }} 30 | # install dependencies 31 | - name: python install 32 | working-directory: ${{ env.WORKING_DIRECTORY }} 33 | run: | 34 | sudo apt install python${{ env.PYTHON_VERSION }}-venv 35 | python -m venv --copies antenv 36 | source antenv/bin/activate 37 | pip install setuptools 38 | pip install -r requirements.txt 39 | # Azure login 40 | - uses: azure/login@v1 41 | with: 42 | creds: ${{ secrets.AZURE_CREDENTIALS }} 43 | - uses: azure/appservice-settings@v1 44 | with: 45 | app-name: ${{ env.AZURE_WEBAPP_NAME }} 46 | mask-inputs: false 47 | general-settings-json: '{"linuxFxVersion": "PYTHON|${{ env.PYTHON_VERSION }}"}' #'General configuration settings as Key Value pairs' 48 | # deploy web app 49 | - uses: azure/webapps-deploy@v2 50 | with: 51 | app-name: ${{ env.AZURE_WEBAPP_NAME }} 52 | package: ${{ env.WORKING_DIRECTORY }} 53 | startup-command: ${{ env.STARTUP_COMMAND }} 54 | # Azure logout 55 | - name: logout 56 | run: | 57 | az logout 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=526682400) 2 | 3 | # Python HTTP API with GitHub Codespaces and Copilot 4 | 5 | _Run a Python API in this ready-to-use-repository in minutes_ 6 | 7 | By opening this template respository in Codespaces, you can quickly get hands-on with a Python web app that serves an HTTP API. You'll get to focus on working with the project instead of setup and configuration. And then you'll make changes to the code using [GitHub Copilot](https://copilot.github.com/), a new AI-powered code completion tool that helps you write code faster. 8 | 9 | ## 🚀 Quick start 10 | 1. [Follow the steps](#--try-it-out) to setup your Codespace and run the app. 11 | 1. [Make changes to the application](#make-changes-using-copilot) using [GitHub Copilot](https://copilot.github.com/) to make changes to the code. 12 | 1. Take the challenge and deploy your app to Azure. 13 | 14 | 🤔 Curious? Watch the following video where we explain all the details: 15 | 16 | [![Python development environment with Codespaces](https://img.youtube.com/vi/_i9Pywj3rSg/0.jpg)](https://youtu.be/_i9Pywj3rSg "Python Development environment with Codespaces") 17 | 18 | 19 |
20 | Learn more about APIs 21 | 22 | An API (Application Programming Interface) describes a way for two computers to interact. 23 | An HTTP API allows an Internet-connected computer to send an HTTP request to another Internet-connected computer 24 | and receive a response. For example, my computer could send a request to 25 | `http://a-weather-website-api.com/api/city=Los+Angeles` and receive back data like `{"high": 72, "low": 66}`. 26 | 27 | HTTP APIs often provide either data or functionality that's unique to a service, like the example API for the weather website. A weather website could provide additional API endpoints for other weather-related functionality, like upcoming forecasts or historical data. Any website can decide to offer an API if it thinks it has helpful functionality to share 28 | with other computers. In this project, you'll run an HTTP API that generates a random token. 29 |
30 | 31 | This template is also ready to be used with [Codespaces](https://github.com/features/codespaces), a developer environment running in the cloud with [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza). 32 | 33 |
34 | 🎥 Watch the video tutorial to learn more about Codespaces 35 | 36 | [![Codespaces Tutorial](https://img.youtube.com/vi/ozuDPmcC1io/0.jpg)](https://aka.ms/CodespacesVideoTutorial "Codespaces Tutorial") 37 |
38 | 39 | ## For students and developers 40 | 41 | Using Codespaces, you get [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza) in the cloud, using a ["development container"](https://containers.dev/). Like a locally running version of [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza), the cloud version also allows you to install extensions and use a terminal. 42 | 43 | You can also configure your development container to run a specific runtime and have it boot up with your favorite extensions. 44 | 45 | Here are the key files and folders that make it happen: 46 | 47 | - [webapp/](./.webapp): The HTTP API code, built with the FastAPI framework. 48 | - [.devcontainer/Dockerfile](./.devcontainer/Dockerfile): Configuration file used by Codespaces to determine operating system and other details. 49 | - [.devcontainer/devcontainer.json](./.devcontainer/devcontainer.json), A configuration file used by Codespaces to configure [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza) settings, such as the enabling of additional extensions. 50 | 51 | ## 🧐 Use Codespaces 52 | 53 | Try out this template repository using Codespaces following these steps: 54 | 55 | 1. Create a repository from this template. Use this [create repo link](https://github.com/microsoft/codespaces-project-template-py/generate). You can make the repository private or public, up to you. 56 | 1. Before creating the codespace, enable GitHub Copilot for your account! If it is not enabled, take a look on [Make changes using Copilot](#make-changes-using-copilot) 57 | 1. Navigate to the main page of the newly created repository. 58 | 1. Under the repository name, use the Code drop-down menu, and in the Codespaces tab, select "Create Codespace on main". 59 | ![Create Codespace](https://docs.github.com/assets/cb-138303/images/help/codespaces/new-codespace-button.png) 60 | 1. Wait as Github initializes the codespace: 61 | ![Creating Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_build.png) 62 | 63 | ### Inspect your Codespaces environment 64 | 65 | What you have at this point is a pre-configured environment where all the runtimes and libraries you need are already installed - a zero config experience. 66 | 67 | ## Running the App 68 | 69 | This Python application is using FastAPI, a powerful web framework that self-documents its API endpoints. The API has only one endpoint that generates a unique pseudo-random string that can be used as a token. 70 | 71 | 72 | ![Running FastAPI](./images/api-running.png) 73 | 74 | 75 |
76 | Run FastAPI inside the Codespace 77 | 78 | The API included in this template repository has a single endpoint that generates a token. Get it up and running using the following steps: 79 | 80 | 1. Open up a terminal window by opening up the command palette (Ctrl-Shift-P or Cmd-Shift-P) and then select "Open new Terminal" command. 81 | 1. Run `uvicorn` in the console to start up your API application: 82 | 83 | ```console 84 | uvicorn --host 0.0.0.0 webapp.main:app --reload 85 | ``` 86 | 87 | You should see output similar to: 88 | 89 | ```output 90 | INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) 91 | INFO: Started reloader process [28720] 92 | INFO: Started server process [28722] 93 | INFO: Waiting for application startup. 94 | INFO: Application startup complete. 95 | ``` 96 | 97 | You'll get a pop-up that says your application is available at port 8000. Click the button to open it in the browser. 98 | 1. Once the site loads, click on the _Try it Out_ button or append `/docs` to the URL in the address bar. The automatically generated API documentation should load and look like this: 99 | 100 | ![OpenAPI docs](./images/fast-api.png) 101 | 102 | 1. Finally, try to interact with the API by sending a request using the self-documented page. Click on the _POST_ button and then on the _Try it Out_ button: 103 | 104 | ![Try a POST request](./images/try-it-out.png) 105 | 106 | 🔒 Do you see the lock next to the URL of the website in the browser? That indicates the website is being served over a secure HTTPS connection which encrypts the HTTP responses. That's very important whenever an API can receive sensitive data or respond with sensitive data (like a password). 107 | 108 |
109 | 110 | ## Customize the Codespace 111 | 112 | You can change your environment and the text editor so that the next time you create (or rebuild) the environment, everything will be set automatically. Let's go through two different challenges that you are likely to want to do: 113 | 114 | 1. Changing the Python version 115 | 1. Adding or modifying a pre-installed editor extension 116 | 117 | 118 |
119 | 120 | ### Step 1: Change the Python environment 121 | 122 | Let's say you want to change which version of Python is installed. This is something you can control. 123 | 124 | Open [.devcontainer/devcontainer.json](./.devcontainer/devcontainer.json) and replace the following section: 125 | 126 | ```json 127 | "VARIANT": "3.8-bullseye" 128 | ``` 129 | 130 | with the following instruction: 131 | 132 | ```json 133 | "VARIANT": "3.9-bullseye" 134 | ``` 135 | 136 | This change instructs Codespaces to use Python 3.9 instead of 3.8. 137 | 138 | If you make any configuration change in `devcontainer.json`, a box will appear after saving. 139 | 140 | ![Recreating Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_rebuild.png) 141 | 142 | Click on rebuild. Wait for your Codespace to rebuild the VS Code environment. 143 | 144 | ### Step 2: Add an extension 145 | 146 | Your environment comes with pre-installed extensions. You can change which extensions your Codespaces environment starts with. Here's how: 147 | 148 | 1. Open file [.devcontainer/devcontainer.json](./.devcontainer/devcontainer.json) and locate the following JSON element **extensions**: 149 | 150 | ```json 151 | "extensions": [ 152 | "ms-python.python", 153 | "ms-python.vscode-pylance" 154 | ] 155 | ``` 156 | 157 | 1. Add _"ms-python.black-formatter"_ to the list of extensions. It should end up looking like the following: 158 | 159 | ```json 160 | "extensions": [ 161 | "ms-python.python", 162 | "ms-python.vscode-pylance", 163 | "ms-python.black-formatter" 164 | ] 165 | ``` 166 | 167 | That string is the unique identifier of [Black Formatter](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter&WT.mc_id=academic-77460-alfredodeza), a popular extension for formatting Python code according to best practices. Adding the _"ms-python.black-formatter"_ identifier to the list lets Codespaces know that this extension should be pre-installed upon startup. 168 | 169 | Reminder: When you change any configuration in the JSON file, a box will appear after saving. 170 | 171 | ![Recreating Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_rebuild.png) 172 | 173 | Click on rebuild. Wait for your Codespace to rebuild the VS Code environment. 174 | 175 | To find the unique identifier of an extension: 176 | 177 | - Navigate to the extension's web page, for example [https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter&WT.mc_id=academic-77460-alfredodeza) 178 | - Locate the *Unique Identifier* field under **More info** section on your right side. 179 | 180 |
181 | 182 | 183 | ## Make changes using Copilot 184 | 185 | Let's go through some steps to make changes to the code using Copilot. This is a great way to learn how to use Copilot and get useful suggestions for faster development. Note that these are suggested solutions, and we advise that you review them to ensure they are applicable to your code. 186 | 187 | This Codespaces repository has the Copilot extension enabled already. Make sure your account has access to it. If you don't have access, you can [request it](https://github.com/login?return_to=%2fgithub-copilot%2fsignup) and then install the extension [here](https://aka.ms/get-copilot). If you are a student, you can get Copilot for free [following these instructions](https://techcommunity.microsoft.com/t5/educator-developer-blog/step-by-step-setting-up-github-student-and-github-copilot-as-an/ba-p/3736279?WT.mc_id=academic-0000-alfredodeza). 188 | 189 | To ensure that Copilot is running correctly, please follow these steps: 190 | 191 | 1. Verify if Copilot is activated by navigating to the extension tab in your codespace and checking the status. 192 | 1. If the status is inactive, recreate the codespace, and enable the extension to ensure that it is activated. 193 | 194 | 🤔 Curious? Watch the following video where we explain all the details: 195 | 196 | [![Assisted AI Coding with GitHub Copilot](https://img.youtube.com/vi/9c7SSHbzD80/0.jpg)](https://youtu.be/9c7SSHbzD80 "Assisted AI Coding with GitHub Copilot") 197 | 198 |
199 | Use Copilot 200 | 201 | ### Step 1: Change the HTML to make it interactive 202 | Open the [index.html file](./webapp/static/index.html) and delete the following line: 203 | 204 | ```html 205 | 206 | ``` 207 | 208 | Now add a comment so that Copilot can generate code for you: 209 | 210 | ```html 211 | 212 | ``` 213 | This should be enough for Copilot to generate code for you after you press `Enter` (or `Return`). 214 | If not, use `Ctrl+Enter` to give multiple suggestions, choose one that fits better to the code below. 215 | Remember, it is possible that copilot will not generate the exact snippet! In this case, type or overwrite the suggestion for the code below. 216 | The generated code should look like this: 217 | 218 | ```html 219 |
220 | 221 | 222 |
223 |
224 | 242 | ``` 243 | 244 | Run the application and verify the form shows up. 245 | 246 | ### Step 2: Update the HTML to fix a bug 247 | The generated code introduced a couple of issues. First, the button is not working. Second, the form is not using the right JSON key when submitting the text to the API endpoint. Let's fix that. 248 | 249 | Change the body of the request to use the length key instead of text: 250 | 251 | ```javascript 252 | body: JSON.stringify({ length: input }) 253 | ``` 254 | 255 | Now, lets change the `innerHTML` to use the `token` key instead of `result`: 256 | 257 | ```javascript 258 | result.innerHTML = data.token; 259 | ``` 260 | 261 | Run the application and verify the form is now working. 262 | 263 | ### Step 3: Change the form to use a dropdown 264 | The form is currently accepting any text as input. Let's change it to use a dropdown instead. Add a comment so that Copilot can generate code for you. Delete the following line: 265 | 266 | ```html 267 | 268 | ``` 269 | 270 | And add the following comment so that Copilot can generate code for you: 271 | 272 | ```html 273 | 274 | ``` 275 | 276 | The generated code should now look like this: 277 | 278 | ```html 279 | 285 | ``` 286 | 287 | Run the application again to verify the dropdown is working. 288 | 289 | ### Step 4: Add a new API endpoint 290 | Now let's add some new functionality to the API. Add a new endpoint to the API that accepts a text and returns a list of tokens. Add the following comment so that Copilot can generate a Pydantic model for you: 291 | 292 | ```python 293 | # Create a Pydantic model that accepts a JSON body with a single field called "text", which is a string 294 | ``` 295 | 296 | The generated model should look like this: 297 | 298 | ```python 299 | class Text(BaseModel): 300 | text: str 301 | ``` 302 | 303 | Next, add the following comment so that Copilot can add a new endpoint: 304 | 305 | ```python 306 | # Create a FastAPI endpoint that accepts a POST request with a JSON body containing a single field called "text" and returns a checksum of the text 307 | ``` 308 | 309 | The generated code should look like this: 310 | 311 | ```python 312 | @app.post('/checksum') 313 | def checksum(body: Text): 314 | """ 315 | Generate a checksum of the text. Example POST request body: 316 | 317 | { 318 | "text": "Hello World!" 319 | } 320 | """ 321 | checksum = base64.b64encode(os.urandom(64))[:20].decode('utf-8') 322 | return {'checksum': checksum} 323 | ``` 324 | 325 | The generated code will cause the application to crash. This is because the `base64` and `os` modules are not imported. Add the following lines to the top of the file: 326 | 327 | ```python 328 | import base64 329 | ``` 330 | 331 | Finally, verify the new endpoint is working by going to the `/docs` page and trying out the new endpoint. 332 | 333 | Congratulations! You've used Copilot to not only generate code, but also do it in a way that is interactive and fun. You can now use Copilot to generate code for you in any of your projects, including writing documentation, generating models, and more! Even portions of this README were generated using Copilot suggestions 🧐 334 | 335 |
336 | 337 | ## 🚀 Next steps 338 | 339 | Take this API application to the next level and deploy it to the cloud! For this learning challenge you'll use a FREE deployment option for Azure and GitHub Actions for the automation. 340 | 341 | Before continuing, make sure you have an Azure account ready. Select any of the following: 342 | 343 | - [Sign in to your Azure account](https://azure.microsoft.com/en-US/?WT.mc_id=academic-77460-alfredodeza) 344 | - [Create a (no Credit Card required) Azure For Students account](https://azure.microsoft.com/free/students/?WT.mc_id=academic-77460-alfredodeza) 345 | - [Create a new Azure account](https://azure.microsoft.com/en-US/?WT.mc_id=academic-77460-alfredodeza) 346 | 347 | There are a few steps involved, so make sure you get everything right! 348 | 349 |
350 | Create an Azure App Service 351 | 352 | Now, you are going to set up automatic deployment of the application using Azure plus GitHub actions! However, you first need to configure some Azure services. 353 | 354 | 1. Open the [Azure Cloud Shell](https://shell.azure.com/?WT.mc_id=academic-77460-alfredodeza). 355 | 1. Use the Bash shell (not PowerShell!) for these steps. 356 | 1. If it says "You have no storage mounted", select a subscription in your account and click "Create storage". The Cloud Shell uses that storage resource to store data generated during your shell sessions. 357 | 1. Create a *Resource Group* which will group together the different Azure resources used for the app: 358 | ``` 359 | az group create --name demo-fastapi --location "East US" 360 | ``` 361 | 1. You'll see a JSON response with details about the newly created resource, for this command and all the commands that follow. 362 | 1. Create the **FREE** *App Service Plan*: 363 | ``` 364 | az appservice plan create --name "demo-fastapi" --resource-group demo-fastapi --is-linux --sku FREE 365 | ``` 366 | 1. Create a random identifier for a unique webapp name: 367 | ``` 368 | let "randomIdentifier=$RANDOM*$RANDOM" 369 | ``` 370 | 1. Create the *Web App Service* with a placeholder container using the `randomIdentifier` variable from before: 371 | ``` 372 | az webapp create --name "demo-fastapi-$randomIdentifier" --resource-group demo-fastapi --plan demo-fastapi --runtime "PYTHON:3.9" 373 | ``` 374 | 1. Head to the Azure portal [App Services list](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites) and confirm that your newly created service is listed. 375 | 376 |
377 | 378 | 379 |
380 | Create an Azure Service Principal 381 | 382 | Next, create an Azure Service Principal, which is a special type of account that has permissions necessary to authenticate from GitHub to Azure: 383 | 384 | 1. Find the ID of your Azure Subscription [in the Azure portal](https://portal.azure.com/#view/Microsoft_Azure_Billing/SubscriptionsBlade?WT.mc_id=academic-77460-alfredodeza) or [by following this guide](https://learn.microsoft.com/azure/azure-portal/get-subscription-tenant-id?WT.mc_id=academic-77460-alfredodeza). 385 | 1. Create a Service Principal with a "contributor" role that is allowed to make changes to any resources in that subscription. Replace $AZURE_SUBSCRIPTION_ID with the ID you found in step 1 and run this command: 386 | 387 | ``` 388 | az ad sp create-for-rbac --sdk-auth --name "github-deployer" --role contributor --scopes /subscriptions/$AZURE_SUBSCRIPTION_ID 389 | ``` 390 | 391 | 1. Capture the output and add it as a [Github repository secret](/../../settings/secrets/actions/new) with the name `AZURE_CREDENTIALS`. (_If that link doesn't work, make sure you're reading this on your own copy of the repo, not the original template._) 392 | 393 |
394 | 395 |
396 | 397 | Setup GitHub Actions 398 | 399 | Now that you have all the Azure resources created, you need to update the GitHub Action workflow file with the name of your webapp. 400 | 401 | 1. Find your app name. It should look something like `demo-fastapi-97709018` but with a different random number at the end, 402 | and you can find it in the Azure portal or the Cloud Shell commands. 403 | 2. Open the [.github/workflows/web_app.yml](/../../edit/main/.github/workflows/web_app.yml) file and update the value of `AZURE_WEBAPP_NAME` to your app name. 404 | 3. Commit and push the changes to the Github repository: 405 | 406 | ``` 407 | git add .github/workflows/web_app.yml 408 | git commit -m "Updating workflow file" 409 | git push 410 | ``` 411 | 412 |
413 | 414 |
415 | 🏃 Deploy your app! 416 | 417 | Before continuing, check the following: 418 | 419 | 1. You've created an Azure Service Principal and saved it as a [repository secret](/../../settings/secrets/) as `AZURE_CREDENTIALS`. 420 | 1. You've created an [App Service](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites) with a valid name and the site is already available with the default static content. 421 | 422 | To deploy: 423 | 424 | 1. Navigate to [repository actions](/../../actions/workflows/web_app.yml). (_If that link doesn't open the "Build and deploy Python app" workflow, make sure you're reading this on your own copy of the repo._) 425 | 3. Select _Run workflow_ and select the green button inside the pop-up to run the workflow. 426 | 427 | **Deploying can take a couple of minutes**. Make sure you stream the logs in the Azure Cloud Shell to check the progress: 428 | 429 | ``` 430 | az webapp log tail --name $AZURE_WEBAPP_NAME --resource-group $AZURE_RESOURCE_GROUP 431 | ``` 432 | 433 | 4. Once deployment is complete, visit your website at a URL like `http://demo-fastapi-97709018.azurewebsites.net/`, 434 | where the random number is your unique random number. You can find the website URL in the Azure portal or in the deployment logs if you forgot the number. 435 | 5. 🎉 Celebrate a successful deployment! You now have a URL that you can share with classmates, friends, and family. 436 | 437 | ### Destroy resources when complete 438 | 439 | You likely don't want to keep this particular website running forever in the cloud, so you should cleanup your Azure resources by destroying the resource group. You can do it in the Azure Cloud Shell by referencing the group name you created initially (`demo-fastapi` in the examples): 440 | 441 | ``` 442 | az group delete --name demo-fastapi 443 | ``` 444 | 445 | ### Deployment Troubleshooting 446 | 447 | When deploying, you might encounter errors or problems, either on the automation part of it (GitHub Actions) or on the deployment destination (Azure Web Apps). 448 | 449 | You can check the logs of the Github Actions workflow by selecting the latest workflow from the _Actions_ tab. Find the first step that has a broken icon next to it, and expand that step to see what went wrong in it. 450 | 451 | If running into trouble with the Azure deployment, check logs in the portal or use the following with the Azure CLI: 452 | 453 | ``` 454 | az webapp log tail --name $AZURE_WEBAPP_NAME --resource-group $AZURE_RESOURCE_GROUP 455 | ``` 456 | 457 | Update both variables to match your environment. 458 | 459 | 460 |
461 | 462 | ## Other Resources 463 | 464 | - [FastAPI](https://fastapi.tiangolo.com/) 465 | - [Codespaces](https://github.com/features/codespaces) 466 | - [Use Dev containers locally](https://github.com/Microsoft/vscode-remote-try-python) 467 | 468 | ### 🔎 Found an issue or have an idea for improvement? 469 | Help us make this template repository better by [letting us know and opening an issue!](/../../issues/new). 470 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 7 | feature request as a new Issue. 8 | 9 | For help and questions about using this project, please [file an issue](/../../issues/new) 10 | 11 | ## Microsoft Support Policy 12 | 13 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above. 14 | -------------------------------------------------------------------------------- /images/api-running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github-education-resources/codespaces-project-template-py/b1d138da684701ede36aa5948ec955ca7c700d0f/images/api-running.png -------------------------------------------------------------------------------- /images/fast-api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github-education-resources/codespaces-project-template-py/b1d138da684701ede36aa5948ec955ca7c700d0f/images/fast-api.png -------------------------------------------------------------------------------- /images/try-it-out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github-education-resources/codespaces-project-template-py/b1d138da684701ede36aa5948ec955ca7c700d0f/images/try-it-out.png -------------------------------------------------------------------------------- /images/video-banner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github-education-resources/codespaces-project-template-py/b1d138da684701ede36aa5948ec955ca7c700d0f/images/video-banner.gif -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi==0.109.1 2 | pydantic 3 | uvicorn[standard] -------------------------------------------------------------------------------- /translations/es/README.md: -------------------------------------------------------------------------------- 1 | [![Abre en GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=526682400) 2 | 3 | # Python HTTP API para utilizar con GitHub Codespaces 4 | 5 | _Ejecute una API de Python en este repositorio listo para usar en minutos_ 6 | 7 | Al abrir este repositorio de plantillas en Codespaces, puedes iniciar rápidamente con una aplicación web de Python que sirve a una API HTTP mediante [FastAPI](https://fastapi.tiangolo.com/) framework. 8 | Podrás centrarse en trabajar con el proyecto en lugar de la instalación y la configuración. 9 | 10 | 🤔 ¿Curioso? Mira el siguiente vídeo donde te explicamos todos los detalles: 11 | 12 | [![Video de Entorno de desarrollo Python con Codespaces](../../images/video-banner.gif)](https://youtu.be/_i9Pywj3rSg "Entorno de desarrollo Python con Codespaces") 13 | 14 | 15 |
16 | Aprende más sobre las APIs 17 | 18 | Una API (Interfaz de programación de aplicaciones) describe una forma en que dos equipos interactúan. 19 | Una API HTTP permite que un equipo conectado a Internet envíe una solicitud HTTP a otro equipo conectado a Internet y recibirá una respuesta. Por ejemplo, mi equipo podría enviar una solicitud a `http://a-weather-website-api.com/api/city=Los+Angeles` y recibirá datos como `{"high": 72, "low": 66}`. 20 | 21 | Las API HTTP a menudo proporcionan datos o funcionalidad que es exclusiva de un servicio, como la API de ejemplo para el sitio web meteorológico. Un sitio web meteorológico podría proporcionar endpoints de API adicionales para otras funciones relacionadas con el clima, como próximos pronósticos o datos históricos. Cualquier sitio web puede decidir ofrecer una API si cree que tiene una funcionalidad útil para compartir con otras computadoras. **En este proyecto, ejecutarás una API HTTP que genera un token aleatorio.** 22 | 23 | 24 |
25 | 26 | Esta plantilla también está lista para ser utilizada con [Codespaces](https://github.com/features/codespaces), un entorno para desarrolladores que se ejecuta en la nube con [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza). 27 | 28 |
29 | 🎥 Ve este video tutorial para obtener más información sobre Codespaces 30 | 31 | [![Codespaces Tutorial](https://img.youtube.com/vi/ozuDPmcC1io/0.jpg)](https://aka.ms/CodespacesVideoTutorial "Codespaces Tutorial") 32 |
33 | 34 | ## Para estudiantes y desarrolladores 35 | 36 | Al utilizar Codespaces, tu tendrás [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza) en la nube, utilizando un ["contenedor para desarrolladores"](https://containers.dev/). Como una versión local de [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza), la versión en la nube también te permite instalar extensiones y usar un terminal. 37 | 38 | También puedes configurar el contenedor de desarrolladores para que ejecutes un runtime específico y haga que arranque con tus extensiones favoritas. 39 | 40 | Estos son los archivos y carpetas clave que lo hacen posible: 41 | 42 | - [webapp/](./.webapp): El código de la API HTTP, creado con el marco FastAPI. 43 | - [.devcontainer/Dockerfile](./.devcontainer/Dockerfile): Archivo de configuración utilizado por Codespaces para determinar el sistema operativo y otros detalles. 44 | - [.devcontainer/devcontainer.json](./.devcontainer/devcontainer.json), un archivo de configuración utilizado por Codespaces para tanto modificar la configuración de [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza), como habilitar extensiones adicionales. 45 | 46 | ## 🧐 ¡Pruébalo! 47 | 48 | Prueba este repositorio de plantillas con Codespaces siguiendo estos pasos: 49 | 50 | 1. Crea un repositorio desde esta plantilla. Utiliza este link [crea un repositorio](https://github.com/microsoft/codespaces-project-template-py/generate). Puedes hacer que tu repositorio sea privado o público, esto depende de ti. 51 | 1. Ve a la página principal del repositorio recién creado. 52 | 1. Debajo del nombre del repositorio, usa el menú desplegable de _Code_ y, en la pestaña Codespaces, selecciona "Crear Codespace en main". 53 | ![Crea el Codespace](https://docs.github.com/assets/cb-138303/images/help/codespaces/new-codespace-button.png) 54 | 1. Espera mientras GitHub inicia el Codespace: 55 | ![Creando el Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_build.png) 56 | 57 | ### Inspeccionar el entorno de Codespaces 58 | 59 | Lo que tienes en este momento es un entorno preconfigurado donde todos los runtimes y bibliotecas que necesitas ya están instalados - esto es una experiencia de configuración cero. 60 | 61 | 62 | ## Ejecuta la App 63 | 64 | Esta aplicación de Python está utilizando FastAPI, un potente framework que auto documenta sus endpoints de API. La API solo tiene un extremo que genera una cadena pseudoaleatoria única que se puede usar como token. 65 | 66 | ![FastAPI Ejecutandose](../../images/api-running.png) 67 | 68 | 69 |
70 | Ejecuta FastAPI dentro del Codespace 71 | 72 | La API incluida en este repositorio de plantillas tiene un único extremo que genera un token. Pon lo en marcha siguiendo estos pasos: 73 | 74 | 1. Abre una terminal utilizando estos comandos (Ctrl-Shift-P o Cmd-Shift-P) y luego selecciona el comando "Abrir nueva terminal". 75 | 1. Ejecuta `uvicorn` en la consola para iniciar la aplicación de API: 76 | 77 | ```console 78 | uvicorn --host 0.0.0.0 webapp.main:app --reload 79 | ``` 80 | 81 | Deberías ver una salida similar a: 82 | 83 | ```output 84 | INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) 85 | INFO: Started reloader process [28720] 86 | INFO: Started server process [28722] 87 | INFO: Waiting for application startup. 88 | INFO: Application startup complete. 89 | ``` 90 | 91 | Aparecerá una ventana que dice que tu aplicación está disponible en el puerto 8000. Haz clic en el botón para abrirlo en el navegador. 92 | 93 | 1. Una vez que se cargue el sitio, haz clic en el botón _Try it Out_ o agregue `/docs` a la URL en la barra de direcciones. La documentación autogenerada de la API debería cargarse y tener este aspecto: 94 | 95 | ![Documentos de OpenAPI](../../images/fast-api.png) 96 | 97 | 1. Finalmente, intenta interactuar con la API enviando una solicitud utilizando la página autodocumentada. Haz clic en el botón _POST_ y luego en el botón _Try it Out_: 98 | 99 | ![Try a POST request](../../images/try-it-out.png) 100 | 101 | 🔒 ¿Ves el candado junto a la URL del sitio web en el navegador? Esto indica que el sitio web esta interactuando a través de una conexión HTTPS segura que cifra las respuestas HTTP. Es muy importante siempre que una API pueda recibir datos confidenciales o responder con datos confidenciales (como una contraseña). 102 | 103 |
104 | 105 | ## Personaliza tu Codespace 106 | 107 | Puedes cambiar tu entorno y el editor de texto para que la próxima vez que crees (o reconstruyas) el entorno, todo se establecerá automáticamente. Repasemos dos retos diferentes que es probable que desees hacer: 108 | 109 | 1. Cambiar la versión de Python instalada 110 | 1. Agrega o modifica una extensión de editor preinstalada 111 | 112 | 113 |
114 | 115 | ### Paso 1: Cambiar el entorno de Python 116 | 117 | Digamos que deseas cambiar la versión de Python que está instalada. Esto es algo que puedes controlar. 118 | 119 | Abre [.devcontainer/devcontainer.json](./.devcontainer/devcontainer.json) y reemplaza la siguiente sección: 120 | 121 | ```json 122 | "VARIANT": "3.8-bullseye" 123 | ``` 124 | 125 | con las siguientes instrucciones: 126 | 127 | ```json 128 | "VARIANT": "3.9-bullseye" 129 | ``` 130 | 131 | Este cambio le indica a Codespaces que ahora debe usar Python 3.9 en lugar de 3.8. 132 | 133 | Si realiza algún cambio de configuración en `devcontainer.json`, aparecerá un cuadro después de guardar. 134 | 135 | ![Recreando el Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_rebuild.png) 136 | 137 | Haz clic en reconstruir. Espera a que Codespace vuelva a generar el entorno de VS Code. 138 | 139 | ### Paso 2: Añade una extensión 140 | 141 | Tu entorno viene con extensiones preinstaladas. Puedes cambiar con qué extensiones comienza tu entorno de Codespaces, a continuación, te indicamos cómo: 142 | 143 | 1. Abre el archivo [.devcontainer/devcontainer.json](./.devcontainer/devcontainer.json) y busca el siguiente elemento JSON **extensions**: 144 | 145 | ```json 146 | "extensions": [ 147 | "ms-python.python", 148 | "ms-python.vscode-pylance" 149 | ] 150 | ``` 151 | 152 | 1. Agrega _"ms-python.black-formatter"_ a la lista de extensiones. Debería terminar pareciéndose a lo siguiente: 153 | 154 | ```json 155 | "extensions": [ 156 | "ms-python.python", 157 | "ms-python.vscode-pylance", 158 | "ms-python.black-formatter" 159 | ] 160 | ``` 161 | 162 | Esa cadena es el identificador único de [Black Formatter](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter&WT.mc_id=academic-77460-alfredodeza), una extensión popular para formatear el código Python de acuerdo con las mejores prácticas. Al añadir el identificador _"ms-python.black-formatter"_ a la lista, le permite a Codespaces saber que esta extensión debe estar preinstalada al iniciarse. 163 | 164 | Recuerda: Cuando cambies cualquier configuración en el json, aparecerá un cuadro después de guardar. 165 | 166 | ![Recreating Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_rebuild.png) 167 | 168 | Haz clic en reconstruir. Espera a que el espacio de código vuelva a generar el entorno de VS Code. 169 | 170 | Para encontrar el identificador único de una extensión: 171 | 172 | - Ingresa a la página web de la extensión, por ejemplo [https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter&WT.mc_id=academic-77460-alfredodeza) 173 | - Localiza el campo *Unique Identifier* bajo la sección **More info** en tu lado derecho. 174 | 175 |
176 | 177 | ## 🚀 Siguientes pasos 178 | 179 | ¡Lleva esta aplicación API al siguiente nivel e impleméntela en la nube! Para este desafío de aprendizaje, utilizaras una opción de implementación GRATUITA para Azure y GitHub Actions para la automatización. 180 | 181 | Antes de continuar, asegúrate de tener una cuenta de Azure lista. Selecciona cualquiera de las siguientes opciones 182 | 183 | - [Inicie sesión en su cuenta de Azure](https://azure.microsoft.com/en-US/?WT.mc_id=academic-77460-alfredodeza) 184 | - [Crear una cuenta de Azure para estudiantes (no se requiere tarjeta de crédito)](https://azure.microsoft.com/free/students/?WT.mc_id=academic-77460-alfredodeza) 185 | - [Creación de una nueva cuenta de Azure](https://azure.microsoft.com/en-US/?WT.mc_id=academic-77460-alfredodeza) 186 | 187 | Hay algunos pasos involucrados, ¡así que asegúrate de hacer todo bien! 188 | 189 |
190 | Crea un Azure App Service 191 | 192 | ¡Ahora, vas a configurar la implementación automática de la aplicación usando Azure más GitHub Actions! Sin embargo, primero debes configurar algunos servicios de Azure. 193 | 194 | 1. Abre [Azure Cloud Shell](https://shell.azure.com/?WT.mc_id=academic-77460-alfredodeza). 195 | 1. Usa el Bash Shell (¡no PowerShell!) para estos pasos. 196 | 1. Si dice "You have no storage mounted", seleccione una suscripción en su cuenta y haga clic en "Create storage". Cloud Shell utiliza ese recurso de almacenamiento para almacenar los datos generados durante las sesiones de shell. 197 | 198 | 1. Crea un *Resource Group* que agrupe los diferentes recursos de Azure usados para la aplicación: 199 | 200 | ``` 201 | az group create --name demo-fastapi --location "East US" 202 | ``` 203 | 1. Veras una respuesta JSON con detalles sobre el recurso recién creado, para este comando y todos los comandos que siguen. 204 | 1. Crea el *App Service Plan* **GRATIS**: 205 | ``` 206 | az appservice plan create --name "demo-fastapi" --resource-group demo-fastapi --is-linux --sku FREE 207 | ``` 208 | 1. Crea un identificador aleatorio para un nombre de aplicación web único: 209 | ``` 210 | let "randomIdentifier=$RANDOM*$RANDOM" 211 | ``` 212 | 1. Crea el *Web App Service* con un contenedor placeholder utilizando la variable 'randomIdentifier' de antes: 213 | ``` 214 | az webapp create --name "demo-fastapi-$randomIdentifier" --resource-group demo-fastapi --plan demo-fastapi --runtime "PYTHON:3.9" 215 | ``` 216 | 1. Dirígete al Portal de Azure [App Services list](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites) y confirma que el servicio recién creado aparece en la lista. 217 |
218 | 219 | 220 |
221 | Creación de un Azure Service Principal 222 | 223 | A continuación, crea un Azure Service Principal, este es un tipo especial de cuenta que tiene los permisos necesarios para autenticarse desde GitHub a Azure: 224 | 225 | 1. Busca el ID de tu suscripción de Azure [en el Portal de Azure](https://portal.azure.com/#view/Microsoft_Azure_Billing/SubscriptionsBlade?WT.mc_id=academic-77460-alfredodeza) o [siguiendo esta guía](https://learn.microsoft.com/azure/azure-portal/get-subscription-tenant-id?WT.mc_id=academic-77460-alfredodeza). 226 | 1. Crea un Service Principal con un rol de "contributor" que permita realizar cambios en cualquier recurso de esa suscripción. Reemplace $AZURE_SUBSCRIPTION_ID por el ID que encontraste en el paso 1 y ejecuta este comando: 227 | 228 | 229 | ``` 230 | az ad sp create-for-rbac --name "CICD" --role contributor --scopes /subscriptions/$AZURE_SUBSCRIPTION_ID --sdk-auth 231 | ``` 232 | 233 | 1. Captura la salida y agrégala como un [Secreto del repositorio de Github](/../../settings/secrets/actions/new) con el nombre `AZURE_CREDENTIALS`. 234 | 235 |
236 | 237 |
238 | 239 | Configura GitHub Actions 240 | 241 | Ahora que ha creado todos los recursos de Azure, debes actualizar el archivo del workflow de GitHub Action con el nombre de su aplicación web. 242 | 243 | 1. Busca el nombre de tu aplicación. Debería tener un aspecto similar a `demo-fastapi-97709018` pero con un número aleatorio diferente al final, y puedes encontrarlo en Azure Portal o con los comandos de Cloud Shell. 244 | 2. Abre el archivo [.github/workflows/web_app.yml](/.. /.. /edit/main/.github/workflows/web_app.yml) y actualiza el valor de `AZURE_WEBAPP_NAME` al nombre de tu aplicación. 245 | 246 |
247 | 248 |
249 | 🏃 ¡Sube tu app! 250 | 251 | Antes de continuar, verifica lo siguiente: 252 | 253 | 1. Has creado un Azure Service Principal y la has guardado un [repositorio secreto](/../../settings/secrets/) como `AZURE_CREDENTIALS`. 254 | 1. Has creado un [App Service](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites) con un nombre válido y el sitio ya está disponible con el contenido estático predeterminado. 255 | 256 | Para implementar: 257 | 258 | 1. Ve a [acciones del repositorio](/../../actions/workflows/web_app.yml)y haz clic en _Run workflow_ y luego en el botón verde para ejecutarlo. 259 | 260 | **La implementación puede tardar un par de minutos**. Asegúrate de ver los registros en Azure Cloud Shell para comprobar el progreso: 261 | 262 | ``` 263 | az webapp log tail --name $AZURE_WEBAPP_NAME --resource-group $AZURE_RESOURCE_GROUP 264 | ``` 265 | 266 | ### Eliminando recursos cuando se complete 267 | 268 | Después de la implementación, asegúrate de limpiar los recursos eliminando el grupo de recursos. Puedes hacerlo en Azure Cloud Shell haciendo referencia al nombre del grupo que creó inicialmente (`demo-fastapi` en los ejemplos): 269 | 270 | ``` 271 | az group delete --name demo-fastapi 272 | ``` 273 | 274 | ### Solución de problemas de implementación 275 | 276 | Al implementar, es posible que encuentres errores o problemas, ya sea en la parte de automatización (GitHub Actions) o en el momento de implementarlo (Azure Web Apps). 277 | 278 | Si tienes problemas, comprueba los registros en el portal o usa lo siguiente con la CLI de Azure: 279 | 280 | ``` 281 | az webapp log tail --name $AZURE_WEBAPP_NAME --resource-group $AZURE_RESOURCE_GROUP 282 | ``` 283 | 284 | Actualice ambas variables para que coincidan con tu entorno. 285 | 286 |
287 | 288 | ## Otros recursos 289 | 290 | - [FastAPI](https://fastapi.tiangolo.com/) 291 | - [Codespaces](https://github.com/features/codespaces) 292 | - [Usar contenedores de desarrollo localmente](https://github.com/Microsoft/vscode-remote-try-python) 293 | 294 | ### 🔎 ¿Has encontrado un problema o tienes una idea para mejorar? 295 | Ayúdanos a mejorar este repositorio de plantillas al [¡abrir un issue!](/../../issues/new). 296 | -------------------------------------------------------------------------------- /translations/pt-BR/README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Abrir no GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=526682400) 3 | 4 | # API HTTP Python com GitHub Codespaces e Copilot 5 | 6 | _Execute uma API Python neste repositório pronto para uso em minutos_ 7 | 8 | Ao abrir este modelo de repositório no Codespaces, você poderá, rapidamente, desenvolver um aplicativo da web Python que serve uma API HTTP. Você poderá se concentrar no trabalho com o projeto em vez de configuração e instalação. Em seguida, você fará alterações no código usando o [GitHub Copilot](https://copilot.github.com/), uma nova ferramenta de conclusão de código alimentada por IA que ajuda você a escrever código mais rapidamente. 9 | 10 | ## 🚀 Início rápido 11 | 1. [Siga as etapas](#--try-it-out) para configurar seu Codespace e executar o aplicativo. 12 | 2. [Faça alterações no aplicativo](#faça-alterações-usando-o-Copilot) usando o [GitHub Copilot](https://copilot.github.com/) para modificar o código. 13 | 3. Aceite o desafio e publique seu aplicativo no Azure. 14 | 15 | 🤔 Curioso? Assista ao seguinte vídeo onde explicamos todos os detalhes: 16 | 17 | [![Ambiente de desenvolvimento Python com Codespaces](https://img.youtube.com/vi/_i9Pywj3rSg/0.jpg)](https://youtu.be/_i9Pywj3rSg "Ambiente de desenvolvimento Python com Codespaces") 18 | 19 |
20 | Saiba mais sobre APIs 21 | 22 | Uma API (Interface de Programação de Aplicativos) descreve uma maneira para dois computadores interagirem. Uma API HTTP permite que um computador conectado à Internet envie uma solicitação HTTP para outro computador conectado à Internet e receba uma resposta. Por exemplo, meu computador pode enviar uma solicitação para `http://um-site-de-previsao-do-tempo.com/api/cidade=Los+Angeles` e receber dados de volta, como `{"alta": 72, "baixa": 66}`. 23 | 24 | APIs HTTP frequentemente fornecem dados ou funcionalidades exclusivas de um serviço, como o exemplo da API do site de previsão do tempo. Um site de previsão do tempo pode fornecer endpoints de API adicionais para outras funcionalidades relacionadas ao clima, como previsões futuras ou dados históricos. Qualquer site pode optar por oferecer uma API se acreditar que possui funcionalidades úteis para compartilhar com outros computadores. Neste projeto, você executará uma API HTTP que gera um token aleatório. 25 |
26 | 27 | Este modelo também está pronto para ser usado com o [Codespaces](https://github.com/features/codespaces), um ambiente de desenvolvimento executado na nuvem com o [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza). 28 | 29 |
30 | 🎥 Assista ao tutorial em vídeo para aprender mais sobre Codespaces 31 | 32 | [![Tutorial do Codespaces](https://img.youtube.com/vi/ozuDPmcC1io/0.jpg)](https://aka.ms/CodespacesVideoTutorial "Tutorial do Codespaces") 33 |
34 | 35 | ## Para estudantes e desenvolvedores 36 | 37 | Usando o Codespaces, você obtém o [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza) na nuvem, usando um ["container de desenvolvimento"](https://containers.dev/). Assim como a versão local do [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza), a versão na nuvem também permite que você instale extensões e use um terminal. 38 | 39 | Você também pode configurar o seu container de desenvolvimento para executar um tempo de execução específico e inicializá-lo com as suas extensões favoritas. 40 | 41 | Aqui estão os arquivos e pastas principais que tornam isso possível: 42 | 43 | - [webapp/](/webapp): O código da API HTTP, construído com o framework FastAPI. 44 | - [.devcontainer/Dockerfile](/.devcontainer/Dockerfile): Arquivo de configuração usado pelo Codespaces para determinar o sistema operacional e outros detalhes. 45 | - [.devcontainer/devcontainer.json](/.devcontainer/devcontainer.json): Um arquivo de configuração usado pelo Codespaces para configurar as configurações do [Visual Studio Code](https://visualstudio.microsoft.com/?WT.mc_id=academic-77460-alfredodeza), como a ativação de extensões adicionais. 46 | 47 | ## 🧐 Usando o Codespaces 48 | 49 | Experimente este modelo de repositório usando o Codespaces seguindo estes passos: 50 | 51 | 1. Crie um repositório a partir deste modelo. Use este [link de criação do repositório](https://github.com/microsoft/codespaces-project-template-py/generate). Você pode tornar o repositório privado ou público, conforme sua preferência. 52 | 2. Antes de criar o codespace, habilite o GitHub Copilot para a sua conta! Se não estiver habilitado, dê uma olhada em [Faça alterações usando o Copilot](#make-changes-using-copilot). 53 | 3. Acesse a página principal do repositório recém-criado. 54 | 4. Abaixo do nome do repositório, use o menu suspenso Code e, na guia Codespaces, selecione "Criar Codespace em main". 55 | ![Criar Codespace](https://docs.github.com/assets/cb-138303/images/help/codespaces/new-codespace-button.png) 56 | 5. Aguarde enquanto o GitHub inicializa o codespace: 57 | ![Criando Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_build.png) 58 | 59 | ### Inspecionando o ambiente do Codespaces 60 | 61 | Neste ponto, você tem um ambiente pré-configurado no qual todos os tempos de execução e bibliotecas de que você precisa já estão instalados - uma experiência de configuração zero. 62 | 63 | ## Executando o aplicativo 64 | 65 | Este aplicativo Python está usando o FastAPI, um poderoso framework da web que documenta automaticamente seus endpoints de API. A API tem apenas um endpoint que gera uma sequência pseudoaleatória única que pode ser usada como um token. 66 | 67 | 68 | ![Executando o FastAPI](https://github.com/Corttezz/codespaces-project-template-py/assets/106662629/87b84e79-51c7-4d73-9c21-ff6403e64e35) 69 | 70 |
71 | O que é um ponto de extremidade? 72 | 73 | Um ponto de extremidade é uma URL estável e durável que representa um recurso específico em uma API. Ele fornece uma maneira de interagir com esse recurso, enviar solicitações e receber respostas. Em termos simples, um ponto de extremidade é um "ponto de entrada" para uma API. 74 | 75 | Características de um ponto de extremidade: 76 | 77 | - **URL estável e durável**: Um ponto de extremidade é acessado por meio de uma URL específica, que permanece consistente ao longo do tempo. Por exemplo, uma URL estável e durável (como endpoint-name.region.inference.ml.azure.com). 78 | 79 | - **Mecanismo de autenticação e autorização**: Para garantir a segurança e controlar o acesso ao recurso, os pontos de extremidade podem exigir autenticação e autorização. Isso pode envolver o uso de tokens, chaves de API ou outros métodos de autenticação. 80 | 81 | - **Implantação e roteamento**: Um ponto de extremidade pode ter várias implantações, que são responsáveis por executar a lógica do recurso e fornecer as respostas adequadas. Essas implantações podem estar localizadas em servidores diferentes, dependendo dos requisitos de recursos e escalabilidade. O mecanismo de roteamento direciona as solicitações recebidas para as implantações corretas. 82 | 83 | Portanto, um ponto de extremidade é um componente fundamental em uma API. Ele representa um recurso específico e define a maneira como os clientes podem interagir com ele, fornecendo uma URL estável, um mecanismo de autenticação e autorização, e encaminhando as solicitações para as implantações corretas. 84 | 85 |
86 |
87 | Executando o FastAPI dentro do Codespace 88 | 89 | A API incluída neste modelo de repositório possui um único ponto de extremidade (endpoint) que gera um token. Coloque-a em funcionamento seguindo as etapas a seguir: 90 | 91 | 1. Abra um terminal, abrindo o painel de comandos (Ctrl-Shift-P ou Cmd-Shift-P) e selecione o comando "Abrir novo terminal". 92 | 2. Execute `uvicorn` no console para iniciar o aplicativo da API: 93 | 94 | ```console 95 | uvicorn --host 0.0.0.0 webapp.main:app --reload 96 | ``` 97 | 98 | Você verá uma saída semelhante a esta: 99 | 100 | ```output 101 | INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) 102 | INFO: Started reloader process [28720] 103 | INFO: Started server process [28722] 104 | INFO: Waiting for application startup. 105 | INFO: Application startup complete. 106 | ``` 107 | 108 | Você verá uma janela pop-up informando que o seu aplicativo está disponível na porta 8000. Clique no botão para abri-lo no navegador. 109 | 3. Assim que o site for carregado, clique no botão _Try it Out_ ou adicione `/docs` à URL na barra de endereços. A documentação da API gerada automaticamente deve ser carregada e parecer assim: 110 | 111 | ![Documentação OpenAPI](https://github.com/Corttezz/codespaces-project-template-py/assets/106662629/ca251db8-30dc-46bb-b91e-4012b18bafaf) 112 | 113 | 114 | 4. Por fim, tente interagir com a API enviando uma solicitação usando a página auto documentada. Clique no botão _POST_ e depois no botão _Try it Out_: 115 | 116 | ![Experimente uma solicitação POST](https://github.com/Corttezz/codespaces-project-template-py/assets/106662629/730e7edc-9669-4c16-9819-466a8b29669b) 117 | 118 | 119 | 🔒 Você vê o cadeado ao lado da URL do site no navegador? Isso indica que o site está sendo servido por meio de uma conexão HTTPS segura, que criptografa as respostas HTTP. Isso é muito importante sempre que uma API pode receber dados sensíveis ou responder com dados sensíveis (como uma senha). 120 | 121 |
122 | 123 | ## Personalize o Codespace 124 | 125 | Você pode alterar o seu ambiente e o editor de texto para que, da próxima vez que você criar (ou reconstruir) o ambiente, tudo seja configurado automaticamente. Vamos abordar dois desafios diferentes e que você provavelmente deseja fazer: 126 | 127 | 1. Alterar a versão do Python instalada 128 | 2. Adicionar ou modificar uma extensão do editor pré-instalada 129 | 130 |
131 | 132 | ### Passo 1: Alterar a versão do Python instalada 133 | 134 | Digamos que você queira alterar a versão do Python que está instalada. Isso é algo que você pode controlar. 135 | 136 | Abra o arquivo [.devcontainer/devcontainer.json](/.devcontainer/devcontainer.json) e substitua a seguinte seção: 137 | 138 | ```json 139 | "VARIANT": "3.8-bullseye" 140 | ``` 141 | 142 | pela seguinte instrução: 143 | 144 | ```json 145 | "VARIANT": "3.9-bullseye" 146 | ``` 147 | 148 | Essa alteração instrui o Codespaces a usar o Python 3.9 em vez do 3.8. 149 | 150 | Se você fizer qualquer alteração de configuração no `devcontainer.json`, uma caixa aparecerá após salvar. 151 | 152 | ![Recriando Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_rebuild.png) 153 | 154 | Clique em Rebuild (em português, "Reconstruir"). Aguarde o seu Codespace reconstruir o ambiente do VS Code. 155 | 156 | ### Passo 2: Adicionar ou modificar uma extensão do editor pré-instalada 157 | 158 | Seu ambiente vem com extensões pré-instaladas. Você pode alterar quais extensões o ambiente do Codespaces inicia. Veja como fazer: 159 | 160 | 1. Abra o arquivo [.devcontainer/devcontainer.json](/.devcontainer/devcontainer.json) e localize o seguinte elemento JSON **extensions**: 161 | 162 | ```json 163 | "extensions": [ 164 | "ms-python.python", 165 | "ms-python.vscode-pylance" 166 | ] 167 | ``` 168 | 169 | 2. Adicione _"ms-python.black-formatter"_ à lista de extensões. Deve ficar assim: 170 | 171 | ```json 172 | "extensions": [ 173 | "ms-python.python", 174 | "ms-python.vscode-pylance", 175 | "ms-python.black-formatter" 176 | ] 177 | ``` 178 | 179 | Essa sequência é o identificador único do [Black Formatter](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter&WT.mc_id=academic-77460-alfredodeza), uma extensão popular para formatar o código Python de acordo com as melhores práticas. Adicionar o identificador _"ms-python.black-formatter"_ à lista informa ao Codespaces que essa extensão deve ser pré-instalada ao iniciar. 180 | 181 | Lembrete: Quando você alterar qualquer configuração no arquivo JSON, uma caixa aparecerá após salvar. 182 | 183 | ![Recriando Codespace](https://github.com/microsoft/codespaces-teaching-template-py/raw/main/images/Codespace_rebuild.png) 184 | 185 | Clique em Rebuild (em português, "Reconstruir"). Aguarde o seu Codespace reconstruir o ambiente do VS Code. 186 | 187 | Para encontrar o identificador único de uma extensão: 188 | 189 | - Acesse a página da extensão, por exemplo [https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter&WT.mc_id=academic-77460-alfredodeza) 190 | - Localize o campo *Identificador Único* na seção **Mais informações** no lado direito. 191 | 192 | 193 | 194 |
195 | 196 | ## Faça alterações usando o Copilot 197 | 198 | Vamos seguir algumas etapas para fazer alterações no código usando o Copilot. Essa é uma ótima maneira de aprender a usar o Copilot e obter sugestões úteis para um desenvolvimento mais rápido. Observe que essas são soluções sugeridas, e aconselhamos que você as revise para garantir que sejam aplicáveis ao seu código. 199 | 200 | Este repositório do Codespaces já tem a extensão Copilot habilitada. Verifique se sua conta tem acesso a ela. Se você não tiver acesso, pode [solicitar](https://github.com/login?return_to=%2fgithub-copilot%2fsignup) e, em seguida, instale a extensão [aqui](https://aka.ms/get-copilot). Se você for estudante, pode obter o Copilot gratuitamente [seguindo estas instruções](https://techcommunity.microsoft.com/t5/desenvolvedores-br/como-obter-github-copilot-gratuito-para-estudantes-e-professores/ba-p/3828780?WT.mc_id=academic-97170-cyzanon). 201 | 202 | Para garantir que o Copilot esteja funcionando corretamente, siga estas etapas: 203 | 204 | 1. Verifique se o Copilot está ativado navegando na guia de extensões em seu Codespace e verificando o status. 205 | 2. Se o status estiver inativo, reconstrua o Codespace e habilite a extensão para garantir que ela seja ativada. 206 | 207 | 🤔 Curioso? Assista ao seguinte vídeo em que explicamos todos os detalhes: 208 | 209 | [![Assisted AI Coding with GitHub Copilot](https://img.youtube.com/vi/9c7SSHbzD80/0.jpg)](https://youtu.be/9c7SSHbzD80 "Assisted AI Coding with GitHub Copilot") 210 | 211 |
212 | Utilizando o Copilot 213 | 214 | ### Passo 1: Alterar o HTML para torná-lo interativo 215 | 216 | Abra o arquivo [index.html](./webapp/static/index.html) e exclua a seguinte linha: 217 | 218 | ```html 219 | 220 | ``` 221 | 222 | Agora, adicione um comentário para que o Copilot possa gerar código para você: 223 | 224 | ```html 225 | 226 | ``` 227 | 228 | Isso deve ser suficiente para o Copilot gerar código para você depois de pressionar `Enter` (ou `Return`). 229 | Se não for o caso, use `Ctrl+Enter` para obter várias sugestões e escolha aquela que se encaixa melhor no código abaixo. 230 | Lembre-se de que é possível que o Copilot não gere o trecho exato! Nesse caso, digite ou substitua a sugestão para o código abaixo. 231 | O código gerado deve ser semelhante a este: 232 | 233 | ```html 234 |
235 | 236 | 237 |
238 |
239 | 259 | ``` 260 | 261 | Execute a aplicação e verifique se o formulário aparece. 262 | 263 | ### Passo 2: Atualizar o HTML para corrigir um bug 264 | 265 | O código gerado introduziu alguns problemas. Primeiro, o botão não está funcionando. Segundo, o formulário não está usando a chave JSON correta ao enviar o texto para o endpoint da API. Vamos corrigir isso. 266 | 267 | Altere o corpo da solicitação para usar a chave `length` em vez de `text`: 268 | 269 | ```javascript 270 | body: JSON.stringify({ length: input }) 271 | ``` 272 | 273 | Agora, vamos alterar o `innerHTML` para usar a chave `token` em vez de `result`: 274 | 275 | ```javascript 276 | result.innerHTML = data.token; 277 | ``` 278 | 279 | Execute a aplicação e verifique se o formulário está funcionando agora. 280 | 281 | ### Passo 3: Alterar o formulário para usar um menu suspenso 282 | 283 | Atualmente, o formulário aceita qualquer texto como entrada. Vamos alterá-lo para usar um menu suspenso. Adicione um comentário para que o Copilot possa gerar código para você. Exclua a seguinte linha: 284 | 285 | ```html 286 | 287 | ``` 288 | 289 | E adicione o seguinte comentário para que o Copilot possa gerar código para você: 290 | 291 | ```html 292 | 293 | ``` 294 | 295 | O código gerado agora deve ficar assim: 296 | 297 | ```html 298 | 304 | ``` 305 | 306 | Execute a aplicação novamente para verificar se o menu suspenso está funcionando corretamente. 307 | 308 | ### Passo 4: Adicionar um novo ponto de extremidade (endpoint) à API 309 | 310 | Agora vamos adicionar uma nova funcionalidade à API. Adicione um novo ponto de extremidade (endpoint) à API que aceite um texto e retorne uma lista de tokens. Adicione o seguinte comentário para que o Copilot possa gerar um modelo Pydantic para você: 311 | 312 | ```python 313 | # Crie um modelo Pydantic que aceita um corpo JSON com um único campo chamado "text", que é uma string 314 | ``` 315 | 316 | O modelo gerado deve ficar assim: 317 | 318 | ```python 319 | class Text(BaseModel): 320 | text: str 321 | ``` 322 | 323 | Em seguida, adicione o seguinte comentário para que o Copilot possa adicionar um novo endpoint: 324 | 325 | ```python 326 | # Crie um endpoint FastAPI que aceita uma solicitação POST com um corpo JSON contendo um único campo chamado "text" e retorna um checksum do texto 327 | ``` 328 | 329 | O código gerado deve ficar assim: 330 | 331 | ```python 332 | @app.post('/checksum') 333 | def checksum(body: Text): 334 | """ 335 | Gere um checksum do texto. Exemplo de corpo de solicitação POST: 336 | 337 | { 338 | "text": "Olá mundo!" 339 | } 340 | """ 341 | checksum = base64.b64encode(os.urandom(64))[:20].decode('utf-8') 342 | return {'checksum': checksum} 343 | ``` 344 | 345 | O código gerado fará com que a aplicação falhe. Isso ocorre porque os módulos `base64` e `os` não estão sendo importados. Adicione as seguintes linhas no início do arquivo: 346 | 347 | ```python 348 | import base64 349 | import os 350 | ``` 351 | 352 | Por fim, verifique se o novo ponto de extremidade (endpoint) está funcionando acessando a página `/docs` e testando o novo endpoint. 353 | 354 | Parabéns! Você usou o Copilot não apenas para gerar código, mas também para fazer isso de forma interativa e divertida. Agora você pode usar o Copilot para gerar código em qualquer um de seus projetos, incluindo escrever documentação, gerar modelos e muito mais! Até mesmo partes deste README foram geradas usando sugestões do Copilot 🧐 355 | 356 |
357 | 358 | ## 🚀 Próximos passos 359 | 360 | Leve essa aplicação da API para o próximo nível e faça a sua publicação na nuvem! Para este desafio de aprendizado, você usará uma opção para publicar GRATUITAMENTE no Azure e o GitHub Actions para a automação. 361 | 362 | Antes de continuar, certifique-se de ter uma conta no Azure pronta. Selecione uma das opções a seguir: 363 | 364 | - [Faça login na sua conta do Azure](https://azure.microsoft.com/en-US/?WT.mc_id=academic-77460-alfredodeza) 365 | - [Crie uma conta no Azure For Students (sem necessidade de cartão de crédito)](https://azure.microsoft.com/free/students/?WT.mc_id=academic-77460-alfredodeza) 366 | - [Crie uma nova conta no Azure](https://azure.microsoft.com/en-US/?WT.mc_id=academic-77460-alfredodeza) 367 | 368 | Há algumas etapas envolvidas, então certifique-se de fazer tudo corretamente! 369 | 370 |
371 | Criar um Serviço de Aplicativo do Azure 372 | 373 | Agora você irá configurar a publicação automática da aplicação usando o Azure e o GitHub Actions! No entanto, primeiro você precisa configurar alguns serviços do Azure. 374 | 375 | 1. Abra o [Azure Cloud Shell](https://shell.azure.com/?WT.mc_id=academic-77460-alfredodeza). 376 | 2. Use o Bash Shell (não o PowerShell!) para executar estas etapas. 377 | 3. Se aparecer a mensagem "You have no storage mounted", selecione uma assinatura em sua conta e clique em "Create storage". O Cloud Shell usará esse recurso de armazenamento para armazenar os dados gerados durante suas sessões no shell. 378 | 4. Crie um *Grupo de Recursos* que agrupará os diferentes recursos do Azure usados pela aplicação: 379 | ``` 380 | az group create --name demo-fastapi --location "East US" 381 | ``` 382 | 5. Você verá uma resposta em JSON com detalhes sobre o novo recurso criado, para este comando e todos os comandos que seguem. 383 | 6. Crie o *Plano de Serviço de Aplicativo* **GRATUITO**: 384 | ``` 385 | az appservice plan create --name "demo-fastapi" --resource-group demo-fastapi --is-linux --sku FREE 386 | ``` 387 | 7. Crie um identificador aleatório para um nome exclusivo do web app: 388 | ``` 389 | let "randomIdentifier=$RANDOM*$RANDOM" 390 | ``` 391 | 8. Crie o *Serviço de Aplicativo da Web* com um contêiner reservado usando a variável `randomIdentifier` criada anteriormente: 392 | ``` 393 | az webapp create --name "demo-fastapi-$randomIdentifier" --resource-group demo-fastapi --plan demo-fastapi --runtime "PYTHON:3.9" 394 | ``` 395 | 9. Acesse a lista de [Serviços de Aplicativos](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites) no portal do Azure e verifique se o serviço recém-criado está listado. 396 | 397 |
398 | 399 | 400 |
401 | Criando um Azure Service Principal 402 | 403 | A seguir, crie um Azure Service Principal, que é um tipo especial de conta que possui as permissões necessárias para autenticação do GitHub no Azure: 404 | 405 | 1. Encontre o ID de sua assinatura do Azure 406 | 407 | [no portal do Azure](https://portal.azure.com/#view/Microsoft_Azure_Billing/SubscriptionsBlade?WT.mc_id=academic-77460-alfredodeza) ou [seguindo este guia](https://learn.microsoft.com/azure/azure-portal/get-subscription-tenant-id?WT.mc_id=academic-77460-alfredodeza). 408 | 2. Crie um Azure Service Principal com a função "contributor" que está autorizada a fazer alterações em todos os recursos dessa assinatura. Substitua $AZURE_SUBSCRIPTION_ID pelo ID encontrado no passo 1 e execute o seguinte comando: 409 | 410 | ``` 411 | az ad sp create-for-rbac --sdk-auth --name "github-deployer" --role contributor --scopes /subscriptions/$AZURE_SUBSCRIPTION_ID 412 | ``` 413 | 414 | 3. Copie a saída e adicione-a como um [segredo do repositório do GitHub](/../../settings/secrets/actions/new) com o nome `AZURE_CREDENTIALS`. (_Se esse link não funcionar, certifique-se de que você está lendo isso em sua própria cópia do repositório, não no modelo original._) 415 | 416 |
417 | 418 |
419 | 420 | Configurar o GitHub Actions 421 | 422 | Agora que você criou todos os recursos do Azure, precisa atualizar o arquivo de fluxo de trabalho do GitHub Actions com o nome do seu web app. 423 | 424 | 1. Encontre o nome do seu aplicativo. Deve ser algo como `demo-fastapi-97709018`, mas com um número aleatório diferente no final, e você pode encontrá-lo no portal do Azure ou nos comandos do Cloud Shell. 425 | 2. Abra o arquivo [.github/workflows/web_app.yml](/../../edit/main/.github/workflows/web_app.yml) e atualize o valor de `AZURE_WEBAPP_NAME` com o nome do seu aplicativo. 426 | 3. Faça o commit e envie as alterações para o repositório do GitHub: 427 | 428 | ``` 429 | git add .github/workflows/web_app.yml 430 | git commit -m "Atualizando arquivo de fluxo de trabalho" 431 | git push 432 | ``` 433 | 434 |
435 | 436 |
437 | 🏃 Implante a sua aplicação! 438 | 439 | Antes de continuar, verifique o seguinte: 440 | 441 | 1. Você criou um Azure Service Principal e o salvou como um [segredo do repositório](/../../settings/secrets/) chamado `AZURE_CREDENTIALS`. 442 | 2. Você criou um [Serviço de Aplicativo](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites) com um nome válido e o site já está disponível com o conteúdo estático padrão. 443 | 444 | Para implantar: 445 | 446 | 1. Acesse [Actions do repositório](/../../actions/workflows/web_app.yml). (_Se esse link não abrir o fluxo de trabalho "Build and deploy Python app", certifique-se de que você está lendo isso em sua própria cópia do repositório._) 447 | 2. Selecione _Run workflow_ e clique no botão verde dentro da janela pop-up para executar o fluxo de trabalho. 448 | 449 | **A implantação pode levar alguns minutos**. Certifique-se de transmitir os logs no Azure Cloud Shell para verificar o progresso: 450 | 451 | ``` 452 | az webapp log tail --name $AZURE_WEBAPP_NAME --resource-group $AZURE_RESOURCE_GROUP 453 | ``` 454 | 455 | 3. Após a conclusão da implantação, acesse seu site em uma URL 456 | 457 | como `http://demo-fastapi-97709018.azurewebsites.net/`, em que o número aleatório é o seu número aleatório exclusivo. Você pode encontrar a URL do site no portal do Azure ou nos logs de implantação, caso tenha esquecido o número. 458 | 4. 🎉 Celebre um implantação bem-sucedida! Agora você tem uma URL que pode compartilhar com colegas, amigos e familiares. 459 | 460 | ### Removendo os recursos quando concluído 461 | 462 | Provavelmente você não deseja manter esse site específico em execução na nuvem para sempre, então você deve limpar seus recursos do Azure excluindo o grupo de recursos. Você pode fazer isso no Azure Cloud Shell referenciando o nome do grupo que você criou inicialmente (`demo-fastapi` nos exemplos): 463 | 464 | ``` 465 | az group delete --name demo-fastapi 466 | ``` 467 | 468 | ### Solução de problemas de implantação 469 | 470 | Ao fazer a implantação, você pode encontrar erros ou problemas, seja na automação (GitHub Actions) ou no destino de implantação (Azure Web Apps). 471 | 472 | Você pode verificar os logs do fluxo de trabalho do GitHub Actions selecionando o fluxo de trabalho mais recente na guia _Actions_. Localize a primeira etapa que tem um ícone quebrado ao lado e expanda essa etapa para ver o que deu errado. 473 | 474 | Se você tiver problemas com a implantação no Azure, verifique os logs no portal ou use o seguinte comando com o Azure CLI: 475 | 476 | ``` 477 | az webapp log tail --name $AZURE_WEBAPP_NAME --resource-group $AZURE_RESOURCE_GROUP 478 | ``` 479 | 480 | Atualize ambas as variáveis para corresponder ao seu ambiente. 481 | 482 |
483 | 484 | ## Outros Recursos 485 | 486 | - [FastAPI](https://fastapi.tiangolo.com/) 487 | - [Codespaces](https://github.com/features/codespaces) 488 | - [Use containers de desenvolvimento localmente](https://github.com/Microsoft/vscode-remote-try-python) 489 | 490 | ### 🔎 Encontrou algum problema ou tem uma ideia de melhoria? 491 | Ajude-nos a melhorar este repositório de modelo [nos informando e abrindo uma issue!](https://github.com/education/codespaces-project-template-py/issues/new). 492 | -------------------------------------------------------------------------------- /webapp/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import base64 3 | from typing import Union 4 | from os.path import dirname, abspath, join 5 | from fastapi import FastAPI 6 | from fastapi.responses import FileResponse 7 | from fastapi.staticfiles import StaticFiles 8 | from pydantic import BaseModel 9 | 10 | current_dir = dirname(abspath(__file__)) 11 | static_path = join(current_dir, "static") 12 | 13 | app = FastAPI() 14 | app.mount("/ui", StaticFiles(directory=static_path), name="ui") 15 | 16 | 17 | class Body(BaseModel): 18 | length: Union[int, None] = 20 19 | 20 | 21 | @app.get('/') 22 | def root(): 23 | html_path = join(static_path, "index.html") 24 | return FileResponse(html_path) 25 | 26 | 27 | @app.post('/generate') 28 | def generate(body: Body): 29 | """ 30 | Generate a pseudo-random token ID of twenty characters by default. Example POST request body: 31 | 32 | { 33 | "length": 20 34 | } 35 | """ 36 | string = base64.b64encode(os.urandom(64))[:body.length].decode('utf-8') 37 | return {'token': string} -------------------------------------------------------------------------------- /webapp/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Codespaces & FastAPI 7 | 8 | 9 | 25 | 26 | 27 |
28 |
29 |
30 |
31 |

32 | 🚀 33 |

34 |
35 |

Containerized Python API 36 |

37 |

This is a containerized application that exposes a JSON API using FastAPI with Azure!

38 |

Use the buttons below to make use of the interactive (OpenAPI) documentation for trying out the API dynamically. 39 | or browse the project source. 40 |

41 | 42 | 43 |
44 |
45 |
46 |
47 |
48 | 49 | 50 | --------------------------------------------------------------------------------