Skip to content

Commit ce14d26

Browse files
Add storage examples
Co-authored-by: Danil Krox <deferred@users.noreply.github.com>
1 parent fbd6399 commit ce14d26

7 files changed

Lines changed: 974 additions & 0 deletions

File tree

examples/storage/README.md

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
# Gcore Storage SDK Examples
2+
3+
This directory contains comprehensive examples demonstrating how to use the Gcore Storage SDK for Python. The examples cover both S3-compatible object storage and SFTP file transfer storage types.
4+
5+
## Directory Structure
6+
7+
The examples are organized into separate files, each with sync and async versions:
8+
9+
```
10+
examples/storage/
11+
├── basic.py # Sync: Basic storage operations
12+
├── basic_async.py # Async: Basic storage operations
13+
├── s3_buckets.py # Sync: S3 bucket management
14+
├── s3_buckets_async.py # Async: S3 bucket management
15+
├── credentials.py # Sync: Credential management
16+
├── credentials_async.py # Async: Credential management
17+
└── README.md # This file
18+
```
19+
20+
## Available Examples
21+
22+
### 1. Basic Operations (`basic.py` / `basic_async.py`)
23+
24+
Demonstrates fundamental storage operations:
25+
- Creating S3 and SFTP storage instances
26+
- Listing existing storages
27+
- Retrieving storage details
28+
- Updating storage configuration (expiration, server alias)
29+
- Deleting storage instances
30+
31+
**Run the sync example:**
32+
```bash
33+
python examples/storage/basic.py
34+
```
35+
36+
**Run the async example:**
37+
```bash
38+
python examples/storage/basic_async.py
39+
```
40+
41+
**Key Features Demonstrated:**
42+
- Storage creation with different types and locations
43+
- Storage lifecycle management
44+
- Error handling
45+
- Proper credential display at creation time
46+
47+
### 2. S3 Bucket Management (`s3_buckets.py` / `s3_buckets_async.py`)
48+
49+
Comprehensive S3 bucket operations:
50+
- Creating S3 storage instances
51+
- Waiting for storage provisioning
52+
- Creating and managing S3 buckets
53+
- Setting bucket lifecycle policies
54+
- Configuring CORS (Cross-Origin Resource Sharing)
55+
- Managing bucket access policies
56+
- Deleting buckets and cleanup
57+
58+
**Run the sync example:**
59+
```bash
60+
python examples/storage/s3_buckets.py
61+
```
62+
63+
**Run the async example:**
64+
```bash
65+
python examples/storage/s3_buckets_async.py
66+
```
67+
68+
**Key Features Demonstrated:**
69+
- Multiple bucket creation and management
70+
- Lifecycle policy configuration (object expiration)
71+
- CORS policy setup for web applications
72+
- Bucket access policy management (public/private access)
73+
- Proper resource cleanup
74+
75+
### 3. Credentials Management (`credentials.py` / `credentials_async.py`)
76+
77+
Advanced credential management operations:
78+
- S3 access key regeneration
79+
- SFTP password management (generate, set custom, remove)
80+
- Credential security best practices
81+
- Managing multiple storage types simultaneously
82+
83+
**Run the sync example:**
84+
```bash
85+
python examples/storage/credentials.py
86+
```
87+
88+
**Run the async example:**
89+
```bash
90+
python examples/storage/credentials_async.py
91+
```
92+
93+
**Key Features Demonstrated:**
94+
- S3 access and secret key regeneration
95+
- SFTP password lifecycle management
96+
- Disabling/enabling password authentication
97+
- Handling multiple storages in a single example
98+
99+
## Storage Types
100+
101+
### S3-Compatible Storage
102+
103+
Gcore's S3-compatible storage provides:
104+
- **Object Storage**: Store and retrieve files via S3 API
105+
- **Bucket Management**: Create, configure, and manage buckets
106+
- **Access Control**: Set bucket policies and CORS configurations
107+
- **Lifecycle Policies**: Automatic object expiration and cleanup
108+
- **API Compatibility**: Works with existing S3 SDKs and tools
109+
110+
**Use Cases:**
111+
- Web application file storage
112+
- Backup and archival
113+
- Static website hosting
114+
- Content distribution
115+
116+
### SFTP Storage
117+
118+
Gcore's SFTP storage provides:
119+
- **File Transfer**: Standard SFTP protocol for file operations
120+
- **Authentication**: Password and SSH key-based authentication
121+
- **Directory Structure**: Traditional filesystem hierarchy
122+
- **Secure Transfer**: Encrypted file transfers
123+
124+
**Use Cases:**
125+
- Legacy application integration
126+
- Secure file transfers
127+
- Automated backup systems
128+
- FTP replacement
129+
130+
## Configuration
131+
132+
The examples require a Gcore API key to authenticate. Set the `GCORE_API_KEY` environment variable before running any example:
133+
134+
**Linux/macOS:**
135+
```bash
136+
export GCORE_API_KEY=your_api_key_here
137+
```
138+
139+
**Windows (Command Prompt):**
140+
```cmd
141+
set GCORE_API_KEY=your_api_key_here
142+
```
143+
144+
**Windows (PowerShell):**
145+
```powershell
146+
$env:GCORE_API_KEY="your_api_key_here"
147+
```
148+
149+
Alternatively, you can create a `.env` file in the project root with:
150+
```
151+
GCORE_API_KEY=your_api_key_here
152+
```
153+
154+
And load it before running examples (Linux/macOS):
155+
```bash
156+
export $(cat .env | xargs)
157+
```
158+
159+
## Geographic Locations
160+
161+
The examples use specific locations based on storage type:
162+
- **S3 storage**: "s-ed1" (Luxembourg) - supports S3-compatible object storage
163+
- **SFTP storage**: "ams" (Amsterdam) - supports SFTP file transfer
164+
165+
You can change these to any available location that supports your desired storage type. To see available locations, use:
166+
167+
```python
168+
from gcore import Gcore
169+
170+
client = Gcore()
171+
locations = client.storage.locations.list()
172+
for location in locations:
173+
print(f"{location.code}: {location.name}")
174+
```
175+
176+
## Code Structure
177+
178+
Each example follows a consistent pattern:
179+
180+
- **Main Function**: Orchestrates the example flow by calling individual operation functions
181+
- **Operation Functions**: Each function handles a complete operation (create, list, update, delete, etc.)
182+
- **Keyword-Only Arguments**: All operation functions use keyword-only parameters for clarity
183+
- **Error Handling**: Appropriate error handling and user feedback
184+
- **Printed Output**: Clear section headers and descriptive output for each operation
185+
186+
### Sync vs Async Examples
187+
188+
The SDK provides both synchronous and asynchronous APIs:
189+
190+
**Sync (`Gcore`):**
191+
- Uses `from gcore import Gcore`
192+
- Straightforward, blocking operations
193+
- Easier to understand and debug
194+
- Best for scripts and simple applications
195+
196+
**Async (`AsyncGcore`):**
197+
- Uses `from gcore import AsyncGcore`
198+
- Non-blocking, concurrent operations
199+
- Requires `async`/`await` syntax
200+
- Best for high-performance applications
201+
- Main function uses `asyncio.run(main())`
202+
- Iteration uses `async for` instead of regular `for`
203+
204+
## Troubleshooting
205+
206+
### Common Issues
207+
208+
1. **Storage Creation Failures**
209+
- Check if location is valid and available
210+
- Verify storage name is unique and follows naming rules (letters, numbers, dashes, underscores)
211+
- Ensure API key has proper permissions
212+
213+
2. **Bucket Operation Errors**
214+
- Ensure storage is S3-compatible (not SFTP)
215+
- Wait for storage to be fully provisioned before bucket operations (status should be "ok")
216+
- Bucket names must be unique and follow S3 naming conventions
217+
218+
3. **Authentication Issues**
219+
- Verify GCORE_API_KEY environment variable is set
220+
- Check that API key is valid and not expired
221+
- Ensure API key has permissions for storage operations
222+
223+
4. **Provisioning Timeouts**
224+
- Storage provisioning can take time, especially for new accounts
225+
- The examples include a 30-second wait with 2-second intervals
226+
- If provisioning takes longer, increase max_wait in wait_for_storage_provisioning()
227+
228+
### Getting Help
229+
230+
- Check the [Gcore API Documentation](https://gcore.com/docs/api-reference/storage)
231+
- Review error messages for specific guidance
232+
- Ensure you're using the latest SDK version: `pip install --upgrade gcore`
233+
234+
## Testing on Real Infrastructure
235+
236+
All examples are designed to run on real Gcore infrastructure. They:
237+
- Create real resources (storages, buckets)
238+
- Perform actual API operations
239+
- Include cleanup functions to delete created resources
240+
- Handle errors gracefully to prevent resource leaks
241+
242+
**Important**: Resources created by these examples will incur charges according to your Gcore pricing plan. Always ensure cleanup functions execute successfully to avoid unexpected costs.
243+
244+
## Credentials Security
245+
246+
- Credentials (S3 keys, SFTP passwords) are only visible at creation time and during regeneration operations
247+
- Never commit credentials to version control
248+
- Store credentials securely (e.g., environment variables, secret managers)
249+
- Rotate credentials regularly for security
250+
- Use SSH keys instead of passwords for SFTP when possible
251+
252+
## Python Version
253+
254+
These examples require Python 3.8 or higher, as specified by the SDK requirements.

examples/storage/basic.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import time
2+
3+
from gcore import Gcore
4+
5+
6+
def main() -> None:
7+
# TODO set API key before running
8+
# api_key = os.environ["GCORE_API_KEY"]
9+
10+
gcore = Gcore(
11+
# No need to explicitly pass to Gcore constructor if using environment variables
12+
# api_key=api_key,
13+
)
14+
15+
storage_id = create_storage(client=gcore)
16+
list_storages(client=gcore)
17+
get_storage(client=gcore, storage_id=storage_id)
18+
update_storage(client=gcore, storage_id=storage_id)
19+
delete_storage(client=gcore, storage_id=storage_id)
20+
21+
22+
def create_storage(*, client: Gcore) -> int:
23+
print("\n=== CREATE STORAGE ===")
24+
name = f"example-s3-storage-{int(time.time())}"
25+
storage = client.storage.create(
26+
name=name,
27+
type="s3",
28+
location="s-ed1",
29+
)
30+
print(f"Created Storage: ID={storage.id}, Name={storage.name}, Type={storage.type}, Location={storage.location}")
31+
print(f"Storage address: {storage.address}")
32+
print(f"S3 Access Key: {storage.credentials.s3.access_key}") # type: ignore[union-attr]
33+
print(f"S3 Secret Key: {storage.credentials.s3.secret_key}") # type: ignore[union-attr]
34+
print("======================")
35+
return storage.id
36+
37+
38+
def list_storages(*, client: Gcore) -> None:
39+
print("\n=== LIST STORAGES ===")
40+
storages = client.storage.list()
41+
for count, storage in enumerate(storages, 1):
42+
print(
43+
f" {count}. Storage: ID={storage.id}, Name={storage.name}, Type={storage.type}, Location={storage.location}, Status={storage.provisioning_status}"
44+
)
45+
print("=====================")
46+
47+
48+
def get_storage(*, client: Gcore, storage_id: int) -> None:
49+
print("\n=== GET STORAGE ===")
50+
storage = client.storage.get(storage_id=storage_id)
51+
print(
52+
f"Storage: ID={storage.id}, Name={storage.name}, Type={storage.type}, Location={storage.location}, Status={storage.provisioning_status}"
53+
)
54+
print(f"Address: {storage.address}, Created: {storage.created_at}, Can Restore: {storage.can_restore}")
55+
print("===================")
56+
57+
58+
def update_storage(*, client: Gcore, storage_id: int) -> None:
59+
print("\n=== UPDATE STORAGE ===")
60+
storage = client.storage.update(
61+
storage_id=storage_id,
62+
expires="30 days",
63+
)
64+
print(f"Updated Storage: ID={storage.id}, Expires: {storage.expires}")
65+
print("======================")
66+
67+
68+
def delete_storage(*, client: Gcore, storage_id: int) -> None:
69+
print("\n=== DELETE STORAGE ===")
70+
client.storage.delete(storage_id=storage_id)
71+
print(f"Storage {storage_id} deleted successfully")
72+
print("======================")
73+
74+
75+
if __name__ == "__main__":
76+
main()

0 commit comments

Comments
 (0)