Convert curl commands to code in several languages
curlconverter.com
curlconverter.com
About a year ago, verhovsky showed up out of nowhere. He rewrote the core of the application and increased the professionalism across the board. (dedicated domain, github page hosting, UI refresh, privacy improvements, and much more)
The tree-sitter PR is a monster achievement: https://github.com/curlconverter/curlconverter/pull/278
Search for parseAnsiCString in there. I don't think that had ever been implemented in JavaScript before.
For you, verhovsky, 10x engineer might be an understatement. Thank you!
On the other hand: "Oh how far have we strayed off the Unix way..."
E.g. it turns curl ftp://host.com into response = requests.get('http://ftp://host.com')
Everything I everywhere now see is just the same: Gluecode, library calls, unnecessary verbosity, Blackbox inside Blackbox etc.
And this project slaps it again into my face, with every example it’s literally always the same - only that language uses a colon, the other a semicolon, the other catches exceptions with ? etc. but in a way it’s all just the same.
How to overcome this?
I find, only pointfree notation has some beauty to it that makes reading code sweet again.
In my experience, the main concepts behind application architecture remains the same regardless of what language you're using. Concepts like asynchronous execution and how it affects composability and resource management transcend syntax.
I would argue against this and claim that it appears to be a competition since “X written in {Rust,Go,SexyLang,…}” became the prevalent bullshit bingo.
Do you want to win bingo (chance) or get steady-pay?
Prevalent is just what you're paying attention too - there are 359 other degrees to enjoy.
The question you have to ask yourself is: Are you juggling for the sake of juggling or to make a good show for the crowd?
If your goal is the outcome, maybe don’t go into juggling bags of poo even though it’s more challenging than chainsaws because they keep changing shape.
Going back to the hammer example, imagine that you've spent your whole life using screws. You are probably going to buy furniture assembled with screws instead of with nails, because you know how easy it is to twist the screw out and put your modification in instead. A clear path exists in your mind, whereas with nail-based furniture, who knows?
Find a problem you feel passionate about solving and then use your skills to go solve it for mankind. You've learned how to be a mason, now go build something beautiful.
You start with branching out to actually different programming languages. If you already know PHP, don't go and learn Java or C#, you basically already know those from PHP, you're only missing knowledge of the public API (what methods should be called when, naming conventions) and so on.
Instead, seek languages that when you see them the first time you say "wow, I don't understand anything" and sit down and try to learn one of those. For me, Clojure was always one of those languages that kindled the "what the hell is that" feeling in me, but after reading a lot of praise for the language, I started learning it anyways.
Now I work on Clojure(Script) code full-time, and programming is finally a fun thing to do again.
I won't try to learn Common Lisp or anything like that next, as I know that if I spent the time, it'd be easy, it's just Clojure but with different functions to call, different conventions, but mostly the same. So the next language I'm targeting is Rust. A C-like language, but new concepts around the borrow-checker and lifetimes, something I've been exposed to before, but not this literally.
I haven't written FORTH code in ages, but I still enjoy reading well written FORTH code for its pure literary pleasure!
https://github.com/MitchBradley/openfirmware/blob/master/for...
So, either Prolog, or Lisp.
Structure and Interpretation of Computer Programs is a good jumping off point for Lisp while also providing fundamental insights.
Prolog.. honestly, just google "basic" array problems and try and do them in prolog. It takes a mental shift, which is hard at first, and you feel silly not being able to count to 10. But learning how to think in this paradigm is useful - e.g. SQL is declarative.
Now you can play a request and boom, you have your code to make this request in your favorite programming language.
I presume they were trying to keep the code to 4 lines or so. The curl library in PHP is rather verbose and requires 5 to 8 lines (depending on if you try to catch the error).
I expect that we'd accept a PR for PHP curl library implementation. Having a non-third-party option would be valuable.
Also check the other pages on the docs.
Here's one example:
file_get_contents('https://ntfy.sh/mytopic', false, stream_context_create([
'http' => [
'method' => 'POST', // PUT also works
'header' => 'Content-Type: text/plain',
'content' => 'Backup successful '
]
]));https://ryan.govost.es/http-translator/ | https://github.com/rgov/http-translator
Mine was a project for learning modern-ish JavaScript, and I found that packages for parsing command line arguments in JS were generally poor. I wrote my own shell lexer that is simpler than Eric S. Raymond's in the Python standard library while passing the test suite, and since Burp Suite generates curl commands that use Bash ANSI C strings, I support those too. https://www.npmjs.com/package/shlex
If I were to do further development, I would ditch my curl command line parsing in favor of building curl with Emscripten and having it generate the full HTTP request, then leverage the existing request parser.
curl already supports a —-libcurl flag that generates equivalent C code, and it might be easy to extract the curl_easy_setopt() calls from it.
Both our projects should probably support the built-in urllib.request for Python; Requests isn’t always necessary anymore.
curl-to-Go
curl-to-PHP
HAR-to-curl
http-translator (Python, JS and JSON)
uncurl (to Python)
hrbrmstr/curlconverter (to R)
curl-to-postman
Insomnia
Paw-cURLImporter public HttpResponse<String> fetch(String url) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
return client.send(request, BodyHandlers.ofString());
}The problem is that even if your own code uses SLF4j correctly as a logging API, and then wires up the correct logging implementation (e.g. Logback, Log4j2, etc), and then finally include the necessary SLF4j "bridge" libraries, you still need to ensure that every 3rd party transitive dependency explicitly excludes Commons Logging, Log4j, etc libraries.
It's a mess, and almost none of projects that I've worked on over the years got it 100% right the first time.
That being said, I see the exact same problem in a lot of the modern Python and Node code that's out there. It just becomes too complicated because there are too many logging options, and when a modern project - in any language - now relies on dozens of 3rd party libraries, then it's likely you're ending up with 5 different incompatible logging implementations in your final runtime, all doing their own thing.
It is a perfect example of the famous XKCD "multiple competing standards."
$ curl —-libcurl curl.c ...
libcurl only gets weird when you're threading multiple fetches or integrating with a GUI toolkit or something. Even then it's not hard at all to integrate with GTK unless you need absolute peak performance or are handling tens of thousands of simultaneous connections.
libcurl does stuff like open files for reading, so you would have to at least modify the code to just pass the file name, you also have to modify the struct.
libcurl parses an array of strings, but curlconverter gets a Bash AST (or a list of strings if you use it from the command line). When there's a bash variable in the command, we want to generate code that gets that environment variable at runtime, e.g. `os.environ['MY_VARIABLE']` in Python so the struct needs to store pointers to AST nodes instead of strings/booleans/ints. Though to be fair curlconverter doesn't work this way either (yet), we convert AST nodes to strings/booleans/ints after command parsing and store that, then when we're generating the code if we see a $ in a string we assume that was a variable in the input AST.
https://github.com/RicoSuter/NSwag
We use it on a project at work in C# and I've also been using it personally on pet projects with TypeScript.
Allows you to automatically generate REST API clients based on Swagger/OpenAPI specs and is very customizable.
Really nice if building out microservices and you're wanting to communicate between each other or building web apps and want to communicate with APIs. Saves a lot of time writing code to make requests and handle different status codes etc. Automatically generates all the classes/interfaces with sane naming schemes etc.
Even has a GUI application to generate the configs also if you wish.
Also, funny enough, the first command I tried didn't work as I expected, but thinking about it, it also seems hard to implement correctly. The cURL command I tried was "curl -v https://google.com/" but none of the implementations include verbose logging.
Weirdly, JSON is listed there, and it is absolutely not clear how JSON can be considered a language that can make HTTP requests. I wonder what client library that is?
import subprocess
import json
result = subprocess.run(['curlconverter', '--language', 'json', 'example.com'], capture_output=True, text=True)
command = json.loads(result.stdout)
print(command)Had completed UI part as of now https://news.ycombinator.com/item?id=30642254
That being said turn off all tracking in postman. I got a creepy sales email once asking about my usage and they had a lot of details that made me feel creepy.
I've developed in Python for >6 years, with tons of deep exploration of the common libraries, and been working in Go for like 3 months - in terms of my ability to understand them, I'll take most Go libraries over Python any day.
also it's only one more line, but they didn't even bother to print the response
once you look at the fact that Go has to have `func main()` declared, the response printing, and the error handling, Go only has a couple more lines than Python
httpConn.getResponseCode() / 100 == 2
instead of:
httpConn.getResponseCode() == 200
They even have some resources to let you turn into python, go, and a few other languages.