or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdindex.mdproject-management.mdpython-api.mdutilities.md

python-api.mddocs/

0

# Python API

1

2

Core Python library functionality for programmatic access to OSF projects. The main entry point is the OSF class, which provides authentication and project access capabilities.

3

4

## Capabilities

5

6

### OSF Client Class

7

8

Main client class for interacting with the Open Science Framework. Handles authentication and provides access to projects.

9

10

```python { .api }

11

class OSF:

12

def __init__(self, username=None, password=None, token=None):

13

"""

14

Initialize OSF client with optional authentication.

15

16

Args:

17

username (str, optional): OSF username for basic authentication

18

password (str, optional): OSF password for basic authentication

19

token (str, optional): Personal Access Token for token authentication

20

21

Note:

22

Authentication is attempted during initialization. If it fails,

23

can_login property will be False but the client can still be used

24

for public projects.

25

"""

26

27

def login(self, username=None, password=None, token=None):

28

"""

29

Authenticate user for protected API calls.

30

31

Args:

32

username (str, optional): OSF username

33

password (str, optional): OSF password

34

token (str, optional): Personal Access Token

35

36

Raises:

37

OSFException: If no login details provided

38

39

Note:

40

Token authentication takes precedence over username/password if both provided.

41

"""

42

43

def project(self, project_id):

44

"""

45

Fetch project by project ID.

46

47

Args:

48

project_id (str): OSF project ID (GUID)

49

50

Returns:

51

Project: Project instance

52

53

Raises:

54

OSFException: If project ID is unrecognized type or not accessible

55

"""

56

57

def guid(self, guid):

58

"""

59

Determine JSONAPI type for provided GUID.

60

61

Args:

62

guid (str): OSF GUID

63

64

Returns:

65

str: JSONAPI type ('nodes', 'registrations', etc.)

66

"""

67

68

@property

69

def username(self):

70

"""

71

Get authenticated username.

72

73

Returns:

74

str or None: Username if using basic auth, None otherwise

75

"""

76

77

@property

78

def password(self):

79

"""

80

Get authenticated password.

81

82

Returns:

83

str or None: Password if using basic auth, None otherwise

84

"""

85

86

@property

87

def token(self):

88

"""

89

Get authentication token.

90

91

Returns:

92

str or None: Token if using token auth, None otherwise

93

"""

94

95

@property

96

def can_login(self):

97

"""

98

Check if authentication succeeded.

99

100

Returns:

101

bool: True if authentication was successful, False otherwise

102

"""

103

```

104

105

### Usage Examples

106

107

Basic authentication:

108

```python

109

from osfclient import OSF

110

111

# Token authentication (recommended)

112

osf = OSF(token='your_personal_access_token')

113

114

# Basic authentication

115

osf = OSF(username='user@example.com', password='password')

116

117

# Check if authentication worked

118

if osf.can_login:

119

print(f"Authenticated as: {osf.username or 'token user'}")

120

else:

121

print("Authentication failed, can only access public projects")

122

```

123

124

Working with projects:

125

```python

126

# Get a project

127

project_id = '9zpcy'

128

project = osf.project(project_id)

129

print(f"Project: {project.title}")

130

print(f"Description: {project.description}")

131

132

# Check project type

133

guid_type = osf.guid(project_id)

134

print(f"Project type: {guid_type}") # 'nodes' or 'registrations'

135

```

136

137

Environment-based authentication:

138

```python

139

import os

140

from osfclient import OSF

141

142

# Using environment variables

143

# Set OSF_TOKEN, OSF_USERNAME, OSF_PASSWORD environment variables

144

osf = OSF(

145

username=os.getenv('OSF_USERNAME'),

146

password=os.getenv('OSF_PASSWORD'),

147

token=os.getenv('OSF_TOKEN')

148

)

149

```

150

151

### Session Management

152

153

The OSF class uses OSFSession internally for HTTP operations with built-in rate limiting and authentication handling. OSFSession extends requests.Session with OSF-specific configuration.

154

155

