A simple Nim REST client for the DataForSEO API (v3). No dependencies (stdlib only), supports both sync and async requests.
This library is intentially low-level and you must refer to the (well-designed) API documentation for proper usage- no hand holding, minimal abstractions. We are using DataForSEO as part of our tooling ecosytem for my SEO agency, SEO Science. We unfortunately do not have the time to make a high-level API and keep up with all changes DFSEO may make.
Updates to this repository will be sporadic, as needed.
The API is expansive and covers endpoints we'll never use, such as the Baidu search engine. These endpoints will likely never be implemented by us.
This doesn't make the library unusable- quite the contrary. We designed the API to be extremely straightforward and simple. The Extending The API section details how you can create an endpoint that isn't currently supported. PRs are welcomed ;)
git clone https://github.com/Niminem/DataForSEO
or (when it's available on Nimble):
nimble install dataforseo
# main.nim
import std/[strutils, json]
import dataforseo
let creds = readFile("creds.txt").splitWhitespace()
var client = newDFSClient(login=creds[0], password=creds[1])
let
keyword = "seo consultant"
data = %*[{"keywords": [keyword]}]
response = client.fetch(ClickstreamGlobalSearchVolume, data)
assert response.code == Http200
let body = response.body.parseJson()
assert body["status_code"].getInt() == 20000
let globalsearchvol = body["tasks"][0]["result"][0]["items"][0]["search_volume"].getInt()
echo "Keyword: ", keyword
echo "Global Search Volume: ", globalsearchvol
client.close()
# nim c -r -d:ssl main.nim
This library supports synchronous and asynchronous requests
via newDFSClient
and newAsyncDFSClient
respectively. Both clients are simply aliases for the http clients within std/httpclient
.
There are currently only two basic functions:
# 1.) DataForSEO HTTPClient
proc newDFSClient*(login, password: string): DFSClient
proc newAsyncDFSClient*(login, password: string): AsyncDFSClient
# 2.) Performs requests for the client
proc fetch*(client: DFSClient | AsyncDFSClient; req: DFSRequest; taskData: JsonNode):
Future[Response | AsyncResponse] {.multisync.}
When calling fetch
, you'll be providing two key arguments:
- req:
DFSRequest
- taskData:
JsonNode
req
is simply a tuple, with the type of http request and the endpoint:
type DFSRequest* = tuple[mthd: HttpMethod, endpoint: string]
We already defined many DFSRequest
constants, named after the endpoint, like what we see above with ClickstreamGlobalSearchVolume.
Refer to the DataForSEO API documentation to see the name of the endpoint you need. If we don't have it yet, the section below will show you how to support it. Again, PRs are welcomed.
taskData
is simply a JsonNode
containing the data structure DataForSEO expects for that endpoint.
%*[{"keywords": [keyword]}]
in the case above.
NOTE: All error handling, abstracting the response body, etc. falls on the developer.
src/dataforseo/endpoints/common
exports the following to help you support wanted endpoints:
type DFSRequest* = tuple[mthd: HttpMethod, endpoint: string]
const EndpointBase* = "https://api.dataforseo.com/v3/"
All you need to do is create a DFSRequest
based on your API.
An example:
const
HistoricalBulkTrafficEstimation*: DFSRequest = (HttpPost,
EndpointBase & "dataforseo_labs/google/historical_bulk_traffic_estimation/live")
Yep. That's it. Just make sure the appropriate HTTP request and endpoint matches, and you'll be able to use any endpoint this way.
# ...
let response = client.fetch(HistoricalBulkTrafficEstimation, myData)
# ...