1+ #ifndef PERPLEXITY_CPP_CONFIG_H
2+ #define PERPLEXITY_CPP_CONFIG_H
3+ #pragma once
4+
5+ #include < string>
6+ #include < optional>
7+ #include < chrono>
8+ #include " exceptions.h"
9+
10+ namespace perplexity {
11+
12+ /* *
13+ * @brief Configuration of the Perplexity API client
14+ *
15+ * Uses the Builder pattern for convenient configuration.
16+ * Applies RAII for secure resource management.
17+ */
18+ class Config {
19+ private:
20+ std::string api_key_;
21+ std::string base_url_ = " https://api.perplexity.ai" ;
22+ std::chrono::seconds timeout_{30 };
23+ int max_retries_ = 3 ;
24+ bool verify_ssl_ = true ;
25+ std::optional<std::string> proxy_;
26+ std::optional<std::string> user_agent_;
27+
28+ // Rate limiting configuration
29+ bool enable_rate_limiting_ = true ;
30+ int max_requests_per_minute_ = 60 ;
31+
32+ public:
33+ Config () = default ;
34+ explicit Config (std::string api_key) : api_key_(std::move(api_key)) {
35+ if (api_key_.empty ()) {
36+ throw ConfigurationError (" API key cannot be empty" );
37+ }
38+ }
39+
40+ // Builder methods (Fluent Interface)
41+ Config& api_key (std::string key) {
42+ if (key.empty ()) {
43+ throw ConfigurationError (" API key cannot be empty" );
44+ }
45+ api_key_ = std::move (key);
46+ return *this ;
47+ }
48+
49+ Config& base_url (std::string url) {
50+ if (url.empty ()) {
51+ throw ConfigurationError (" Base URL cannot be empty" );
52+ }
53+ base_url_ = std::move (url);
54+ return *this ;
55+ }
56+
57+ Config& timeout (std::chrono::seconds t) {
58+ if (t.count () <= 0 ) {
59+ throw ConfigurationError (" Timeout must be positive" );
60+ }
61+ timeout_ = t;
62+ return *this ;
63+ }
64+
65+ Config& max_retries (int retries) {
66+ if (retries < 0 ) {
67+ throw ConfigurationError (" Max retries cannot be negative" );
68+ }
69+ max_retries_ = retries;
70+ return *this ;
71+ }
72+
73+ Config& verify_ssl (bool verify) {
74+ verify_ssl_ = verify;
75+ return *this ;
76+ }
77+
78+ Config& proxy (std::string proxy_url) {
79+ proxy_ = std::move (proxy_url);
80+ return *this ;
81+ }
82+
83+ Config& user_agent (std::string agent) {
84+ user_agent_ = std::move (agent);
85+ return *this ;
86+ }
87+
88+ Config& enable_rate_limiting (bool enable) {
89+ enable_rate_limiting_ = enable;
90+ return *this ;
91+ }
92+
93+ Config& max_requests_per_minute (int max_requests) {
94+ if (max_requests <= 0 ) {
95+ throw ConfigurationError (" Max requests per minute must be positive" );
96+ }
97+ max_requests_per_minute_ = max_requests;
98+ return *this ;
99+ }
100+
101+ // Getters
102+ const std::string& get_api_key () const { return api_key_; }
103+ const std::string& get_base_url () const { return base_url_; }
104+ std::chrono::seconds get_timeout () const { return timeout_; }
105+ int get_max_retries () const { return max_retries_; }
106+ bool should_verify_ssl () const { return verify_ssl_; }
107+ const std::optional<std::string>& get_proxy () const { return proxy_; }
108+ const std::optional<std::string>& get_user_agent () const { return user_agent_; }
109+ bool is_rate_limiting_enabled () const { return enable_rate_limiting_; }
110+ int get_max_requests_per_minute () const { return max_requests_per_minute_; }
111+
112+ // Configuration validation
113+ void validate () const {
114+ if (api_key_.empty ()) {
115+ throw ConfigurationError (" API key must be set" );
116+ }
117+ if (base_url_.empty ()) {
118+ throw ConfigurationError (" Base URL must be set" );
119+ }
120+ if (timeout_.count () <= 0 ) {
121+ throw ConfigurationError (" Timeout must be positive" );
122+ }
123+ }
124+
125+ // Creating a configuration from environment variables
126+ static Config from_environment () {
127+ const char * api_key_env = std::getenv (" PERPLEXITY_API_KEY" );
128+ if (!api_key_env) {
129+ throw ConfigurationError (
130+ " PERPLEXITY_API_KEY environment variable not set"
131+ );
132+ }
133+
134+ Config config (api_key_env);
135+
136+ if (const char * base_url_env = std::getenv (" PERPLEXITY_BASE_URL" )) {
137+ config.base_url (base_url_env);
138+ }
139+
140+ if (const char * timeout_env = std::getenv (" PERPLEXITY_TIMEOUT" )) {
141+ try {
142+ int timeout_seconds = std::stoi (timeout_env);
143+ config.timeout (std::chrono::seconds (timeout_seconds));
144+ } catch (const std::exception&) {
145+ throw ConfigurationError (" Invalid PERPLEXITY_TIMEOUT value" );
146+ }
147+ }
148+
149+ if (const char * proxy_env = std::getenv (" PERPLEXITY_PROXY" )) {
150+ config.proxy (proxy_env);
151+ }
152+
153+ return config;
154+ }
155+ };
156+
157+ } // namespace perplexity
158+ #endif // PERPLEXITY_CPP_CONFIG_H
0 commit comments