HOME / BLOG / 42API Projects
42API Projects
over 1 year
2023 03
In this tutorial we will explore how to fetch information from 42API using Ruby.
We just launched an easter Hackathon, for that you will need to use 42API and fetch data from there!
In this tutorial you will learn how to integrate 42API into your project, or download the data to your computer and later parse it as you want.
We are lucky to have an API available, which is made possible by 42dev team, so shoutout to them! 😊
[Few schools make that possible]
❹❷ 🫶
In this tutorial you will learn how to integrate 42API into your project, or download the data to your computer and later parse it as you want.
We are lucky to have an API available, which is made possible by 42dev team, so shoutout to them! 😊
[Few schools make that possible]
❹❷ 🫶
What is even an API?
APIs enable a commmunication mechanism using defined protocols in order to interact with the application.
Okay okay, that is a very wordy and rigurous explanation, in simple words; an API is a tool that helps you interact with an application.
For example, let's say you want to create a bot for your Discord Server, then you can use Discord's API to automate your bot answers and process the input.
Another example, which is the case for this project. You want to know 42 projects and you want to retrieve all the projects that a certain user already compleated.
Okay okay, that is a very wordy and rigurous explanation, in simple words; an API is a tool that helps you interact with an application.
For example, let's say you want to create a bot for your Discord Server, then you can use Discord's API to automate your bot answers and process the input.
Another example, which is the case for this project. You want to know 42 projects and you want to retrieve all the projects that a certain user already compleated.
API stands for Application Programming Interface. In the context of APIs, the word Application refers to any software with a distinct function. Interface can be thought of as a contract of service between two applications. This contract defines how the two communicate with each other using requests and responses. Their API documentation contains information on how developers are to structure those requests and responses. "https://aws.amazon.com/what-is/api/"
42API is a RESTful kind of API and it uses JSON over HTTPS.
What are REST APIs and what does it mean JSON over HTTPS???
HTTPS is a secure protocole, and JSON is an acronym for JS Object Notation, it is a format pattern to exchange data.
REST stands for Representational State Transfer. REST defines a set of functions like GET, PUT, DELETE, etc. that clients can use to access server data. Clients and servers exchange data using HTTP.
We only need to use GET, because we will only fetch data from 42, we don't want to update data create or delete any data.
We only need to use GET, because we will only fetch data from 42, we don't want to update data create or delete any data.
Setup
42 protects the data and it is not supposed to be open to the public, that is why you must generate some credentials to access 42API. You can get your credentials on intra.
Go to settings ⚙️ → API → REGISTER NEW APP → fill the form → Submit.
Go to settings ⚙️ → API → REGISTER NEW APP → fill the form → Submit.
How to fill the FORM:
- Name: Choose whatever you want
- Image: [Optional] If you want you can choose one
- Description: The description about your project and why you need 42API
- Website: [Optional] You can put a link for other people to visit your app
- Redirect URI: You don't need it now for this example, just put https://profile.intra.42.fr or something like that.
- Scopes: Don't change it.
Then you wil have access to the UID and SECRET, you need this two strings to access the API.
[NEVER EVER EVER EVER SHARE YOUR SECRET OR PUBLISH IT TO GITHUB!]
You also need to install ruby and oauth2
Most OS's have ruby preinstalled ;)
Once you've installed ruby just do:
gem install oauth2
GET all common-core projects from 42API
42 API
We must use the Endpoint /v2/cursus/:cursus_id/projects. It will return exactly what we want, but there is something we must concider first...
What is the :cursus_id? And why does it have ":"? When you see that format it means that you must replace that with the actuall id, of course the cursus id. So we should find out what is the common core cursus_id so we can retrieve all projects from there.
You will find that there is a section on the API cursus and there we can consult the 42 common core id, the name might change but it's common sense to find the correct id.
RUBY
Tested with ruby versions:
- ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20]
- ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin20]
cursus.rb
require "oauth2" puts "What is your UID?" UID = gets.chomp puts "What is your SECRET?" SECRET = gets.chomp client = OAuth2::Client.new(UID, SECRET, site: "https://api.intra.42.fr") if (not client) puts "Sorry, could't resolve any client with those credentials" end token = client.client_credentials.get_token puts "Generated the token 🔑, now fetching v2/cursus" response = token.get("/v2/cursus") puts "Reponse Status: #{response.status}" # => 200 SUCCESS puts response.parsed
Execute the script:
ruby cursus.rb
JSON
{"id"=>67, "created_at"=>"2023-03-22T07:11:41.847Z", "name"=>"42 events", "slug"=>"42-events", "kind"=>"external"} {"id"=>66, "created_at"=>"2023-03-08T08:57:17.181Z", "name"=>"C-Piscine-Reloaded", "slug"=>"c-piscine-reloaded", "kind"=>"external"} {"id"=>65, "created_at"=>"2022-12-20T13:37:48.590Z", "name"=>"C Piscine Antwerp", "slug"=>"c-piscine-antwerp", "kind"=>"piscine"} {"id"=>64, "created_at"=>"2022-12-20T13:36:59.815Z", "name"=>"C Piscine Brussels", "slug"=>"c-piscine-brussels", "kind"=>"piscine"} {"id"=>63, "created_at"=>"2022-06-15T15:51:56.477Z", "name"=>"Discovery | Nice", "slug"=>"discovery-nice", "kind"=>"external"} {"id"=>62, "created_at"=>"2022-04-22T05:21:02.828Z", "name"=>"Abu Dhabi", "slug"=>"abu-dhabi", "kind"=>"external"} {"id"=>61, "created_at"=>"2022-04-11T09:23:58.639Z", "name"=>"CodingInActionLabs", "slug"=>"codinginactionlabs", "kind"=>"external"} {"id"=>60, "created_at"=>"2022-03-16T13:54:08.992Z", "name"=>"42Cursus-WarmUp-SP", "slug"=>"42cursus-warmup-sp", "kind"=>"piscine_community"} {"id"=>59, "created_at"=>"2022-03-14T17:33:32.942Z", "name"=>"Turbo 4.2", "slug"=>"turbo-4-2", "kind"=>"external"} {"id"=>58, "created_at"=>"2022-03-02T12:43:51.471Z", "name"=>"Bootcamp Cybersecurity", "slug"=>"bootcamp-cybersecurity", "kind"=>"external"} {"id"=>57, "created_at"=>"2022-02-18T21:15:10.672Z", "name"=>"42 Labs São Paulo", "slug"=>"42-labs-sao-paulo", "kind"=>"external"} {"id"=>56, "created_at"=>"2021-12-22T00:58:23.589Z", "name"=>"Seoul Labs", "slug"=>"seoul-labs", "kind"=>"external"} {"id"=>54, "created_at"=>"2021-10-21T19:02:56.177Z", "name"=>"NetworkTest", "slug"=>"networktest", "kind"=>"test"} {"id"=>53, "created_at"=>"2021-10-20T07:14:44.406Z", "name"=>"42.zip", "slug"=>"42-zip", "kind"=>"main"} {"id"=>52, "created_at"=>"2021-08-18T15:46:14.648Z", "name"=>"Basecamp Warm Up| Rio", "slug"=>"basecamp-warm-up-rio", "kind"=>"piscine_community"} {"id"=>51, "created_at"=>"2021-08-16T21:50:53.100Z", "name"=>"Basecamp | Rio", "slug"=>"basecamp-rio", "kind"=>"piscine_community"} {"id"=>50, "created_at"=>"2021-07-01T09:58:06.110Z", "name"=>"Road to", "slug"=>"road-to", "kind"=>"external"} {"id"=>49, "created_at"=>"2021-04-15T05:09:11.919Z", "name"=>"Hive Basecamp", "slug"=>"hive-basecamp", "kind"=>"piscine_community"} {"id"=>48, "created_at"=>"2021-04-06T04:53:28.009Z", "name"=>"problem-solving", "slug"=>"problem-solving", "kind"=>"external"} {"id"=>47, "created_at"=>"2021-03-11T18:45:50.082Z", "name"=>"Bocom test", "slug"=>"bocom-test", "kind"=>"test"} {"id"=>46, "created_at"=>"2021-02-13T19:34:26.027Z", "name"=>"GBRE", "slug"=>"gbre", "kind"=>"external"} {"id"=>44, "created_at"=>"2021-01-21T15:03:04.380Z", "name"=>"Paris Basecamp", "slug"=>"paris-basecamp", "kind"=>"piscine_community"} {"id"=>43, "created_at"=>"2021-01-11T16:38:46.008Z", "name"=>"Brussels Basecamp", "slug"=>"brussels-basecamp", "kind"=>"piscine_community"} {"id"=>42, "created_at"=>"2021-01-06T16:09:07.027Z", "name"=>"Germany Basecamp", "slug"=>"germany-basecamp", "kind"=>"piscine_community"} {"id"=>41, "created_at"=>"2021-01-04T20:55:03.543Z", "name"=>"Basecamp Warm Up Germany", "slug"=>"basecamp-warm-up-germany", "kind"=>"piscine_community"} {"id"=>40, "created_at"=>"2021-01-04T20:54:25.011Z", "name"=>"test-gb-v1", "slug"=>"test-gb-v1", "kind"=>"test"} {"id"=>39, "created_at"=>"2020-12-04T06:47:52.980Z", "name"=>"101", "slug"=>"101", "kind"=>"external"} {"id"=>38, "created_at"=>"2020-10-19T20:19:23.526Z", "name"=>"Basecamp WarmUp", "slug"=>"basecamp-warmup", "kind"=>"piscine_community"} {"id"=>37, "created_at"=>"2020-10-08T12:43:22.188Z", "name"=>"msk-test", "slug"=>"msk-test", "kind"=>"test"} {"id"=>36, "created_at"=>"2020-09-28T20:18:44.438Z", "name"=>"Basecamp", "slug"=>"basecamp", "kind"=>"piscine_community"}
In this case I didn't find my school cursus, and that is because this fetch is paginated. This means that not all the cursus will be returned, only X elements will be returned, and you can provide a number of the page to see more results.
Usually that is mentioned in the documentation, and in this case it was, it says:
Usually that is mentioned in the documentation, and in this case it was, it says:
This resource is paginated by 30 items
Although you can also just handle the data and count the number of elements with something like:
puts "The number of cursus in this page is: #{response.parsed.length}"
Let's review the Parameters listed on the Cursus 42API Reference Guide.
Let's say I want to display 10 elements maximum and I want to see any page, then you should change the code to the following example:
response = token.get("/v2/cursus", params: {page: {number: page_number, size: max_elements}})
Here it is an interactive script which produces the video bellow:
require "oauth2" puts "What is your UID?" UID = gets.chomp puts "What is your SECRET?" SECRET = gets.chomp client = OAuth2::Client.new(UID, SECRET, site: "https://api.intra.42.fr") begin token = client.client_credentials.get_token rescue puts "Sorry, could't resolve any client with those credentials" exit else puts "Generated the token 🔑, now fetching v2/cursus" end puts "How many elements do you want to see for each page?" max_elements = gets.chomp.to_i || 5 while (true) puts "Please input the page you want to see" page_number = gets.chomp.to_i begin response = token.get("/v2/cursus", params: {page: {number: page_number, size: max_elements}}) puts "Reponse Status: #{response.status}" rescue puts "Sorry something went wrong with the API or params" else info = response.parsed.map{|cursus| [cursus["id"], cursus["name"]]} puts "\e[H\e[2J" puts " # ID | NAME " puts "-------|------" info.each_with_index do |c, i| puts "[#{i + 1}] #{c.first} | #{c.last}" end end puts "The number of cursus for page #{page_number} is: #{response.parsed.length}" end
Now that we can see any cursus ID we can combine that to retrieve any project we want.
You might be overwhelmed by the amount of information that one single. project returns, but there are tools that can help you visualize the data easy so you can fetch anything you want.
In ruby you can convert a list to json with the to_json method, and that's what I did after fetching the project from curssus_id = 1. I printed the json result and then I used this tool to view the json easy. https://jsonviewer.com/
You might be overwhelmed by the amount of information that one single. project returns, but there are tools that can help you visualize the data easy so you can fetch anything you want.
In ruby you can convert a list to json with the to_json method, and that's what I did after fetching the project from curssus_id = 1. I printed the json result and then I used this tool to view the json easy. https://jsonviewer.com/
Now you can fetch the projects for a cursus! That is a great start, also if you want you can download my script to generate and see all the code.
There is also a GET fetch which returns a USER projects that one is quite good for the portfolio hackathon I think. With what you´ve lernt you should be able to retrieve that one!
There is also a GET fetch which returns a USER projects that one is quite good for the portfolio hackathon I think. With what you´ve lernt you should be able to retrieve that one!