turash/eu_funding_api.go
Damir Mukimov 0161394b9b
Initial commit: Turash Industrial Symbiosis Platform
- Complete platform specification and architecture
- MVP concept and business model
- Technical implementation plans and roadmaps
- Financial projections and funding strategy
- Brand identity and marketing materials
- Mathematical models for resource matching
- Competitive analysis and market research
- Go-based core models and algorithms

Turash guides businesses to optimal resource exchanges, navigating the complex landscape of industrial symbiosis and providing direction to sustainable profitability.
2025-11-25 05:34:50 +01:00

371 lines
10 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"strings"
"time"
)
// EUFundingAPI represents the EU Funding & Tenders Portal API client
type EUFundingAPI struct {
BaseURL string
SearchAPIKey string
FAQAPIKey string
PersonAPIKey string
Client *http.Client
}
// NewEUFundingAPI creates a new API client instance
func NewEUFundingAPI() *EUFundingAPI {
return &EUFundingAPI{
BaseURL: "https://api.tech.ec.europa.eu/search-api/prod/rest",
SearchAPIKey: "SEDIA",
FAQAPIKey: "SEDIA_FAQ",
PersonAPIKey: "SEDIA_PERSON",
Client: &http.Client{
Timeout: 30 * time.Second,
},
}
}
// SearchQuery represents the Elasticsearch query structure
type SearchQuery struct {
Bool struct {
Must []interface{} `json:"must"`
} `json:"bool"`
}
// APIResponse represents the standard API response
type APIResponse struct {
Results []map[string]interface{} `json:"results"`
Total int `json:"total"`
}
// makeRequest performs HTTP requests to the API
func (api *EUFundingAPI) makeRequest(endpoint string, method string, data interface{}) (*APIResponse, error) {
var body io.Reader
if data != nil && method == "POST" {
jsonData, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("failed to marshal request data: %v", err)
}
body = bytes.NewBuffer(jsonData)
}
req, err := http.NewRequest(method, endpoint, body)
if err != nil {
return nil, fmt.Errorf("failed to create request: %v", err)
}
req.Header.Set("User-Agent", "EU-Funding-API-Client-Go/1.0")
req.Header.Set("Accept", "application/json")
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
resp, err := api.Client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
}
var response APIResponse
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
return nil, fmt.Errorf("failed to decode response: %v", err)
}
return &response, nil
}
// SearchGrantsTenders searches for grants and tenders
func (api *EUFundingAPI) SearchGrantsTenders(query *SearchQuery) (*APIResponse, error) {
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.SearchAPIKey)
if query == nil {
// Default query to get all grants and tenders
query = &SearchQuery{}
query.Bool.Must = []interface{}{
map[string]interface{}{
"terms": map[string][]string{
"type": {"0", "1", "2", "8"}, // All types
},
},
map[string]interface{}{
"terms": map[string][]string{
"status": {"31094501", "31094502", "31094503"}, // All statuses
},
},
}
}
return api.makeRequest(endpoint, "POST", query)
}
// GetTopicDetails gets detailed information about a specific topic
func (api *EUFundingAPI) GetTopicDetails(topicIdentifier string) (*APIResponse, error) {
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=\"%s\"", api.BaseURL, api.SearchAPIKey, topicIdentifier)
return api.makeRequest(endpoint, "GET", nil)
}
// SearchGrantUpdates searches for grant updates
func (api *EUFundingAPI) SearchGrantUpdates(frameworkProgramme string) (*APIResponse, error) {
query := &SearchQuery{}
query.Bool.Must = []interface{}{
map[string]interface{}{
"terms": map[string][]string{
"type": {"6"}, // Grant updates
},
},
}
if frameworkProgramme != "" {
query.Bool.Must = append(query.Bool.Must, map[string]interface{}{
"terms": map[string][]string{
"frameworkProgramme": {frameworkProgramme},
},
})
}
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.SearchAPIKey)
return api.makeRequest(endpoint, "POST", query)
}
// SearchFAQs searches FAQs
func (api *EUFundingAPI) SearchFAQs(programme string) (*APIResponse, error) {
query := &SearchQuery{}
query.Bool.Must = []interface{}{
map[string]interface{}{
"terms": map[string][]string{
"type": {"0", "1"}, // FAQ types
},
},
map[string]interface{}{
"terms": map[string][]string{
"status": {"0", "1"}, // All statuses
},
},
}
if programme != "" {
query.Bool.Must = append(query.Bool.Must, map[string]interface{}{
"term": map[string]string{
"programme": programme,
},
})
}
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.FAQAPIKey)
return api.makeRequest(endpoint, "POST", query)
}
// GetOrganizationData gets organization public data
func (api *EUFundingAPI) GetOrganizationData(picCode string) (*APIResponse, error) {
endpoint := fmt.Sprintf("%s/document/%s?apiKey=%s", api.BaseURL, picCode, api.PersonAPIKey)
return api.makeRequest(endpoint, "GET", nil)
}
// SearchPartners searches for partners in a specific topic
func (api *EUFundingAPI) SearchPartners(topic string) (*APIResponse, error) {
query := &SearchQuery{}
query.Bool.Must = []interface{}{
map[string]interface{}{
"terms": map[string][]string{
"topics": {topic},
},
},
map[string]interface{}{
"terms": map[string][]string{
"type": {"ORGANISATION", "PERSON"},
},
},
}
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.SearchAPIKey)
return api.makeRequest(endpoint, "POST", query)
}
// SearchProjects searches for EU funded projects
func (api *EUFundingAPI) SearchProjects(programmeID, missionGroup string) (*APIResponse, error) {
query := &SearchQuery{}
if programmeID != "" {
query.Bool.Must = append(query.Bool.Must, map[string]interface{}{
"terms": map[string][]string{
"programId": {programmeID},
},
})
}
if missionGroup != "" {
query.Bool.Must = append(query.Bool.Must, map[string]interface{}{
"terms": map[string][]string{
"missionGroup": {missionGroup},
},
})
}
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.SearchAPIKey)
return api.makeRequest(endpoint, "POST", query)
}
func main() {
fmt.Println("EU Funding & Tenders Portal API Client (Go)")
fmt.Println("=" + strings.Repeat("=", 50))
api := NewEUFundingAPI()
// Example 1: Search for EIC Accelerator opportunities
fmt.Println("\n1. Searching for EIC Accelerator opportunities...")
eicQuery := &SearchQuery{}
eicQuery.Bool.Must = []interface{}{
map[string]interface{}{
"terms": map[string][]string{
"type": {"1", "2", "8"}, // Grants
},
},
map[string]interface{}{
"terms": map[string][]string{
"status": {"31094501", "31094502", "31094503"}, // All statuses
},
},
map[string]interface{}{
"term": map[string]string{
"callIdentifier": "HORIZON-EIC-2026-ACCELERATOR-01",
},
},
}
results, err := api.SearchGrantsTenders(eicQuery)
if err != nil {
log.Printf("Error searching grants: %v", err)
} else {
fmt.Printf("Found %d EIC Accelerator opportunities\n", len(results.Results))
for i, result := range results.Results {
if i >= 3 { // Show first 3
break
}
if title, ok := result["title"].(string); ok {
fmt.Printf("- %s\n", title)
}
}
}
// Example 2: Get topic details for EIC Accelerator
fmt.Println("\n2. Getting EIC Accelerator topic details...")
topicDetails, err := api.GetTopicDetails("HORIZON-EIC-2026-ACCELERATOR-01")
if err != nil {
log.Printf("Error getting topic details: %v", err)
} else {
fmt.Println("Topic details retrieved successfully")
if len(topicDetails.Results) > 0 {
topic := topicDetails.Results[0]
if title, ok := topic["title"].(string); ok {
fmt.Printf("Title: %s\n", title)
}
if status, ok := topic["status"].(string); ok {
fmt.Printf("Status: %s\n", status)
}
if deadline, ok := topic["deadline"].(string); ok {
fmt.Printf("Deadline: %s\n", deadline)
}
}
}
// Example 3: Search for grant updates
fmt.Println("\n3. Searching for recent grant updates...")
updates, err := api.SearchGrantUpdates("43108390") // Horizon Europe
if err != nil {
log.Printf("Error searching updates: %v", err)
} else {
fmt.Printf("Found %d grant updates\n", len(updates.Results))
}
// Example 4: Search FAQs
fmt.Println("\n4. Searching for FAQs...")
faqs, err := api.SearchFAQs("")
if err != nil {
log.Printf("Error searching FAQs: %v", err)
} else {
fmt.Printf("Found %d FAQs\n", len(faqs.Results))
}
fmt.Println("\nGo API client demonstration completed!")
}
// EICAcceleratorMonitor monitors EIC Accelerator opportunities
func EICAcceleratorMonitor() {
fmt.Println("EIC Accelerator Monitor")
fmt.Println("=" + strings.Repeat("=", 30))
api := NewEUFundingAPI()
// Query for EIC Accelerator opportunities
query := &SearchQuery{}
query.Bool.Must = []interface{}{
map[string]interface{}{
"terms": map[string][]string{
"type": {"1", "2", "8"},
},
},
map[string]interface{}{
"terms": map[string][]string{
"status": {"31094501", "31094502"}, // Open and forthcoming
},
},
map[string]interface{}{
"term": map[string]string{
"frameworkProgramme": "43108390", // Horizon Europe
},
},
map[string]interface{}{
"query_string": map[string]interface{}{
"query": "EIC Accelerator",
"default_field": "title",
},
},
}
results, err := api.SearchGrantsTenders(query)
if err != nil {
log.Printf("Error monitoring EIC Accelerator: %v", err)
return
}
if results != nil && len(results.Results) > 0 {
fmt.Printf("Found %d EIC Accelerator opportunities:\n", len(results.Results))
for _, opp := range results.Results {
title := getStringValue(opp, "title")
identifier := getStringValue(opp, "identifier")
status := getStringValue(opp, "status")
deadline := getStringValue(opp, "deadline")
fmt.Printf("\n📋 %s\n", title)
fmt.Printf(" ID: %s\n", identifier)
fmt.Printf(" Status: %s\n", status)
fmt.Printf(" Deadline: %s\n", deadline)
}
} else {
fmt.Println("No EIC Accelerator opportunities found")
}
}
// Helper function to safely get string values from map
func getStringValue(data map[string]interface{}, key string) string {
if value, ok := data[key].(string); ok {
return value
}
return "N/A"
}</content>
<parameter name="filePath">/Users/damirmukimov/city_resource_graph/eu_funding_api.go