Files
Georgios Komninos af155eecb7 feat: Adds saas mode and provisioner (#239)
This patch adds functionality to automatically
provisiomn a webserver that exposes:
- a REST API to submit keywords for scraping
- a WebUI to automatically workers
2026-03-08 15:32:24 +02:00

469 lines
17 KiB
Go

// Package docs Code generated by swaggo/swag. DO NOT EDIT
package docs
import "github.com/swaggo/swag"
const docTemplate = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"contact": {
"name": "API Support",
"url": "https://github.com/gosom/google-maps-scraper"
},
"license": {
"name": "MIT",
"url": "https://opensource.org/licenses/MIT"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/api/v1/health": {
"get": {
"description": "Check if the API service is healthy",
"produces": [
"application/json"
],
"tags": [
"health"
],
"summary": "Health check",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.HealthCheckResponse"
}
}
}
}
},
"/api/v1/jobs": {
"get": {
"description": "List all scrape jobs with pagination and optional state filtering",
"produces": [
"application/json"
],
"tags": [
"scrape"
],
"summary": "List jobs",
"parameters": [
{
"type": "string",
"description": "Filter by state (available, running, completed, cancelled, discarded, pending, retryable, scheduled)",
"name": "state",
"in": "query"
},
{
"type": "integer",
"description": "Number of jobs to return (default: 20, max: 100)",
"name": "limit",
"in": "query"
},
{
"type": "string",
"description": "Cursor for pagination",
"name": "cursor",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.ListJobsResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
},
"/api/v1/jobs/{job_id}": {
"get": {
"description": "Get the status and results of a scrape job",
"produces": [
"application/json"
],
"tags": [
"scrape"
],
"summary": "Get job status",
"parameters": [
{
"type": "string",
"description": "Job ID",
"name": "job_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/api.JobStatusResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
},
"delete": {
"description": "Queues deletion of a job and its results. Running jobs are cancelled first.",
"tags": [
"scrape"
],
"summary": "Delete a job",
"parameters": [
{
"type": "string",
"description": "Job ID",
"name": "job_id",
"in": "path",
"required": true
}
],
"responses": {
"202": {
"description": "Accepted",
"schema": {
"$ref": "#/definitions/api.DeleteJobResponse"
}
},
"400": {
"description": "Invalid job ID",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"404": {
"description": "Job not found",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
},
"/api/v1/scrape": {
"post": {
"description": "Submit a new Google Maps scrape job for processing",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"scrape"
],
"summary": "Submit a scrape job",
"parameters": [
{
"description": "Scrape request parameters",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api.ScrapeRequest"
}
}
],
"responses": {
"202": {
"description": "Accepted",
"schema": {
"$ref": "#/definitions/api.ScrapeResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
}
},
"definitions": {
"api.DeleteJobResponse": {
"description": "Response returned after successfully queueing a job for deletion",
"type": "object",
"properties": {
"message": {
"description": "Status message",
"type": "string",
"example": "deletion queued"
}
}
},
"api.ErrorResponse": {
"description": "Error response returned when a request fails",
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "invalid request body"
}
}
},
"api.HealthCheckResponse": {
"description": "Health check response indicating service status",
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "ok"
}
}
},
"api.JobStatusResponse": {
"description": "Detailed status of a scrape job including results when completed",
"type": "object",
"properties": {
"completed_at": {
"description": "When the job completed",
"type": "string",
"example": "2024-01-15T10:35:00Z"
},
"created_at": {
"description": "When the job was created",
"type": "string",
"example": "2024-01-15T10:30:00Z"
},
"error": {
"description": "Error message if job failed",
"type": "string",
"example": ""
},
"job_id": {
"description": "Unique job identifier",
"type": "string",
"example": "kYzR8xLmNpQvWjX3"
},
"keyword": {
"description": "Search keyword used for this job",
"type": "string",
"example": "restaurants in New York"
},
"result_count": {
"description": "Number of results found",
"type": "integer",
"example": 25
},
"results": {
"description": "Scrape results (array of place data)"
},
"started_at": {
"description": "When the job started processing",
"type": "string",
"example": "2024-01-15T10:30:05Z"
},
"status": {
"description": "Current job status (pending, running, completed, failed)",
"type": "string",
"example": "completed"
}
}
},
"api.JobSummary": {
"description": "Summary of a job without the full result data",
"type": "object",
"properties": {
"completed_at": {
"description": "When the job completed",
"type": "string",
"example": "2024-01-15T10:35:00Z"
},
"created_at": {
"description": "When the job was created",
"type": "string",
"example": "2024-01-15T10:30:00Z"
},
"error": {
"description": "Error message if job failed",
"type": "string",
"example": ""
},
"job_id": {
"description": "Unique job identifier (encoded)",
"type": "string",
"example": "kYzR8xLmNpQvWjX3"
},
"keyword": {
"description": "Search keyword used for this job",
"type": "string",
"example": "restaurants in New York"
},
"result_count": {
"description": "Number of results found",
"type": "integer",
"example": 25
},
"started_at": {
"description": "When the job started processing",
"type": "string",
"example": "2024-01-15T10:30:05Z"
},
"status": {
"description": "Current job status",
"type": "string",
"example": "completed"
}
}
},
"api.ListJobsResponse": {
"description": "Paginated list of jobs with cursor for next page",
"type": "object",
"properties": {
"has_more": {
"description": "Whether there are more results",
"type": "boolean",
"example": true
},
"jobs": {
"description": "List of jobs",
"type": "array",
"items": {
"$ref": "#/definitions/api.JobSummary"
}
},
"next_cursor": {
"description": "Cursor for next page (empty if no more results)",
"type": "string",
"example": "eyJpZCI6MTIzfQ=="
}
}
},
"api.ScrapeRequest": {
"description": "Request body for submitting a scrape job",
"type": "object",
"properties": {
"email": {
"description": "Whether to extract email addresses from websites",
"type": "boolean",
"example": false
},
"extra_reviews": {
"description": "Extract additional reviews",
"type": "boolean",
"example": false
},
"fast_mode": {
"description": "Use fast mode (stealth HTTP instead of browser)",
"type": "boolean",
"example": false
},
"geo_coordinates": {
"description": "Geographic coordinates in \"lat,lon\" format",
"type": "string",
"example": "40.7128,-74.0060"
},
"keyword": {
"description": "Search keyword (e.g., \"restaurants in New York\")",
"type": "string",
"example": "restaurants in New York"
},
"lang": {
"description": "Language code for results (default: \"en\")",
"type": "string",
"example": "en"
},
"max_depth": {
"description": "Maximum depth for pagination (default: 1, max: 100)",
"type": "integer",
"example": 1
},
"radius": {
"description": "Search radius in kilometers",
"type": "number",
"example": 5
},
"timeout": {
"description": "Job timeout in seconds (1-300, default: 300)",
"type": "integer",
"example": 300
},
"zoom": {
"description": "Zoom level for map search (1-21)",
"type": "integer",
"example": 14
}
}
},
"api.ScrapeResponse": {
"description": "Response returned after successfully submitting a scrape job",
"type": "object",
"properties": {
"job_id": {
"description": "Unique job identifier",
"type": "string",
"example": "kYzR8xLmNpQvWjX3"
},
"status": {
"description": "Current job status",
"type": "string",
"example": "pending"
}
}
}
}
}`
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "1.0",
Host: "localhost:8080",
BasePath: "/",
Schemes: []string{"http", "https"},
Title: "Google Maps Scraper Pro API",
Description: "API for scraping Google Maps data asynchronously",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}
func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}