```python { .api }

156

class OSFSession:

157

def __init__(self):

158

"""

159

Handle HTTP session related work with OSF-specific configuration.

160

161

Automatically configures OSF API headers and base URL.

162

Inherits from requests.Session for full HTTP functionality.

163

"""

164

165

def basic_auth(self, username, password):

166

"""

167

Configure basic authentication.

168

169

Args:

170

username (str): OSF username

171

password (str): OSF password

172

173

Note:

174

Removes any existing Authorization header and stores credentials

175

for HTTP basic authentication. Mutually exclusive with token auth.

176

"""

177

178

def token_auth(self, token):

179

"""

180

Configure token authentication.

181

182

Args:

183

token (str): Personal Access Token

184

185

Note:

186

Sets Authorization: Bearer header and stores token.

187

Takes precedence over basic authentication.

188

"""

189

190

def get(self, url, *args, **kwargs):

191

"""

192

Rate-limited GET request with automatic 401 error handling.

193

194

Args:

195

url (str): Request URL

196

*args, **kwargs: Passed to requests.Session.get()

197

198

Returns:

199

requests.Response: HTTP response object

200

201

Raises:

202

UnauthorizedException: If response status is 401

203

204

Note:

205

Rate limited to 1 request per second.

206

"""

207

208

def put(self, url, *args, **kwargs):

209

"""

210

Rate-limited PUT request with automatic 401 error handling.

211

212

Args:

213

url (str): Request URL

214

*args, **kwargs: Passed to requests.Session.put()

215

216

Returns:

217

requests.Response: HTTP response object

218

219

Raises:

220

UnauthorizedException: If response status is 401

221

222

Note:

223

Rate limited to 1 request per second.

224

"""

225

226

def patch(self, url, *args, **kwargs):

227

"""

228

PATCH request with automatic 401 error handling.

229

230

Args:

231

url (str): Request URL

232

*args, **kwargs: Passed to requests.Session.patch()

233

234

Returns:

235

requests.Response: HTTP response object

236

237

Raises:

238

UnauthorizedException: If response status is 401

239

"""

240

241

def delete(self, url, *args, **kwargs):

242

"""

243

DELETE request with automatic 401 error handling.

244

245

Args:

246

url (str): Request URL

247

*args, **kwargs: Passed to requests.Session.delete()

248

249

Returns:

250

requests.Response: HTTP response object

251

252

Raises:

253

UnauthorizedException: If response status is 401

254

"""

255

256

def build_url(self, *args):

257

"""

258

Build OSF API URLs with canonical trailing slash.

259

260

Args:

261

*args: URL path components

262

263

Returns:

264

str: Complete OSF API URL ending with '/'

265

266

Example:

267

build_url('nodes', 'abc123', 'files')

268

# Returns: 'https://api.osf.io/v2/nodes/abc123/files/'

269

"""

270

271

@property

272

def base_url(self):

273

"""

274

OSF API base URL.

275

276

Returns:

277

str: 'https://api.osf.io/v2/'

278

"""

279

280

@property

281

def auth(self):

282

"""

283

Basic authentication credentials.

284

285

Returns:

286

tuple or None: (username, password) if basic auth configured, None otherwise

287

"""

288

289

@property

290

def token(self):

291

"""

292

Authentication token.

293

294

Returns:

295

str or None: Personal Access Token if token auth configured, None otherwise

296

"""

297

298

@property

299

def last_request(self):

300

"""

301

Timestamp of last HTTP request for rate limiting.

302

303

Returns:

304

float or None: Unix timestamp of last request, None if no requests made

305

"""

306

307

@property

308

def headers(self):

309

"""

310

Default HTTP headers for OSF API requests.

311

312

Returns:

313

dict: Headers including Accept, Content-Type, User-Agent, and Authorization

314

315

Note:

316

Automatically configured with OSF-specific headers:

317

- Accept: application/vnd.api+json

318

- Accept-Charset: utf-8

319

- Content-Type: application/json

320

- User-Agent: osfclient v{version}

321

- Authorization: Bearer {token} (if token auth configured)

322

"""

323

```

324

325

Advanced session usage:

326

```python

327

from osfclient.models import OSFSession

328

from osfclient.exceptions import UnauthorizedException

329

330

# Custom session configuration

331

session = OSFSession()

332

session.token_auth('your_token')

333

334

# Build custom URLs

335

url = session.build_url('nodes', 'project_id', 'files')

336

# Returns: 'https://api.osf.io/v2/nodes/project_id/files/'

337

338

# Direct HTTP operations with rate limiting and error handling

339

try:

340

response = session.get(url)

341

data = response.json()

342

print(f"Found {len(data['data'])} files")

343

except UnauthorizedException:

344

print("Authentication required or token expired")

345

346

# Check session state

347

print(f"Using token auth: {session.token is not None}")

348

print(f"Using basic auth: {session.auth is not None}")

349

print(f"Base URL: {session.base_url}")

350

351

# Access default headers

352

headers = session.headers

353

print(f"User-Agent: {headers.get('User-Agent')}")

354

print(f"Accept: {headers.get('Accept')}")

355

```

356

357

### Rate Limiting and Error Handling

358

359

OSFSession implements automatic rate limiting (1 request per second) and consistent error handling:

360

361

```python

362

import time

363

from osfclient.models import OSFSession

364

365

session = OSFSession()

366

session.token_auth('your_token')

367

368

# Rate limiting example

369

start_time = time.time()

370

response1 = session.get('https://api.osf.io/v2/nodes/project_id/')

371

response2 = session.get('https://api.osf.io/v2/nodes/project_id/files/')

372

elapsed = time.time() - start_time

373

374

# Second request automatically delayed to respect rate limit

375

print(f"Two requests took {elapsed:.2f} seconds (min 1.0s due to rate limiting)")

376

377

# Automatic 401 error handling

378

try:

379

session.basic_auth('invalid', 'credentials')

380

response = session.get('https://api.osf.io/v2/nodes/private_project/')

381

except UnauthorizedException as e:

382

print(f"Authentication failed: {e}")

383

# Session automatically handles 401 responses

384

```