Metadata-Version: 2.4
Name: http2postman
Version: 0.1.0
Summary: Convert JetBrains HTTP Client / REST Client .http files into a Postman Collection v2.1 JSON
Author: Ali Tabatabaei
License-Expression: MIT
Project-URL: Homepage, https://github.com/salitaba/http2postman
Project-URL: Issues, https://github.com/salitaba/http2postman/issues
Keywords: postman,http-client,rest-client,jetbrains,converter,cli
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# http2postman

Convert JetBrains HTTP Client / VSCode REST Client `.http` / `.rest` files
into a Postman Collection v2.1 JSON file that imports cleanly into Postman.

Python 3.10+, standard library only.

## Installation

```sh
pip install http2postman
```

Or install from this repository (editable install for development):

```sh
pip install -e .
```

On systems with an externally managed Python (Debian/Ubuntu: PEP 668),
install in a virtual environment instead:

```sh
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```

Note: `activate` is a shell script meant to be **sourced** — the command is
`source .venv/bin/activate`, not `.venv/bin/activate`. The name of the venv
directory is your choice (`.venv`, `.env`, `venv`, ...) — just keep it
consistent when activating.

No runtime dependencies are required — setuptools is only a build-time
dependency.

If you do not want to install anything, the tool also runs directly from the
repo checkout:

```sh
python3 -m http2postman requests.http
```

## Usage

```sh
http2postman requests.http
http2postman requests.http -o my-collection.json
http2postman apis/ --name "My API"        # recursively scans directories
http2postman a.http b.http --quiet
http2postman requests.http --prefer-env dev   # bake env values into collection variables
http2postman requests.http --env-file .env    # resolve {{$dotenv VAR}} from a specific file
python3 -m http2postman requests.http
```

- `-o OUTPUT` — output JSON path (default `postman_collection.json` next to
  the input).
- `--name NAME` — collection name (default: first input file's basename).
- `--env-file PATH` — `.env` file for `{{$dotenv VAR}}` resolution (default:
  `.env` next to each input).
- `--prefer-env NAME` — use the named environment from `http-client.env.json`
  (plus `http-client.private.env.json`, merged on top) next to the first
  input as **default values** for the collection variables. Environment
  values win over file-level `@var` definitions; scalar values are coerced to
  strings, complex values to compact JSON. Missing file or environment name
  is an error (exit 1).
- `--quiet` — suppress the stdout report.

Exit codes: `0` success, `1` conversion/validation failure, `2` usage error.

Output is written atomically (temp file + rename); source files are never
modified.

### `--prefer-env` example

JetBrains environment files map environment names to variable values:

```json
// http-client.env.json (next to the .http file)
{
  "dev":  { "baseUrl": "https://dev.example.com",  "apiKey": "dev-key" },
  "prod": { "baseUrl": "https://prod.example.com" }
}
```

```sh
http2postman requests.http --prefer-env dev
# -> collection variables: baseUrl = https://dev.example.com, apiKey = dev-key
```

Secrets can live in `http-client.private.env.json` (same shape, merged on
top). The report prints `Env: dev` so you can see which environment was used.

## What is supported

- `###` request names, `# @name` overrides, all HTTP methods (unknown methods
  pass through verbatim)
- headers (order/casing preserved; `Content-Length` dropped)
- raw / JSON / XML / urlencoded / multipart / external-file bodies
- GraphQL requests via `X-REQUEST-TYPE: GraphQL`
- file-level `@name = value` variables -> collection variables
- `{{var}}` tokens (kept byte-for-byte), JetBrains dynamic variables mapped
  to Postman equivalents (`$uuid` -> `{{$guid}}`, `$random.email` ->
  `{{$randomEmail}}`, etc. — unlisted `$random.*` tokens are reported)
- `## Folder` / `@group` folder grouping
- **JetBrains environments**: `--prefer-env NAME` uses the values from
  `http-client.env.json` / `http-client.private.env.json` as the collection
  variable defaults (see the example above).
- **Scripts**: `< {% ... %}` pre-request and `> {% ... %}` response scripts
  are captured and translated into Postman Pre-request Script / Tests tabs
  (`client.test` -> `pm.test`, `client.assert` ->
  `pm.expect(!!(cond)[, msg]).to.be.true` — JetBrains' assert is a truthiness
  check, and Postman's sandbox does not support Chai's `.truthy`, so the
  condition is boolean-coerced with `!!()` and asserted with the documented
  `.to.be.true` —,
  `client.global.set` -> `pm.collectionVariables.set`,
  `request.variables.set` -> `pm.variables.set`,
  `request.environment.get` -> `pm.variables.get` (resolves through the
  Postman variable chain, so `--prefer-env` defaults are visible to scripts),
  `response.status` -> `pm.response.code`,
  `response.body` -> `pm.response.json()` (parsed body, like JetBrains),
  `response.contentType/time` -> `pm.response.*`, ...).
  Unrecognized statements pass through unchanged.
- **dotenv**: `{{$dotenv VAR}}` references resolve from the `.env` file next
  to each input file, or the file given with `--env-file`. Unresolved
  references are kept as-is and reported.
- **Auth**: OAuth2 client-credentials token requests (POST to a token/oauth
  URL with `grant_type=client_credentials` and a literal `Basic` header) get a
  Postman `oauth2` auth object; `Bearer {{token}}` and literal
  `Basic base64(user:pass)` / `Basic {{user}} {{pass}}` headers become
  `bearer` / `basic` auth objects (the header is removed).
- WebSocket (`WEBSOCKET ws://...`) and gRPC (`GRPC host/service/method`)
  blocks are parsed and reported under `Unsupported:` — the Postman Collection
  v2.1 schema cannot express them — with a `file:line` reference for manual
  porting.

The stdout report lists `Requests: N | Folders: N | Variables: N |
Scripts: N` (translated script blocks), an `Env:` line when `--prefer-env` is
used, and an `Unsupported:` line for anything left (unmapped dynamic
variables, unresolved dotenv refs, WebSocket/gRPC blocks).

## Tests

```sh
python3 -m unittest discover -s tests
```
