One place for hosting & domains

      September 2020

      How To Convert Integers to Floats in Python 3


      Python’s float() method will convert integers to floats. To use this function, add an integer inside of the parentheses:

      float(57)
      

      In this case, 57 will be converted to 57.0.

      You can also use this with a variable. Let’s declare f as equal to 57, and then print out the new float:

      f = 57
      print(float(f))
      

      Output

      57.0

      By using the float() function, we’ve converted an integer to a float.

      If you’d like to learn more about converting different data types in Python, check out our How To Convert Data Types in Python 3 tutorial. Read more about Python in our How To Code in Python 3 series.



      Source link

      How To Build a Photo Search App with React Using the Unsplash API


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      According to the StackOverflow 2020 Developer Survey, React is one of the most popular JavaScript frameworks, and there are many reasons for this, like efficiently changing web app views with the Virtual DOM, using reusable, composable, and stateful components to increase scalability, and more. Beginner React developers often need experience putting their knowledge to use in real-life applications. This tutorial will give you that experience by showing you how to use React Hooks, use useState(), and make API calls in React.

      This article will discuss the step-by-step process of building a photo search application with React using the Unsplash API. Unsplash is currently one of the most used and popular photo search engines, and can be a great data provider when building projects and applications.

      At the end of this tutorial, you’ll have a working application that uses React Hooks to query the Unsplash API. This project can also act as a boilerplate, since you can re-use the same programming logic and can use it as a base to build other projects involving API calls. Your photo search application will include a search bar and rendered results, as shown in the following:

      Photo Search Application

      If you would like to see the complete code, take a look at the DigitalOcean Community GitHub Repository.

      Prerequisites

      In order to follow this guide:

      Step 1 — Creating an Empty Project

      In this step, you will make use of Create React App, which will get the initial project running without doing any manual configuration. In your project directory, run the following command.

      • npx create-react-app react-photo-search

      This command will create a folder named react-photo-search with all the necessary files and configuration for a working React web aplication.

      Use the cd command to change directory and go inside this folder by running the following command:

      Next, start the development server by running the following command:

      For information on this start script, check out How To Set Up a React Project with Create React App.

      Next, head over to http://localhost:3000 in a web browser, or if you are running this from a remote server, http://your_domain:3000.

      You will find the React template:

      React starting template with React logo

      Before moving further, you will have to clean the files. Create React App comes with sample code that is not needed and should be removed before building a project to ensure code maintainability.

      You will now need to open another terminal since one is already taken up by npm start.

      Delete the default styling in index.css by running the following command:

      Next, open index.js in a code editor with the following command:

      Since you have deleted index.css, remove import './index.css'; from index.js.

      Your index.js will be similar to this once you are done removing import ./index.css from it.

      react-photo-search/src/index.js

      
      import React from 'react';
      import ReactDOM from 'react-dom';
      import App from './App';
      import * as serviceWorker from './serviceWorker';
      
      ReactDOM.render(
        <React.StrictMode>
          <App />
        </React.StrictMode>,
        document.getElementById('root')
      );
      
      // If you want your app to work offline and load faster, you can change
      // unregister() to register() below. Note this comes with some pitfalls.
      // Learn more about service workers: https://bit.ly/CRA-PWA
      serviceWorker.unregister();
      

      Save and exit the file.

      Now delete the React logo by running the following command in the terminal:

      Open App.css with the following command:

      Remove everything from App.css, then save and exit the file. You will update this in Step 3 with your new styling.

      Open src/App.js with the following command:

      The next step is to remove import logo from './logo.svg'; and remove the JSX from the div with the className="App" in App.js file. This will remove the HTML elements of the template.

      Modify App.js to look like this:

      react-photo-search/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return (
          <div className="App">
      
          </div>
        );
      }
      
      export default App;
      

      Your http://localhost:3000 will be blank now.

      You’ve now initialized a React app and cleaned the sample code from it. Next, you will create a new application in the Unsplash Developer dashboard and copy the Access Key and Secret Key of the application you just created to gain access to the Unsplash API.

      Step 2 — Acquiring Unsplash API Credentials

      In this section, you will apply for an Unsplash Developer Account, create a new application for this project, and copy the Access Key and Secret Key of this application to gain access to the Unsplash API. Since the Unsplash API is not a public API, you will need your own set of Unsplash API keys for this project.

      Head over to Unsplash Developer Home and register as a developer. Since you already created an Unsplash Account this will be a quick process.

      On the Unsplash Developer page, click the Register as a developer button.

      Unsplash Developer page

      Fill in your credentials to register.

      After registering as a developer, you will be automatically redirected to your developer dashboard. Click on New Application.

      Unsplash Developer Dashboard with New Application

      You will be asked to accept the API Use and Guidelines. Click the checkboxes then the Accept terms button to proceed further:

      Unsplash API Use and Guidelines

      You will then be prompted to give your Application information. Give your application an appropriate name and description, and click Create application.

      Unsplash Application Information Pop-up

      With this, you have created an application and can now access your Access Key and Secret Key under the Keys section. Copy these keys to a secure location; you will need them later in your code.

      Keys section of the Unsplash Application Page

      Note that you will see a Demo tag after your application name:

      Demottag Next To Unsplash Application Name

      This tag means your application is in development mode and the requests are limited to 50 per hour. For a personal project, this is more than enough, but you can also apply for production which will increase the requests limit to 5000 per hour. Do remember to follow the API Guidelines before applying.

      In this section, you created an Unsplash API application and acquired the keys required for this project. For this project, you will use the official Unsplash JavaScript Library, unsplash-js, to integrate the API with your app. You will install unsplash.js and add CSS to style your project in the next step.

      Step 3 — Installing Dependencies and Adding CSS

      You will now install the unsplash-js package as a dependency and add custom CSS to style your project. If at any point you get stuck, refer to the DigitalOcean Community Repository for this project.

      To install unsplash-js library with the npm package manager, run the following in your project directory:

      This is the only library that you will need to install to follow this tutorial; later on, you can experiment with different React User Interface libraries like React-Bootstrap, Semantic UI React, etc. You should add these libraries if, after following this tutorial, you want to tweak this project and change its layout.

      Next, you will style your React app. Open App.css by running the following command.

      This tutorial will discuss the CSS piece by piece.

      First is the * selector, which selects all the elements. Add the following code:

      react-photo-search/src/App.css

      * {
        box-sizing: border-box;
        background-color: rgb(244, 244, 244);
        color: #333;
        font-size: 10px;
      }
      

      The box-sizing property sets how the total width and height of an element is calculated and, in this case, it tells the browser to take border and padding into the calculation for an element’s width and height. The background color is set using background-color and the value is rgb(244, 244, 244), which gives a pale white color to the background. color sets the color of the text of the elements; here hexcode #333 is used, which is a dark shade of gray. font-size sets the size of the font.

      Next, add the .App block, which selects the element with the className="App". By default the parent element (className="App") has some margin and padding, so the following code sets margin and padding of all four sides to 0:

      react-photo-search/src/App.css

      * {
        box-sizing: border-box;
        background-color: rgb(244, 244, 244);
        color: #333;
        font-size: 10px;
      }
      
      .App {
        margin: 0;
        padding: 0;
      }
      

      Next, add styling to the div element with the className="container". This is the child element of the div with className="App". Everything including title, form, button, and images will be included in this div:

      react-photo-search/src/App.css

      * {
        box-sizing: border-box;
        background-color: rgb(244, 244, 244);
        color: #333;
        font-size: 10px;
      }
      
      .App {
        margin: 0;
        padding: 0;
      }
      
      .container {
        margin: 0 auto;
        max-width: 1000px;
        padding: 40px;
      }
      

      The margin property is used to defined space around elements. margin can be set for top, right, bottom, and left. If only one value is added, then this one value will set for all top, right, bottom, and left. If two values are added in margin, then the first value will be set for top and bottom, and the second will be set for right and left.

      According to margin: 0 auto;, top and bottom have 0 margins while left and right have auto. This auto means that the browser will set the margin based on the container. An example to understand this will be if the parent element is 100px and the child element is 50px, then the left, and right margins will be 25px, which will center the child element inside the parent element.

      max-width sets the maximum value of width of the element, which in this case is 1000px. If the content is larger than 1000px, then the height property of the element will change accordingly, else max-width will have no effect.

      As discussed above, margin sets the space around the element while padding sets the space between an element and its content. The earlier code means that the container div and the elements inside it will have 40px of space between them from all four sides.

      Next, add styling for the title of the application:

      react-photo-search/src/App.css

      ...
      .container {
        margin: 0 auto;
        max-width: 1000px;
        padding: 40px;
      }
      
      .title {
        font-size: 4.4rem;
        font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
      }
      

      .title corresponds to the title of your App, which is “React Photo Search”. Only two properties are set, which are font-size and font-family. Here, the rem unit is used for the font-size value. rem values are relative to the root html element, unlike em values, which are relative to the parent element. Here the 4.4rem means 44px (4.4 x 10). This multiplication by 10px is because you set the font size of all elements to 10px using * selector. font-family specifies the font of the element. There are many values passed in the code to act as a fallback system; if the browser does not provide the first font, the next font is set.

      Next is the .form CSS block, which includes the form that will be used to search for images. This includes the input search field, button, and label.

      react-photo-search/src/App.css

      ...
      .title {
        font-size: 4.4rem;
        font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
      }
      
      .form {
        display: grid;
      }
      

      Here, only the display property is set. This property specifies the display behavior of the element. It can take different values like grid, flex, block, inline, etc. grid displays an element as a block-level and renders the content according to the grid model.

      Next is the .label and the .input CSS block:

      react-photo-search/src/App.css

      ...
      .form {
        display: grid;
      }
      
      .label {
        font-size: 3rem;
        margin-bottom: 1rem;
      }
      
      .input {
        font-size: 1.6rem;
        padding: 0.5rem 2rem;
        line-height: 2.8rem;
        border-radius: 20px;
        background-color: white;
        margin-bottom: 1rem;
      }
      

      We have already discussed font-size, padding, background-color, and margin-bottom, so let’s discuss line-height and border-radius. border-radius defines the radius of the element’s corners. Here the value is set to 20px, which will be used for all the four sides. Setting border-radius to 50% can make a square element into an oval. line-height specified the height of the line, which is set to 2.8rem or 28px.

      Next is the .button CSS block, which styles the Search button:

      react-photo-search/src/App.css

      ...
      .input {
        font-size: 1.6rem;
        padding: 0.5rem 2rem;
        line-height: 2.8rem;
        border-radius: 20px;
        background-color: white;
        margin-bottom: 1rem;
      }
      
      .button {
        background-color: rgba(0, 0, 0, 0.75);
        color: white;
        padding: 1rem 2rem;
        border: 1px solid rgba(0, 0, 0, 0.75);
        border-radius: 20px;
        font-size: 1.4rem;
        cursor: pointer;
        transition: background-color 250ms;
      }
      

      We have already discussed background-color, color, padding, border-radius, and font-size. border sets the style, width, and color of the border of an element. Here border is used as a shorthand property for border-width, border-style, and border-color. This code adds a solid black color border of 1px around the Search button. cursor specifies the mouse cursor when pointing over an element.

      Next is the :hover selector, which is used on .button.

      react-photo-search/src/App.css

      ...
      .button {
        background-color: rgba(0, 0, 0, 0.75);
        color: white;
        padding: 1rem 2rem;
        border: 1px solid rgba(0, 0, 0, 0.75);
        border-radius: 20px;
        font-size: 1.4rem;
        cursor: pointer;
        transition: background-color 250ms;
      }
      
      .button:hover {
        background-color: rgba(0, 0, 0, 0.85);
      }
      

      This means that when the mouse is hovered over the .button element, the background color will change.

      The next CSS block is .card-list, which corresponds to the div with className="card-list". This div will display all the images inside it:

      react-photo-search/src/App.css

      ...
      .button:hover {
        background-color: rgba(0, 0, 0, 0.85);
      }
      
      .card-list {
        column-count: 3;
      }
      

      column-count divides the element into columns according to the value that is passed inside it. This code will divide the card-list div into three columns, and the images will be displayed within these three columns.

      Next are the .card and .card--image CSS blocks. .card refers to the individual div with an image inside it, and .card--image is the className of this image:

      react-photo-search/src/App.css

      ...
      .card-list {
        column-count: 3;
      }
      
      .card {
          margin-bottom: 1rem;
          display: flex;
      }
      
      .card--image {
          flex: 100%;
          margin-top: 1rem;
          border-radius: 10px;
      }
      

      We have already discussed margin, display, and border-radius. In .card, display is set to flex, which means the elements will behave like block elements, and the display will be set according to the flexbox model. By using the shorthand property flex:100%;, you set the value for flex-grow, flex-shrink, and flex-basis. You can read more about it at the Mozilla Developer Network.

      The final CSS blocks involve media queries. By using the @media rule, you can apply different styles for different media types/devices:

      react-photo-search/src/App.css

      ...
      .card--image {
          flex: 100%;
          margin-top: 1rem;
          border-radius: 10px;
      }
      
      @media (min-width: 768px) {
        .form {
          grid-template-columns: auto 1fr auto;
          grid-gap: 1rem;
          align-items: center;
        }
        .input {
          margin-bottom: 0;
        }
      }
      
      @media only screen and (max-width: 600px) {
          .card-list {
              column-count: 1;
          }
      }
      

      According to this code, column-count will change from 3 to 1 when the browser window is 600px or less (applicable for most mobile devices). This used the max-width property with the @media rule. The code before that uses min-width, which changes the style of the elements inside the @media rule when the width is 768px or more.

      grid-template-columns is used to specify columns in the grid model. The number of columns is equal to the number of values passed, which is three according to the code (auto 1fr auto). The first and third grid element’s size will be according to their container size or the content’s size. The second element will be given 1fr (Fractional Unit), or the space left after the first and third elements have occupied according to their size. These three elements will be a camera emoji, the search input field, and the Search button. After the emoji and the button have taken the space according to their size, the rest of the area will go to the search input field, and it will change its width accordingly.

      grid-gap: 1rem; creates a space of 1rem between two grid lines. align-items:center; positions the items in the center of the container.

      This finishes the styling of your application. Save and exit from src/App.css. If you’d like to see the whole CSS file together, take a look at the GitHub repository for this code.

      Now that you have installed the necessary dependency and added the custom CSS needed to style your project, you can move forward to the next section and design the UI or layout of the project.

      Step 4 — Designing the User Interface

      In this section, you will design the UI of the project. This will include elements like a heading, label, input field, and button.

      Open the src/App.js file with the following command:

      To add a heading to your project, create a div with the className="container" inside your App.js. Inside this div add an h1 tag with the className="title" and write React Photo Search inside the tag. This will be the title heading:

      react-photo-search/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return (
          <div className="App">
            <div className="container">
              <h1 className="title">React Photo Search</h1>
            </div>
          </div>
        );
      }
      

      Save and exit the file. In your browser, your app will now show your title:

      Application with

      Next, you will create a form that will take input from the user. This form will consist of an input text field and a submit button.

      For this, create a new component named <SearchPhotos />. It is not necessary to create a separate component, but as you develop this project, splitting code into components makes it easier to write and maintain code.

      In the src folder, create and open a new file called searchPhotos.js with the following command:

      Inside searchPhotos.js, you export a functional component named <SearchPhotos />:

      react-photo-search/src/searchPhotos.js

      import React from "react";
      
      export default function SearchPhotos() {
        return (
          <>
      
          </>
        );
      }
      

      This is the basic structure of a functional component that you need to add to the searchPhotos.jsfile. Save this file.

      The next step is to import and use the SearchPhotos component in App.js.

      In a new terminal window, open up App.js:

      Add the following highlighted lines to App.js:

      react-photo-search/src/App.js

      import React from "react";
      import "./App.css";
      import SearchPhotos from "./searchPhotos"
      
      function App() {
        return (
          <div className="App">
            <div className="container">
              <h1 className="title">React Photo Search</h1>
              <SearchPhotos />
      
            </div>
          </div>
        );
      }
      export default App;
      

      Save this file.

      To create the search form, you will use the form tag and inside it, create an input field using the input tag and a button using the button tag.

      Give the elements the className of their respective tags. While you are doing this, add a label with a camera emoji inside it for styling:

      react-photo-search/src/searchPhotos.js

      ...
      export default function SearchPhotos() {
        return (
          <>
            <form className="form"> 
              <label className="label" htmlFor="query"> 
                {" "}
                📷
              </label>
              <input
                type="text"
                name="query"
                className="input"
                placeholder={`Try "dog" or "apple"`}
              />
              <button type="submit" className="button">
                Search
              </button>
            </form>
          </>
        );
      }
      

      First, you created a form element with a className="form", and inside it a label with a camera emoji. Then comes the input element with attributes type="text", since the search query will be a string. The name="query" attribute specifies the name of the input element, className="input" gives the element a class for styling, and the placeholder value for the search bar is set to Try "dog" or "apple". The final element in form is a button with the type="submit".

      Save and exit the file. Your app will now have a search bar after the title:

      Application with search bar and placeholder text of 'Try "dog" or "apple"'

      Now that the UI of the app is complete, you can start working on the functionalities by first storing the input query from the user in the next section.

      Step 5 — Setting State Using Search Query

      In this step, you will learn about states and React Hooks and then use them to store user input.

      Now that you have constructed your application’s basic structure, we can discuss the React side of things. You have a form, but it doesn’t do anything yet, so the first thing to do is to take the input from the search bar and access it. You can do this with states.

      States at their core are objects that are used to store the property values of components. Every time the state changes, the component re-renders. For this app, you need a state that will store the input or query from the search bar whenever the Search button is clicked.

      One of the things that you may have noticed is that this project is using functional components. This allows you to use React Hooks to manage state. Hooks are functions that use React features like defining a state without writing a class. In this tutorial, you will make use of the useState() Hook.

      The first thing to do is import useState inside your searchPhotos.js file.

      Open up the file:

      Modify the first line of searchPhotos.js file to the following:

      react-photo-search/src/searchPhotos.js

      import React, { useState } from "react";
      
      export default function SearchPhotos() {
      ...
      

      Next, you will implement useState(). This is the syntax for the useState() Hook:

      useState(initialState)
      

      useState() returns the current state and a function commonly known as an updater function. To store these, you can use array destructuring:

      const [query, setQuery] = useState(initialState);
      

      In this example, query stores the current state of the component, and setQuery is a function that can be called to update the state. initialState defines the initial state value; it can be a string, a number, an array, or an object depending on the use.

      In your project, the input from the search bar is a string, so you will use an empty string as an initial value of the state.

      In your searchPhotos.js file, add the following line of code:

      react-photo-search/src/searchPhotos.js

      ...
      
      export default function SearchPhotos() {
        const [query, setQuery] = useState("");
      
        return (
          <>
            <form className="form">
              <label className="label" htmlFor="query">
                {" "}
                📷
              </label>
      ...
      

      The next step is to set the value of the input text field to query and add an onChange() event to it. This onChange() event will have a function, inside which setQuery() will be used to update the state. The input string is retrieved using e.target.value:

      react-photo-search/src/searchPhotos.js

      ...
      <input
          type="text"
          name="query"
          className="input"
          placeholder={`Try "dog" or "apple"`}
          value={query}
          onChange={(e) => setQuery(e.target.value)}
      />
      ...
      

      Now, the state and the input field’s values are interlinked, and you can use this search query to search for the image.

      You can view the input from the search bar inside the query in real-time for testing purposes. Add console.log(query) just after where you defined state:

      react-photo-search/src/searchPhotos.js

      ...
      export default function SearchPhotos() {
         const [query, setQuery] = useState("");
         console.log(query);
      
        return (
          <>
          //
          </>
        );
      }
      

      Save the file.

      You will now receive the input queries inside the console. You can open your console, using F12 in Chrome or Ctrl+Shift+K in Firefox:

      Browser console demonstrating the logging of the user input for this application.

      Now, searchPhotos.js will look like this:

      react-photo-search/src/searchPhotos.js

      
      import React, { useState } from "react";
      export default function SearchPhotos() {
        const [query, setQuery] = useState("");
        console.log(query);
      
        return (
          <>
            <form className="form">
              <label className="label" htmlFor="query">
                {" "}
                📷
              </label>
              <input
                type="text"
                name="query"
                className="input"
                placeholder={`Try "dog" or "apple"`}
                value={query}
                onChange={(e) => setQuery(e.target.value)}
              />
              <button type="submit" className="button">
                Search
              </button>
            </form>
          </>
        );
      }
      

      This section discussed states and React Hooks and stored the user input in the input field inside the query state. In the next section, you will use this search query to search for the image and store the response inside another state.

      Step 6 — Making API Requests to Unsplash

      You will now use the unsplash-js library to search for images using the query from the input field. The response will be stored inside another state named pics.

      You have already installed the unsplash-js library, so import it in searchPhotos.js file. You can also remove the console.log() statement from the previous section:

      react-photo-search/src/searchPhotos.js

      import React, { useState } from "react";
      import Unsplash, { toJson } from "unsplash-js";
      
      ...
      

      toJson is a helper function in the unsplash-js library that is used to convert the response into JSON format. You can learn more about helper functions at the unsplash-js GitHub page.

      To use Unsplash in your app, make an instance of it using the new keyword like this:

      react-photo-search/src/searchPhotos.js

      import React, { useState } from "react";
      import Unsplash, { toJson } from "unsplash-js";
      
      const unsplash = new Unsplash({
        accessKey: "your_Access_Key",
      });
      

      Paste your Unsplash Access Key to replace your_Access_Key and you can now make API requests.

      Warning: One should never share any access keys or Client ID’s for an API or any service. Potential bad actors can misuse them over the internet. In this scenario, they can make an unusual amount of requests that can be flagged as spam by your service provider, which can deactivate your application and account.

      Now you will create an asynchronous function that will be triggered when clicking the Search button.

      Just after where you defined state for query, define an async function:

      react-photo-search/src/searchPhotos.js

      ...
      export default function SearchPhotos() {
        const [query, setQuery] = useState("");
      
        const searchPhotos = async (e) => {
          e.preventDefault();
          console.log("Submitting the Form")
        };
      

      Here e.preventDefault() stops the page from reloading whenever the Search button is clicked. You can pass this function in the onSubmit event inside the form tag. You can read more about this in the official React docs.

      react-photo-search/src/searchPhotos.js

      ...
        return (
          <>
            <form className="form" onSubmit={searchPhotos}>
      ...
      

      Save the file. Now, if you click the Search button, you will receive Submitting the Form in the console. You can remove this console.log() after a successful response in the console.

      Inside your searchPhotos() function, you will use the Unsplash instance (unsplash). You can use the search method for searching the images. Here is the syntax for that:

      search.photos(keyword, page, per_page, filters)
      

      Here is the code to search for an image; add this code inside your searchPhotos() function:

      react-photo-search/src/searchPhotos.js

      ...
      const searchPhotos = async (e) => {
        e.preventDefault();
        unsplash.search
          .photos(query)
          .then(toJson)
          .then((json) => {
            console.log(json);
          });
      };
      ...
      

      First, you use unsplash.search and then specify what to search for, which is in this case photos. We can also search for users or collections. photos takes the first required argument as the keyword to search for, which is query; you can also specify the page, responses per page, image orientation, etc., through the optional arguments. For this tutorial, you only need the page and per_page arguments, limiting the response items you get from Unsplash.

      Here are all the arguments that can be provided in photos

      Argument Type Opt/Required Default
      keyword string Required
      page number Optional
      per_page number Optional 10
      filters object Optional
      filters.orientation string Optional
      filters.collections array Optional

      You can learn more about them at the unsplash-js GitHub page.

      You use the toJson method to convert the response into JSON, and finally, console.log() the response to test that API requests are made without any error. You will remove this console .log () in the next steps.

      Save the file. Now open your console and click the Search button. You will find a response JSON like this:

      {
        "results": [{
           "description": "Pink Wall Full of Dogs",
           "alt_description": "litter of dogs fall in line beside wall",
           "urls": {
                 "raw": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjE0MTQxN30",
                 "full": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0MTQxN30",
                 "regular": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30",
                 "small": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30",
                 "thumb": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30"
                      },
          ...
      }
      

      You can remove or comment the console.log() statement when you find a successful response from the Unsplash API, which means your code is working fine. This app will use the "urls" field, since that will be the source of the image.

      You’ve now used the query from the user to search for images when the Search button was clicked using the unsplash-js library. Next, you will store the response inside another state named pics and display the images by mapping the elements inside this state.

      Step 7 — Displaying Images on the Webpage

      In this last section, you will store the response from Unsplash API inside another state named pics and then map over the elements of this state to display the images on the webpage.

      To show images, you need to access the response JSON, and for that, another state will be needed. The previous state query stored queries from the user, which was used to make requests to the Unsplash API. This state pics will store the image response you get from Unsplash API.

      In searchPhotos.js define another state like this:

      react-photo-search/src/searchPhotos.js

      ...
        const [query, setQuery] = useState("");
        const [pics, setPics] = useState([]);
      ...
      

      This state has been initialized with an empty array, and all the responses will be stored as an object inside this state. In other words, this is an array of objects.

      To update this state with the JSON, you will use setPics inside unsplash API request:

      react-photo-search/src/searchPhotos.js

      ...
          unsplash.search
            .photos(query, 1, 20)
            .then(toJson)
            .then((json) => {
              setPics(json.results);
        });
      ...
      

      Now every time you search for a new query, this state will be updated accordingly.

      Next, create a div with the className="card-list" just after where form tags end:

      react-photo-search/src/searchPhotos.js

      ...
              <button type="submit" className="button">
                Search
              </button>
            </form>
            <div className="card-list">
            </div>
          </>
        );
      }
      

      Inside this div, you will map through the state and display the id of the image:

      react-photo-search/src/searchPhotos.js

      ...
              <button type="submit" className="button">
                Search
              </button>
            </form>
            <div className="card-list">
              {pics.map((pic) => pic.id )}
            </div>
          </>
        );
      }
      

      You first use {} to pass the JavaScript expression, inside which you use the .map() method on your state.

      Save your file. If you search now, you will see ids associated with different objects on the webpage:

      Application with overlapping ID results rendered on the webpage

      This is messy, but this also means your application is working.

      Instead of displaying pic.id, open up JSX inside the map function and create a new div with the className="card". This is going to be the container for each individual image:

      react-photo-search/src/searchPhotos.js

      ...
              <button type="submit" className="button">
                Search
              </button>
            </form>
            <div className="card-list">
              {
                pics.map((pic) => <div className="card"></div>);
              }
            </div>
          </>
        );
      }
      

      You can now display an image inside this div:

      react-photo-search/src/searchPhotos.js

      ...
              <button type="submit" className="button">
                Search
              </button>
            </form>
            <div className="card-list">
              {
                pics.map((pic) => 
                  <div className="card">
                    <img
                      className="card--image"
                      alt={pic.alt_description}
                      src={pic.urls.full}
                      width="50%"
                      height="50%"
                    ></img>
                  </div>);
              }
            </div>
          </>
        );
      }
      

      If you go back and see the response JSON, you will find a different kind of information. "urls" contains the path to the image, so here pic.urls.full is the actual path to the image and pic.alt_description is the alt description of the picture.

      There are different fields inside "urls" that give different data, such as:

      raw : Actual raw image taken by a user.
      full : Raw image in .jpg format.
      regular : Best for practical uses, width=1080px.
      small : Perfect for slow internet speed, width=400px.
      thumb : Thumbnail version of the image, width=200px.

      In this tutorial, you are using full, but you can experiment with other types, too. You have also given a default height and width to the image.

      Save your file.

      Your application is almost finished; if you search now, you will be able to see your application in action. But there is still a small line of code left. If you search for your image and go to your console in the browser, you will see a warning.

      Web console

      Warning: Each child in a list should have a unique "key" prop.

      To fix this, pass a unique key to every child using the id of the image. This key prop explicitly tells React the identity of each child in a list; this also prevents children from losing state between renders:

      react-photo-search/src/searchPhotos.js

      ...
            <div className="card-list">
              {pics.map((pic) =>
                <div className="card" key={pic.id}>
                  <img
                    className="card--image"
                    alt={pic.alt_description}
                    src={pic.urls.full}
                    width="50%"
                    height="50%"
                  ></img>
                </div>)};
            </div>
          </>
        );
      }
      

      You can adjust the number of images you want to show by passing the corresponding argument to unsplash.search.photos().

      Save and exit the file. You’ll now have a working photo search app:

      Animation of searching the term

      In this section, you stored the response from Unsplash API inside the pics state and displayed the images by mapping over the elements in pics.

      Conclusion

      In this tutorial, you developed a React Photo Search app with the Unsplash API. In building the project, the tutorial discussed how to use React Hooks, query an API, and style a user interface.

      There is much that can be done with this application to extend it. For example, you could add a Random button to display random images, create a checkbox to toggle between searching for photos or the users that posted them according to the user’s preference, add an infinite scroll to display more images, and more. You can also use the same concept and make other projects involving API requests, like the Hacker News API.

      If you would like to look at more React tutorials, check out our React Topic page.



      Source link

      How To Install Jenkins on Kubernetes


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Continuous Integration/Continuous Deployment (CI/CD) pipelines are one of the core components of the DevOps environment. They help streamline the workflow between multiple teams and increase productivity. Jenkins is a widely-used open source automation server that can set up CI/CD pipelines.

      In this tutorial, you will install Jenkins on Kubernetes. You will then access the Jenkins UI and run a sample pipeline.

      Prerequisites

      To follow this tutorial, you will need:

      Step 1 — Installing Jenkins on Kubernetes

      Kubernetes has a declarative API and you can convey the desired state using either a YAML or JSON file. For this tutorial, you will use a YAML file to deploy Jenkins. Make sure you have the kubectl command configured for the cluster.

      First, use kubectl to create the Jenkins namespace:

      • kubectl create namespace jenkins

      Next, create the YAML file that will deploy Jenkins.

      Create and open a new file called jenkins.yaml using nano or your preferred editor:

      Now add the following code to define the Jenkins image, its port, and several more configurations:

      jenkins.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: jenkins
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: jenkins
        template:
          metadata:
            labels:
              app: jenkins
          spec:
            containers:
            - name: jenkins
              image: jenkins/jenkins:lts
              ports:
                - name: http-port
                  containerPort: 8080
                - name: jnlp-port
                  containerPort: 50000
              volumeMounts:
                - name: jenkins-vol
                  mountPath: /var/jenkins_vol
            volumes:
              - name: jenkins-vol
                emptyDir: {}
      

      This YAML file creates a deployment using the Jenkins LTS image and also opens port 8080 and 50000. You use these ports to access Jenkins and accept connections from Jenkins workers respectively.

      Now create this deployment in the jenkins namespace:

      • kubectl create -f jenkins.yaml --namespace jenkins

      Give the cluster a few minutes to pull the Jenkins image and get the Jenkins pod running.

      Use kubectl to verify the pod’s state:

      • kubectl get pods -n jenkins

      You will receive an output like this:

      NAME                       READY   STATUS    RESTARTS   AGE
      jenkins-6fb994cfc5-twnvn   1/1     Running   0          95s
      

      Note that the pod name will be different in your environment.

      Once the pod is running, you need to expose it using a Service. You will use the NodePort Service type for this tutorial. Also, you will create a ClusterIP type service for workers to connect to Jenkins.

      Create and open a new file called jenkins-service.yaml:

      • nano jenkins-service.yaml

      Add the following code to define the NodePort Service:

      jenkins-service.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: jenkins
      spec:
        type: NodePort
        ports:
          - port: 8080
            targetPort: 8080
            nodePort: 30000
        selector:
          app: jenkins
      
      ---
      
      apiVersion: v1
      kind: Service
      metadata:
        name: jenkins-jnlp
      spec:
        type: ClusterIP
        ports:
          - port: 50000
            targetPort: 50000
        selector:
          app: jenkins
      

      In the above YAML file, you define your NodePort Service and then expose port 8080 of the Jenkins pod to port 30000.

      Now create the Service in the same namespace:

      • kubectl create -f jenkins-service.yaml --namespace jenkins

      Check that the Service is running:

      • kubectl get services --namespace jenkins

      You will receive an output like this:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE jenkins NodePort your_cluster_ip <none> 8080:30000/TCP 15d

      With NodePort and Jenkins operational, you are ready to access the Jenkins UI and begin exploring it.

      Step 2 — Accessing the Jenkins UI

      In this step, you will access and explore the Jenkins UI. Your NodePort service is accessible on port 30000 across the cluster nodes. You need to retrieve a node IP to access the Jenkins UI.

      Use kubectl to retrieve your node IPs:

      • kubectl get nodes -o wide

      kubectl will produce an output with your external IPs:

      Output

      NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME your_node Ready <none> 16d v1.18.8 your_internal_ip your_external_ip Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 your_node Ready <none> 16d v1.18.8 your_internal_ip your_external_ip Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 your_node Ready <none> 16d v1.18.8 your_internal_ip your_external_ip Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9

      Copy one of the your_external_ip values.

      Now open a web browser and navigate to http://your_external_ip:30000.

      A page will appear asking for an administrator password and instructions on retrieving this password from the Jenkins Pod logs.

      Let’s use kubectl to pull the password from those logs.

      First, return to your terminal and retrieve your Pod name:

      • kubectl get pods -n jenkins

      You will receive an output like this:

      NAME                       READY   STATUS    RESTARTS   AGE
      jenkins-6fb994cfc5-twnvn   1/1     Running   0          9m54s
      

      Next, check the Pod’s logs for the admin password. Replace the highlighted section with your pod name:

      • kubectl logs jenkins-6fb994cfc5-twnvn -n jenkins

      You might need to scroll up or down to find the password:

      Running from: /usr/share/jenkins/jenkins.war
      webroot: EnvVars.masterEnvVars.get("JENKINS_HOME")
      . . .
      
      Jenkins initial setup is required. An admin user has been created and a password generated.
      Please use the following password to proceed to installation:
      
      your_jenkins_password
      
      This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
      . . .
      

      Copy your_jenkins_password. Now return to your browser and paste it into the Jenkins UI.

      Once you enter the password, Jenkins will prompt you to install plugins. Because you are not doing anything unusual, select Install suggested plugins.

      After installation, Jenkins will load a new page and ask you to create an admin user. Fill out the fields, or skip this step by pressing the skip and continue as admin link. This will leave your username as admin and your password as your_jenkins_password.

      Another screen will appear asking about instance configuration. Click the Not now link and continue.

      After this, Jenkins will create a summary of your choices and print Jenkins is ready! Click on start using Jenkins and the Jenkins home page will appear.

      jenkins wizard

      Now that you have installed and configured Jenkins on your cluster let’s demonstrate its capabilities and run a sample pipeline.

      Step 3 — Running a Sample Pipeline

      Jenkins excels at creating pipelines and managing CI/CD workflows. In this step we will build one of Jenkins’ sample pipelines.

      From the Jenkins home page, click on the New item link on the left-hand menu.

      A new page will appear. Choose Pipeline and press OK.

      jenkins wizard

      Jenkins will redirect you to the pipeline’s configuration. Find the Pipeline section and select Hello World from the try sample pipeline dropdown menu. This menu appears on the right-hand side. After selecting Hello World, click the Save button.

      jenkins wizard

      Jenkins will redirect you to the pipeline home page. Click on build now from the left-hand menu and watch the pipeline begin to run. The #1 signifies that this is the first build. Once the task completes, you will see some stats about the build.

      jenkins wizard

      You can also check the console output to see what happened while the pipeline was running. Hover over #1 and a dropdown menu will appear. Choose console output to view the build’s details.

      Your Hello World pipeline is not very sophisticated, but it does demonstrate just how well Jenkins can create and manage CI/CD workflows.

      Conclusion

      In this tutorial, you installed and configured Jenkins on a Kubernetes cluster and then you ran a sample pipeline. Jenkins has a large repository of plugins that can help you perform very complex operations. You can also add your GitHub repositories, multiple types of worker instances, and more. To learn more about using Jenkins, explore the official Jenkins documentation.



      Source link