How to Prevent Timeout Issues in Code Handling Large Page Numbers in Axios API Request?

This topic was automatically generated from Slack. You can find the original thread here.

I have some code which works fine when there are limited pages (2 works fine so far) but times out when there are 20+ pages. Is there anything I can do?

import axios from 'axios';

export default defineComponent({
  props: {
    labelId: {
      type: "string",
      label: "Discogs Label ID",
      description: "Enter the Discogs label ID you want to fetch releases for.",
    },
    discogsKey: {
      type: "string",
      label: "Discogs API Key",
      description: "Enter your Discogs API key.",
      secret: true,  // Ensures the API key is not exposed
    },
    discogsSecret: {
      type: "string",
      label: "Discogs API Secret",
      description: "Enter your Discogs API secret.",
      secret: true,  // Ensures the API secret is not exposed
    },
  },
  async run({ steps }) {
    let page = 1;
    let perPage = 100;
    let morePages = true;
    let allReleases = [];

    while (morePages) {
      const url = `https://api.discogs.com/labels/${this.labelId}/releases?page=${page}&per_page=${perPage}`;

      try {
        // Log the current page being requested
        console.log(`Requesting page ${page}`);

        // Make the API request with the required headers
        let response = await axios({
          method: 'GET',
          url: url,
          headers: {
            'User-Agent': 'pipedream/1',  // Your User-Agent
            'Authorization': `Discogs key=${this.discogsKey}, secret=${this.discogsSecret}` // Use dynamic keys and secrets
          }
        });

        // Append the releases from this page to the overall array
        allReleases = allReleases.concat(response.data.releases);

        // Check the pagination object
        const pagination = response.data.pagination;

        // Log total pages and current page status
        console.log(`Page ${pagination.page} of ${pagination.pages}`);

        // Determine if there are more pages
        if (pagination.page  pagination.pages) {
          page++;
        } else {
          morePages = false;
        }

        // Adding a delay of 1 second (1000 milliseconds) to prevent exceeding rate limits
        await new Promise(resolve = setTimeout(resolve, 1000));

      } catch (error) {
        console.error(`Error requesting page ${page}:`, error.message);
        morePages = false;
      }
    }

    // Return the array of all releases
    return allReleases;
  }
});

Hi , you can try to remove the 1 second delay and optimize the logic to prevent rate limit. For example, you can try sending request as soon as possible, then when facing rate limit error, delay then retry the request. You can ask Pi to write the logic for you

I have some code which works fine when there are limited pages (2 works fine so far) but times out when there are 20+ pages. Can you try to remove the 1 second delay and optimize the logic to prevent rate limit. For example, you can try sending request as soon as possible, then when facing rate limit error, delay then retry the request. Discogs is rate limited to 60 requests/min.

import axios from 'axios';

export default defineComponent({
  props: {
    labelId: {
      type: "string",
      label: "Discogs Label ID",
      description: "Enter the Discogs label ID you want to fetch releases for.",
    },
    discogsKey: {
      type: "string",
      label: "Discogs API Key",
      description: "Enter your Discogs API key.",
      secret: true,  // Ensures the API key is not exposed
    },
    discogsSecret: {
      type: "string",
      label: "Discogs API Secret",
      description: "Enter your Discogs API secret.",
      secret: true,  // Ensures the API secret is not exposed
    },
  },
  async run({ steps }) {
    let page = 1;
    let perPage = 100;
    let morePages = true;
    let allReleases = [];

    while (morePages) {
      const url = https://api.discogs.com/labels/${this.labelId}/releases?page=${page}&per_page=${perPage};

      try {
        // Log the current page being requested
        console.log(Requesting page ${page});

        // Make the API request with the required headers
        let response = await axios({
          method: 'GET',
          url: url,
          headers: {
            'User-Agent': 'pipedream/1',  // Your User-Agent
            'Authorization': Discogs key=${this.discogsKey}, secret=${this.discogsSecret} // Use dynamic keys and secrets
          }
        });

        // Append the releases from this page to the overall array
        allReleases = allReleases.concat(response.data.releases);

        // Check the pagination object
        const pagination = response.data.pagination;

        // Log total pages and current page status
        console.log(Page ${pagination.page} of ${pagination.pages});

        // Determine if there are more pages
        if (pagination.page < pagination.pages) {
          page++;
        } else {
          morePages = false;
        }

        // Adding a delay of 1 second (1000 milliseconds) to prevent exceeding rate limits
        await new Promise(resolve => setTimeout(resolve, 1000));

      } catch (error) {
        console.error(Error requesting page ${page}:, error.message);
        morePages = false;
      }
    }

    // Return the array of all releases
    return allReleases;
  }
});

