-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[HOTFIX] change list backets method from HEAD to POST. And simplify m…
…igration on your server, example for languages (#14) * change contract for list buckets. HEAD -> POST * add example for go and python * simplify selfhost
- Loading branch information
Showing
11 changed files
with
327 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
/data/ | ||
/data/ | ||
.github/ | ||
/site/ | ||
/examples/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
## Golang example | ||
|
||
1. Change you api key ```apiKey := "CHANGE-ME"``` | ||
2. run ```go run ./examples/golang/main.go``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
) | ||
|
||
type KVRestAPI struct { | ||
APIKey string | ||
BaseURL string | ||
Client *http.Client | ||
} | ||
|
||
type BucketListResponse struct { | ||
Buckets []string `json:"buckets"` | ||
} | ||
|
||
type KeyListResponse struct { | ||
Keys []string `json:"keys"` | ||
} | ||
|
||
func NewKVRestAPI(apiKey string) *KVRestAPI { | ||
return &KVRestAPI{ | ||
APIKey: apiKey, | ||
BaseURL: "https://kvrest.dev/api", | ||
Client: &http.Client{}, | ||
} | ||
} | ||
|
||
func (api *KVRestAPI) makeRequest(method, endpoint string, body interface{}) ([]byte, error) { | ||
url := fmt.Sprintf("%s%s", api.BaseURL, endpoint) | ||
var reqBody []byte | ||
|
||
if body != nil { | ||
var err error | ||
reqBody, err = json.Marshal(body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
req, err := http.NewRequest(method, url, bytes.NewBuffer(reqBody)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
req.Header.Set("API-KEY", api.APIKey) | ||
req.Header.Set("Content-Type", "application/json") | ||
|
||
resp, err := api.Client.Do(req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
respBody, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if resp.StatusCode < 200 || resp.StatusCode >= 300 { | ||
return nil, fmt.Errorf("API request failed with status: %s, response: %s", resp.Status, string(respBody)) | ||
} | ||
|
||
return respBody, nil | ||
} | ||
|
||
func (api *KVRestAPI) CreateBucket(bucketName string) error { | ||
_, err := api.makeRequest("PUT", "/"+bucketName, nil) | ||
return err | ||
} | ||
|
||
func (api *KVRestAPI) DeleteBucket(bucketName string) error { | ||
_, err := api.makeRequest("DELETE", "/"+bucketName, nil) | ||
return err | ||
} | ||
|
||
func (api *KVRestAPI) ListBuckets() ([]string, error) { | ||
respBody, err := api.makeRequest("POST", "/buckets", nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var bucketResponse BucketListResponse | ||
err = json.Unmarshal(respBody, &bucketResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return bucketResponse.Buckets, nil | ||
} | ||
|
||
func (api *KVRestAPI) CreateOrUpdateKeyValue(bucketName, key string, value interface{}) error { | ||
_, err := api.makeRequest("PUT", fmt.Sprintf("/%s/%s", bucketName, key), value) | ||
return err | ||
} | ||
|
||
func (api *KVRestAPI) GetValue(bucketName, key string, target interface{}) error { | ||
respBody, err := api.makeRequest("GET", fmt.Sprintf("/%s/%s", bucketName, key), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = json.Unmarshal(respBody, target) | ||
return err | ||
} | ||
|
||
func (api *KVRestAPI) DeleteKeyValue(bucketName, key string) error { | ||
_, err := api.makeRequest("DELETE", fmt.Sprintf("/%s/%s", bucketName, key), nil) | ||
return err | ||
} | ||
|
||
func (api *KVRestAPI) ListKeys(bucketName string) ([]string, error) { | ||
respBody, err := api.makeRequest("GET", "/"+bucketName, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Assuming the response is a JSON array of keys | ||
var keysResponse KeyListResponse | ||
err = json.Unmarshal(respBody, &keysResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return keysResponse.Keys, nil | ||
} | ||
|
||
func main() { | ||
apiKey := "CHANGE-ME" // Replace with your actual API key | ||
api := NewKVRestAPI(apiKey) | ||
|
||
bucketName := "my-test-bucket-go" | ||
key := "my-key" | ||
value := map[string]string{"message": "Hello from Go!"} | ||
|
||
// Create a bucket | ||
err := api.CreateBucket(bucketName) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("Bucket '%s' created successfully.\n", bucketName) | ||
|
||
// Create a key-value pair | ||
err = api.CreateOrUpdateKeyValue(bucketName, key, value) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("Key-value pair created/updated for key '%s'.\n", key) | ||
|
||
// Retrieve the value | ||
var retrievedValue map[string]string | ||
err = api.GetValue(bucketName, key, &retrievedValue) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("Retrieved value for key '%s': %+v\n", key, retrievedValue) | ||
|
||
// List all buckets | ||
buckets, err := api.ListBuckets() | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("All buckets: %+v\n", buckets) | ||
|
||
// List keys in the bucket | ||
keys, err := api.ListKeys(bucketName) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("Keys in bucket '%s': %+v\n", bucketName, keys) | ||
|
||
// Delete the key-value pair | ||
err = api.DeleteKeyValue(bucketName, key) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("Key-value pair with key '%s' deleted.\n", key) | ||
|
||
// Delete the bucket | ||
err = api.DeleteBucket(bucketName) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf("Bucket '%s' deleted.\n", bucketName) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
## Python example | ||
|
||
1. Change you api key ```api_key = "CHANGE_ME"``` | ||
2. run ```python ./examples/python/main.py``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import requests | ||
|
||
class KVRestAPI: | ||
def __init__(self, api_key, base_url="https://kvrest.dev/api"): | ||
self.api_key = api_key | ||
self.base_url = base_url | ||
self.headers = {"API-KEY": self.api_key, "Content-Type": "application/json"} | ||
|
||
def _make_request(self, method, endpoint, json=None): | ||
url = f"{self.base_url}{endpoint}" | ||
response = requests.request(method, url, headers=self.headers, json=json) | ||
|
||
if response.status_code not in (200, 201): | ||
response.raise_for_status() # Raise an exception for bad status codes | ||
|
||
try: | ||
if response.text: # Check if response has content | ||
return response.json() | ||
else: | ||
return {} # Or return None, depending on how you want to handle it | ||
except ValueError as e: | ||
# Log the error and the raw response for debugging | ||
print(f"Error parsing JSON response: {e}, Raw Response: {response.text}") | ||
return None # Or raise the exception again if needed | ||
|
||
def create_bucket(self, bucket_name): | ||
"""Create a new bucket.""" | ||
endpoint = f"/{bucket_name}" | ||
self._make_request("PUT", endpoint) | ||
|
||
def delete_bucket(self, bucket_name): | ||
"""Delete an existing bucket.""" | ||
endpoint = f"/{bucket_name}" | ||
self._make_request("DELETE", endpoint) | ||
|
||
def list_buckets(self): | ||
"""List all buckets.""" | ||
endpoint = "/buckets" | ||
return self._make_request("POST", endpoint) | ||
|
||
def create_or_update_key_value(self, bucket_name, key, value): | ||
"""Create or update a key-value pair.""" | ||
endpoint = f"/{bucket_name}/{key}" | ||
self._make_request("PUT", endpoint, json=value) | ||
|
||
def get_value(self, bucket_name, key): | ||
"""Retrieve a value for a key.""" | ||
endpoint = f"/{bucket_name}/{key}" | ||
return self._make_request("GET", endpoint) | ||
|
||
def delete_key_value(self, bucket_name, key): | ||
"""Delete a key-value pair.""" | ||
endpoint = f"/{bucket_name}/{key}" | ||
self._make_request("DELETE", endpoint) | ||
|
||
def list_keys(self, bucket_name): | ||
"""List all keys in a bucket.""" | ||
endpoint = f"/{bucket_name}" | ||
return self._make_request("GET", endpoint) | ||
|
||
|
||
if __name__ == "__main__": | ||
api_key = "CHANGE_ME" # Replace with your actual API key | ||
api = KVRestAPI(api_key) | ||
|
||
# Example usage: | ||
try: | ||
bucket_name = "my-test-bucket" | ||
key = "my-key" | ||
value = {"message": "Hello from the API!"} | ||
|
||
# Create a bucket | ||
api.create_bucket(bucket_name) | ||
print(f"Bucket '{bucket_name}' created successfully.") | ||
|
||
# Create a key-value pair | ||
api.create_or_update_key_value(bucket_name, key, value) | ||
print(f"Key-value pair created/updated for key '{key}'.") | ||
|
||
# Retrieve the value | ||
retrieved_value = api.get_value(bucket_name, key) | ||
print(f"Retrieved value for key '{key}': {retrieved_value}") | ||
|
||
# List all buckets | ||
buckets = api.list_buckets() | ||
print(f"All buckets: {buckets}") | ||
|
||
# List keys in the bucket | ||
keys = api.list_keys(bucket_name) | ||
print(f"Keys in bucket '{bucket_name}': {keys}") | ||
|
||
# Delete the key-value pair | ||
api.delete_key_value(bucket_name, key) | ||
print(f"Key-value pair with key '{key}' deleted.") | ||
|
||
# Delete the bucket | ||
api.delete_bucket(bucket_name) | ||
print(f"Bucket '{bucket_name}' deleted.") | ||
|
||
except requests.exceptions.RequestException as e: | ||
print(f"An error occurred: {e}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.