hoppscotch / hoppscotch

Open source API development ecosystem - https://hoppscotch.io (open-source alternative to Postman, Insomnia)
https://hoppscotch.io
MIT License
65.72k stars 4.57k forks source link

[bug]: Unable to import Hoppscotch collections into Postman #3961

Open Michele971 opened 7 months ago

Michele971 commented 7 months ago

Is there an existing issue for this?

Current behavior

I'm encountering difficulties when attempting to import Hoppscotch collections into Postman. Despite following the recommended steps for migration, the imported collections do not appear in Postman as expected.

The issues persists across multiple attempts to import the collection into Postman. No error messages or notifications are displayed during the import process, suggesting that the migration is successfull.

I'm seeking guidance, insights, or potential workarounds to successfully import Hoppscotch collections.

Thank you in advance!

Steps to reproduce

1) export a collection in Hoppsctoch 2) import the collection into Postman

Environment

Production

Version

Cloud

jobartim44 commented 7 months ago

When you say that you are "following the recommended steps", you talk about Postman documentation ?

If you export to JSON format and Postman can't succeed in importing the file is looks like a bug in postman more than in hoppscotch to me.

imhmdb commented 6 months ago

if anyone is facing the same issue and needs a quick/dirty solution, I made this python script to convert Hoppscotch JSON collections into Postman's... the result is not perfect but it was really helpful for my case.

https://gist.github.com/imhmdb/0aa11fd56f6c6d88172dd38e72a703ea

axad1 commented 6 months ago

if anyone is facing the same issue and needs a quick/dirty solution, I made this python script to convert Hoppscotch JSON

Thanks. It works.

anik587 commented 1 month ago

Here is the updated converter for Hoppscotch to Postman

import json
import os
from urllib.parse import urlparse, parse_qs

# Hardcoded path to the Hopscotch collection JSON file
hopscotch_file_path = "file/path/file.json"  # Replace with your actual file path

# Read the Hopscotch collection from the provided file path
try:
    with open(hopscotch_file_path, 'r') as hopscotch_file:
        hopscotch_collection = json.load(hopscotch_file)
except FileNotFoundError:
    print("The specified file was not found. Please check the path and try again.")
    exit(1)
except json.JSONDecodeError:
    print("Error decoding JSON. Please ensure the file is valid JSON.")
    exit(1)

# Debugging: Print the loaded collection
print("Loaded Hopscotch collection:", json.dumps(hopscotch_collection, indent=2))

postman_collection = {
    "info": {
        "name": hopscotch_collection["name"],
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
    },
    "item": []
}

# Function to replace specific values with environment variables
def replace_with_env_vars(value):
    return value.replace("<<url>>", "{{url}}") \
                .replace("<<X-Decoded-Payload>>", "{{X-Decoded-Payload}}") \
                .replace("<<X-Apigateway-Api-Userinfo>>", "{{X-Apigateway-Api-Userinfo}}")

# Function to convert Hopscotch requests to Postman format
def convert_requests(requests, parent_item=None):
    for hopscotch_req in requests:
        if isinstance(hopscotch_req, dict):
            # Parse the URL
            parsed_url = urlparse(replace_with_env_vars(hopscotch_req['endpoint']))  # Use replacement here
            postman_req = {
                "name": hopscotch_req.get("name", "Converted Request"),
                "request": {
                    "method": hopscotch_req['method'],
                    "header": [
                        {"key": h['key'], "value": replace_with_env_vars(h['value']), "type": "text"} for h in hopscotch_req.get('headers', [])
                    ],
                    "body": {
                        "mode": "raw",
                        "raw": hopscotch_req['body']['body']  # Accessing the body content directly
                    },
                    "url": {
                        "raw": replace_with_env_vars(hopscotch_req['endpoint']),  # Replace endpoint with env vars
                        "protocol": parsed_url.scheme,
                        "host": parsed_url.netloc.split('.'),
                        "path": parsed_url.path.lstrip('/').split('/'),  # Remove leading slash
                        "query": [{"key": k, "value": v[0]} for k, v in parse_qs(parsed_url.query).items()]  # Extract all query parameters
                    }
                }
            }

            # Include query parameters from the request's 'params' field, if present
            if 'params' in hopscotch_req:
                postman_req['request']['url']['query'].extend(
                    [{"key": param['key'], "value": replace_with_env_vars(param['value'])} for param in hopscotch_req['params']]
                )

            # If parent_item is provided, append the request to the corresponding folder
            if parent_item:
                parent_item['item'].append(postman_req)
            else:
                postman_collection['item'].append(postman_req)
        else:
            print(f"Unexpected item format: {hopscotch_req}")  # Debugging output

# Function to convert folders
def convert_folders(folders):
    for folder in folders:
        if isinstance(folder, dict):
            postman_folder = {
                "name": folder["name"],
                "item": []
            }
            # Convert requests within this folder
            convert_requests(folder.get("requests", []), postman_folder)
            # Add the folder to the Postman collection
            postman_collection['item'].append(postman_folder)

# Process the top-level folders and their requests
convert_folders(hopscotch_collection.get("folders", []))

# Define the output file path for the Postman collection
postman_file_path = os.path.splitext(hopscotch_file_path)[0] + "_postman_collection.json"

# Write the Postman collection to a file
try:
    with open(postman_file_path, 'w') as postman_file:
        json.dump(postman_collection, postman_file, indent=2)
    print(f"Postman collection saved to: {postman_file_path}")
except Exception as e:
    print(f"An error occurred while writing the Postman collection: {e}")