Hello do you need me to repeat the message?

Hello! It seems like you might be asking if I need you to repeat your message. If you have a specific question or need assistance with something related to Pipedream, please feel free to let me know. I’m here to help!

To optimize your code for handling rate limits and removing the 1-second delay, you can implement a retry mechanism that waits only when a rate limit error occurs. Here’s an updated version of your code: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { labelId: { type: “string”, label: “Discogs Label ID”, description: “Enter the Discogs label ID you want to fetch releases for.”, }, discogsKey: { type: “string”, label: “Discogs API Key”, description: “Enter your Discogs API key.”, secret: true, }, discogsSecret: { type: “string”, label: “Discogs API Secret”, description: “Enter your Discogs API secret.”, secret: true, }, }, async run({ steps, $ }) { let page = 1; let perPage = 100; let morePages = true; let allReleases = ; while (morePages) { const url = https://api.discogs.com/labels/${this.labelId}/releases?page=${page}&per_page=${perPage}; try { console.log(Requesting page ${page}); let response = await axios($, { method: ‘GET’, url: url, headers: { ‘User-Agent’: ‘pipedream/1’, ‘Authorization’: Discogs key=${this.discogsKey}, secret=${this.discogsSecret} } }); allReleases = allReleases.concat(response.releases); const pagination = response.pagination; console.log(Page ${pagination.page} of ${pagination.pages}); if (pagination.page < pagination.pages) { page++; } else { morePages = false; } } catch (error) { if (error.response && error.response.status === 429) { console.error(Rate limit hit, retrying after delay...); await new Promise(resolve => setTimeout(resolve, 1000)); } else { console.error(Error requesting page ${page}:, error.message); morePages = false; } } } return allReleases; } });

it didn’t time out but it didn’t return the values either. Is there a way to log what it did do? Its just stopping after about 30seconds.

It sounds like you’re experiencing an issue where your Pipedream workflow is not returning values and is stopping unexpectedly. To help diagnose the problem, you can add logging to your workflow to see what it is doing at each step. Here’s how you can do that: 1. Add Console Logs: You can use console.log() to log information at various points in your workflow. This will help you understand what data is being processed and where it might be stopping. export default defineComponent({ async run({ steps, $ }) { console.log("Step started"); // Your code here console.log("Data:", someData); // More code console.log("Step completed"); } }); 2. Check the Execution Logs: After running your workflow, check the execution logs in the Pipedream UI. These logs will show you the output of your console.log() statements and any errors that might have occurred. 3. Use $.export for Debugging: You can use $.export to export specific data at any point in a step. This can be useful for debugging purposes to see the state of your data at different points in the workflow. ```
$.export(“debugData”, someData);

would it make any sense to do this as an if logic workflow where it returns t the step if it hasnt finished paginating and then sends all of the results to a single step? or is that not possible in pipedream yet?

It sounds like you’re considering implementing a loop or conditional logic within a Pipedream workflow to handle pagination and collect all results before proceeding to the next step. This is indeed possible in Pipedream. You can use the $.flow.rerun method to rerun the workflow from a specific step if a condition is met (e.g., if pagination is not complete). Here’s a general approach: 1. Initial API Call: Start by making an API call to fetch data with pagination. 2. Check for More Data: Use an if condition to check if there are more pages to fetch. 3. Rerun Workflow: If there are more pages, use $.flow.rerun to rerun the workflow from the step where you make the API call, passing the necessary parameters to fetch the next page. 4. Collect Results: Store the results in a data store or a variable that accumulates data across workflow runs. 5. Continue Workflow: Once all pages are fetched, proceed to the next step to process the collected data. This approach allows you to handle pagination effectively within a single workflow. If you have more specific requirements or need help with the code, feel free to ask!

are you able to remember previous comments in our conversation or do I need to give you all of the things we’ve discussed in each comment/query?

I don’t have the ability to remember previous comments or conversations. Each query is treated independently, so you’ll need to provide all relevant information in each comment or query. If you have any specific questions or need assistance, feel free to ask!